@ai-ecoverse/slicc-browsers 1.19.0 → 1.19.2
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/guard-driver.mjs +44 -0
- package/guard-runner.mjs +10 -9
- package/guard-vectors.json +5 -5
- package/package.json +4 -4
package/guard-driver.mjs
CHANGED
|
@@ -354,11 +354,25 @@ export const skipReason = (vector, target, scope) => {
|
|
|
354
354
|
|
|
355
355
|
export const inapplicable = (vector, target, scope) => skipReason(vector, target, scope) !== null;
|
|
356
356
|
|
|
357
|
+
const trustedEmulationMethods = new Set([
|
|
358
|
+
'Emulation.setLocaleOverride',
|
|
359
|
+
'Emulation.setTimezoneOverride',
|
|
360
|
+
]);
|
|
361
|
+
|
|
362
|
+
const canTrustedEmulation = (vector) =>
|
|
363
|
+
flatten(named([...(vector?.setup ?? []), ...(vector?.trigger ?? [])])).some((step) =>
|
|
364
|
+
trustedEmulationMethods.has(step.cdp)
|
|
365
|
+
);
|
|
366
|
+
|
|
357
367
|
function skipWhy(vector, row, known, guard) {
|
|
358
368
|
const { reason } = row;
|
|
359
369
|
if (typeof reason !== 'string' || reason === '') return 'skip without a reason';
|
|
360
370
|
if (reason === skipReason(vector, row.target, guard)) return null;
|
|
361
371
|
if (originReason(vector, row, reason)) return null;
|
|
372
|
+
if (reason === 'not-supported:trustedEmulation')
|
|
373
|
+
return canTrustedEmulation(vector)
|
|
374
|
+
? null
|
|
375
|
+
: `skip with a reason the runner never gives: ${reason}`;
|
|
362
376
|
if (reason.startsWith('not-supported:') && known.has(reason.slice('not-supported:'.length)))
|
|
363
377
|
return null;
|
|
364
378
|
return `skip with a reason the runner never gives: ${reason}`;
|
|
@@ -369,6 +383,7 @@ function forgeries(set, results, guard) {
|
|
|
369
383
|
const known = new Set([
|
|
370
384
|
'browserSession',
|
|
371
385
|
'unguarded-observer',
|
|
386
|
+
'trustedEmulation',
|
|
372
387
|
...capabilities(set.vectors).filter((c) => typeof c === 'string' && c !== ''),
|
|
373
388
|
]);
|
|
374
389
|
return results.flatMap((row) => {
|
|
@@ -443,3 +458,32 @@ export const idleDebuggerCleanup = (vector, step, phase, out) =>
|
|
|
443
458
|
|
|
444
459
|
export const debuggerPaused = (events, session) =>
|
|
445
460
|
events.some((event) => event.sessionId === session && event.method === 'Debugger.paused');
|
|
461
|
+
|
|
462
|
+
const cdpError = (error) => {
|
|
463
|
+
const code = error?.code;
|
|
464
|
+
const message = error?.message;
|
|
465
|
+
if (code !== undefined && code !== null) return { code, message };
|
|
466
|
+
if (typeof message !== 'string') return { code, message };
|
|
467
|
+
try {
|
|
468
|
+
const parsed = JSON.parse(message);
|
|
469
|
+
if (
|
|
470
|
+
parsed &&
|
|
471
|
+
typeof parsed === 'object' &&
|
|
472
|
+
typeof parsed.code === 'number' &&
|
|
473
|
+
typeof parsed.message === 'string'
|
|
474
|
+
)
|
|
475
|
+
return { code: parsed.code, message: parsed.message };
|
|
476
|
+
} catch {}
|
|
477
|
+
return { code, message };
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
export const trustedClientOnly = (step, out) => {
|
|
481
|
+
if (!trustedEmulationMethods.has(step.cdp) || out.ok) return false;
|
|
482
|
+
const { code, message } = cdpError(out.error);
|
|
483
|
+
return (
|
|
484
|
+
Number(code) === -32000 && /only available to trusted clients/i.test(String(message ?? ''))
|
|
485
|
+
);
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
export const refusalError = (step, out, refused, gone, phase, vector) =>
|
|
489
|
+
step.refusable && !out.ok && !refused && !gone && !idleDebuggerCleanup(vector, step, phase, out);
|
package/guard-runner.mjs
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
debuggerPaused,
|
|
13
13
|
expand,
|
|
14
14
|
hop,
|
|
15
|
-
idleDebuggerCleanup,
|
|
16
15
|
inapplicable,
|
|
17
16
|
isRefusal,
|
|
18
17
|
knownOrigins,
|
|
@@ -21,10 +20,12 @@ import {
|
|
|
21
20
|
outcome,
|
|
22
21
|
owned,
|
|
23
22
|
parseURL,
|
|
23
|
+
refusalError,
|
|
24
24
|
summary as report,
|
|
25
25
|
result,
|
|
26
26
|
skipReason,
|
|
27
27
|
steps,
|
|
28
|
+
trustedClientOnly,
|
|
28
29
|
waitFor,
|
|
29
30
|
} from './guard-driver.mjs';
|
|
30
31
|
import { createObserverTarget, discoveryViolation } from './observer-target.mjs';
|
|
@@ -145,6 +146,7 @@ class Execution {
|
|
|
145
146
|
this.pending = [];
|
|
146
147
|
this.errors = [];
|
|
147
148
|
this.incomplete = [];
|
|
149
|
+
this.unsupported = undefined;
|
|
148
150
|
this.preSent = [];
|
|
149
151
|
this.notes = [];
|
|
150
152
|
this.answers = [];
|
|
@@ -685,14 +687,10 @@ class Execution {
|
|
|
685
687
|
!refused &&
|
|
686
688
|
/timeout|timed out|no answer/i.test(String(out.error?.message ?? out.error));
|
|
687
689
|
if (step.refusable) this.refused[step.refusal.name] = unanswered ? 'incomplete' : refused;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
!refused &&
|
|
693
|
-
!gone &&
|
|
694
|
-
!idleDebuggerCleanup(this.vector, step, phase, out)
|
|
695
|
-
)
|
|
690
|
+
const trusted = this.side === 'control' && trustedClientOnly(step, out);
|
|
691
|
+
if (trusted) this.unsupported = 'trustedEmulation';
|
|
692
|
+
else if (unanswered) this.incomplete.push(`${step.refusal.name}: no answer`);
|
|
693
|
+
else if (refusalError(step, out, refused, gone, phase, this.vector))
|
|
696
694
|
this.errors.push(
|
|
697
695
|
`${step.refusal.name} failed without a refusal: ${String(out.error?.message ?? out.error)}`
|
|
698
696
|
);
|
|
@@ -1447,6 +1445,7 @@ class Execution {
|
|
|
1447
1445
|
errors: this.errors,
|
|
1448
1446
|
notes: this.notes,
|
|
1449
1447
|
incomplete: this.incomplete,
|
|
1448
|
+
unsupported: this.unsupported,
|
|
1450
1449
|
evidence: Object.fromEntries(
|
|
1451
1450
|
Object.entries(this.calls)
|
|
1452
1451
|
.filter(
|
|
@@ -1758,6 +1757,8 @@ async function executeRow(job, opts, made, set, slot, index, flights) {
|
|
|
1758
1757
|
flight.abandoned = true;
|
|
1759
1758
|
return timedOut(stuck, base, made, sides, opts);
|
|
1760
1759
|
}
|
|
1760
|
+
if (legs.control.unsupported === 'trustedEmulation')
|
|
1761
|
+
return skipRow(base, 'not-supported:trustedEmulation');
|
|
1761
1762
|
const row = {
|
|
1762
1763
|
...result(vector, {
|
|
1763
1764
|
...base,
|
package/guard-vectors.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"setVersion": "1.19.
|
|
3
|
+
"setVersion": "1.19.2",
|
|
4
4
|
"sources": [
|
|
5
5
|
{
|
|
6
6
|
"repo": "ai-ecoverse/slicc-cli",
|
|
@@ -17369,7 +17369,7 @@
|
|
|
17369
17369
|
"targets": ["seven", "vault", "vault-x", "apex"],
|
|
17370
17370
|
"observe": {
|
|
17371
17371
|
"locale": {
|
|
17372
|
-
"means": "{target}/doc?n={tag} formats in
|
|
17372
|
+
"means": "when the client can override locale, {target}/doc?n={tag} formats in fr-CH",
|
|
17373
17373
|
"dependsOn": ["refused.2"],
|
|
17374
17374
|
"check": {
|
|
17375
17375
|
"expression": "(location.href === '{target}/doc?n={tag}') ? Intl.DateTimeFormat().resolvedOptions().locale : 'elsewhere'",
|
|
@@ -17387,7 +17387,7 @@
|
|
|
17387
17387
|
}
|
|
17388
17388
|
}
|
|
17389
17389
|
},
|
|
17390
|
-
"live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
|
|
17390
|
+
"live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step; Chrome's trusted-client-only refusal of Emulation.setLocaleOverride on the ordinary control is not-supported:trustedEmulation",
|
|
17391
17391
|
"control": {
|
|
17392
17392
|
"origin": "ordinary",
|
|
17393
17393
|
"via": "guard",
|
|
@@ -17490,7 +17490,7 @@
|
|
|
17490
17490
|
"targets": ["seven", "vault", "vault-x", "apex"],
|
|
17491
17491
|
"observe": {
|
|
17492
17492
|
"timezone": {
|
|
17493
|
-
"means": "{target}/doc?n={tag} runs in
|
|
17493
|
+
"means": "when the client can override the time zone, {target}/doc?n={tag} runs in Pacific/Chatham",
|
|
17494
17494
|
"dependsOn": ["refused.2"],
|
|
17495
17495
|
"check": {
|
|
17496
17496
|
"expression": "(location.href === '{target}/doc?n={tag}') ? Intl.DateTimeFormat().resolvedOptions().timeZone : 'elsewhere'",
|
|
@@ -17508,7 +17508,7 @@
|
|
|
17508
17508
|
}
|
|
17509
17509
|
}
|
|
17510
17510
|
},
|
|
17511
|
-
"live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
|
|
17511
|
+
"live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step; Chrome's trusted-client-only refusal of Emulation.setTimezoneOverride on the ordinary control is not-supported:trustedEmulation",
|
|
17512
17512
|
"control": {
|
|
17513
17513
|
"origin": "ordinary",
|
|
17514
17514
|
"via": "guard",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-browsers",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.2",
|
|
4
4
|
"description": "SLICC's shared browser catalog, JSON schemas and discovery conformance corpus",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"validate": "node scripts/validate.mjs",
|
|
72
72
|
"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",
|
|
73
73
|
"format": "biome check --write . && gofmt -w . && cargo fmt",
|
|
74
|
-
"test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/debugger-stage1-packaging.test.mjs test/integration/debugger-raw-control.test.mjs test/integration/debugger-cleanup.test.mjs test/integration/debugger-stage1-install-vectors.test.mjs test/integration/protected-premise.test.mjs test/integration/debugger-stage1-vectors.test.mjs test/integration/self-contained.test.mjs test/integration/seven-corpus.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-unparseable-wipe.test.mjs test/integration/guard-browser-ui.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-error-page-events.test.mjs test/integration/guard-error-page-reload.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/chromium-launch.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",
|
|
74
|
+
"test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/debugger-stage1-packaging.test.mjs test/integration/debugger-raw-control.test.mjs test/integration/debugger-cleanup.test.mjs test/integration/debugger-stage1-install-vectors.test.mjs test/integration/protected-premise.test.mjs test/integration/debugger-stage1-vectors.test.mjs test/integration/self-contained.test.mjs test/integration/seven-corpus.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-unparseable-wipe.test.mjs test/integration/guard-browser-ui.test.mjs test/integration/guard-snapshot-settle.test.mjs test/integration/guard-stall.test.mjs test/integration/guard-forged.test.mjs test/integration/guard-trusted-emulation.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-error-page-events.test.mjs test/integration/guard-error-page-reload.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/chromium-launch.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",
|
|
75
75
|
"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 ./...",
|
|
76
76
|
"build": "go build ./... && cargo build --all-features && cargo build --target wasm32-wasip1 --all-features && npm pack --dry-run",
|
|
77
77
|
"prepublishOnly": "node scripts/set-crate-version.mjs \"$npm_package_version\"",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"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"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
|
-
"@ai-ecoverse/slicc-cdp": "1.
|
|
86
|
-
"@ai-ecoverse/slicc-shared-web": "2.13.
|
|
85
|
+
"@ai-ecoverse/slicc-cdp": "1.45.0",
|
|
86
|
+
"@ai-ecoverse/slicc-shared-web": "2.13.10",
|
|
87
87
|
"@biomejs/biome": "2.6.3",
|
|
88
88
|
"ajv": "8.20.0",
|
|
89
89
|
"ajv-formats": "3.0.1",
|