@ai-ecoverse/slicc-browsers 1.18.12 → 1.18.14
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/extension-world.mjs +26 -1
- package/guard-driver.mjs +11 -2
- package/guard-runner.mjs +46 -7
- package/guard-vectors.json +1 -1
- package/package.json +5 -5
package/extension-world.mjs
CHANGED
|
@@ -9,6 +9,28 @@ const marker =
|
|
|
9
9
|
'typeof root !== "undefined" && root === document.documentElement && root.dataset.sliccHarnessExtension === chrome.runtime.id';
|
|
10
10
|
const refused = (out) => !out.ok && /^slicc: refused:/.test(out.error?.message ?? '');
|
|
11
11
|
|
|
12
|
+
async function painted(reader, observer, ms) {
|
|
13
|
+
let timer;
|
|
14
|
+
const expired = new Promise((resolve) => {
|
|
15
|
+
timer = setTimeout(resolve, ms);
|
|
16
|
+
});
|
|
17
|
+
await Promise.race([
|
|
18
|
+
outcome(
|
|
19
|
+
reader.send(
|
|
20
|
+
'Runtime.evaluate',
|
|
21
|
+
{
|
|
22
|
+
expression: `new Promise((resolve) => { setTimeout(resolve, ${ms}); requestAnimationFrame(() => requestAnimationFrame(resolve)); })`,
|
|
23
|
+
awaitPromise: true,
|
|
24
|
+
returnByValue: true,
|
|
25
|
+
},
|
|
26
|
+
observer
|
|
27
|
+
)
|
|
28
|
+
),
|
|
29
|
+
expired,
|
|
30
|
+
]);
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
}
|
|
33
|
+
|
|
12
34
|
async function discover(reader, session, extensionId) {
|
|
13
35
|
const start = reader.events.length;
|
|
14
36
|
await reader.send('Runtime.enable', {}, session);
|
|
@@ -29,7 +51,7 @@ async function discover(reader, session, extensionId) {
|
|
|
29
51
|
throw new Error(`extensionWorld: no content-script context for ${extensionId}`);
|
|
30
52
|
}
|
|
31
53
|
|
|
32
|
-
async function drivable({ client, session, live, reader, observer }) {
|
|
54
|
+
async function drivable({ client, session, live, reader, observer, frameMs }) {
|
|
33
55
|
const setup = await outcome(
|
|
34
56
|
client.send(
|
|
35
57
|
'Runtime.evaluate',
|
|
@@ -45,6 +67,7 @@ async function drivable({ client, session, live, reader, observer }) {
|
|
|
45
67
|
client.send('DOMSnapshot.captureSnapshot', { computedStyles: [] }, session)
|
|
46
68
|
);
|
|
47
69
|
await outcome(reader.send('Page.bringToFront', {}, observer));
|
|
70
|
+
await painted(reader, observer, frameMs);
|
|
48
71
|
const down = await outcome(
|
|
49
72
|
client.send(
|
|
50
73
|
'Input.dispatchMouseEvent',
|
|
@@ -324,6 +347,7 @@ export async function extensionWorld({
|
|
|
324
347
|
controls,
|
|
325
348
|
extensionId = DEFAULT_EXTENSION_WORLD_ID,
|
|
326
349
|
pauseMs = side === 'control' ? 5000 : 1500,
|
|
350
|
+
frameMs = 1000,
|
|
327
351
|
}) {
|
|
328
352
|
const attached = await reader.send('Target.attachToTarget', { targetId, flatten: true });
|
|
329
353
|
const observer = attached.sessionId;
|
|
@@ -395,6 +419,7 @@ export async function extensionWorld({
|
|
|
395
419
|
side,
|
|
396
420
|
controls,
|
|
397
421
|
pauseMs,
|
|
422
|
+
frameMs,
|
|
398
423
|
};
|
|
399
424
|
if (mode === 'drivable') return await drivable(input);
|
|
400
425
|
if (mode === 'debugger') return await debuggerWorld(input);
|
package/guard-driver.mjs
CHANGED
|
@@ -135,7 +135,7 @@ export async function load(client, sessionId, url, ms = 20000) {
|
|
|
135
135
|
throw new Error(`load of ${url} timed out`);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
export async function waitFor(check, ms, step = 25) {
|
|
138
|
+
export async function waitFor(check, ms, step = 25, bounded = false) {
|
|
139
139
|
const start = Date.now();
|
|
140
140
|
const limit = start + ms + Math.max(ms * 4, 30000);
|
|
141
141
|
let deadline = start + ms;
|
|
@@ -147,14 +147,23 @@ export async function waitFor(check, ms, step = 25) {
|
|
|
147
147
|
last = now;
|
|
148
148
|
};
|
|
149
149
|
let timer;
|
|
150
|
+
let expire;
|
|
150
151
|
const tick = () => {
|
|
151
152
|
beat();
|
|
153
|
+
if (Date.now() > deadline) expire?.();
|
|
152
154
|
timer = setTimeout(tick, step);
|
|
153
155
|
};
|
|
154
156
|
timer = setTimeout(tick, step);
|
|
155
157
|
try {
|
|
156
158
|
for (;;) {
|
|
157
|
-
|
|
159
|
+
const expired = bounded
|
|
160
|
+
? new Promise((resolve) => {
|
|
161
|
+
expire = () => resolve(false);
|
|
162
|
+
})
|
|
163
|
+
: undefined;
|
|
164
|
+
const met = bounded ? await Promise.race([check(), expired]) : await check();
|
|
165
|
+
expire = undefined;
|
|
166
|
+
if (met) return true;
|
|
158
167
|
beat();
|
|
159
168
|
if (Date.now() > deadline) return false;
|
|
160
169
|
await new Promise((resolve) => setTimeout(resolve, step));
|
package/guard-runner.mjs
CHANGED
|
@@ -70,6 +70,13 @@ const observedValue = (out, path) => {
|
|
|
70
70
|
|
|
71
71
|
const address = (value) =>
|
|
72
72
|
typeof value === 'string' ? value : hop(value.hops.slice(value.index ?? 0), value.to);
|
|
73
|
+
const resultNames = (check) =>
|
|
74
|
+
[
|
|
75
|
+
check?.result,
|
|
76
|
+
...[...(check?.all ?? []), ...(check?.any ?? []), ...(check?.not ? [check.not] : [])].flatMap(
|
|
77
|
+
resultNames
|
|
78
|
+
),
|
|
79
|
+
].filter(Boolean);
|
|
73
80
|
const stateCheck = (check) =>
|
|
74
81
|
check?.state ||
|
|
75
82
|
[...(check?.all ?? []), ...(check?.any ?? []), ...(check?.not ? [check.not] : [])]
|
|
@@ -235,8 +242,8 @@ class Execution {
|
|
|
235
242
|
return Math.round(ms * (absent ? this.refusalScale : this.scale));
|
|
236
243
|
}
|
|
237
244
|
|
|
238
|
-
async poll(predicate, ms = 1500, absent = false) {
|
|
239
|
-
return waitFor(predicate, this.bound(ms, absent));
|
|
245
|
+
async poll(predicate, ms = 1500, absent = false, bounded = false) {
|
|
246
|
+
return waitFor(predicate, this.bound(ms, absent), 25, bounded);
|
|
240
247
|
}
|
|
241
248
|
|
|
242
249
|
async prepareState(spec) {
|
|
@@ -705,6 +712,7 @@ class Execution {
|
|
|
705
712
|
async execute(list, childSession, phase = 'child') {
|
|
706
713
|
if (phase === 'trigger') await this.childrenSettled();
|
|
707
714
|
for (const [index, raw] of list.entries()) {
|
|
715
|
+
if (phase === 'observation' && this.clients.flight?.abandoned) return;
|
|
708
716
|
if (this.clients.flight)
|
|
709
717
|
Object.assign(this.clients.flight, { leg: this.side, phase, step: index });
|
|
710
718
|
const step = expand(raw, this.vars);
|
|
@@ -846,6 +854,7 @@ class Execution {
|
|
|
846
854
|
side: this.side,
|
|
847
855
|
controls: (this.clients.extensionWorldControls ??= {}),
|
|
848
856
|
pauseMs: this.bound(this.side === 'control' ? 5000 : 1500, this.side !== 'control'),
|
|
857
|
+
frameMs: this.bound(1000),
|
|
849
858
|
extensionId: this.options.extensionWorldId,
|
|
850
859
|
})
|
|
851
860
|
);
|
|
@@ -1069,12 +1078,42 @@ class Execution {
|
|
|
1069
1078
|
(at(this.calls[check.result], check.path) === 'incomplete' || this.unmeasured(check))
|
|
1070
1079
|
)
|
|
1071
1080
|
return 'incomplete';
|
|
1072
|
-
|
|
1081
|
+
const plan = steps(this.vector, this.side, this.vars);
|
|
1082
|
+
const names = resultNames(check);
|
|
1083
|
+
const snapshots =
|
|
1084
|
+
this.side === 'control' && want === true && !this.clients.flight?.abandoned
|
|
1085
|
+
? [...plan.setup, ...plan.trigger].filter(
|
|
1086
|
+
(step) =>
|
|
1087
|
+
names.includes(step.as) &&
|
|
1088
|
+
!step.refusable &&
|
|
1089
|
+
['Page.getFrameTree', 'Target.getTargets'].includes(step.cdp) &&
|
|
1090
|
+
supported(step.requires, this.options.capabilities)
|
|
1091
|
+
)
|
|
1092
|
+
: [];
|
|
1093
|
+
if (want !== true || (check?.observer !== 'fixture' && !snapshots.length))
|
|
1094
|
+
return this.check(check);
|
|
1073
1095
|
let seen = false;
|
|
1074
|
-
await this.poll(
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1096
|
+
const met = await this.poll(
|
|
1097
|
+
async () => {
|
|
1098
|
+
if (this.clients.flight?.abandoned) return true;
|
|
1099
|
+
seen = await this.check(check);
|
|
1100
|
+
if (seen !== true && snapshots.length) {
|
|
1101
|
+
await this.execute(snapshots, undefined, 'observation');
|
|
1102
|
+
if (this.clients.flight?.abandoned) return true;
|
|
1103
|
+
seen = await this.check(check);
|
|
1104
|
+
}
|
|
1105
|
+
return seen === true;
|
|
1106
|
+
},
|
|
1107
|
+
observeMs,
|
|
1108
|
+
false,
|
|
1109
|
+
snapshots.length > 0
|
|
1110
|
+
);
|
|
1111
|
+
if ((!met || this.clients.flight?.abandoned) && snapshots.length) {
|
|
1112
|
+
this.incomplete.push(
|
|
1113
|
+
`${name}: snapshot evidence not observed within ${this.bound(observeMs)}ms`
|
|
1114
|
+
);
|
|
1115
|
+
return 'incomplete';
|
|
1116
|
+
}
|
|
1078
1117
|
return seen;
|
|
1079
1118
|
}
|
|
1080
1119
|
|
package/guard-vectors.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-browsers",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.14",
|
|
4
4
|
"description": "SLICC's shared browser catalog, JSON schemas and discovery conformance corpus",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"validate": "node scripts/validate.mjs",
|
|
69
69
|
"lint": "slicc-lint && test -z \"$(gofmt -l .)\" && go mod tidy -diff && go vet ./... && GOOS=darwin go vet ./... && GOOS=windows go vet ./... && golangci-lint run && cargo fmt --check && cargo clippy --all-features --all-targets -- -D warnings && cargo check --target wasm32-wasip1 --no-default-features && cargo check --target wasm32-wasip1 --features serde && cargo check --target wasm32-wasip1 --all-features",
|
|
70
70
|
"format": "biome check --write . && gofmt -w . && cargo fmt",
|
|
71
|
-
"test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/self-contained.test.mjs test/integration/browser-runner.test.mjs test/integration/fixture-client.test.mjs test/integration/guard-redirect-carrier.test.mjs test/integration/guard-redirect-session-end.test.mjs test/integration/guard-redirect-history.test.mjs test/integration/guard-redirect-iframe.test.mjs test/integration/guard-incomplete.test.mjs test/integration/guard-stall.test.mjs test/integration/guard-forged.test.mjs test/integration/guard-exit-steps.test.mjs test/integration/guard-exit-refusal.test.mjs test/integration/guard-frame-read.test.mjs test/integration/guard-bfcache.test.mjs test/integration/guard-bfcache-marker.test.mjs test/integration/guard-bfcache-history.test.mjs test/integration/guard-bfcache-review.test.mjs test/integration/guard-bfcache-quarantine.test.mjs test/integration/guard-error-page-navigation.test.mjs test/integration/gates.test.mjs test/integration/validate.test.mjs test/integration/go.test.mjs test/integration/cargo.test.mjs test/integration/workflows.test.mjs test/integration/guard-sweep-union.test.mjs && node --test --test-concurrency=2 test/integration/guard-lifecycle.test.mjs test/integration/guard-fit.test.mjs test/integration/guard-chain.test.mjs test/integration/guard-validation.test.mjs test/integration/guard-liveness.test.mjs test/integration/guard-observations.test.mjs test/integration/guard-child-latency.test.mjs test/integration/guard-adoption.test.mjs test/integration/guard-scoping.test.mjs test/integration/guard-late-pause.test.mjs test/integration/guard-legs.test.mjs test/integration/guard-fetch-enable.test.mjs test/integration/guard-diagnostics.test.mjs test/integration/guard-chrome.test.mjs test/integration/guard-worlds.test.mjs test/integration/guard-world-discovery.test.mjs test/integration/guard-world-guesses.test.mjs test/integration/guard-unparseable.test.mjs test/integration/guard-redirect-secret.test.mjs test/integration/guard-error-page.test.mjs test/integration/guard-discovery.test.mjs test/integration/guard-bfcache-chrome.test.mjs test/integration/guard-browser-page.test.mjs test/integration/guard-scales.test.mjs test/integration/guard-shared-log.test.mjs test/integration/guard-pre-beacon.test.mjs test/integration/guard-world-pause.test.mjs test/integration/guard-parallel.test.mjs test/integration/guard-client-exit.test.mjs test/integration/guard-runner.test.mjs test/integration/guard-sweep-ordinary.test.mjs test/integration/guard-sweep-seven.test.mjs test/integration/guard-sweep-vault.test.mjs test/integration/guard-sweep-vault-x.test.mjs test/integration/guard-sweep-apex.test.mjs test/integration/guard-sweep-others.test.mjs",
|
|
71
|
+
"test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/self-contained.test.mjs test/integration/browser-runner.test.mjs test/integration/fixture-client.test.mjs test/integration/guard-redirect-carrier.test.mjs test/integration/guard-redirect-session-end.test.mjs test/integration/guard-redirect-history.test.mjs test/integration/guard-redirect-iframe.test.mjs test/integration/guard-incomplete.test.mjs test/integration/guard-snapshot-settle.test.mjs test/integration/guard-stall.test.mjs test/integration/guard-forged.test.mjs test/integration/guard-exit-steps.test.mjs test/integration/guard-exit-refusal.test.mjs test/integration/guard-frame-read.test.mjs test/integration/guard-bfcache.test.mjs test/integration/guard-bfcache-marker.test.mjs test/integration/guard-bfcache-history.test.mjs test/integration/guard-bfcache-review.test.mjs test/integration/guard-bfcache-quarantine.test.mjs test/integration/guard-error-page-navigation.test.mjs test/integration/guard-world-paint.test.mjs test/integration/gates.test.mjs test/integration/validate.test.mjs test/integration/go.test.mjs test/integration/cargo.test.mjs test/integration/workflows.test.mjs test/integration/guard-sweep-union.test.mjs && node --test --test-concurrency=2 test/integration/guard-lifecycle.test.mjs test/integration/guard-fit.test.mjs test/integration/guard-chain.test.mjs test/integration/guard-validation.test.mjs test/integration/guard-liveness.test.mjs test/integration/guard-observations.test.mjs test/integration/guard-child-latency.test.mjs test/integration/guard-adoption.test.mjs test/integration/guard-scoping.test.mjs test/integration/guard-late-pause.test.mjs test/integration/guard-legs.test.mjs test/integration/guard-fetch-enable.test.mjs test/integration/guard-diagnostics.test.mjs test/integration/guard-chrome.test.mjs test/integration/guard-worlds.test.mjs test/integration/guard-world-discovery.test.mjs test/integration/guard-world-guesses.test.mjs test/integration/guard-unparseable.test.mjs test/integration/guard-redirect-secret.test.mjs test/integration/guard-error-page.test.mjs test/integration/guard-discovery.test.mjs test/integration/guard-bfcache-chrome.test.mjs test/integration/guard-browser-page.test.mjs test/integration/guard-scales.test.mjs test/integration/guard-shared-log.test.mjs test/integration/guard-pre-beacon.test.mjs test/integration/guard-world-pause.test.mjs test/integration/guard-parallel.test.mjs test/integration/guard-client-exit.test.mjs test/integration/guard-runner.test.mjs test/integration/guard-sweep-ordinary.test.mjs test/integration/guard-sweep-seven.test.mjs test/integration/guard-sweep-vault.test.mjs test/integration/guard-sweep-vault-x.test.mjs test/integration/guard-sweep-apex.test.mjs test/integration/guard-sweep-others.test.mjs",
|
|
72
72
|
"test:unit": "mkdir -p coverage/unit && node --experimental-test-coverage --test --test-concurrency=1 --test-reporter=lcov --test-reporter-destination=coverage/unit/lcov.info test/unit/*.test.mjs && go test -race -cover ./...",
|
|
73
73
|
"build": "go build ./... && cargo build --all-features && cargo build --target wasm32-wasip1 --all-features && npm pack --dry-run",
|
|
74
74
|
"prepublishOnly": "node scripts/set-crate-version.mjs \"$npm_package_version\"",
|
|
@@ -76,11 +76,11 @@
|
|
|
76
76
|
"trust:dry": "npx fledgling sync --dry-run -y --skip-publish",
|
|
77
77
|
"release": "semantic-release",
|
|
78
78
|
"test:unit:redirect": "mkdir -p coverage/unit && node --experimental-test-coverage --test --test-concurrency=1 --test-coverage-include=redirect-secret.mjs --test-coverage-include=redirect-fragments.mjs --test-reporter=lcov --test-reporter-destination=coverage/unit/redirect.lcov test/unit/guard-redirect-*.test.mjs && slicc-diff-cover coverage/unit/redirect.lcov",
|
|
79
|
-
"test:unit:guard": "mkdir -p coverage/unit && node --experimental-vm-modules --no-warnings --experimental-test-coverage --test --test-concurrency=1 --test-coverage-include=guard-runner.mjs --test-coverage-include=fixture-server.mjs --test-coverage-include=fixture-client.mjs --test-coverage-include=observer-target.mjs --test-coverage-include=frame-read.mjs --test-coverage-include=bfcache-restore.mjs --test-coverage-include=protected-error-page.mjs --test-coverage-include=unparseable-url.mjs --test-coverage-include=scripts/browser-runner.mjs --test-coverage-include=scripts/validate.mjs --test-reporter=lcov --test-reporter-destination=coverage/unit/guard.lcov test/unit/guard-*.test.mjs && slicc-diff-cover coverage/unit/guard.lcov"
|
|
79
|
+
"test:unit:guard": "mkdir -p coverage/unit && node --experimental-vm-modules --no-warnings --experimental-test-coverage --test --test-concurrency=1 --test-coverage-include=guard-runner.mjs --test-coverage-include=guard-driver.mjs --test-coverage-include=fixture-server.mjs --test-coverage-include=fixture-client.mjs --test-coverage-include=observer-target.mjs --test-coverage-include=frame-read.mjs --test-coverage-include=bfcache-restore.mjs --test-coverage-include=protected-error-page.mjs --test-coverage-include=unparseable-url.mjs --test-coverage-include=scripts/browser-runner.mjs --test-coverage-include=scripts/validate.mjs --test-reporter=lcov --test-reporter-destination=coverage/unit/guard.lcov test/unit/guard-*.test.mjs && slicc-diff-cover coverage/unit/guard.lcov"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@ai-ecoverse/slicc-cdp": "1.
|
|
83
|
-
"@ai-ecoverse/slicc-shared-web": "2.
|
|
82
|
+
"@ai-ecoverse/slicc-cdp": "1.41.8",
|
|
83
|
+
"@ai-ecoverse/slicc-shared-web": "2.12.1",
|
|
84
84
|
"@biomejs/biome": "2.5.15",
|
|
85
85
|
"ajv": "8.20.0",
|
|
86
86
|
"ajv-formats": "3.0.1",
|