craftdriver 1.7.0 → 1.8.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 +23 -11
- package/README.md +13 -4
- 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 +42 -0
- package/dist/cli/pageSemantics.d.ts.map +1 -0
- package/dist/cli/pageSemantics.js +194 -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/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 -18
- package/dist/cli/snapshot.d.ts.map +1 -1
- package/dist/cli/snapshot.js +248 -102
- 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 +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- 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 +7 -2
- package/dist/lib/bidi/types.d.ts.map +1 -1
- package/dist/lib/browser.d.ts +6 -3
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +140 -30
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/browserContext.d.ts +54 -18
- package/dist/lib/browserContext.d.ts.map +1 -1
- package/dist/lib/browserContext.js +295 -92
- package/dist/lib/browserContext.js.map +1 -1
- package/dist/lib/by.d.ts +3 -3
- package/dist/lib/by.d.ts.map +1 -1
- package/dist/lib/by.js +7 -3
- package/dist/lib/by.js.map +1 -1
- package/dist/lib/driver.d.ts +7 -0
- package/dist/lib/driver.d.ts.map +1 -1
- package/dist/lib/driver.js +12 -0
- package/dist/lib/driver.js.map +1 -1
- package/dist/lib/errors.d.ts +8 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +8 -0
- package/dist/lib/errors.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/page.d.ts +22 -0
- package/dist/lib/page.d.ts.map +1 -1
- package/dist/lib/page.js +48 -0
- package/dist/lib/page.js.map +1 -1
- 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/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/agents.md +56 -61
- package/docs/api-reference.md +2 -1
- package/docs/browser-api.md +24 -4
- package/docs/browser-context.md +18 -12
- package/docs/cli.md +346 -26
- package/docs/error-codes.md +5 -4
- package/docs/getting-started.md +6 -1
- package/docs/index.md +1 -1
- package/docs/mcp.md +129 -62
- 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/recipes/login-once-reuse-session.md +32 -4
- package/docs/session-management.md +64 -3
- package/docs/why-craftdriver.md +1 -1
- package/package.json +3 -1
- 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 +14 -8
- package/skills/craftdriver/workflow.md +149 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Explore an application and write a CraftDriver test
|
|
2
|
+
|
|
3
|
+
This workflow turns live browser evidence into an ordinary, reviewable test.
|
|
4
|
+
|
|
5
|
+
## 1. Learn the project
|
|
6
|
+
|
|
7
|
+
Before editing, inspect `package.json`, existing test files, fixtures, and the
|
|
8
|
+
commands the repository already uses. Reuse its test runner, naming, setup, URL,
|
|
9
|
+
and browser lifecycle. Do not create a second test framework or edit repository
|
|
10
|
+
assistant instructions.
|
|
11
|
+
|
|
12
|
+
## 2. Start the application and browser
|
|
13
|
+
|
|
14
|
+
Run the project's existing app command in its own process. Then:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx craftdriver daemon start
|
|
18
|
+
npx craftdriver go http://127.0.0.1:3000
|
|
19
|
+
npx craftdriver snapshot
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Use the actual project URL and wait for a clear page condition when necessary.
|
|
23
|
+
On Windows the daemon is unavailable; use the configured MCP server, or put
|
|
24
|
+
the complete exploration flow into one `--ephemeral` script.
|
|
25
|
+
|
|
26
|
+
## 3. Inspect before acting
|
|
27
|
+
|
|
28
|
+
Read role/name, labels, test IDs, visible text, and nearby DOM structure from the
|
|
29
|
+
snapshot. Prefer a semantic selector and prove it:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx craftdriver exists 'role=button[name=Sign in]'
|
|
33
|
+
npx craftdriver find 'label=Email' --all
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Refs from the snapshot are safe to act on: a ref binds to one element, and if
|
|
37
|
+
that element is gone or the page navigated, the command fails with `STALE_REF`
|
|
38
|
+
instead of hitting something else. Take a fresh snapshot when that happens.
|
|
39
|
+
|
|
40
|
+
Never copy `ref=eN` into test code. When you have the right element, ask for a
|
|
41
|
+
durable selector and let CraftDriver validate it against the live page:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx craftdriver locators ref=e7
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use a candidate it reports as `unique`. If none is unique, add a `data-testid`
|
|
48
|
+
to the application rather than committing a positional selector.
|
|
49
|
+
|
|
50
|
+
## 4. Exercise the user flow
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx craftdriver fill 'label=Email' alice@example.test
|
|
54
|
+
npx craftdriver fill 'label=Password' secret
|
|
55
|
+
npx craftdriver click 'role=button[name=Sign in]'
|
|
56
|
+
npx craftdriver text 'testid=welcome'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
After each meaningful mutation, inspect fresh output or snapshot state. If a
|
|
60
|
+
selector is ambiguous, refine it from observed structure and validate again.
|
|
61
|
+
|
|
62
|
+
**The DOM is not the whole story.** An application can fail while showing a
|
|
63
|
+
generic message, or succeed while logging an error you should not ship. Check
|
|
64
|
+
what the page actually did:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx craftdriver logs --kind error # exceptions + console.error
|
|
68
|
+
npx craftdriver logs --kind request,response --contains /api/
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Capture is already running before your first command, so this works after the
|
|
72
|
+
fact — you never re-run a flow to observe it. Assert on what you find, not on
|
|
73
|
+
what the page happens to render.
|
|
74
|
+
|
|
75
|
+
## 5. Write the smallest durable test
|
|
76
|
+
|
|
77
|
+
Follow the repository's style. A direct test may look like:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { Browser, By, expect } from 'craftdriver';
|
|
81
|
+
|
|
82
|
+
const browser = await Browser.launch({ browserName: 'chrome' });
|
|
83
|
+
try {
|
|
84
|
+
await browser.navigateTo('http://127.0.0.1:3000');
|
|
85
|
+
await browser.locator(By.labelText('Email')).fill('alice@example.test');
|
|
86
|
+
await browser.locator(By.labelText('Password')).fill('secret');
|
|
87
|
+
await browser.locator(By.role('button', { name: 'Sign in' })).click();
|
|
88
|
+
await expect(browser.locator(By.testId('welcome'))).toHaveText(/welcome/i);
|
|
89
|
+
} finally {
|
|
90
|
+
await browser.quit();
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Use the exact public API patterns already present in the repository when they
|
|
95
|
+
differ from this standalone example.
|
|
96
|
+
|
|
97
|
+
## 6. Run and debug
|
|
98
|
+
|
|
99
|
+
Run the narrowest existing test command. On failure:
|
|
100
|
+
|
|
101
|
+
1. read the stable CraftDriver error code;
|
|
102
|
+
2. reproduce against the current app;
|
|
103
|
+
3. take a fresh snapshot and re-check the locator with `locators`;
|
|
104
|
+
4. inspect only the relevant page value/text/attribute;
|
|
105
|
+
5. **read the evidence before theorising** — see below;
|
|
106
|
+
6. change application or test source through an explicit diff;
|
|
107
|
+
7. rerun the focused test, then the repository's required checks.
|
|
108
|
+
|
|
109
|
+
### Read the evidence
|
|
110
|
+
|
|
111
|
+
Most failures that look mysterious in the DOM are explicit in the console or
|
|
112
|
+
the network journal:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx craftdriver logs --kind error # exceptions and console.error
|
|
116
|
+
npx craftdriver logs --kind response --contains /api/ # status codes
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
A page that renders "Something went wrong" tells you nothing; a 4xx on
|
|
120
|
+
`/api/checkout` and a matching `console.error` tell you exactly where to look.
|
|
121
|
+
`--kind error` covers both uncaught exceptions and `console.error`, since a
|
|
122
|
+
caller asking for errors means both.
|
|
123
|
+
Quote that evidence when you explain the failure, rather than guessing from the
|
|
124
|
+
rendered text.
|
|
125
|
+
|
|
126
|
+
For a failure that a snapshot cannot explain — a race, or something that only
|
|
127
|
+
happens mid-flow — record the whole run and inspect it afterwards:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx craftdriver trace start bug
|
|
131
|
+
# …reproduce…
|
|
132
|
+
npx craftdriver trace stop --zip
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To confirm a diagnosis, drive the branch directly instead of waiting for the
|
|
136
|
+
real backend to misbehave:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx craftdriver mock add '**/api/checkout*' --status 500
|
|
140
|
+
npx craftdriver mock clear # always clean up; mocks outlive the command
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Never heal a test at runtime
|
|
144
|
+
|
|
145
|
+
Do not make a failing test green through sleeps, broad catch blocks, weaker
|
|
146
|
+
assertions, or silent runtime selector substitution. If the application
|
|
147
|
+
changed, change the test in an explicit source diff and say what changed and
|
|
148
|
+
why. A test that hides a real application change is worse than a failing one,
|
|
149
|
+
because it removes the signal without fixing the cause.
|