Skip to content

Commit f4f143c

Browse files
authored
fix: restore helper subpath exports (#402)
* fix: restore helper subpath exports * fix: polish helper subpath typings
1 parent b0f52a9 commit f4f143c

File tree

11 files changed

+256
-0
lines changed

11 files changed

+256
-0
lines changed

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
"import": "./dist/src/index.js",
1313
"types": "./dist/src/index.d.ts"
1414
},
15+
"./artifacts": {
16+
"import": "./dist/src/artifacts.js",
17+
"types": "./dist/src/artifacts.d.ts"
18+
},
1519
"./metro": {
1620
"import": "./dist/src/metro.js",
1721
"types": "./dist/src/metro.d.ts"
@@ -20,9 +24,21 @@
2024
"import": "./dist/src/remote-config.js",
2125
"types": "./dist/src/remote-config.d.ts"
2226
},
27+
"./install-source": {
28+
"import": "./dist/src/install-source.js",
29+
"types": "./dist/src/install-source.d.ts"
30+
},
2331
"./contracts": {
2432
"import": "./dist/src/contracts.js",
2533
"types": "./dist/src/contracts.d.ts"
34+
},
35+
"./selectors": {
36+
"import": "./dist/src/selectors.js",
37+
"types": "./dist/src/selectors.d.ts"
38+
},
39+
"./finders": {
40+
"import": "./dist/src/finders.js",
41+
"types": "./dist/src/finders.d.ts"
2642
}
2743
},
2844
"engines": {

rslib.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ export default defineConfig({
1717
source: {
1818
entry: {
1919
index: 'src/index.ts',
20+
artifacts: 'src/artifacts.ts',
2021
metro: 'src/metro.ts',
2122
'remote-config': 'src/remote-config.ts',
23+
'install-source': 'src/install-source.ts',
2224
contracts: 'src/contracts.ts',
25+
selectors: 'src/selectors.ts',
26+
finders: 'src/finders.ts',
2327
},
2428
tsconfigPath: 'tsconfig.lib.json',
2529
},
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import assert from 'node:assert/strict';
2+
import { test } from 'vitest';
3+
4+
import { resolveAndroidArchivePackageName } from '../artifacts.ts';
5+
6+
const resolver: (archivePath: string) => Promise<string | undefined> =
7+
resolveAndroidArchivePackageName;
8+
9+
test('package subpath exports android archive package resolver', () => {
10+
assert.equal(typeof resolver, 'function');
11+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import assert from 'node:assert/strict';
2+
import { test } from 'vitest';
3+
import {
4+
findBestMatchesByLocator,
5+
normalizeRole,
6+
normalizeText,
7+
parseFindArgs,
8+
} from '../finders.ts';
9+
import type { SnapshotNode } from '../utils/snapshot.ts';
10+
11+
function makeNode(ref: string, label?: string): SnapshotNode {
12+
return {
13+
index: Number(ref.replace('e', '')) || 0,
14+
ref,
15+
type: 'XCUIElementTypeButton',
16+
label,
17+
};
18+
}
19+
20+
test('public finders entrypoint re-exports pure helpers', () => {
21+
const nodes: SnapshotNode[] = [makeNode('e1', 'Continue')];
22+
23+
const parsed = parseFindArgs(['label', 'Continue', 'click']);
24+
const best = findBestMatchesByLocator(nodes, 'label', 'Continue');
25+
const requireRectLegacy = findBestMatchesByLocator(nodes, 'label', 'Continue', true);
26+
const requireRectOptions = findBestMatchesByLocator(nodes, 'label', 'Continue', {
27+
requireRect: true,
28+
});
29+
30+
assert.equal(normalizeText(' Continue\nNow '), 'continue now');
31+
assert.equal(normalizeRole('XCUIElementTypeApplication.XCUIElementTypeButton'), 'button');
32+
assert.equal(parsed.action, 'click');
33+
assert.equal(best.matches.length, 1);
34+
assert.equal(requireRectLegacy.matches.length, 0);
35+
assert.equal(requireRectOptions.matches.length, 0);
36+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import assert from 'node:assert/strict';
2+
import { test } from 'vitest';
3+
4+
import {
5+
ARCHIVE_EXTENSIONS,
6+
isTrustedInstallSourceUrl,
7+
materializeInstallablePath,
8+
validateDownloadSourceUrl,
9+
} from '../install-source.ts';
10+
11+
test('public install-source entrypoint re-exports pure helpers', () => {
12+
assert.deepEqual(ARCHIVE_EXTENSIONS, ['.zip', '.tar', '.tar.gz', '.tgz']);
13+
assert.equal(
14+
isTrustedInstallSourceUrl('https://api.github.com/repos/acme/app/actions/artifacts/1/zip'),
15+
true,
16+
);
17+
assert.equal(typeof materializeInstallablePath, 'function');
18+
assert.equal(typeof validateDownloadSourceUrl, 'function');
19+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import assert from 'node:assert/strict';
2+
import { test } from 'vitest';
3+
import {
4+
findSelectorChainMatch,
5+
formatSelectorFailure,
6+
isNodeEditable,
7+
isNodeVisible,
8+
isSelectorToken,
9+
parseSelectorChain,
10+
resolveSelectorChain,
11+
tryParseSelectorChain,
12+
type Selector,
13+
type SelectorChain,
14+
type SelectorDiagnostics,
15+
type SelectorResolution,
16+
} from '../selectors.ts';
17+
import type { SnapshotNode } from '../utils/snapshot.ts';
18+
19+
const nodes: SnapshotNode[] = [
20+
{
21+
ref: 'e1',
22+
index: 0,
23+
type: 'android.widget.Button',
24+
label: 'Continue',
25+
rect: { x: 0, y: 0, width: 120, height: 48 },
26+
enabled: true,
27+
},
28+
{
29+
ref: 'e2',
30+
index: 1,
31+
type: 'android.widget.EditText',
32+
label: 'Email',
33+
rect: { x: 0, y: 64, width: 200, height: 48 },
34+
enabled: true,
35+
},
36+
];
37+
38+
test('public selector subpath exposes platform-aware matching helpers', () => {
39+
const chain: SelectorChain = parseSelectorChain('role=button label="Continue" visible=true');
40+
const firstSelector: Selector = chain.selectors[0];
41+
assert.equal(firstSelector.raw, 'role=button label="Continue" visible=true');
42+
assert.equal(tryParseSelectorChain(chain.raw)?.raw, chain.raw);
43+
assert.equal(isSelectorToken('visible=true'), true);
44+
45+
const match = findSelectorChainMatch(nodes, chain, {
46+
platform: 'android',
47+
requireRect: true,
48+
});
49+
assert.ok(match);
50+
assert.equal(match.matches, 1);
51+
52+
const resolved: SelectorResolution | null = resolveSelectorChain(nodes, chain, {
53+
platform: 'android',
54+
requireRect: true,
55+
});
56+
assert.equal(resolved?.node.ref, 'e1');
57+
58+
assert.equal(isNodeVisible(nodes[0]), true);
59+
assert.equal(isNodeEditable(nodes[1], 'android'), true);
60+
});
61+
62+
test('public selector diagnostics format failures', () => {
63+
const chain = parseSelectorChain('label=Missing');
64+
const diagnostics: SelectorDiagnostics[] = [{ selector: 'label=Missing', matches: 0 }];
65+
66+
assert.equal(
67+
formatSelectorFailure(chain, diagnostics, { unique: false }),
68+
'Selector did not match (label=Missing -> 0)',
69+
);
70+
});

src/artifacts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { resolveAndroidArchivePackageName } from './platforms/android/manifest.ts';

src/finders.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export type { FindLocator } from './utils/finders.ts';
2+
export type { SnapshotNode } from './utils/snapshot.ts';
3+
export { normalizeRole, normalizeText, parseFindArgs } from './utils/finders.ts';
4+
5+
import {
6+
findBestMatchesByLocator as findBestMatchesByLocatorInternal,
7+
type FindLocator,
8+
} from './utils/finders.ts';
9+
import type { SnapshotNode } from './utils/snapshot.ts';
10+
11+
export type FindMatchOptions = {
12+
requireRect?: boolean;
13+
};
14+
15+
export function findBestMatchesByLocator(
16+
nodes: SnapshotNode[],
17+
locator: FindLocator,
18+
query: string,
19+
options?: boolean | FindMatchOptions,
20+
) {
21+
const matchOptions = typeof options === 'boolean' ? { requireRect: options } : options;
22+
return findBestMatchesByLocatorInternal(nodes, locator, query, matchOptions);
23+
}

src/install-source.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export {
2+
ARCHIVE_EXTENSIONS,
3+
isBlockedIpAddress,
4+
isBlockedSourceHostname,
5+
isTrustedInstallSourceUrl,
6+
materializeInstallablePath,
7+
validateDownloadSourceUrl,
8+
} from './platforms/install-source.ts';
9+
10+
export type {
11+
MaterializeInstallSource,
12+
MaterializedInstallable,
13+
} from './platforms/install-source.ts';

src/selectors.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export type {
2+
Selector,
3+
SelectorChain,
4+
SelectorDiagnostics,
5+
SelectorResolution,
6+
} from './daemon/selectors.ts';
7+
export type { SnapshotNode } from './utils/snapshot.ts';
8+
9+
export {
10+
findSelectorChainMatch,
11+
formatSelectorFailure,
12+
isNodeEditable,
13+
isNodeVisible,
14+
isSelectorToken,
15+
parseSelectorChain,
16+
resolveSelectorChain,
17+
tryParseSelectorChain,
18+
} from './daemon/selectors.ts';

0 commit comments

Comments
 (0)