craftdriver 1.4.0 → 1.6.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 +17 -3
- package/README.md +6 -2
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +4 -0
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +4 -0
- package/dist/cli/mcp/server.js.map +1 -1
- package/dist/cli/parseArgs.d.ts +2 -2
- package/dist/cli/parseArgs.d.ts.map +1 -1
- package/dist/cli/parseArgs.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/bidi/storage.d.ts +13 -0
- package/dist/lib/bidi/storage.d.ts.map +1 -1
- package/dist/lib/bidi/storage.js +81 -32
- package/dist/lib/bidi/storage.js.map +1 -1
- package/dist/lib/browser.d.ts +48 -3
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +212 -86
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +2 -2
- package/dist/lib/browserContext.d.ts.map +1 -1
- package/dist/lib/browserContext.js +1 -1
- package/dist/lib/builder.d.ts +16 -2
- package/dist/lib/builder.d.ts.map +1 -1
- package/dist/lib/builder.js +46 -2
- package/dist/lib/builder.js.map +1 -1
- package/dist/lib/capabilities.d.ts +20 -2
- package/dist/lib/capabilities.d.ts.map +1 -1
- package/dist/lib/capabilities.js +109 -48
- package/dist/lib/capabilities.js.map +1 -1
- package/dist/lib/driver.d.ts +33 -2
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +91 -2
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/driverManager.d.ts +28 -0
- package/dist/lib/driverManager.d.ts.map +1 -1
- package/dist/lib/driverManager.js +60 -0
- package/dist/lib/driverManager.js.map +1 -1
- package/dist/lib/elementHandle.d.ts.map +1 -1
- package/dist/lib/elementHandle.js +34 -0
- package/dist/lib/elementHandle.js.map +1 -1
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +31 -10
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/launchTarget.d.ts +22 -3
- package/dist/lib/launchTarget.d.ts.map +1 -1
- package/dist/lib/launchTarget.js +159 -9
- package/dist/lib/launchTarget.js.map +1 -1
- package/dist/lib/remote.d.ts +55 -0
- package/dist/lib/remote.d.ts.map +1 -0
- package/dist/lib/remote.js +127 -0
- package/dist/lib/remote.js.map +1 -0
- package/dist/lib/safari.d.ts +90 -0
- package/dist/lib/safari.d.ts.map +1 -0
- package/dist/lib/safari.js +136 -0
- package/dist/lib/safari.js.map +1 -0
- package/dist/lib/tracing.d.ts +1 -1
- package/dist/lib/tracing.d.ts.map +1 -1
- package/dist/lib/tracing.js.map +1 -1
- package/dist/lib/types.d.ts +63 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/vibiumTrace.d.ts +1 -1
- package/dist/lib/vibiumTrace.d.ts.map +1 -1
- package/dist/lib/webelement.d.ts.map +1 -1
- package/dist/lib/webelement.js +118 -2
- package/dist/lib/webelement.js.map +1 -1
- package/docs/api-reference.md +6 -2
- package/docs/browser-api.md +5 -4
- package/docs/driver-configuration.md +60 -0
- package/docs/getting-started.md +30 -10
- package/docs/index.md +2 -1
- package/docs/keyboard-mouse.md +7 -5
- package/docs/public/examples/displayed.html +86 -0
- package/docs/recipes/run-on-browserstack.md +265 -0
- package/docs/recipes.md +15 -1
- package/docs/remote-webdriver.md +308 -0
- package/docs/safari.md +118 -0
- package/docs/standards.md +18 -0
- package/docs/why-craftdriver.md +3 -1
- package/docs/zero-config-drivers.md +12 -0
- package/package.json +5 -1
- package/skills/craftdriver/SKILL.md +4 -1
- package/skills/craftdriver/cheatsheet.md +4 -1
package/docs/safari.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Safari
|
|
2
|
+
|
|
3
|
+
CraftDriver drives **real desktop Safari on macOS** through W3C WebDriver
|
|
4
|
+
Classic.
|
|
5
|
+
|
|
6
|
+
## One-time setup
|
|
7
|
+
|
|
8
|
+
Safari's driver (`safaridriver`) ships with macOS — **nothing to install or
|
|
9
|
+
download**. You only have to turn on automation **once per machine**:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
safaridriver --enable
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This is the single prerequisite.
|
|
16
|
+
|
|
17
|
+
CraftDriver never runs `--enable` for you. If automation isn't enabled, a
|
|
18
|
+
launch fails immediately with that exact remedy rather than hanging.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { Browser } from 'craftdriver';
|
|
24
|
+
|
|
25
|
+
const browser = await Browser.launch({ browserName: 'safari' });
|
|
26
|
+
await browser.navigateTo('http://127.0.0.1:8080/login.html');
|
|
27
|
+
await browser.getByLabel('Username').fill('alice');
|
|
28
|
+
await browser.getByLabel('Password').fill('secret');
|
|
29
|
+
await browser.getByRole('button', { name: 'Sign in' }).click();
|
|
30
|
+
await browser.expect('#welcome').toHaveText('Welcome back, alice!');
|
|
31
|
+
await browser.quit();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Same API as every other browser — locators, actions, assertions, and
|
|
35
|
+
auto-waiting all work unchanged.
|
|
36
|
+
|
|
37
|
+
## What works
|
|
38
|
+
|
|
39
|
+
Navigation, locators, and element queries · click / fill / clear / keyboard /
|
|
40
|
+
desktop mouse · `evaluate()` (sync & async JS) · frames and iframes · window &
|
|
41
|
+
popup enumeration · **imperative dialogs** (`getAlertText` / `acceptAlert` /
|
|
42
|
+
`dismissAlert` / `sendAlertText`) · viewport and element screenshots · cookies
|
|
43
|
+
and storage (via the standard Classic cookie endpoints) · accessibility checks.
|
|
44
|
+
|
|
45
|
+
## What isn't supported
|
|
46
|
+
|
|
47
|
+
Safari exposes no WebDriver BiDi endpoint, so everything event- or
|
|
48
|
+
BiDi-driven is unavailable — and each of these throws a clear
|
|
49
|
+
[`UNSUPPORTED`](./error-codes.md) error immediately, never a silent hang:
|
|
50
|
+
|
|
51
|
+
- network mocking / interception and request/response waits
|
|
52
|
+
- console & JavaScript-error capture, tracing
|
|
53
|
+
- BiDi user contexts and emulation (permissions, geolocation,
|
|
54
|
+
locale/timezone, offline, color-scheme)
|
|
55
|
+
- init/preload scripts and the virtual clock
|
|
56
|
+
- event-driven dialogs (`onDialog` / `waitForDialog`) — use the imperative
|
|
57
|
+
methods above
|
|
58
|
+
- full-page screenshots and `openPage()`
|
|
59
|
+
- CraftDriver-managed downloads (`waitForDownload`)
|
|
60
|
+
|
|
61
|
+
Desktop Safari is also **not** iPhone/iPad Safari — there is no mobile or
|
|
62
|
+
touch emulation.
|
|
63
|
+
|
|
64
|
+
## Limitations to plan around
|
|
65
|
+
|
|
66
|
+
- **macOS-only.** There is no Safari for Linux or Windows, and none is coming.
|
|
67
|
+
Trying to launch Safari off macOS throws `UNSUPPORTED`.
|
|
68
|
+
- **Headed only.** No headless mode — every launch opens a visible automation
|
|
69
|
+
window (with a purple banner). Don't interact with it while a test runs.
|
|
70
|
+
Setting `HEADLESS=true` with Safari is rejected up front.
|
|
71
|
+
- **Serial only.** Only one Safari WebDriver session can be active on a Mac at
|
|
72
|
+
a time. A second concurrent launch is refused with an actionable error
|
|
73
|
+
(never a hang) — run Safari tests serially.
|
|
74
|
+
|
|
75
|
+
## Safari Technology Preview
|
|
76
|
+
|
|
77
|
+
STP ships its own `safaridriver`; point `SafariService` at it. This is also
|
|
78
|
+
the one way to get a **second concurrent session** on one Mac — stable Safari
|
|
79
|
+
and STP each run one session at the same time.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Browser, SafariService } from 'craftdriver';
|
|
83
|
+
|
|
84
|
+
const browser = await Browser.launch({
|
|
85
|
+
browserName: 'safari',
|
|
86
|
+
safariService: new SafariService({
|
|
87
|
+
binaryPath: '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver',
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Enable automation once for STP too: `/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver --enable`.
|
|
93
|
+
|
|
94
|
+
## Running Safari tests
|
|
95
|
+
|
|
96
|
+
Run Safari **serially** — one session at a time. With Vitest that's
|
|
97
|
+
`--maxWorkers=1`:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
vitest run --maxWorkers=1
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Keep it headed (don't set `HEADLESS`), on macOS with Remote Automation enabled.
|
|
104
|
+
In CI, use a macOS runner; parallelism across Safari needs **separate macOS
|
|
105
|
+
hosts**.
|
|
106
|
+
|
|
107
|
+
## Troubleshooting
|
|
108
|
+
|
|
109
|
+
| Symptom | Fix |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `You must enable 'Allow remote automation'…` | Run `safaridriver --enable` once (see [setup](#one-time-setup)). |
|
|
112
|
+
| Second launch fails while one session is open | Expected — Safari is serial. Serialize your tests, or use STP for a second session. |
|
|
113
|
+
| `Could not find 'safaridriver'` | You're not on macOS, or Safari is missing. For a non-standard install, set `CRAFTDRIVER_SAFARIDRIVER_PATH` or `SafariService({ binaryPath })`. |
|
|
114
|
+
|
|
115
|
+
## See also
|
|
116
|
+
|
|
117
|
+
- [Driver Configuration → Safari](./driver-configuration.md#safari-macos-driver-ships-with-the-browser) — the no-download driver-resolution chain.
|
|
118
|
+
- [WebDriver Standards](./standards.md#safari-is-classic-only) — why Safari is Classic-only.
|
package/docs/standards.md
CHANGED
|
@@ -16,6 +16,24 @@ That protocol choice is the center of the project. CraftDriver tries to provide
|
|
|
16
16
|
|
|
17
17
|
CraftDriver picks the practical protocol path behind a single public API. You call `browser.click()`, `browser.navigateTo()`, `browser.network.mock()`, or `browser.startTrace()`; the library handles the transport details.
|
|
18
18
|
|
|
19
|
+
### Remote sessions use the same two protocols
|
|
20
|
+
|
|
21
|
+
`Browser.launch({ remote })` connects to a W3C-compatible remote endpoint
|
|
22
|
+
(a self-hosted Selenium Grid, BrowserStack, or another cloud provider). The
|
|
23
|
+
same protocols are used, but the endpoint decides which browser features and
|
|
24
|
+
BiDi proxying are available. Remote uploads and downloads also have a
|
|
25
|
+
different lifecycle. See [Remote WebDriver](./remote-webdriver.md).
|
|
26
|
+
|
|
27
|
+
### Safari is Classic-only
|
|
28
|
+
|
|
29
|
+
Apple does not currently document a supported WebDriver BiDi endpoint for
|
|
30
|
+
Safari or Safari Technology Preview. A local Safari launch therefore rejects
|
|
31
|
+
`enableBiDi: true` and BiDi-only methods fail with `UNSUPPORTED`. Remote
|
|
32
|
+
Safari defaults to Classic too; an explicit remote opt-in is forwarded because
|
|
33
|
+
the remote endpoint owns negotiation, and it is usable only if that endpoint
|
|
34
|
+
returns a working `webSocketUrl`. See the [Safari guide](./safari.md) for the
|
|
35
|
+
local Classic feature set.
|
|
36
|
+
|
|
19
37
|
## Why It Matters
|
|
20
38
|
|
|
21
39
|
Standards-based automation gives projects a few useful properties:
|
package/docs/why-craftdriver.md
CHANGED
|
@@ -5,7 +5,7 @@ CraftDriver is for writing boringly reliable automation against real browsers, w
|
|
|
5
5
|
## What It Cares About
|
|
6
6
|
|
|
7
7
|
- 🍺 **Focused Node.js API** - browser automation without a giant framework around it.
|
|
8
|
-
- 🧭 **Real browsers** - drives installed Chrome, Chromium, and Firefox instead of patched browser engine builds.
|
|
8
|
+
- 🧭 **Real browsers** - drives installed Chrome, Chromium, and Firefox instead of patched browser engine builds, plus real [Safari on macOS](./safari.md).
|
|
9
9
|
- 🌐 **Standards that age well** - W3C WebDriver standards stay stable while browser-private protocols change.
|
|
10
10
|
- 🚦 **Readable, auto-waited flows** - role, label, text, test id, CSS, XPath, click, fill, and expect.
|
|
11
11
|
- 📡 **Network control** - mock, block, intercept, and wait for browser requests and responses.
|
|
@@ -13,6 +13,8 @@ CraftDriver is for writing boringly reliable automation against real browsers, w
|
|
|
13
13
|
- ⏱️ **Virtual clock** - freeze or fast-forward `Date`, timers, and time-sensitive UI.
|
|
14
14
|
- ♿ **Accessibility audits** - run axe-core checks on pages, elements, and locators.
|
|
15
15
|
- 🧾 **Trace evidence** - capture actions, console output, errors, network events, and screenshots.
|
|
16
|
+
- ⚛️ **Electron apps** - drive packaged Electron desktop app renderers, matched to the app's bundled Chromium.
|
|
17
|
+
- ☁️ **Remote WebDriver** - use the Browser API with a self-hosted Selenium Grid or a cloud provider like [BrowserStack](https://www.browserstack.com/).
|
|
16
18
|
- 🤖 **Agent-friendly** - CLI, MCP, and assistant rules when coding agents need the browser.
|
|
17
19
|
|
|
18
20
|
## Good Fits
|
|
@@ -62,3 +62,15 @@ Manual configuration is useful when:
|
|
|
62
62
|
[Driver Configuration → Browser Binary Configuration](./driver-configuration.md#browser-binary-configuration)
|
|
63
63
|
|
|
64
64
|
See [Driver Configuration](./driver-configuration.md) for the full reference.
|
|
65
|
+
|
|
66
|
+
## Safari: nothing to resolve, nothing to download
|
|
67
|
+
|
|
68
|
+
The auto-download model above doesn't apply to `browserName: 'safari'`.
|
|
69
|
+
`safaridriver` ships as part of macOS/Safari itself — there's no version to
|
|
70
|
+
match, no binary to fetch, and no cache to warm. CraftDriver only ever
|
|
71
|
+
**locates** the driver Apple already installed. The single prerequisite is
|
|
72
|
+
turning automation on once per Mac with `safaridriver --enable`.
|
|
73
|
+
|
|
74
|
+
See the [**Safari guide**](./safari.md) for setup and capabilities, and
|
|
75
|
+
[Driver Configuration → Safari](./driver-configuration.md#safari-macos-driver-ships-with-the-browser)
|
|
76
|
+
for the driver-resolution chain.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "craftdriver",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Modern WebDriver automation library for NodeJS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,8 +17,11 @@
|
|
|
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
|
+
"test:safari": "BROWSER_NAME=safari vitest run tests/safari.test.ts --maxWorkers=1",
|
|
20
21
|
"test:recipes": "HEADLESS=true vitest run --config vitest.recipes.config.ts",
|
|
21
22
|
"test:electron": "vitest run --config vitest.electron.config.ts",
|
|
23
|
+
"test:browserstack": "vitest run --config vitest.browserstack.config.ts",
|
|
24
|
+
"test:grid": "vitest run --config vitest.grid.config.ts",
|
|
22
25
|
"bench": "HEADLESS=true vitest run --config vitest.perf.config.ts",
|
|
23
26
|
"clean": "rimraf dist",
|
|
24
27
|
"serve": "http-server ./examples -a 127.0.0.1 -p 8080 -c-1 --cors",
|
|
@@ -40,6 +43,7 @@
|
|
|
40
43
|
"firefox",
|
|
41
44
|
"chrome",
|
|
42
45
|
"chromium",
|
|
46
|
+
"safari",
|
|
43
47
|
"electron",
|
|
44
48
|
"electron-testing",
|
|
45
49
|
"desktop-app-testing",
|
|
@@ -36,7 +36,10 @@ break the moment markup shifts.
|
|
|
36
36
|
4. BiDi features (`network`, `logs`, tracing, init scripts, true load
|
|
37
37
|
events) work out of the box — `enableBiDi` defaults to `true`. They only
|
|
38
38
|
break if you explicitly pass `enableBiDi: false`; the error code on the
|
|
39
|
-
wrong transport is `UNSUPPORTED`.
|
|
39
|
+
wrong transport is `UNSUPPORTED`. Exception: `browserName: 'safari'`
|
|
40
|
+
defaults `enableBiDi` to `false` and rejects `true` — Safari is
|
|
41
|
+
Classic-only (macOS, headed, one session at a time). See
|
|
42
|
+
[docs/safari.md](../../docs/safari.md).
|
|
40
43
|
5. Tests fetch from the example server. Start it in a separate
|
|
41
44
|
terminal: `npm run examples:start` before `npm test`.
|
|
42
45
|
|
|
@@ -10,11 +10,14 @@ list.
|
|
|
10
10
|
import { Browser } from 'craftdriver';
|
|
11
11
|
|
|
12
12
|
const browser = await Browser.launch({
|
|
13
|
-
browserName: 'chrome', // 'chrome' | 'chromium' | 'firefox'
|
|
13
|
+
browserName: 'chrome', // 'chrome' | 'chromium' | 'firefox' | 'safari'
|
|
14
14
|
headless: true,
|
|
15
15
|
// enableBiDi defaults to true — network / logs / tracing / init scripts
|
|
16
16
|
// all need it, so only set enableBiDi: false if you must disable it.
|
|
17
17
|
});
|
|
18
|
+
// 'safari' is macOS-only, headed only (no `headless`),
|
|
19
|
+
// one session at a time, WebDriver Classic only (enableBiDi is rejected).
|
|
20
|
+
// See docs/safari.md.
|
|
18
21
|
try {
|
|
19
22
|
await browser.navigateTo('https://example.com');
|
|
20
23
|
// ...
|