craftdriver 1.7.0 → 1.9.0
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/CHANGELOG.md +25 -12
- package/README.md +16 -6
- package/dist/cli/agentSession.d.ts +62 -0
- package/dist/cli/agentSession.d.ts.map +1 -0
- package/dist/cli/agentSession.js +100 -0
- package/dist/cli/agentSession.js.map +1 -0
- package/dist/cli/artifactPaths.d.ts +42 -0
- package/dist/cli/artifactPaths.d.ts.map +1 -0
- package/dist/cli/artifactPaths.js +144 -0
- package/dist/cli/artifactPaths.js.map +1 -0
- package/dist/cli/bounds.d.ts +88 -0
- package/dist/cli/bounds.d.ts.map +1 -0
- package/dist/cli/bounds.js +128 -0
- package/dist/cli/bounds.js.map +1 -0
- package/dist/cli/client.d.ts +3 -0
- package/dist/cli/client.d.ts.map +1 -1
- package/dist/cli/client.js +24 -8
- package/dist/cli/client.js.map +1 -1
- package/dist/cli/daemon.d.ts +3 -0
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +152 -39
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/defaults.d.ts +23 -3
- package/dist/cli/defaults.d.ts.map +1 -1
- package/dist/cli/defaults.js +50 -5
- package/dist/cli/defaults.js.map +1 -1
- package/dist/cli/dispatcher.d.ts +54 -11
- package/dist/cli/dispatcher.d.ts.map +1 -1
- package/dist/cli/dispatcher.js +851 -54
- package/dist/cli/dispatcher.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +305 -56
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +14 -14
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +328 -180
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/journal.d.ts +153 -0
- package/dist/cli/journal.d.ts.map +1 -0
- package/dist/cli/journal.js +252 -0
- package/dist/cli/journal.js.map +1 -0
- package/dist/cli/lineReader.d.ts +33 -0
- package/dist/cli/lineReader.d.ts.map +1 -0
- package/dist/cli/lineReader.js +66 -0
- package/dist/cli/lineReader.js.map +1 -0
- package/dist/cli/locatorCandidates.d.ts +44 -0
- package/dist/cli/locatorCandidates.d.ts.map +1 -0
- package/dist/cli/locatorCandidates.js +190 -0
- package/dist/cli/locatorCandidates.js.map +1 -0
- package/dist/cli/mcp/artifacts.d.ts +39 -1
- package/dist/cli/mcp/artifacts.d.ts.map +1 -1
- package/dist/cli/mcp/artifacts.js +104 -9
- package/dist/cli/mcp/artifacts.js.map +1 -1
- package/dist/cli/mcp/bounds.d.ts +65 -0
- package/dist/cli/mcp/bounds.d.ts.map +1 -0
- package/dist/cli/mcp/bounds.js +124 -0
- package/dist/cli/mcp/bounds.js.map +1 -0
- package/dist/cli/mcp/params.d.ts +38 -0
- package/dist/cli/mcp/params.d.ts.map +1 -0
- package/dist/cli/mcp/params.js +174 -0
- package/dist/cli/mcp/params.js.map +1 -0
- package/dist/cli/mcp/server.d.ts +94 -16
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +304 -150
- package/dist/cli/mcp/server.js.map +1 -1
- package/dist/cli/mcp/tools.d.ts +62 -17
- package/dist/cli/mcp/tools.d.ts.map +1 -1
- package/dist/cli/mcp/tools.js +373 -158
- package/dist/cli/mcp/tools.js.map +1 -1
- package/dist/cli/pageSemantics.d.ts +6 -0
- package/dist/cli/pageSemantics.d.ts.map +1 -0
- package/dist/cli/pageSemantics.js +6 -0
- package/dist/cli/pageSemantics.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +6 -18
- package/dist/cli/parseArgs.d.ts.map +1 -1
- package/dist/cli/parseArgs.js +689 -45
- package/dist/cli/parseArgs.js.map +1 -1
- package/dist/cli/protocol.d.ts +8 -0
- package/dist/cli/protocol.d.ts.map +1 -1
- package/dist/cli/selector.d.ts +3 -3
- package/dist/cli/selector.d.ts.map +1 -1
- package/dist/cli/selector.js +6 -9
- package/dist/cli/selector.js.map +1 -1
- package/dist/cli/sessionRegistry.d.ts +42 -0
- package/dist/cli/sessionRegistry.d.ts.map +1 -0
- package/dist/cli/sessionRegistry.js +99 -0
- package/dist/cli/sessionRegistry.js.map +1 -0
- package/dist/cli/snapshot.d.ts +100 -19
- package/dist/cli/snapshot.d.ts.map +1 -1
- package/dist/cli/snapshot.js +295 -108
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/stateStore.d.ts +50 -0
- package/dist/cli/stateStore.d.ts.map +1 -0
- package/dist/cli/stateStore.js +122 -0
- package/dist/cli/stateStore.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/a11y.d.ts +6 -2
- package/dist/lib/a11y.d.ts.map +1 -1
- package/dist/lib/a11y.js +3 -1
- package/dist/lib/a11y.js.map +1 -1
- package/dist/lib/bidi/evaluate.d.ts +11 -0
- package/dist/lib/bidi/evaluate.d.ts.map +1 -0
- package/dist/lib/bidi/evaluate.js +25 -0
- package/dist/lib/bidi/evaluate.js.map +1 -0
- package/dist/lib/bidi/index.d.ts +1 -1
- package/dist/lib/bidi/index.d.ts.map +1 -1
- package/dist/lib/bidi/index.js +2 -2
- package/dist/lib/bidi/index.js.map +1 -1
- package/dist/lib/bidi/logs.d.ts +3 -0
- package/dist/lib/bidi/logs.d.ts.map +1 -1
- package/dist/lib/bidi/logs.js +7 -0
- package/dist/lib/bidi/logs.js.map +1 -1
- package/dist/lib/bidi/network.d.ts +14 -1
- package/dist/lib/bidi/network.d.ts.map +1 -1
- package/dist/lib/bidi/network.js +45 -7
- package/dist/lib/bidi/network.js.map +1 -1
- package/dist/lib/bidi/storage.d.ts +30 -6
- package/dist/lib/bidi/storage.d.ts.map +1 -1
- package/dist/lib/bidi/storage.js +190 -45
- package/dist/lib/bidi/storage.js.map +1 -1
- package/dist/lib/bidi/types.d.ts +9 -2
- package/dist/lib/bidi/types.d.ts.map +1 -1
- package/dist/lib/browser.d.ts +7 -4
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +186 -65
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +58 -24
- package/dist/lib/browserContext.d.ts.map +1 -1
- package/dist/lib/browserContext.js +300 -99
- package/dist/lib/browserContext.js.map +1 -1
- package/dist/lib/by.d.ts +68 -30
- package/dist/lib/by.d.ts.map +1 -1
- package/dist/lib/by.js +54 -23
- package/dist/lib/by.js.map +1 -1
- package/dist/lib/clearFastPath.d.ts.map +1 -1
- package/dist/lib/clearFastPath.js +2 -0
- package/dist/lib/clearFastPath.js.map +1 -1
- package/dist/lib/clickFastPath.d.ts.map +1 -1
- package/dist/lib/clickFastPath.js +2 -0
- package/dist/lib/clickFastPath.js.map +1 -1
- package/dist/lib/driver.d.ts +26 -0
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +123 -4
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/elementHandle.d.ts +13 -10
- package/dist/lib/elementHandle.d.ts.map +1 -1
- package/dist/lib/elementHandle.js +119 -50
- package/dist/lib/elementHandle.js.map +1 -1
- package/dist/lib/errors.d.ts +12 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +12 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/expect.d.ts +10 -0
- package/dist/lib/expect.d.ts.map +1 -1
- package/dist/lib/expect.js +76 -49
- package/dist/lib/expect.js.map +1 -1
- package/dist/lib/fillFastPath.d.ts.map +1 -1
- package/dist/lib/fillFastPath.js +2 -0
- package/dist/lib/fillFastPath.js.map +1 -1
- package/dist/lib/frame.d.ts.map +1 -1
- package/dist/lib/frame.js +29 -17
- package/dist/lib/frame.js.map +1 -1
- package/dist/lib/initScript.d.ts +9 -0
- package/dist/lib/initScript.d.ts.map +1 -0
- package/dist/lib/initScript.js +14 -0
- package/dist/lib/initScript.js.map +1 -0
- package/dist/lib/locator.d.ts +21 -54
- package/dist/lib/locator.d.ts.map +1 -1
- package/dist/lib/locator.js +165 -208
- package/dist/lib/locator.js.map +1 -1
- package/dist/lib/page.d.ts +22 -0
- package/dist/lib/page.d.ts.map +1 -1
- package/dist/lib/page.js +71 -13
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/pageSemantics.d.ts +42 -0
- package/dist/lib/pageSemantics.d.ts.map +1 -0
- package/dist/lib/pageSemantics.js +216 -0
- package/dist/lib/pageSemantics.js.map +1 -0
- package/dist/lib/query.d.ts +68 -0
- package/dist/lib/query.d.ts.map +1 -0
- package/dist/lib/query.js +590 -0
- package/dist/lib/query.js.map +1 -0
- package/dist/lib/secureFile.d.ts +8 -0
- package/dist/lib/secureFile.d.ts.map +1 -0
- package/dist/lib/secureFile.js +67 -0
- package/dist/lib/secureFile.js.map +1 -0
- package/dist/lib/sessionStateValidation.d.ts +35 -0
- package/dist/lib/sessionStateValidation.d.ts.map +1 -0
- package/dist/lib/sessionStateValidation.js +223 -0
- package/dist/lib/sessionStateValidation.js.map +1 -0
- package/dist/lib/shadowRoot.d.ts +21 -0
- package/dist/lib/shadowRoot.d.ts.map +1 -0
- package/dist/lib/shadowRoot.js +29 -0
- package/dist/lib/shadowRoot.js.map +1 -0
- package/dist/lib/shadowRootLocator.d.ts +31 -0
- package/dist/lib/shadowRootLocator.d.ts.map +1 -0
- package/dist/lib/shadowRootLocator.js +55 -0
- package/dist/lib/shadowRootLocator.js.map +1 -0
- package/dist/lib/timing.d.ts +2 -2
- package/dist/lib/timing.js +2 -2
- package/dist/lib/tracing.d.ts +2 -1
- package/dist/lib/tracing.d.ts.map +1 -1
- package/dist/lib/tracing.js +12 -1
- package/dist/lib/tracing.js.map +1 -1
- package/docs/accessibility.md +9 -1
- package/docs/agents.md +56 -61
- package/docs/api-reference.md +5 -1
- package/docs/browser-api.md +27 -7
- package/docs/browser-context.md +21 -15
- package/docs/cli.md +353 -30
- package/docs/error-codes.md +7 -4
- package/docs/getting-started.md +6 -1
- package/docs/index.md +1 -1
- package/docs/mcp.md +136 -65
- package/docs/public/examples/agent-actions.html +48 -0
- package/docs/public/examples/agent-debug.html +86 -0
- package/docs/public/examples/agent-late-mutation.html +18 -0
- package/docs/public/examples/agent-ref-shift.html +33 -0
- package/docs/public/examples/iframe-child.html +12 -1
- package/docs/public/examples/shadow-dom.html +137 -0
- package/docs/recipes/login-once-reuse-session.md +33 -5
- package/docs/selectors.md +61 -0
- package/docs/session-management.md +80 -12
- package/docs/why-craftdriver.md +1 -1
- package/package.json +5 -3
- package/skills/craftdriver/SKILL.md +59 -75
- package/skills/craftdriver/agents/openai.yaml +4 -0
- package/skills/craftdriver/cheatsheet.md +18 -4
- package/skills/craftdriver/cli.md +194 -68
- package/skills/craftdriver/patterns.md +17 -8
- package/skills/craftdriver/workflow.md +149 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure writer for credential-bearing state files.
|
|
3
|
+
*
|
|
4
|
+
* A saved `SessionState` holds live session cookies, so it is written the way a
|
|
5
|
+
* credential file should be: the parent directory is created, an existing
|
|
6
|
+
* symlink at the destination is refused, the content is written to a
|
|
7
|
+
* same-directory temporary file with owner-only permissions, and that temp file
|
|
8
|
+
* is atomically renamed into place. A crash therefore never leaves a
|
|
9
|
+
* half-written file, and the bytes never pass through a symlink that could
|
|
10
|
+
* redirect them elsewhere.
|
|
11
|
+
*
|
|
12
|
+
* POSIX permissions are best-effort — Windows ignores the mode, so callers must
|
|
13
|
+
* not assume `0600` there. This module is intentionally free of any CLI
|
|
14
|
+
* dependency so the public library owns its own persistence discipline.
|
|
15
|
+
*/
|
|
16
|
+
import fs from 'fs/promises';
|
|
17
|
+
import { basename, dirname, join, resolve } from 'path';
|
|
18
|
+
import { randomBytes } from 'crypto';
|
|
19
|
+
import { CraftdriverError, ErrorCode } from './errors.js';
|
|
20
|
+
/**
|
|
21
|
+
* Atomically write `contents` to `destPath` with owner-only permissions.
|
|
22
|
+
*
|
|
23
|
+
* @throws {CraftdriverError} `INVALID_ARGUMENT` if the destination already
|
|
24
|
+
* exists as a symlink.
|
|
25
|
+
*/
|
|
26
|
+
export async function writeSecureFile(destPath, contents) {
|
|
27
|
+
const abs = resolve(destPath);
|
|
28
|
+
const dir = dirname(abs);
|
|
29
|
+
await fs.mkdir(dir, { recursive: true });
|
|
30
|
+
// Refuse an existing symlink at the destination: writing "through" it could
|
|
31
|
+
// land the credentials outside `dir`. (The atomic rename below already
|
|
32
|
+
// replaces a link rather than following it, so this is a clear error rather
|
|
33
|
+
// than the load-bearing defense.)
|
|
34
|
+
try {
|
|
35
|
+
const st = await fs.lstat(abs);
|
|
36
|
+
if (st.isSymbolicLink()) {
|
|
37
|
+
throw new CraftdriverError(ErrorCode.INVALID_ARGUMENT, `refusing to write state through a symlink: ${abs}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof CraftdriverError)
|
|
42
|
+
throw err;
|
|
43
|
+
// ENOENT is the normal case — the destination does not exist yet. Any other
|
|
44
|
+
// lstat failure (EACCES, ELOOP, a broken path component, …) is a real
|
|
45
|
+
// problem; propagate it rather than blindly proceeding to write.
|
|
46
|
+
if (err.code !== 'ENOENT')
|
|
47
|
+
throw err;
|
|
48
|
+
}
|
|
49
|
+
const tmp = join(dir, `.${basename(abs)}.${randomBytes(6).toString('hex')}.tmp`);
|
|
50
|
+
try {
|
|
51
|
+
// `wx` fails if the temp name somehow exists; `mode` requests owner-only at
|
|
52
|
+
// creation. chmod after is belt-and-suspenders for platforms/umasks that do
|
|
53
|
+
// not honor the create mode.
|
|
54
|
+
await fs.writeFile(tmp, contents, { encoding: 'utf-8', mode: 0o600, flag: 'wx' });
|
|
55
|
+
await fs.chmod(tmp, 0o600).catch(() => {
|
|
56
|
+
/* Windows / unsupported fs — mode is best-effort */
|
|
57
|
+
});
|
|
58
|
+
await fs.rename(tmp, abs);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
await fs.rm(tmp, { force: true }).catch(() => {
|
|
62
|
+
/* nothing to clean up */
|
|
63
|
+
});
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=secureFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secureFile.js","sourceRoot":"","sources":["../../src/lib/secureFile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,QAAgB;IACtE,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAEzB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAC5E,kCAAkC;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,gBAAgB,CACxB,SAAS,CAAC,gBAAgB,EAC1B,8CAA8C,GAAG,EAAE,CACpD,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,gBAAgB;YAAE,MAAM,GAAG,CAAC;QAC/C,4EAA4E;QAC5E,sEAAsE;QACtE,iEAAiE;QACjE,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,GAAG,CAAC;IAClE,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjF,IAAI,CAAC;QACH,4EAA4E;QAC5E,4EAA4E;QAC5E,6BAA6B;QAC7B,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACpC,oDAAoD;QACtD,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3C,yBAAyB;QAC3B,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CraftdriverError } from './errors.js';
|
|
2
|
+
import type { CookieInput, SessionState } from './bidi/types.js';
|
|
3
|
+
export interface StorageStateErrorContext {
|
|
4
|
+
operation?: string;
|
|
5
|
+
browserName?: string;
|
|
6
|
+
protocol?: 'bidi' | 'classic' | string;
|
|
7
|
+
}
|
|
8
|
+
export declare function storageStateDetail(context: StorageStateErrorContext | undefined, phase: string, extra?: Record<string, unknown>): Record<string, unknown>;
|
|
9
|
+
/** True for an error already carrying this feature's structured contract. */
|
|
10
|
+
export declare function isStorageStateError(error: unknown): error is CraftdriverError;
|
|
11
|
+
/** A canonical http(s) origin: `scheme://host[:port]`, no path or trailing slash. */
|
|
12
|
+
export declare function isHttpOrigin(origin: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Parse `source` (a path or an in-memory object) into a validated
|
|
15
|
+
* {@link SessionState}. Malformed shapes throw `INVALID_ARGUMENT`; unknown or
|
|
16
|
+
* legacy sections throw `UNSUPPORTED`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseSessionState(source: SessionState | string, context?: StorageStateErrorContext): Promise<SessionState>;
|
|
19
|
+
/** Origins in `map` that actually carry at least one entry. */
|
|
20
|
+
export declare function nonEmptyOrigins(map?: Record<string, Record<string, string>>): string[];
|
|
21
|
+
/** True when the state carries at least one origin with ≥1 sessionStorage entry. */
|
|
22
|
+
export declare function hasNonEmptySessionStorage(state: SessionState): boolean;
|
|
23
|
+
/** True when a valid state has no cookie or storage mutations to apply. */
|
|
24
|
+
export declare function isSessionStateEmpty(state: SessionState): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Convert a captured cookie into the one canonical restore shape used by every
|
|
27
|
+
* protocol path. Browser read APIs may report `sameSite: 'default'`, and some
|
|
28
|
+
* engines report insecure `sameSite: 'none'`; neither can be replayed literally
|
|
29
|
+
* through all WebDriver cookie commands, so omit sameSite and let the engine
|
|
30
|
+
* apply its default consistently. `size` is capture-only and is never written.
|
|
31
|
+
*/
|
|
32
|
+
export declare function normalizeCookieForRestore(cookie: CookieInput & {
|
|
33
|
+
size?: number;
|
|
34
|
+
}): CookieInput;
|
|
35
|
+
//# sourceMappingURL=sessionStateValidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionStateValidation.d.ts","sourceRoot":"","sources":["../../src/lib/sessionStateValidation.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,gBAAgB,EAAa,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQjE,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;CACxC;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,wBAAwB,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE7E;AAkBD,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOpD;AAwGD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,GAAG,MAAM,EAC7B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,YAAY,CAAC,CAuCvB;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,CAGtF;AAED,oFAAoF;AACpF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEtE;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAMhE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAkB9F"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsing and validation for saved session state, shared by every restore entry
|
|
3
|
+
* point. The whole state is validated *before* any browser mutation, so a
|
|
4
|
+
* malformed or unsupported file fails loudly and leaves the browser untouched.
|
|
5
|
+
*
|
|
6
|
+
* Unknown or unsupported sections (including the legacy Playwright `origins`
|
|
7
|
+
* field) are rejected rather than silently ignored — a saved snapshot must mean
|
|
8
|
+
* exactly what it says.
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'fs/promises';
|
|
11
|
+
import { CraftdriverError, ErrorCode } from './errors.js';
|
|
12
|
+
const KNOWN_SECTIONS = new Set(['cookies', 'localStorage', 'sessionStorage']);
|
|
13
|
+
const COOKIE_FIELDS = new Set([
|
|
14
|
+
'name', 'value', 'domain', 'path', 'httpOnly', 'secure', 'sameSite', 'expiry', 'size',
|
|
15
|
+
]);
|
|
16
|
+
const SAME_SITE_VALUES = new Set(['strict', 'lax', 'none', 'default']);
|
|
17
|
+
export function storageStateDetail(context, phase, extra) {
|
|
18
|
+
return {
|
|
19
|
+
feature: 'storageState',
|
|
20
|
+
operation: context?.operation ?? 'restore',
|
|
21
|
+
browserName: context?.browserName ?? 'unknown',
|
|
22
|
+
protocol: context?.protocol ?? 'unknown',
|
|
23
|
+
phase,
|
|
24
|
+
...extra,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** True for an error already carrying this feature's structured contract. */
|
|
28
|
+
export function isStorageStateError(error) {
|
|
29
|
+
return CraftdriverError.is(error) && error.detail?.feature === 'storageState';
|
|
30
|
+
}
|
|
31
|
+
function invalid(message, context, extra) {
|
|
32
|
+
throw new CraftdriverError(ErrorCode.INVALID_ARGUMENT, message, {
|
|
33
|
+
detail: storageStateDetail(context, 'validation', extra),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function isPlainObject(value) {
|
|
37
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
38
|
+
return false;
|
|
39
|
+
const proto = Object.getPrototypeOf(value);
|
|
40
|
+
return proto === Object.prototype || proto === null;
|
|
41
|
+
}
|
|
42
|
+
/** A canonical http(s) origin: `scheme://host[:port]`, no path or trailing slash. */
|
|
43
|
+
export function isHttpOrigin(origin) {
|
|
44
|
+
try {
|
|
45
|
+
const u = new URL(origin);
|
|
46
|
+
return (u.protocol === 'http:' || u.protocol === 'https:') && u.origin === origin;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function validateOriginMap(section, map, context) {
|
|
53
|
+
if (map === undefined)
|
|
54
|
+
return;
|
|
55
|
+
if (!isPlainObject(map)) {
|
|
56
|
+
invalid(`state.${section} must be an object keyed by origin`, context, { section });
|
|
57
|
+
}
|
|
58
|
+
for (const [origin, entries] of Object.entries(map)) {
|
|
59
|
+
if (!isHttpOrigin(origin)) {
|
|
60
|
+
invalid(`state.${section} contains a non-canonical HTTP(S) origin`, context, {
|
|
61
|
+
section,
|
|
62
|
+
origin,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (!isPlainObject(entries)) {
|
|
66
|
+
invalid(`state.${section} entries must be maps of string keys to string values`, context, {
|
|
67
|
+
section,
|
|
68
|
+
origin,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
for (const value of Object.values(entries)) {
|
|
72
|
+
if (typeof value !== 'string') {
|
|
73
|
+
invalid(`state.${section} values must be strings`, context, { section, origin });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function validateCookies(cookies, context) {
|
|
79
|
+
if (cookies === undefined)
|
|
80
|
+
return;
|
|
81
|
+
if (!Array.isArray(cookies))
|
|
82
|
+
invalid('state.cookies must be an array', context, { section: 'cookies' });
|
|
83
|
+
for (const entry of cookies) {
|
|
84
|
+
if (!isPlainObject(entry)) {
|
|
85
|
+
invalid('state.cookies entries must be plain objects', context, { section: 'cookies' });
|
|
86
|
+
}
|
|
87
|
+
const cookie = entry;
|
|
88
|
+
// BiDi implementations may attach namespaced, capture-only metadata
|
|
89
|
+
// (`goog:priority`, etc.). Preserve compatibility with files CraftDriver
|
|
90
|
+
// previously emitted; normalization drops these fields before mutation.
|
|
91
|
+
const unknown = Object.keys(cookie).find((key) => !COOKIE_FIELDS.has(key) && !key.includes(':'));
|
|
92
|
+
if (unknown) {
|
|
93
|
+
invalid('state.cookies contains an unsupported cookie field', context, {
|
|
94
|
+
section: 'cookies',
|
|
95
|
+
field: unknown,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (typeof cookie.name !== 'string' || cookie.name.length === 0) {
|
|
99
|
+
invalid('each cookie needs a non-empty string name', context, { section: 'cookies' });
|
|
100
|
+
}
|
|
101
|
+
if (/[^\u0021-\u007E]|[()<>@,;:\\"/\[\]?={}]/.test(cookie.name)) {
|
|
102
|
+
invalid('cookie name contains characters WebDriver cannot set', context, { section: 'cookies' });
|
|
103
|
+
}
|
|
104
|
+
if (typeof cookie.value !== 'string') {
|
|
105
|
+
invalid('each cookie value must be a string', context, { section: 'cookies' });
|
|
106
|
+
}
|
|
107
|
+
if (typeof cookie.domain !== 'string' || cookie.domain.trim().length === 0) {
|
|
108
|
+
invalid('each cookie needs a non-empty string domain', context, { section: 'cookies' });
|
|
109
|
+
}
|
|
110
|
+
if (typeof cookie.domain === 'string' &&
|
|
111
|
+
(/\s/.test(cookie.domain) || cookie.domain.includes('/') || cookie.domain.endsWith('.'))) {
|
|
112
|
+
invalid('cookie domain is not a valid host or domain suffix', context, { section: 'cookies' });
|
|
113
|
+
}
|
|
114
|
+
if (cookie.path !== undefined &&
|
|
115
|
+
(typeof cookie.path !== 'string' || !cookie.path.startsWith('/'))) {
|
|
116
|
+
invalid('cookie path must be a string beginning with "/"', context, { section: 'cookies' });
|
|
117
|
+
}
|
|
118
|
+
for (const field of ['httpOnly', 'secure']) {
|
|
119
|
+
if (cookie[field] !== undefined && typeof cookie[field] !== 'boolean') {
|
|
120
|
+
invalid(`cookie ${field} must be a boolean`, context, { section: 'cookies', field });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (cookie.sameSite !== undefined &&
|
|
124
|
+
(typeof cookie.sameSite !== 'string' || !SAME_SITE_VALUES.has(cookie.sameSite))) {
|
|
125
|
+
invalid('cookie sameSite must be strict, lax, none, or default', context, {
|
|
126
|
+
section: 'cookies',
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (cookie.expiry !== undefined &&
|
|
130
|
+
(typeof cookie.expiry !== 'number' || !Number.isFinite(cookie.expiry))) {
|
|
131
|
+
invalid('cookie expiry must be a finite number', context, { section: 'cookies' });
|
|
132
|
+
}
|
|
133
|
+
if (cookie.size !== undefined &&
|
|
134
|
+
(typeof cookie.size !== 'number' || !Number.isInteger(cookie.size) || cookie.size < 0)) {
|
|
135
|
+
invalid('cookie size must be a non-negative integer', context, { section: 'cookies' });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Parse `source` (a path or an in-memory object) into a validated
|
|
141
|
+
* {@link SessionState}. Malformed shapes throw `INVALID_ARGUMENT`; unknown or
|
|
142
|
+
* legacy sections throw `UNSUPPORTED`.
|
|
143
|
+
*/
|
|
144
|
+
export async function parseSessionState(source, context) {
|
|
145
|
+
let raw;
|
|
146
|
+
if (typeof source === 'string') {
|
|
147
|
+
let text;
|
|
148
|
+
try {
|
|
149
|
+
text = await fs.readFile(source, 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
invalid(`could not read state file ${source}: ${err.message}`, context);
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
raw = JSON.parse(text);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
invalid(`state file ${source} is not valid JSON`, context);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
raw = source;
|
|
163
|
+
}
|
|
164
|
+
if (!isPlainObject(raw)) {
|
|
165
|
+
invalid('session state must be a plain JSON object', context);
|
|
166
|
+
}
|
|
167
|
+
const obj = raw;
|
|
168
|
+
for (const key of Object.keys(obj)) {
|
|
169
|
+
if (!KNOWN_SECTIONS.has(key)) {
|
|
170
|
+
throw new CraftdriverError(ErrorCode.UNSUPPORTED, `unsupported state section ${JSON.stringify(key)} — craftdriver restores ` +
|
|
171
|
+
`cookies, localStorage, and sessionStorage only`, { detail: storageStateDetail(context, 'validation', { section: key }) });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
validateCookies(obj.cookies, context);
|
|
175
|
+
validateOriginMap('localStorage', obj.localStorage, context);
|
|
176
|
+
validateOriginMap('sessionStorage', obj.sessionStorage, context);
|
|
177
|
+
return obj;
|
|
178
|
+
}
|
|
179
|
+
/** Origins in `map` that actually carry at least one entry. */
|
|
180
|
+
export function nonEmptyOrigins(map) {
|
|
181
|
+
if (!map)
|
|
182
|
+
return [];
|
|
183
|
+
return Object.keys(map).filter((origin) => map[origin] && Object.keys(map[origin]).length > 0);
|
|
184
|
+
}
|
|
185
|
+
/** True when the state carries at least one origin with ≥1 sessionStorage entry. */
|
|
186
|
+
export function hasNonEmptySessionStorage(state) {
|
|
187
|
+
return nonEmptyOrigins(state.sessionStorage).length > 0;
|
|
188
|
+
}
|
|
189
|
+
/** True when a valid state has no cookie or storage mutations to apply. */
|
|
190
|
+
export function isSessionStateEmpty(state) {
|
|
191
|
+
return ((state.cookies?.length ?? 0) === 0 &&
|
|
192
|
+
nonEmptyOrigins(state.localStorage).length === 0 &&
|
|
193
|
+
nonEmptyOrigins(state.sessionStorage).length === 0);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Convert a captured cookie into the one canonical restore shape used by every
|
|
197
|
+
* protocol path. Browser read APIs may report `sameSite: 'default'`, and some
|
|
198
|
+
* engines report insecure `sameSite: 'none'`; neither can be replayed literally
|
|
199
|
+
* through all WebDriver cookie commands, so omit sameSite and let the engine
|
|
200
|
+
* apply its default consistently. `size` is capture-only and is never written.
|
|
201
|
+
*/
|
|
202
|
+
export function normalizeCookieForRestore(cookie) {
|
|
203
|
+
const normalized = {
|
|
204
|
+
name: cookie.name,
|
|
205
|
+
value: cookie.value,
|
|
206
|
+
domain: cookie.domain,
|
|
207
|
+
};
|
|
208
|
+
if (cookie.path !== undefined)
|
|
209
|
+
normalized.path = cookie.path;
|
|
210
|
+
if (cookie.httpOnly !== undefined)
|
|
211
|
+
normalized.httpOnly = cookie.httpOnly;
|
|
212
|
+
if (cookie.secure !== undefined)
|
|
213
|
+
normalized.secure = cookie.secure;
|
|
214
|
+
if (cookie.expiry !== undefined)
|
|
215
|
+
normalized.expiry = cookie.expiry;
|
|
216
|
+
if (cookie.sameSite !== undefined &&
|
|
217
|
+
cookie.sameSite !== 'default' &&
|
|
218
|
+
!(cookie.sameSite === 'none' && !cookie.secure)) {
|
|
219
|
+
normalized.sameSite = cookie.sameSite;
|
|
220
|
+
}
|
|
221
|
+
return normalized;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=sessionStateValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionStateValidation.js","sourceRoot":"","sources":["../../src/lib/sessionStateValidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { By } from './by.js';
|
|
2
|
+
import type { Driver } from './driver.js';
|
|
3
|
+
import type { WebElement } from './webelement.js';
|
|
4
|
+
/** W3C WebDriver shadow-root reference key. */
|
|
5
|
+
export declare const W3C_SHADOW_ROOT_KEY = "shadow-6066-11e4-a52e-4f735466cecf";
|
|
6
|
+
/**
|
|
7
|
+
* A WebDriver Classic shadow-root search context.
|
|
8
|
+
*
|
|
9
|
+
* This is intentionally internal. The public API exposes the lazy
|
|
10
|
+
* `ShadowRootLocator`, not a cacheable wire reference that can detach.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ClassicShadowRoot {
|
|
13
|
+
private driver;
|
|
14
|
+
private shadowRootId;
|
|
15
|
+
constructor(driver: Driver, shadowRootId: string);
|
|
16
|
+
getId(): string;
|
|
17
|
+
findElement(locator: By): Promise<WebElement>;
|
|
18
|
+
findElements(locator: By): Promise<WebElement[]>;
|
|
19
|
+
toJSON(): Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=shadowRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowRoot.d.ts","sourceRoot":"","sources":["../../src/lib/shadowRoot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB,uCAAuC,CAAC;AAExE;;;;;GAKG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;gBADZ,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM;IAG9B,KAAK,IAAI,MAAM;IAIf,WAAW,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7C,YAAY,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIhD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAGjC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** W3C WebDriver shadow-root reference key. */
|
|
2
|
+
export const W3C_SHADOW_ROOT_KEY = 'shadow-6066-11e4-a52e-4f735466cecf';
|
|
3
|
+
/**
|
|
4
|
+
* A WebDriver Classic shadow-root search context.
|
|
5
|
+
*
|
|
6
|
+
* This is intentionally internal. The public API exposes the lazy
|
|
7
|
+
* `ShadowRootLocator`, not a cacheable wire reference that can detach.
|
|
8
|
+
*/
|
|
9
|
+
export class ClassicShadowRoot {
|
|
10
|
+
driver;
|
|
11
|
+
shadowRootId;
|
|
12
|
+
constructor(driver, shadowRootId) {
|
|
13
|
+
this.driver = driver;
|
|
14
|
+
this.shadowRootId = shadowRootId;
|
|
15
|
+
}
|
|
16
|
+
getId() {
|
|
17
|
+
return this.shadowRootId;
|
|
18
|
+
}
|
|
19
|
+
findElement(locator) {
|
|
20
|
+
return this.driver.findElementFromShadowRoot(this.shadowRootId, locator);
|
|
21
|
+
}
|
|
22
|
+
findElements(locator) {
|
|
23
|
+
return this.driver.findElementsFromShadowRoot(this.shadowRootId, locator);
|
|
24
|
+
}
|
|
25
|
+
toJSON() {
|
|
26
|
+
return { [W3C_SHADOW_ROOT_KEY]: this.shadowRootId };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=shadowRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowRoot.js","sourceRoot":"","sources":["../../src/lib/shadowRoot.ts"],"names":[],"mappings":"AAIA,+CAA+C;AAC/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,oCAAoC,CAAC;AAExE;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAElB;IACA;IAFV,YACU,MAAc,EACd,YAAoB;QADpB,WAAM,GAAN,MAAM,CAAQ;QACd,iBAAY,GAAZ,YAAY,CAAQ;IAC3B,CAAC;IAEJ,KAAK;QACH,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,WAAW,CAAC,OAAW;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,YAAY,CAAC,OAAW;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,CAAC,mBAAmB,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;IACtD,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { By, type ExactLocatorOptions, type RoleLocatorOptions } from './by.js';
|
|
2
|
+
import type { Driver } from './driver.js';
|
|
3
|
+
import { ElementHandle } from './elementHandle.js';
|
|
4
|
+
import { Locator } from './locator.js';
|
|
5
|
+
import { QueryEnvironment, type SearchRootPlan } from './query.js';
|
|
6
|
+
/**
|
|
7
|
+
* Lazy, explicit search context for one open ShadowRoot.
|
|
8
|
+
*
|
|
9
|
+
* It deliberately exposes lookup methods only: a ShadowRoot is a document
|
|
10
|
+
* fragment, not an actionable element.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ShadowRootLocator {
|
|
13
|
+
private driver;
|
|
14
|
+
private root;
|
|
15
|
+
private getDefaultTimeout;
|
|
16
|
+
private environment;
|
|
17
|
+
constructor(driver: Driver, root: SearchRootPlan, getDefaultTimeout: () => number, environment: QueryEnvironment);
|
|
18
|
+
locator(selector: string | By): Locator;
|
|
19
|
+
find(selector: string | By): ElementHandle;
|
|
20
|
+
findAll(selector: string | By): Promise<ElementHandle[]>;
|
|
21
|
+
getByRole(role: string, options?: RoleLocatorOptions): Locator;
|
|
22
|
+
getByText(text: string, options?: {
|
|
23
|
+
exact?: boolean;
|
|
24
|
+
}): Locator;
|
|
25
|
+
getByLabel(text: string, options?: ExactLocatorOptions): Locator;
|
|
26
|
+
getByPlaceholder(text: string, options?: ExactLocatorOptions): Locator;
|
|
27
|
+
getByAltText(text: string, options?: ExactLocatorOptions): Locator;
|
|
28
|
+
getByTitle(text: string, options?: ExactLocatorOptions): Locator;
|
|
29
|
+
getByTestId(id: string): Locator;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=shadowRootLocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowRootLocator.d.ts","sourceRoot":"","sources":["../../src/lib/shadowRootLocator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,gBAAgB,EAEhB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,WAAW;gBAHX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,EACpB,iBAAiB,EAAE,MAAM,MAAM,EAC/B,WAAW,EAAE,gBAAgB;IAGvC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,GAAG,OAAO;IAUvC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,GAAG,aAAa;IAUpC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAI9D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO;IAI9D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IAI/D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO;IAIhE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO;IAItE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO;IAIlE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO;IAIhE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAGjC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { By } from './by.js';
|
|
2
|
+
import { ElementHandle } from './elementHandle.js';
|
|
3
|
+
import { Locator } from './locator.js';
|
|
4
|
+
import { createLocatorPlan, } from './query.js';
|
|
5
|
+
/**
|
|
6
|
+
* Lazy, explicit search context for one open ShadowRoot.
|
|
7
|
+
*
|
|
8
|
+
* It deliberately exposes lookup methods only: a ShadowRoot is a document
|
|
9
|
+
* fragment, not an actionable element.
|
|
10
|
+
*/
|
|
11
|
+
export class ShadowRootLocator {
|
|
12
|
+
driver;
|
|
13
|
+
root;
|
|
14
|
+
getDefaultTimeout;
|
|
15
|
+
environment;
|
|
16
|
+
constructor(driver, root, getDefaultTimeout, environment) {
|
|
17
|
+
this.driver = driver;
|
|
18
|
+
this.root = root;
|
|
19
|
+
this.getDefaultTimeout = getDefaultTimeout;
|
|
20
|
+
this.environment = environment;
|
|
21
|
+
}
|
|
22
|
+
locator(selector) {
|
|
23
|
+
const by = typeof selector === 'string' ? By.css(selector) : selector;
|
|
24
|
+
return Locator.fromPlan(this.driver, createLocatorPlan(by, this.root), this.getDefaultTimeout, this.environment);
|
|
25
|
+
}
|
|
26
|
+
find(selector) {
|
|
27
|
+
const locator = this.locator(selector);
|
|
28
|
+
return ElementHandle.fromTarget(this.driver, { kind: 'locator', plan: locator._queryPlan() }, this.getDefaultTimeout, this.environment);
|
|
29
|
+
}
|
|
30
|
+
async findAll(selector) {
|
|
31
|
+
return this.locator(selector).all();
|
|
32
|
+
}
|
|
33
|
+
getByRole(role, options) {
|
|
34
|
+
return this.locator(By.role(role, options));
|
|
35
|
+
}
|
|
36
|
+
getByText(text, options) {
|
|
37
|
+
return this.locator(By.text(text, options));
|
|
38
|
+
}
|
|
39
|
+
getByLabel(text, options) {
|
|
40
|
+
return this.locator(By.labelText(text, options));
|
|
41
|
+
}
|
|
42
|
+
getByPlaceholder(text, options) {
|
|
43
|
+
return this.locator(By.placeholder(text, options));
|
|
44
|
+
}
|
|
45
|
+
getByAltText(text, options) {
|
|
46
|
+
return this.locator(By.altText(text, options));
|
|
47
|
+
}
|
|
48
|
+
getByTitle(text, options) {
|
|
49
|
+
return this.locator(By.title(text, options));
|
|
50
|
+
}
|
|
51
|
+
getByTestId(id) {
|
|
52
|
+
return this.locator(By.testId(id));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=shadowRootLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadowRootLocator.js","sourceRoot":"","sources":["../../src/lib/shadowRootLocator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAqD,MAAM,SAAS,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAEL,iBAAiB,GAElB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAElB;IACA;IACA;IACA;IAJV,YACU,MAAc,EACd,IAAoB,EACpB,iBAA+B,EAC/B,WAA6B;QAH7B,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAgB;QACpB,sBAAiB,GAAjB,iBAAiB,CAAc;QAC/B,gBAAW,GAAX,WAAW,CAAkB;IACpC,CAAC;IAEJ,OAAO,CAAC,QAAqB;QAC3B,MAAM,EAAE,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtE,OAAO,OAAO,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,EACX,iBAAiB,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAChC,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,WAAW,CACjB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAqB;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,aAAa,CAAC,UAAU,CAC7B,IAAI,CAAC,MAAM,EACX,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,EAC/C,IAAI,CAAC,iBAAiB,EACtB,IAAI,CAAC,WAAW,CACjB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAqB;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;IACtC,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,OAA4B;QAClD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,OAA6B;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,OAA6B;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,gBAAgB,CAAC,IAAY,EAAE,OAA6B;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,YAAY,CAAC,IAAY,EAAE,OAA6B;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,OAA6B;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,WAAW,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;CACF"}
|
package/dist/lib/timing.d.ts
CHANGED
|
@@ -117,8 +117,8 @@ export declare const SESSION_CREATE_BACKOFF_STEP_MS = 500;
|
|
|
117
117
|
* a barrier the BiDi side respects — an immediately following `{ context }`
|
|
118
118
|
* script call can land while BiDi is still swapping the old realm for the new
|
|
119
119
|
* one. The error is pre-execution (the script never ran, no side effects), so a
|
|
120
|
-
* short retry that re-resolves the context is safe.
|
|
121
|
-
*
|
|
120
|
+
* short retry that re-resolves the context is safe. The injected-error
|
|
121
|
+
* regression case lives in `tests/evaluate.test.ts`.
|
|
122
122
|
*/
|
|
123
123
|
export declare const EVAL_REALM_RETRY_ATTEMPTS = 3;
|
|
124
124
|
export declare const EVAL_REALM_RETRY_DELAY_MS = 25;
|
package/dist/lib/timing.js
CHANGED
|
@@ -121,8 +121,8 @@ export const SESSION_CREATE_BACKOFF_STEP_MS = 500;
|
|
|
121
121
|
* a barrier the BiDi side respects — an immediately following `{ context }`
|
|
122
122
|
* script call can land while BiDi is still swapping the old realm for the new
|
|
123
123
|
* one. The error is pre-execution (the script never ran, no side effects), so a
|
|
124
|
-
* short retry that re-resolves the context is safe.
|
|
125
|
-
*
|
|
124
|
+
* short retry that re-resolves the context is safe. The injected-error
|
|
125
|
+
* regression case lives in `tests/evaluate.test.ts`.
|
|
126
126
|
*/
|
|
127
127
|
export const EVAL_REALM_RETRY_ATTEMPTS = 3;
|
|
128
128
|
export const EVAL_REALM_RETRY_DELAY_MS = 25;
|
package/dist/lib/tracing.d.ts
CHANGED
|
@@ -97,6 +97,7 @@ export type TraceEvent = {
|
|
|
97
97
|
};
|
|
98
98
|
export declare class Tracer {
|
|
99
99
|
private browserName;
|
|
100
|
+
private isInternalContext;
|
|
100
101
|
private browser;
|
|
101
102
|
private conn;
|
|
102
103
|
private startedAtMs;
|
|
@@ -113,7 +114,7 @@ export declare class Tracer {
|
|
|
113
114
|
private actionIndex;
|
|
114
115
|
/** Tracks in-flight screenshot captures so `stop()` can drain them. */
|
|
115
116
|
private pendingCaptures;
|
|
116
|
-
constructor(browser: Browser, conn: BiDiConnection, browserName: string);
|
|
117
|
+
constructor(browser: Browser, conn: BiDiConnection, browserName: string, isInternalContext?: (context: string | null | undefined) => boolean);
|
|
117
118
|
get isRunning(): boolean;
|
|
118
119
|
start(opts: TraceStartOptions): Promise<void>;
|
|
119
120
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/lib/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,mCAAmC;AACnC,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACjF;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACrH;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAA;CAAE,GAC3G;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,qBAAa,MAAM;IAqBf,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/lib/tracing.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/tracing.js
CHANGED
|
@@ -16,6 +16,7 @@ import { join } from 'node:path';
|
|
|
16
16
|
import { writeVibiumTraceZip } from './vibiumTrace.js';
|
|
17
17
|
export class Tracer {
|
|
18
18
|
browserName;
|
|
19
|
+
isInternalContext;
|
|
19
20
|
browser;
|
|
20
21
|
conn;
|
|
21
22
|
startedAtMs = 0;
|
|
@@ -32,8 +33,9 @@ export class Tracer {
|
|
|
32
33
|
actionIndex = 0;
|
|
33
34
|
/** Tracks in-flight screenshot captures so `stop()` can drain them. */
|
|
34
35
|
pendingCaptures = [];
|
|
35
|
-
constructor(browser, conn, browserName) {
|
|
36
|
+
constructor(browser, conn, browserName, isInternalContext = () => false) {
|
|
36
37
|
this.browserName = browserName;
|
|
38
|
+
this.isInternalContext = isInternalContext;
|
|
37
39
|
this.browser = browser;
|
|
38
40
|
this.conn = conn;
|
|
39
41
|
}
|
|
@@ -86,6 +88,9 @@ export class Tracer {
|
|
|
86
88
|
if (consoleOn) {
|
|
87
89
|
this.unsubs.push(this.conn.on('log.entryAdded', (params) => {
|
|
88
90
|
const p = params;
|
|
91
|
+
const source = (p.source ?? {});
|
|
92
|
+
if (this.isInternalContext(source.context))
|
|
93
|
+
return;
|
|
89
94
|
const text = String(p.text ?? '');
|
|
90
95
|
if (p.type === 'console') {
|
|
91
96
|
this.push({ type: 'console', level: String(p.level ?? 'info'), text });
|
|
@@ -100,6 +105,8 @@ export class Tracer {
|
|
|
100
105
|
if (networkOn) {
|
|
101
106
|
this.unsubs.push(this.conn.on('network.beforeRequestSent', (params) => {
|
|
102
107
|
const p = params;
|
|
108
|
+
if (this.isInternalContext(p.context))
|
|
109
|
+
return;
|
|
103
110
|
const req = (p.request ?? {});
|
|
104
111
|
this.push({
|
|
105
112
|
type: 'request',
|
|
@@ -110,6 +117,8 @@ export class Tracer {
|
|
|
110
117
|
}));
|
|
111
118
|
this.unsubs.push(this.conn.on('network.responseCompleted', (params) => {
|
|
112
119
|
const p = params;
|
|
120
|
+
if (this.isInternalContext(p.context))
|
|
121
|
+
return;
|
|
113
122
|
const req = (p.request ?? {});
|
|
114
123
|
const res = (p.response ?? {});
|
|
115
124
|
const ev = {
|
|
@@ -128,6 +137,8 @@ export class Tracer {
|
|
|
128
137
|
}
|
|
129
138
|
this.unsubs.push(this.conn.on('browsingContext.navigationStarted', (params) => {
|
|
130
139
|
const p = params;
|
|
140
|
+
if (this.isInternalContext(p.context))
|
|
141
|
+
return;
|
|
131
142
|
this.push({
|
|
132
143
|
type: 'navigation',
|
|
133
144
|
url: String(p.url ?? ''),
|