e2e 0.21.1 → 0.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +2 -0
  2. package/dist/.build.json +1 -1
  3. package/dist/agent/act-validation.js +1 -0
  4. package/dist/agent/act.js +7 -3
  5. package/dist/agent/action-dispatcher.js +30 -8
  6. package/dist/agent/actions.d.ts +2 -0
  7. package/dist/agent/actions.js +5 -2
  8. package/dist/agent/error.js +1 -0
  9. package/dist/agent/executor.d.ts +14 -6
  10. package/dist/agent/index.js +5 -1
  11. package/dist/agent/invocation.d.ts +3 -0
  12. package/dist/agent/model/sdk.d.ts +5 -0
  13. package/dist/agent/model/sdk.js +18 -1
  14. package/dist/agent/observation.js +1 -0
  15. package/dist/agent/primitives.js +14 -3
  16. package/dist/agent/replay.js +9 -3
  17. package/dist/agent/step-cache.d.ts +3 -2
  18. package/dist/agent/step-cache.js +7 -4
  19. package/dist/agent/tool-loop.js +4 -1
  20. package/dist/cache/context.js +1 -1
  21. package/dist/cache/recorder.d.ts +2 -1
  22. package/dist/cache/recorder.js +11 -2
  23. package/dist/cache/trace-fields.d.ts +10 -0
  24. package/dist/cache/trace-fields.js +17 -0
  25. package/dist/cache/trace.d.ts +9 -1
  26. package/dist/cache/trace.js +26 -7
  27. package/dist/cli/feedback.js +2 -1
  28. package/dist/cli/init/sibling-versions.json +1 -1
  29. package/dist/collect/select.js +12 -2
  30. package/dist/config/agent.d.ts +1 -1
  31. package/dist/config/diagnose.js +9 -3
  32. package/dist/config/esm-hooks.js +3 -2
  33. package/dist/config/resolve.js +3 -2
  34. package/dist/config/typescript.js +52 -2
  35. package/dist/engine/contract.d.ts +3 -2
  36. package/dist/engine/manifest.js +2 -2
  37. package/dist/internal/errors.js +5 -2
  38. package/dist/internal/source.js +2 -0
  39. package/dist/internal/unserved-model.d.ts +5 -0
  40. package/dist/internal/unserved-model.js +22 -0
  41. package/dist/locator/screen.js +1 -2
  42. package/dist/oauth/copilot.js +23 -5
  43. package/dist/oauth/device-code.js +35 -19
  44. package/dist/oauth/errors.d.ts +3 -0
  45. package/dist/oauth/errors.js +26 -11
  46. package/dist/oauth/providers/github-copilot.d.ts +4 -0
  47. package/dist/oauth/providers/github-copilot.js +64 -16
  48. package/dist/oauth/providers/openai.d.ts +2 -2
  49. package/dist/oauth/providers/openai.js +47 -19
  50. package/dist/oauth/providers/opencode-console.js +36 -15
  51. package/dist/oauth/providers/xai.js +18 -9
  52. package/dist/oauth/token-endpoint.d.ts +15 -6
  53. package/dist/oauth/token-endpoint.js +18 -6
  54. package/dist/report/code-frame.js +9 -3
  55. package/dist/report/failure-text.d.ts +10 -2
  56. package/dist/report/failure-text.js +24 -8
  57. package/dist/report/list-model.d.ts +13 -0
  58. package/dist/report/list-steps.d.ts +6 -1
  59. package/dist/report/list-steps.js +29 -0
  60. package/dist/report/list.d.ts +1 -0
  61. package/dist/report/list.js +16 -7
  62. package/dist/report/live-window.js +2 -1
  63. package/dist/report/markdown.js +1 -1
  64. package/dist/run/fixtures.js +2 -0
  65. package/dist/run/host-trace.d.ts +3 -2
  66. package/dist/run/host-trace.js +2 -1
  67. package/dist/run/last-run.d.ts +9 -0
  68. package/dist/run/last-run.js +28 -0
  69. package/dist/run/open-session.d.ts +3 -1
  70. package/dist/run/open-session.js +1 -1
  71. package/dist/run/runner.js +6 -2
  72. package/dist/run/sessions.js +3 -3
  73. package/dist/run/standalone-attempt.d.ts +2 -1
  74. package/dist/run/standalone-attempt.js +3 -1
  75. package/dist/run/steps.d.ts +3 -1
  76. package/dist/run/units.d.ts +8 -0
  77. package/dist/run/units.js +14 -0
  78. package/dist/run/worker-models.d.ts +2 -0
  79. package/dist/run/worker-models.js +7 -0
  80. package/dist/types.d.ts +2 -2
  81. package/docs/authentication.mdx +26 -23
  82. package/docs/browser.mdx +7 -4
  83. package/docs/bug-bash.mdx +2 -2
  84. package/docs/cache.mdx +6 -1
  85. package/docs/ci/bitrise.mdx +1 -1
  86. package/docs/ci/codemagic.mdx +2 -2
  87. package/docs/ci/eas-workflows.mdx +1 -1
  88. package/docs/coding-agents.mdx +7 -35
  89. package/docs/debugging.mdx +24 -36
  90. package/docs/executors.mdx +1 -1
  91. package/docs/github.mdx +2 -1
  92. package/docs/integrations/eas.mdx +1 -1
  93. package/docs/integrations/index.mdx +6 -0
  94. package/docs/integrations/lightpanda.mdx +192 -0
  95. package/docs/integrations/testmu.mdx +152 -0
  96. package/docs/mcp.mdx +123 -0
  97. package/docs/migrate/detox.mdx +1 -1
  98. package/docs/migrate/maestro.mdx +101 -105
  99. package/docs/migrate/playwright.mdx +65 -70
  100. package/docs/mobile.mdx +18 -3
  101. package/docs/models.mdx +4 -2
  102. package/docs/quickstart.mdx +7 -0
  103. package/docs/reference/agent.mdx +369 -277
  104. package/docs/reference/app.mdx +141 -32
  105. package/docs/reference/cli.mdx +674 -558
  106. package/docs/reference/config.mdx +1406 -752
  107. package/docs/reference/engine.mdx +1062 -256
  108. package/docs/reference/environment.mdx +156 -84
  109. package/docs/reference/errors.mdx +106 -72
  110. package/docs/reference/expect.mdx +752 -372
  111. package/docs/reference/mcp.mdx +366 -141
  112. package/docs/reference/mobile.mdx +844 -403
  113. package/docs/reference/reporters.mdx +312 -106
  114. package/docs/reference/runner.mdx +373 -174
  115. package/docs/reference/screen.mdx +931 -398
  116. package/docs/reference/security.mdx +106 -40
  117. package/docs/reference/test.mdx +626 -273
  118. package/docs/reference/web.mdx +956 -533
  119. package/docs/security.mdx +6 -5
  120. package/docs/snippets/model-provider.jsx +763 -0
  121. package/docs/snippets/setup-prompt-card.jsx +22 -0
  122. package/docs/snippets/show-more.jsx +22 -0
  123. package/docs/snippets/video-card.jsx +34 -0
  124. package/docs/snippets/video.jsx +25 -0
  125. package/docs/subscriptions.mdx +10 -3
  126. package/docs/telemetry.mdx +39 -39
  127. package/package.json +3 -2
  128. package/schema/report-v1.schema.json +6 -0
  129. package/skills/e2e/references/agent.md +8 -3
  130. package/skills/e2e/references/debugging.md +1 -1
  131. package/skills/e2e/references/mcp.md +1 -1
  132. package/skills/e2e/references/setup.md +12 -3
  133. package/skills/e2e/references/writing-tests.md +1 -1
@@ -9,7 +9,28 @@ icon: "lock"
9
9
  The [Security](/security) guide explains the trust boundary. This page
10
10
  lists the rules behind it, as the code enforces them.
11
11
 
12
- ## Model input
12
+ ## Reference
13
+
14
+ | Section | Covers |
15
+ | --- | --- |
16
+ | [Model input](#model-input) | What the model reads in each step |
17
+ | [Tool calls](#tool-calls) | Built-in and project tools, node ids |
18
+ | [Policy denials](#policy-denials) | Calls that fail with `POLICY_DENIED` |
19
+ | [Navigation](#navigation) | URL schemes per entry point |
20
+ | [Site check](#site-check) | Headers, child frames, `basicAuth` |
21
+ | [Secret fills](#secret-fills) | `type_secret`, `fill(secret)` |
22
+ | [Screenshots after a secret fill](#screenshots-after-a-secret-fill) | Screenshots, pixel tools, restored sessions |
23
+ | [Secrets in engine options](#secrets-in-engine-options) | `basicAuth` and other engine options |
24
+ | [Redaction](#redaction) | Model input, reports, downloads, output |
25
+ | [Where redaction stops](#where-redaction-stops) | Transformed values, video, `command.log` |
26
+ | [Downloads](#downloads) | Files the app served |
27
+ | [Sessions](#sessions) | Saved authentication state |
28
+ | [Cache trust](#cache-trust) | Replay cache files and `cache.store` |
29
+ | [Artifacts](#artifacts) | Files under the output directory |
30
+ | [Outbound connections](#outbound-connections) | Destinations the runner connects to |
31
+ | [MCP and explore](#mcp-and-explore) | MCP sessions, the explorer's sign-ins |
32
+
33
+ ### Model input
13
34
 
14
35
  The model reads app content as quoted evidence, kept apart from runner policy
15
36
  and trusted project context. App content can't grant tools, credentials, or a
@@ -23,22 +44,26 @@ larger budget. [How agent steps work](/agent-steps) explains a step in full.
23
44
  | A screenshot | When needed or requested, and only if the engine proves secure fields are masked and no secret was filled in the attempt. |
24
45
  | Prior steps | `agent.act` receives bounded records from the same test or serial group. Judgments use only the current screen and instruction. |
25
46
 
26
- ## Tool calls
47
+ ### Tool calls
27
48
 
28
49
  - Built-in tools have closed schemas and appear only when the engine
29
50
  supports them.
30
51
  - Project tools must use `defineTool` with an `execute` and can't replace a
31
- built-in name. Any other tool fails the config load with `INVALID_CONFIG`.
52
+ built-in name.
32
53
  - Only read-only project tools may request an observation.
33
54
  - A call to a tool the step doesn't offer, or with an undeclared argument,
34
55
  never runs. The model reads the refusal as the call's result and tries
35
56
  again.
36
- - A node id that isn't on the current screen fails the action with
37
- `LOCATOR_NOT_FOUND`.
38
57
  - The runner never evaluates model text as code, selectors, shell commands,
39
58
  or config.
40
59
 
41
- ## Policy denials
60
+ | Fails with | When |
61
+ | --- | --- |
62
+ | `CONFIG_LOAD_FAILED` | A `defineTool` without an `execute`, at config load. |
63
+ | `INVALID_CONFIG` | A tool not created with `defineTool`, or one named after a built-in or harness tool. |
64
+ | `LOCATOR_NOT_FOUND` | A node id that isn't on the current screen. The action fails, and the model reads the failure and acts again. |
65
+
66
+ ### Policy denials
42
67
 
43
68
  These calls fail with `POLICY_DENIED`.
44
69
 
@@ -53,24 +78,29 @@ These calls fail with `POLICY_DENIED`.
53
78
  | A password into a field that isn't a password field | Purpose must match. A generic secret fills any editable input. |
54
79
  | A mutating project tool requesting an observation | Observe in a separate call. |
55
80
  | `vision: 'only'` when pixels are withheld | There is nothing to fall back to. |
56
- | `app.screenshot()` or `toHaveScreenshot()` after a secret fill | The app may show the secret outside a secure field. |
81
+ | `browser.setCookies` with a cookie URL that isn't `http:` or `https:` | Only a web origin holds cookies. |
82
+ | `app.screenshot()` or `toHaveScreenshot()` after a secret fill | See [Screenshots after a secret fill](#screenshots-after-a-secret-fill). |
57
83
  | `toHaveScreenshot()` when the engine can't prove every secure field is masked | The screenshot isn't kept. |
58
84
  | An agent, executor, or MCP `upload` of a file outside the project root, a hidden file, or a file under a hidden directory | Only project files can leave the computer through a form. |
59
85
  | An `act` or `vision: true` step whose semantic capture times out after a secret fill | It can't fall back to a screenshot. |
60
86
 
61
- ## Navigation
87
+ ### Navigation
88
+
89
+ | Entry point | Accepts | Refuses |
90
+ | --- | --- | --- |
91
+ | `app.open`, `browser.goto`, the agent's `navigate` verb | `http:`, `https:`, and the exact `about:blank` | Every other scheme |
92
+ | `device.openLink` | Any absolute URL: an app's custom scheme, or `http:` and `https:` | `file:`, `data:`, `javascript:`, `view-source:`, `blob:`, `filesystem:` |
93
+ | `device.openApp`, the `open_app` tool | An app id | A link |
62
94
 
63
- - There is no origin allowlist. The agent can follow the app to other sites
64
- and use the step's secrets there.
65
- - `app.open`, `browser.goto`, and the agent's `navigate` verb accept only
66
- `http:`, `https:`, and the exact `about:blank`.
67
- - `device.openLink` accepts an app's custom scheme and refuses `file:`,
68
- `data:`, `javascript:`, `view-source:`, `blob:`, and `filesystem:`.
69
- - `device.openApp` and the `open_app` tool take an app id and refuse a link.
70
95
  - The runner doesn't re-check redirects or attach to popup pages. Register
71
96
  `browser.onDialog` to handle browser dialogs.
72
97
 
73
- ## Site check
98
+ <Warning>
99
+ There is no origin allowlist. The agent can follow the app to other sites
100
+ and use the step's secrets there.
101
+ </Warning>
102
+
103
+ ### Site check
74
104
 
75
105
  The browser engine compares hostnames to decide what counts as the target's
76
106
  site.
@@ -83,12 +113,23 @@ site.
83
113
  - `basicAuth` ignores the site check. It answers a `401` challenge from any
84
114
  origin.
85
115
 
86
- ## Secret fills
116
+ ### Secret fills
87
117
 
88
118
  A `Secret` is an opaque handle with no plaintext accessor. Three sinks accept
89
119
  one: a locator's `fill`, the params of an agent step, and an engine option
90
120
  that declares it.
91
121
 
122
+ ```ts title="tests/stripe.e2e.ts"
123
+ import { secrets, test } from 'e2e';
124
+
125
+ test('connect Stripe', async ({ screen, agent }) => {
126
+ await screen.getByLabel('Secret key').fill(secrets.get('stripe-key'));
127
+ await agent.act('Connect Stripe with the given key', {
128
+ params: { apiKey: secrets.get('stripe-key') },
129
+ });
130
+ });
131
+ ```
132
+
92
133
  | Fill | Checks before the value resolves |
93
134
  | --- | --- |
94
135
  | Model-directed (`type_secret`) | The step declared the secret. The secret is configured. The target is an enabled, editable input on the newest observation. A password goes into a password field. Replay repeats these checks. |
@@ -97,7 +138,7 @@ that declares it.
97
138
  The runner resolves the value on the host and passes it to the engine. The
98
139
  model never sees or picks it.
99
140
 
100
- ## Screenshots after a secret fill
141
+ ### Screenshots after a secret fill
101
142
 
102
143
  After any secret fill, for the rest of the attempt:
103
144
 
@@ -116,11 +157,29 @@ setting a session cookie with `browser.setCookies`, leaves screenshots on for
116
157
  the tests that restore it. A value it uses is redacted only if it's a
117
158
  configured secret.
118
159
 
119
- ## Secrets in engine options
160
+ ### Secrets in engine options
120
161
 
121
162
  A secret in an engine option, such as
122
163
  `web({ basicAuth: { password: secrets.get(name) } })`, isn't a fill.
123
164
 
165
+ ```ts title="e2e.config.ts"
166
+ import type { E2EConfig } from 'e2e';
167
+ import { secrets } from 'e2e';
168
+ import { web } from '@e2e-dev/web';
169
+
170
+ export default {
171
+ targets: [
172
+ {
173
+ engine: web({
174
+ basicAuth: { username: 'preview', password: secrets.get('previewPassword') },
175
+ }),
176
+ app: { url: 'https://staging.example.com' },
177
+ },
178
+ ],
179
+ secrets: { previewPassword: () => process.env.PREVIEW_PASSWORD ?? '' },
180
+ } satisfies E2EConfig;
181
+ ```
182
+
124
183
  - The runner resolves it on the host when each attempt starts.
125
184
  - It registers the value for redaction, together with what the engine
126
185
  derives from it. For basic auth, that is the base64 `user:password` in the
@@ -130,7 +189,7 @@ A secret in an engine option, such as
130
189
  - Screenshots and the model's pixels stay on. A page that shows the password
131
190
  on screen isn't masked in pixels.
132
191
 
133
- ## Redaction
192
+ ### Redaction
134
193
 
135
194
  The runner replaces every registered secret value with `<secret:name>` in:
136
195
 
@@ -159,12 +218,13 @@ on.
159
218
  | Assertions | Unaffected. Redaction rewrites only what the runner reports. |
160
219
  | Cache entries | Secret values and their cut parts never enter them. |
161
220
 
162
- ## Where redaction stops
221
+ ### Where redaction stops
163
222
 
164
223
  Redaction matches strings. These pass through:
165
224
 
166
225
  - a transformed value, such as its last four characters,
167
- - a value encoded as a whole, such as base64 or a hash,
226
+ - a value encoded as a whole, such as a hash, or base64 outside a text
227
+ [download](#downloads),
168
228
  - a value in another Unicode normalization form, such as decomposed accents
169
229
  where the secret has composed ones,
170
230
  - text that drops the whitespace inside the value. Text that widens it passes
@@ -183,11 +243,11 @@ Redaction matches strings. These pass through:
183
243
  service, and the report holds only its URL,
184
244
  - `command.log`: the runner captures your app's output as written.
185
245
 
186
- ## Downloads
246
+ ### Downloads
187
247
 
188
248
  A download is what the app served. When the session knows a secret value,
189
- the runner rewrites a text download (`text/*` or JSON, by file extension) and
190
- labels it `redaction: "complete"`. It replaces with `<secret:name>`:
249
+ the runner rewrites a text download (`.txt`, `.csv`, `.json`, `.html`, or
250
+ `.htm`) and labels it `redaction: "complete"`. It replaces with `<secret:name>`:
191
251
 
192
252
  - every whole occurrence of a value,
193
253
  - any run of 8 or more of its characters, whitespace collapsed or not, so
@@ -195,16 +255,19 @@ labels it `redaction: "complete"`. It replaces with `<secret:name>`:
195
255
  - a base64 or base64url run that decodes to either.
196
256
 
197
257
  Every other download is kept as served and labeled
198
- `redaction: "incomplete"`: a binary, one that isn't valid UTF-8 or can't be
199
- rewritten, and any download from a session that knows no secret value.
258
+ `redaction: "incomplete"`:
259
+
260
+ - any other extension,
261
+ - one that isn't valid UTF-8 or can't be rewritten,
262
+ - any download from a session that knows no secret value.
200
263
 
201
- ## Sessions
264
+ ### Sessions
202
265
 
203
266
  A saved session holds authentication state. It also carries, in the same
204
- ciphertext, the secret values the setup test resolved from a provider and
205
- whether a secret was filled. The test that restores it redacts those values
206
- and keeps its pixels withheld. The envelope names the secrets in the clear,
207
- authenticated.
267
+ ciphertext, the secret values the setup test resolved from a provider. The
268
+ test that restores it redacts those values and keeps its pixels withheld. The
269
+ envelope holds, unencrypted but authenticated, the secret names and whether a
270
+ secret was filled.
208
271
 
209
272
  | Property | Value |
210
273
  | --- | --- |
@@ -218,7 +281,7 @@ authenticated.
218
281
  The runner refuses an invalid, expired, missing, or mismatched session. See
219
282
  the [session errors](/reference/errors).
220
283
 
221
- ## Cache trust
284
+ ### Cache trust
222
285
 
223
286
  Cache entries replay actions without a model and aren't signed.
224
287
 
@@ -235,7 +298,7 @@ Cache entries replay actions without a model and aren't signed.
235
298
  | Git | `e2e init` ignores `.e2e/cache/`. If you [commit recordings](/cache#commit-the-replay-cache), review their actions and typed values. |
236
299
  | `cache.store` | Receives every recorded entry and supplies every replayed one. What comes back is validated again. |
237
300
 
238
- ## Artifacts
301
+ ### Artifacts
239
302
 
240
303
  A run writes under `.e2e/` by default. The
241
304
  [`output`](/reference/config#output) option or `--output` moves it. The
@@ -259,11 +322,11 @@ project-relative path you configure.
259
322
  An `artifacts.store` receives each artifact's bytes as they're produced,
260
323
  after download redaction, with the `redaction` label the report records.
261
324
 
262
- ## Outbound connections
325
+ ### Outbound connections
263
326
 
264
327
  | Destination | When |
265
328
  | --- | --- |
266
- | `eu.i.posthog.com` | One telemetry request per CLI invocation, plus at most one per session `e2e mcp` serves, unless you opt out ([Telemetry](/telemetry)). One request per `e2e feedback` you run. |
329
+ | `eu.i.posthog.com` | One telemetry request per CLI invocation or per `run()` from `e2e/runner` that returns a report, plus at most one per session `e2e mcp` serves, unless you opt out ([Telemetry](/telemetry)). One request per `e2e feedback` report sent: none under `--dry-run` or `E2E_TELEMETRY_DEBUG`, for a bug without `--repro`, or under `E2E_TELEMETRY_DISABLED` or `DO_NOT_TRACK`. |
267
330
  | Your model provider | Agent steps that call a model. Deterministic tests and fully replayed steps make no model call. |
268
331
  | A subscription provider's sign-in and model-list endpoints | `e2e login` and `e2e models` ([Subscriptions](/subscriptions)). |
269
332
  | The app's `readyUrl` | Readiness probes for an app the runner starts. |
@@ -271,17 +334,20 @@ after download redaction, with the `redaction` label the report records.
271
334
  | The DevTools endpoint in `web({ connect })` | Every run of that target. |
272
335
  | The GitHub API | Only from the `@e2e-dev/github` reporter. |
273
336
  | `registry.npmjs.org` | One request per `e2e feedback` you run, to check for a newer e2e release. Skipped with `--allow-outdated` and under `E2E_TELEMETRY_DISABLED` or `DO_NOT_TRACK`. |
337
+ | `api.limrun.com` (or `LIMRUN_BASE_URL`) and its devices | Only from [`limrun()`](/integrations/limrun). It signs in with `LIMRUN_API_KEY`. |
274
338
  | The Kernel API and its hosted browsers | Only from [`kernel()`](/integrations/kernel). |
275
339
  | The Expo API and the simulators' agent-device daemons | Only from [`easSimulators()`](/integrations/eas). It signs in with `EXPO_TOKEN`, else with the eas-cli login in `~/.expo/state.json`. On a CI runner, set `EXPO_TOKEN` or keep that login out of the runner's home. |
276
340
  | `mcr.microsoft.com` | Only from [`smol()`](/integrations/smol), to pull the Playwright image. The machines then have unrestricted network access, and reach every port on your computer's loopback through `host.smolvm.internal`, not only `hostPorts` ([Set up the provider](/integrations/smol#set-up-the-provider)). |
277
341
  | The package registry | When `e2e init` installs dependencies. |
278
342
  | The app under test | Every run, plus whatever the app itself loads. |
279
343
 
280
- There is no crash reporting, and no update check outside `e2e feedback`. `--ai-trace` writes a local file
281
- and doesn't upload it. Your test code, plugins, and app can make more
282
- connections.
344
+ <Note>
345
+ There is no crash reporting, and no update check outside `e2e feedback`.
346
+ `--ai-trace` writes a local file and doesn't upload it. Your test code,
347
+ plugins, and app can make more connections.
348
+ </Note>
283
349
 
284
- ## MCP and explore
350
+ ### MCP and explore
285
351
 
286
352
  | Command | Rule |
287
353
  | --- | --- |