craftdriver 0.2.2 → 1.0.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/CHANGELOG.md +84 -0
- package/dist/cli/mcp/server.js +16 -3
- package/dist/cli/mcp/server.js.map +1 -1
- package/dist/lib/bidi/connection.d.ts +1 -1
- package/dist/lib/bidi/connection.d.ts.map +1 -1
- package/dist/lib/bidi/connection.js +3 -2
- package/dist/lib/bidi/connection.js.map +1 -1
- package/dist/lib/bidi/index.d.ts +40 -3
- package/dist/lib/bidi/index.d.ts.map +1 -1
- package/dist/lib/bidi/index.js +55 -18
- package/dist/lib/bidi/index.js.map +1 -1
- package/dist/lib/bidi/logs.d.ts.map +1 -1
- package/dist/lib/bidi/logs.js +7 -2
- package/dist/lib/bidi/logs.js.map +1 -1
- package/dist/lib/bidi/network.d.ts +9 -0
- package/dist/lib/bidi/network.d.ts.map +1 -1
- package/dist/lib/bidi/network.js +26 -11
- package/dist/lib/bidi/network.js.map +1 -1
- package/dist/lib/browser.d.ts +42 -4
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +140 -62
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +7 -2
- package/dist/lib/browserContext.d.ts.map +1 -1
- package/dist/lib/browserContext.js +15 -6
- package/dist/lib/browserContext.js.map +1 -1
- package/dist/lib/builder.d.ts +2 -1
- package/dist/lib/builder.d.ts.map +1 -1
- package/dist/lib/builder.js +35 -5
- package/dist/lib/builder.js.map +1 -1
- package/dist/lib/clickFastPath.d.ts +7 -0
- package/dist/lib/clickFastPath.d.ts.map +1 -0
- package/dist/lib/clickFastPath.js +39 -0
- package/dist/lib/clickFastPath.js.map +1 -0
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +21 -6
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/driverManager.d.ts +6 -0
- package/dist/lib/driverManager.d.ts.map +1 -1
- package/dist/lib/driverManager.js +97 -22
- package/dist/lib/driverManager.js.map +1 -1
- package/dist/lib/elementHandle.d.ts.map +1 -1
- package/dist/lib/elementHandle.js +7 -2
- package/dist/lib/elementHandle.js.map +1 -1
- package/dist/lib/expect.d.ts.map +1 -1
- package/dist/lib/expect.js +91 -229
- package/dist/lib/expect.js.map +1 -1
- package/dist/lib/firefox.d.ts.map +1 -1
- package/dist/lib/firefox.js +2 -1
- package/dist/lib/firefox.js.map +1 -1
- package/dist/lib/frame.d.ts.map +1 -1
- package/dist/lib/frame.js +7 -7
- package/dist/lib/frame.js.map +1 -1
- package/dist/lib/http.d.ts +7 -0
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +112 -3
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/loadState.d.ts +23 -0
- package/dist/lib/loadState.d.ts.map +1 -0
- package/dist/lib/loadState.js +25 -0
- package/dist/lib/loadState.js.map +1 -0
- package/dist/lib/locator.d.ts +2 -0
- package/dist/lib/locator.d.ts.map +1 -1
- package/dist/lib/locator.js +19 -6
- package/dist/lib/locator.js.map +1 -1
- package/dist/lib/mouse.d.ts.map +1 -1
- package/dist/lib/mouse.js +2 -1
- package/dist/lib/mouse.js.map +1 -1
- package/dist/lib/page.d.ts +14 -1
- package/dist/lib/page.d.ts.map +1 -1
- package/dist/lib/page.js +66 -15
- package/dist/lib/page.js.map +1 -1
- package/dist/lib/service.d.ts +1 -0
- package/dist/lib/service.d.ts.map +1 -1
- package/dist/lib/service.js +21 -3
- package/dist/lib/service.js.map +1 -1
- package/dist/lib/timing.d.ts +104 -0
- package/dist/lib/timing.d.ts.map +1 -0
- package/dist/lib/timing.js +108 -0
- package/dist/lib/timing.js.map +1 -0
- package/dist/lib/wait.d.ts.map +1 -1
- package/dist/lib/wait.js +13 -6
- package/dist/lib/wait.js.map +1 -1
- package/docs/bidi-features.md +10 -2
- package/docs/browser-api.md +2 -1
- package/docs/browser-context.md +11 -14
- package/docs/dialogs.md +14 -3
- package/docs/driver-configuration.md +126 -8
- package/docs/emulation.md +8 -4
- package/docs/error-codes.md +9 -4
- package/docs/keyboard-mouse.md +20 -7
- package/docs/session-management.md +1 -1
- package/package.json +4 -1
- package/skills/craftdriver/SKILL.md +3 -2
|
@@ -7,13 +7,25 @@ Craftdriver resolves the WebDriver binary through a chain — first match wins:
|
|
|
7
7
|
| 1 | `driverPath` option in `Browser.launch()` |
|
|
8
8
|
| 2 | `CRAFTDRIVER_CHROMEDRIVER_PATH` / `CRAFTDRIVER_GECKODRIVER_PATH` env var |
|
|
9
9
|
| 3 | `CRAFTDRIVER_DRIVER_PATH` env var (generic fallback for either browser) |
|
|
10
|
-
| 4 | `
|
|
11
|
-
| 5 |
|
|
12
|
-
| 6 |
|
|
10
|
+
| 4 | Legacy/Selenium-compatible env vars: `CHROMEDRIVER_PATH`, `SE_CHROMEDRIVER` (chromedriver) or `GECKODRIVER_PATH`, `GECKODRIVER_FILEPATH`, `SE_GECKODRIVER` (geckodriver) |
|
|
11
|
+
| 5 | **Cached auto-resolution** — the path a previous auto-resolve settled on, reused within the `CRAFTDRIVER_DRIVER_TTL` window |
|
|
12
|
+
| 6 | `chromedriver` / `geckodriver` in `node_modules/.bin` |
|
|
13
|
+
| 7 | `chromedriver` / `geckodriver` on `PATH` |
|
|
14
|
+
| 8 | **Auto-download from Chrome for Testing / GitHub** ← the zero-config default |
|
|
13
15
|
|
|
14
|
-
Downloaded drivers are cached in `~/.cache/craftdriver
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
Downloaded drivers are cached in `~/.cache/craftdriver`, and so is the
|
|
17
|
+
*resolution itself* — which driver path to use. Within the
|
|
18
|
+
`CRAFTDRIVER_DRIVER_TTL` window (default 24 h), craftdriver reuses the
|
|
19
|
+
resolved path directly and skips the system-browser probes it would
|
|
20
|
+
otherwise run on **every** launch: launching the browser binary just to read
|
|
21
|
+
its version string, and a `PATH` lookup. Both are blocking calls, so caching
|
|
22
|
+
the resolution measurably speeds up launch — most noticeably when several
|
|
23
|
+
browsers start in parallel (see [Performance](#performance)). After the TTL
|
|
24
|
+
expires, or if Chrome reports that the cached chromedriver is for the wrong
|
|
25
|
+
major version after a browser upgrade, the driver is re-resolved and
|
|
26
|
+
re-downloaded if needed. Only the driver binary is ever downloaded, never the
|
|
27
|
+
browser itself. Explicit configuration (steps 1–4) always takes precedence over
|
|
28
|
+
the cache.
|
|
17
29
|
|
|
18
30
|
## Environment variables
|
|
19
31
|
|
|
@@ -24,7 +36,7 @@ never the browser itself.
|
|
|
24
36
|
| `CRAFTDRIVER_DRIVER_PATH` | Generic fallback path (either browser) | — |
|
|
25
37
|
| `CRAFTDRIVER_CACHE_DIR` | Directory for cached driver downloads | `~/.cache/craftdriver` |
|
|
26
38
|
| `CRAFTDRIVER_OFFLINE` | Set to `1` to disable all network calls | — |
|
|
27
|
-
| `CRAFTDRIVER_DRIVER_TTL` |
|
|
39
|
+
| `CRAFTDRIVER_DRIVER_TTL` | Driver-resolution cache lifetime, in seconds (both browsers). `0` disables the cache | `86400` (24 h) |
|
|
28
40
|
|
|
29
41
|
## Examples
|
|
30
42
|
|
|
@@ -35,7 +47,7 @@ CRAFTDRIVER_CHROMEDRIVER_PATH=/usr/bin/chromedriver npm test
|
|
|
35
47
|
# Pin a specific geckodriver
|
|
36
48
|
CRAFTDRIVER_GECKODRIVER_PATH=/usr/local/bin/geckodriver npm test
|
|
37
49
|
|
|
38
|
-
# Never make a network call (requires a local driver to exist in steps 1–
|
|
50
|
+
# Never make a network call (requires a local driver to exist in steps 1–7)
|
|
39
51
|
CRAFTDRIVER_OFFLINE=1 npm test
|
|
40
52
|
|
|
41
53
|
# Change the cache location
|
|
@@ -45,6 +57,112 @@ CRAFTDRIVER_CACHE_DIR=/tmp/my-driver-cache npm test
|
|
|
45
57
|
CRAFTDRIVER_DRIVER_TTL=3600 npm test
|
|
46
58
|
```
|
|
47
59
|
|
|
60
|
+
## Performance
|
|
61
|
+
|
|
62
|
+
Most of the time `Browser.launch()` spends is the browser process starting up
|
|
63
|
+
(that's the same for WebDriver Classic and BiDi and there's little a client
|
|
64
|
+
library can do about it). The part craftdriver *does* control is resolving and
|
|
65
|
+
starting the driver, and it's tuned to stay out of the way:
|
|
66
|
+
|
|
67
|
+
- **Driver resolution is cached** (see above). Without a cache, resolving a
|
|
68
|
+
chromedriver means launching your Chrome binary just to read its version
|
|
69
|
+
string — a blocking call of a few hundred milliseconds on *every* launch.
|
|
70
|
+
The TTL cache skips that after the first launch.
|
|
71
|
+
- **Point at a driver explicitly to skip resolution entirely.** If you set
|
|
72
|
+
`CRAFTDRIVER_CHROMEDRIVER_PATH` / `CRAFTDRIVER_GECKODRIVER_PATH` (or pass
|
|
73
|
+
`chromeService: new ChromeService({ binaryPath })`), craftdriver uses it
|
|
74
|
+
directly — no version detection, no `PATH` lookup, no cache read. This is
|
|
75
|
+
the fastest and most deterministic option and is recommended for CI:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
CRAFTDRIVER_CHROMEDRIVER_PATH=/opt/chromedriver/chromedriver npm test
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- **Parallel runs benefit the most.** The resolution work that the cache (or an
|
|
82
|
+
explicit path) removes was synchronous and blocked the event loop, so it
|
|
83
|
+
serialized when several browsers were launched at once. Removing it lets
|
|
84
|
+
concurrent `Browser.launch()` calls overlap their startup (measured ~17–20%
|
|
85
|
+
faster wall time for a batch of concurrent launches).
|
|
86
|
+
|
|
87
|
+
### Concurrency and oversubscription
|
|
88
|
+
|
|
89
|
+
Once resolution is out of the way, the rest of launch time is the browser
|
|
90
|
+
process starting — and that is **CPU-bound**. Starting many browsers at once
|
|
91
|
+
on a machine with fewer CPU cores oversubscribes the CPU, and each browser's
|
|
92
|
+
startup slows down roughly in proportion. On an 8-core machine, for example, a
|
|
93
|
+
single launch is ~2s but 20 simultaneous launches take ~25s *each* (they still
|
|
94
|
+
finish sooner in aggregate than launching serially, just with diminishing
|
|
95
|
+
returns). This is not a craftdriver limitation — it's the browser competing for
|
|
96
|
+
CPU — and no client-side change removes it.
|
|
97
|
+
|
|
98
|
+
Practical guidance for parallel test suites (e.g. Vitest / Jest / Playwright
|
|
99
|
+
Test): **cap worker concurrency at roughly the number of CPU cores.** More
|
|
100
|
+
workers than cores mostly adds launch latency, and a launch that is merely slow
|
|
101
|
+
under heavy load can trip a short per-test/hook timeout and look like a hang.
|
|
102
|
+
With Vitest, set `maxWorkers` (or `poolOptions`) accordingly; a generous
|
|
103
|
+
`hookTimeout` for the `beforeAll` that launches the browser also helps on
|
|
104
|
+
loaded CI runners.
|
|
105
|
+
|
|
106
|
+
Indicative numbers from the `tests/perf/launch-critical-path.perf.ts`
|
|
107
|
+
benchmark (macOS, Chrome, headless — absolute values are machine-dependent,
|
|
108
|
+
but the direction holds):
|
|
109
|
+
|
|
110
|
+
| Scenario | Before | After |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `Browser.launch()` (BiDi) | ~2760ms | ~2240ms |
|
|
113
|
+
| `Browser.launch()` (Classic) | ~2400ms | ~1860ms |
|
|
114
|
+
| 4 browsers launched concurrently | ~6450ms | ~5130ms |
|
|
115
|
+
|
|
116
|
+
Run it yourself with `npm run bench -- launch-critical-path`.
|
|
117
|
+
|
|
118
|
+
### Browser startup flags (advanced, opt-in)
|
|
119
|
+
|
|
120
|
+
craftdriver launches the browser with **no performance flags of its own** — it
|
|
121
|
+
stays unopinionated so it never silently changes browser behavior underneath
|
|
122
|
+
you. If you want to experiment, you can pass extra browser command-line flags
|
|
123
|
+
via the `args` launch option (appended to `goog:chromeOptions.args` for
|
|
124
|
+
Chrome/Chromium, `moz:firefoxOptions.args` for Firefox):
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const browser = await Browser.launch({
|
|
128
|
+
browserName: 'chrome',
|
|
129
|
+
args: [
|
|
130
|
+
'--no-first-run',
|
|
131
|
+
'--no-default-browser-check',
|
|
132
|
+
'--disable-background-networking',
|
|
133
|
+
'--disable-component-update',
|
|
134
|
+
'--disable-default-apps',
|
|
135
|
+
'--disable-extensions',
|
|
136
|
+
'--disable-sync',
|
|
137
|
+
'--metrics-recording-only',
|
|
138
|
+
'--disable-background-timer-throttling',
|
|
139
|
+
'--disable-backgrounding-occluded-windows',
|
|
140
|
+
'--disable-renderer-backgrounding',
|
|
141
|
+
'--mute-audio',
|
|
142
|
+
'--no-service-autorun',
|
|
143
|
+
'--password-store=basic',
|
|
144
|
+
'--use-mock-keychain', // macOS: skip keychain access
|
|
145
|
+
'--disable-features=Translate,BackForwardCache,AcceptCHFrame,MediaRouter,OptimizationHints',
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
> `args` are **browser** flags. They are distinct from the **driver**
|
|
151
|
+
> (chromedriver/geckodriver) args you'd pass via `chromeService` /
|
|
152
|
+
> `firefoxService` below.
|
|
153
|
+
|
|
154
|
+
**Set expectations honestly:** on a normal local machine this set moved
|
|
155
|
+
`Browser.launch()` wall time by **~0.4% (≈8ms — noise)** in our measurements.
|
|
156
|
+
Cold browser startup is dominated by unavoidable process/engine init; these
|
|
157
|
+
flags mostly suppress *background* work (auto-updates, telemetry, background
|
|
158
|
+
networking, sync) that happens after startup rather than on the launch critical
|
|
159
|
+
path. So their real value is **determinism and avoiding intermittent stalls in
|
|
160
|
+
CI / constrained environments** (no update popups, no background network
|
|
161
|
+
calls), not raw local launch speed. If you adopt them, **measure on your own
|
|
162
|
+
environment** — the payoff is environment-dependent, and some flags can change
|
|
163
|
+
behavior (e.g. `--no-sandbox`, or `--disable-features=...` entries a page or
|
|
164
|
+
fixture relies on).
|
|
165
|
+
|
|
48
166
|
## Pinning via code
|
|
49
167
|
|
|
50
168
|
For tighter control (custom port, extra driver flags), pass a `ChromeService`
|
package/docs/emulation.md
CHANGED
|
@@ -25,12 +25,16 @@ await browser.emulate({
|
|
|
25
25
|
|
|
26
26
|
| Option | What the page sees | Transport | Cross-browser |
|
|
27
27
|
|---|---|---|---|
|
|
28
|
-
| `colorScheme` | `prefers-color-scheme` media query |
|
|
29
|
-
| `reducedMotion` | `prefers-reduced-motion` media query |
|
|
30
|
-
| `forcedColors` | `forced-colors` media query |
|
|
28
|
+
| `colorScheme` | `prefers-color-scheme` media query | CDP `Emulation.setEmulatedMedia` (over the BiDi+CDP bridge) | Chromium only |
|
|
29
|
+
| `reducedMotion` | `prefers-reduced-motion` media query | CDP `Emulation.setEmulatedMedia` (over the BiDi+CDP bridge) | Chromium only |
|
|
30
|
+
| `forcedColors` | `forced-colors` media query | CDP `Emulation.setEmulatedMedia` (over the BiDi+CDP bridge) | Chromium only |
|
|
31
31
|
| `locale` | `navigator.language`, `Intl.*` formatting | BiDi `emulation.setLocaleOverride` | yes |
|
|
32
32
|
| `timezoneId` | `Intl.DateTimeFormat`, `Date` offsets | BiDi `emulation.setTimezoneOverride` | yes |
|
|
33
|
-
| `offline` | `navigator.onLine`, network stack |
|
|
33
|
+
| `offline` | `navigator.onLine`, network stack | CDP `Network.emulateNetworkConditions` (over the BiDi+CDP bridge) | Chromium only |
|
|
34
|
+
|
|
35
|
+
All options still require an active BiDi session (`enableBiDi: true`, the
|
|
36
|
+
default) — the four CDP-backed options ride over a CDP bridge that BiDi
|
|
37
|
+
opens, they don't work with BiDi disabled.
|
|
34
38
|
|
|
35
39
|
- Pass `null` for any field to clear that override.
|
|
36
40
|
- Calling `emulate({})` is a no-op.
|
package/docs/error-codes.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Error codes
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Nearly every error thrown from the public craftdriver API is a
|
|
4
4
|
[`CraftdriverError`](../src/lib/errors.ts), carrying:
|
|
5
5
|
|
|
6
6
|
- `code` — a stable, machine-readable identifier from the table below.
|
|
@@ -12,6 +12,11 @@ Every error thrown from the public craftdriver API is a
|
|
|
12
12
|
`CraftdriverError extends Error`, so `instanceof Error` keeps working
|
|
13
13
|
and stack traces are preserved.
|
|
14
14
|
|
|
15
|
+
> A few edge cases still throw a plain `Error` instead — e.g. calling
|
|
16
|
+
> `startTrace()` again while a trace is already running, or without
|
|
17
|
+
> `outDir`. Guard against these with normal usage (don't call `startTrace()`
|
|
18
|
+
> twice without `stopTrace()`) rather than a `code` check.
|
|
19
|
+
|
|
15
20
|
```ts
|
|
16
21
|
import { CraftdriverError, ErrorCode } from 'craftdriver';
|
|
17
22
|
|
|
@@ -38,12 +43,12 @@ try {
|
|
|
38
43
|
| `TIMEOUT` | Generic `WebDriverWait.until(...)` timeout with no more specific code. | Same as above — check the condition. |
|
|
39
44
|
| `EXPECT_MISMATCH` | An `expect(locator).to…()` assertion failed after auto-waiting. | Inspect `error.detail` for the selector and observed value. |
|
|
40
45
|
| `A11Y_VIOLATIONS` | `browser.a11y.check()` (or scoped variants) found axe-core violations. | Iterate over `error.violations` — each has an `id`, `impact`, and `helpUrl`. |
|
|
41
|
-
| `EVAL_THREW` | The function passed to `evaluate()` threw inside the page. | The page-side exception text is in `error.detail.exception`. |
|
|
46
|
+
| `EVAL_THREW` | The function passed to `evaluate()` threw inside the page. Also fires for `browser.clock` methods (`tick()`, `setSystemTime()`, `runFor()`) called before `install()` — they run as in-page scripts under the hood. | The page-side exception text is in `error.detail.exception`. |
|
|
42
47
|
| `EVAL_BAD_ARG` | `evaluate()` / `addInitScript()` received a non-JSON-serializable argument (function, Symbol, DOM node…). | Pass plain JSON values. |
|
|
43
48
|
| `INVALID_ARGUMENT` | Caller passed an invalid value (bad enum, wrong shape, unparseable duration…). | Read the message; it lists the accepted forms. |
|
|
44
49
|
| `UNSUPPORTED` | Feature exists but is unavailable on this browser/transport (e.g. Chromium-only over Firefox, or a BiDi-only feature with BiDi disabled). | Enable BiDi (`enableBiDi: true`) or switch browser. |
|
|
45
|
-
| `STATE_INVALID` | Method called in the wrong state (e.g. `stopTrace()` without `startTrace()
|
|
46
|
-
| `DRIVER_ERROR` |
|
|
50
|
+
| `STATE_INVALID` | Method called in the wrong state (e.g. `stopTrace()` without `startTrace()`). | Call the prerequisite first. |
|
|
51
|
+
| `DRIVER_ERROR` | A WebDriver command returned a protocol error (non-200 response) — e.g. `stale element reference`, `element click intercepted`, `invalid selector` — or a transport-level failure. | `error.detail.webDriverError` carries the W3C JSON error code and `error.detail.webDriverMessage` the driver's message; recovery loops match on `webDriverError`. Also inspect `error.cause`. |
|
|
47
52
|
|
|
48
53
|
## Stability
|
|
49
54
|
|
package/docs/keyboard-mouse.md
CHANGED
|
@@ -98,22 +98,35 @@ await browser.keyboard.press('Backspace');
|
|
|
98
98
|
|
|
99
99
|
## Mouse
|
|
100
100
|
|
|
101
|
-
Access the mouse API via `browser.mouse`.
|
|
101
|
+
Access the mouse API via `browser.mouse`. `click()`, `move()`, and
|
|
102
|
+
`dragAndDrop()` all accept a `Target`: a CSS selector string, a `By`
|
|
103
|
+
locator, or `{ x, y }` coordinates.
|
|
102
104
|
|
|
103
|
-
### click(
|
|
105
|
+
### click(target, options?)
|
|
104
106
|
|
|
105
|
-
Click at
|
|
107
|
+
Click at coordinates or on an element.
|
|
106
108
|
|
|
107
109
|
```typescript
|
|
108
|
-
await browser.mouse.click(100, 200);
|
|
110
|
+
await browser.mouse.click({ x: 100, y: 200 });
|
|
111
|
+
await browser.mouse.click('#submit');
|
|
112
|
+
await browser.mouse.click('#submit', { button: 'right', clickCount: 2 });
|
|
109
113
|
```
|
|
110
114
|
|
|
111
|
-
###
|
|
115
|
+
### dblclick(target, options?)
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
Double-click at coordinates or on an element (shorthand for `click(target, { clickCount: 2 })`).
|
|
114
118
|
|
|
115
119
|
```typescript
|
|
116
|
-
await browser.mouse.
|
|
120
|
+
await browser.mouse.dblclick('#item');
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### move(target, options?)
|
|
124
|
+
|
|
125
|
+
Move the mouse to coordinates or over an element.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
await browser.mouse.move({ x: 150, y: 300 });
|
|
129
|
+
await browser.mouse.move('#target');
|
|
117
130
|
```
|
|
118
131
|
|
|
119
132
|
### down()
|
|
@@ -213,7 +213,7 @@ async function testLoginPersistence() {
|
|
|
213
213
|
| `includeCookies` | `boolean` | `true` | Include cookies in saved state |
|
|
214
214
|
| `includeLocalStorage` | `boolean` | `true` | Include localStorage |
|
|
215
215
|
| `includeSessionStorage` | `boolean` | `false` | Include sessionStorage |
|
|
216
|
-
| `origins` | `string[]` | all |
|
|
216
|
+
| `origins` | `string[]` | all | Filter localStorage/sessionStorage capture by origin. Capture is always scoped to the page's *current* origin — this only decides whether that one origin is included, it does not collect storage from other origins the page hasn't visited. Cookies are unaffected by this option. |
|
|
217
217
|
|
|
218
218
|
### SessionStateManager (browser.storage)
|
|
219
219
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "craftdriver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Modern WebDriver automation library for NodeJS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"test:firefox": "BROWSER_NAME=firefox HEADLESS=true vitest run --maxWorkers=2",
|
|
18
18
|
"test:chrome": "BROWSER_NAME=chrome vitest run",
|
|
19
19
|
"test:chromium": "BROWSER_NAME=chromium vitest run",
|
|
20
|
+
"bench": "HEADLESS=true vitest run --config vitest.perf.config.ts",
|
|
21
|
+
"bench:realapp": "HEADLESS=true vitest run --config vitest.perf.realapp.config.ts",
|
|
20
22
|
"clean": "rimraf dist",
|
|
21
23
|
"serve": "http-server ./examples -a 127.0.0.1 -p 8080 -c-1 --cors",
|
|
22
24
|
"examples:start": "npm run serve",
|
|
@@ -87,6 +89,7 @@
|
|
|
87
89
|
"overrides": {
|
|
88
90
|
"brace-expansion": "5.0.6",
|
|
89
91
|
"ip-address": "10.1.1",
|
|
92
|
+
"npm": "^11.18.0",
|
|
90
93
|
"undici": "7.28.0"
|
|
91
94
|
}
|
|
92
95
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# craftdriver — SKILL
|
|
2
2
|
|
|
3
|
-
Modern
|
|
4
|
-
|
|
3
|
+
Modern WebDriver library for Node.js — picks the fastest correct protocol
|
|
4
|
+
(Classic or BiDi) per command. Playwright ergonomics, WebDriver
|
|
5
|
+
standards-compliance, no AI in the hot path.
|
|
5
6
|
|
|
6
7
|
## Core loop
|
|
7
8
|
|