@vmz/test 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-protocol.js +12 -13
- package/dist/browser-serve.d.ts +1 -1
- package/dist/browser-serve.js +19 -1
- package/dist/browser.js +16 -4
- package/package.json +3 -3
package/dist/browser-protocol.js
CHANGED
|
@@ -11,9 +11,7 @@ export const BROWSER_LOCATOR_KINDS = Object.freeze(['role', 'label', 'text', 'te
|
|
|
11
11
|
*/
|
|
12
12
|
export function parseActionLocator(action) {
|
|
13
13
|
const warnings = [];
|
|
14
|
-
const loc = action && typeof action.locator === 'object' && action.locator
|
|
15
|
-
? action.locator
|
|
16
|
-
: null;
|
|
14
|
+
const loc = action && typeof action.locator === 'object' && action.locator ? action.locator : null;
|
|
17
15
|
if (loc) {
|
|
18
16
|
const kind = String(loc.kind || '');
|
|
19
17
|
if (kind === 'role') {
|
|
@@ -75,18 +73,21 @@ export function resolveLocatorInPage(locator, opts = {}) {
|
|
|
75
73
|
const root = document.getElementById('app') || document.body;
|
|
76
74
|
if (!root)
|
|
77
75
|
return { ok: false, count: 0, actionable: false, reason: '#app missing', index: -1 };
|
|
78
|
-
const normalize = (s) => String(s || '')
|
|
76
|
+
const normalize = (s) => String(s || '')
|
|
77
|
+
.replace(/\s+/g, ' ')
|
|
78
|
+
.trim();
|
|
79
79
|
const nameOf = (el) => {
|
|
80
80
|
const labelled = el.getAttribute('aria-label');
|
|
81
81
|
if (labelled)
|
|
82
82
|
return normalize(labelled);
|
|
83
|
+
const id = el.id;
|
|
84
|
+
if (id) {
|
|
85
|
+
const lab = root.querySelector(`label[for="${CSS.escape(id)}"]`);
|
|
86
|
+
if (lab)
|
|
87
|
+
return normalize(lab.textContent || '');
|
|
88
|
+
}
|
|
83
89
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
84
|
-
|
|
85
|
-
if (id) {
|
|
86
|
-
const lab = root.querySelector(`label[for="${CSS.escape(id)}"]`);
|
|
87
|
-
if (lab)
|
|
88
|
-
return normalize(lab.textContent || '');
|
|
89
|
-
}
|
|
90
|
+
// already covered by id+for above; keep text fallback below
|
|
90
91
|
}
|
|
91
92
|
return normalize(el.innerText || el.textContent || '');
|
|
92
93
|
};
|
|
@@ -165,9 +166,7 @@ export function resolveLocatorInPage(locator, opts = {}) {
|
|
|
165
166
|
found = pool.filter((el) => {
|
|
166
167
|
const n = nameOf(el);
|
|
167
168
|
const optVal = el.getAttribute('data-vmz-option') || (el instanceof HTMLOptionElement ? el.value : '');
|
|
168
|
-
return locator.exact
|
|
169
|
-
? n === want || optVal === want
|
|
170
|
-
: n.includes(want) || String(optVal).includes(want);
|
|
169
|
+
return locator.exact ? n === want || optVal === want : n.includes(want) || String(optVal).includes(want);
|
|
171
170
|
});
|
|
172
171
|
}
|
|
173
172
|
else {
|
package/dist/browser-serve.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type ServeHostHandle = {
|
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* Resolve author RouteId / pathPattern to a pathname for page.goto.
|
|
11
|
-
* Prefers explicit path; then
|
|
11
|
+
* Prefers explicit path; then `vmz-deployment.json` pathPattern; then CDN / realization.
|
|
12
12
|
*/
|
|
13
13
|
export declare function resolveRoutePath(outDir: string, opts: {
|
|
14
14
|
routeId?: string;
|
package/dist/browser-serve.js
CHANGED
|
@@ -23,7 +23,7 @@ function freePort() {
|
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Resolve author RouteId / pathPattern to a pathname for page.goto.
|
|
26
|
-
* Prefers explicit path; then
|
|
26
|
+
* Prefers explicit path; then `vmz-deployment.json` pathPattern; then CDN / realization.
|
|
27
27
|
*/
|
|
28
28
|
export function resolveRoutePath(outDir, opts) {
|
|
29
29
|
if (typeof opts.path === 'string' && opts.path.trim()) {
|
|
@@ -32,6 +32,24 @@ export function resolveRoutePath(outDir, opts) {
|
|
|
32
32
|
const routeId = String(opts.routeId || '').trim();
|
|
33
33
|
if (!routeId)
|
|
34
34
|
throw new Error('open/navigate: routeId or path required');
|
|
35
|
+
const depPath = path.join(outDir, 'vmz-deployment.json');
|
|
36
|
+
if (fs.existsSync(depPath)) {
|
|
37
|
+
try {
|
|
38
|
+
const dep = JSON.parse(fs.readFileSync(depPath, 'utf8'));
|
|
39
|
+
const units = Array.isArray(dep.units) ? dep.units : [];
|
|
40
|
+
const pages = units.filter((u) => u.kind === 'page');
|
|
41
|
+
const hit = pages.find((u) => u.routeId === routeId) ||
|
|
42
|
+
pages.find((u) => u.chunkId === routeId) ||
|
|
43
|
+
pages.find((u) => u.chunkId === `pages/${routeId}`) ||
|
|
44
|
+
pages.find((u) => String(u.chunkId || '').endsWith(`/${routeId}`));
|
|
45
|
+
const pattern = String(hit?.pathPattern || '').trim();
|
|
46
|
+
if (pattern)
|
|
47
|
+
return applyParams(pattern, opts.params);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* fall through */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
35
53
|
const cdnPath = path.join(outDir, '_vmz', 'cdn-policy-manifest.json');
|
|
36
54
|
if (fs.existsSync(cdnPath)) {
|
|
37
55
|
try {
|
package/dist/browser.js
CHANGED
|
@@ -17,7 +17,7 @@ import net from 'node:net';
|
|
|
17
17
|
import os from 'node:os';
|
|
18
18
|
import path from 'node:path';
|
|
19
19
|
import { resolveChunkArtifacts } from './compile.js';
|
|
20
|
-
import { createArtifactsDir, writeFailureEvidence, writeTimingOnly
|
|
20
|
+
import { createArtifactsDir, writeFailureEvidence, writeTimingOnly } from './browser-evidence.js';
|
|
21
21
|
import { isServeHostManifest, resolveRoutePath, startServeHost } from './browser-serve.js';
|
|
22
22
|
import { defaultClickLocator, parseActionLocator, resolveLocatorInPage, sleep, } from './browser-protocol.js';
|
|
23
23
|
const MIME = {
|
|
@@ -977,8 +977,7 @@ async function fillTarget(page, value) {
|
|
|
977
977
|
}
|
|
978
978
|
async function pressTarget(page, key) {
|
|
979
979
|
const ok = await page.evaluate((k) => {
|
|
980
|
-
const el = document.querySelector('[data-vmz-bh-target="1"]') ||
|
|
981
|
-
document.activeElement;
|
|
980
|
+
const el = document.querySelector('[data-vmz-bh-target="1"]') || document.activeElement;
|
|
982
981
|
if (!el)
|
|
983
982
|
return false;
|
|
984
983
|
el.dispatchEvent(new KeyboardEvent('keydown', { key: String(k), bubbles: true }));
|
|
@@ -998,6 +997,7 @@ async function pageText(page) {
|
|
|
998
997
|
}
|
|
999
998
|
/**
|
|
1000
999
|
* Native <select> or listbox/combobox (data-vmz-option / role=option).
|
|
1000
|
+
* Prefer option value (data-vmz-option) then accessible name/label.
|
|
1001
1001
|
*/
|
|
1002
1002
|
async function selectTarget(page, value, opts = {}) {
|
|
1003
1003
|
const want = String(value ?? '');
|
|
@@ -1015,7 +1015,9 @@ async function selectTarget(page, value, opts = {}) {
|
|
|
1015
1015
|
return { ok: true, kind: 'native' };
|
|
1016
1016
|
}
|
|
1017
1017
|
// Custom combobox/listbox: open if needed, then click option.
|
|
1018
|
-
el.
|
|
1018
|
+
const expanded = el.getAttribute('aria-expanded');
|
|
1019
|
+
if (expanded !== 'true')
|
|
1020
|
+
el.click();
|
|
1019
1021
|
return { ok: true, kind: 'custom' };
|
|
1020
1022
|
}, want);
|
|
1021
1023
|
if (!native || !native.ok) {
|
|
@@ -1023,6 +1025,16 @@ async function selectTarget(page, value, opts = {}) {
|
|
|
1023
1025
|
}
|
|
1024
1026
|
if (native.kind === 'native')
|
|
1025
1027
|
return;
|
|
1028
|
+
// Prefer stable option value contract, then accessible name.
|
|
1029
|
+
const byValue = { kind: 'css', selector: `[data-vmz-option="${want.replace(/"/g, '\\"')}"]` };
|
|
1030
|
+
try {
|
|
1031
|
+
await waitForLocator(page, byValue, opts);
|
|
1032
|
+
await clickTarget(page);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
catch {
|
|
1036
|
+
/* fall through to role=option name */
|
|
1037
|
+
}
|
|
1026
1038
|
const optionLocator = { kind: 'role', role: 'option', name: want };
|
|
1027
1039
|
await waitForLocator(page, optionLocator, opts);
|
|
1028
1040
|
await clickTarget(page);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vmz/test",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "VMZ native test protocol + Compile/Logic/Browser/SSR/Resume/Deployment hosts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"build": "tsc -p tsconfig.json"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@vmz/core": "0.1.
|
|
31
|
-
"@vmz/protocol": "0.1.
|
|
30
|
+
"@vmz/core": "0.1.1",
|
|
31
|
+
"@vmz/protocol": "0.1.1",
|
|
32
32
|
"linkedom": "^0.18.13",
|
|
33
33
|
"puppeteer-core": "^24.11.2"
|
|
34
34
|
},
|