Download Latest Version e2e@0.18.0 source code.zip (5.4 MB) Google Add to Preferred Sources
Home / e2e@0.18.0
Name Modified Size InfoDownloads / Week
Parent folder
e2e@0.18.0 source code.tar.gz < 9 hours ago 4.6 MB
e2e@0.18.0 source code.zip < 9 hours ago 5.4 MB
README.md < 9 hours ago 16.8 kB
Totals: 3 Items   10.0 MB 0

Minor Changes

  • #851 dc2afca Thanks @KrzysztofMoch! - e2e mcp sessions are now headless by default, the same as e2e run and e2e explore, and the agent decides per session: open_session {headed: true} shows the browser or simulator, headed: false hides it. --headed makes headed the default for sessions that do not say. Before, sessions were headed outside CI and only the server's --headless could hide them; --headless is still accepted, since it now asks for the default, but it is no longer documented.

  • #790 0d1ed15 Thanks @okwasniewski! - Breaking: e2e and every @e2e-dev package now need Node.js 22.22.3 or newer on Node.js 22, or 24.8.0 or newer (engines.node is ^22.22.3 || >=24.8.0). Node.js 22.12 through 22.22.2, 23, and 24.0 through 24.7 are no longer supported, and the CLI refuses to start on them, naming the versions to upgrade to. Those releases fail when a CommonJS file a test imports requires TypeScript through the new loader's module.registerHooks (nodejs/node#59679 fixed it in 22.22.3 and 24.8.0).

e2e now loads TypeScript with its own loader, built on oxc, instead of tsx. tsx brought in esbuild, whose postinstall script made every pnpm install on pnpm 11 and later fail with ERR_PNPM_IGNORED_BUILDS until the project approved the build; nothing e2e installs runs an install script now. Config and tests load as before: ESM whatever package.json says, ./x.js and ./x resolve to x.ts and ./x.jsx to x.tsx, directory index imports, tsconfig paths and baseUrl, workspace packages exporting .ts source, JSX in .tsx and .jsx, enums, namespaces, experimentalDecorators, and source-mapped stack traces. JSON imported without with { type: 'json' } still loads. A test file whose name holds %, #, or a space now collects with its source location instead of failing with "URI malformed" or losing the location. Each file reads its nearest tsconfig.json rather than the one in the working directory. What changes: import statements in a .cts file are no longer compiled into require calls (write import x = require()); standard decorators without experimentalDecorators, auto-accessors, and ES module import and value export declarations in .cts are refused with their line (import type, export type, import x = require(), and export = work); the CLI refuses the Bun (bun --bun) and Deno runtimes (install with any package manager, run on Node.js); a type imported without import type that stays in the output (a decorated member's type under emitDecoratorMetadata) fails to load, with an error naming the import; a .ts file a CommonJS file requires runs as an ES module like every other .ts, so one written with module.exports needs the .cts extension; and an import written in a JavaScript file resolves as Node.js resolves it, without TypeScript's extension rules or tsconfig paths. TypeScript inside an installed package compiles without the project's tsconfig.json.

  • #840 b33398f Thanks @Mohit20057! - screen.swipe({ from, to, duration }) adds an optional duration for path swipes, controlling how long the gesture takes in milliseconds.

Patch Changes

  • #834 8bc7d85 Thanks @Ray0907! - A recorded step that types an empty value, which clears a field, replays instead of failing with REPLAY_STALE (invalid-entry). The cache wrote the entry but its reader rejected the empty type or typeText value, so such a step could never replay from a recording.

  • #806 f7f60ba Thanks @DeryFerd! - A text download is rewritten with the full ledger pass — fragments and base64-encoded forms of a secret included — the way trace text entries already are. The download path only matched whole values while still labeling the file redaction: "complete", so a cut or base64 copy of a secret could sit in a download the report vouched for as clean.

  • #803 f2f9a53 Thanks @fecolinhares! - EnginePrepareInfo.headed is now required, alongside the headed an engine already receives on init. A host that builds a prepare call now passes the run's mode, so an engine provisions for the browser that run launches.

  • #836 5603af1 Thanks @DeryFerd! - Run-level errors in reports (hook, collection, provisioning, and worker failures) are now redacted with the config's secrets.

  • #819 aeaca4f Thanks @okwasniewski! - A failed attempt on an app that stops answering no longer waits 5 s for failure evidence at every capture point, or forever when the engine ignores cancellation. The runner captures the screen and screenshot once per attempt, stops waiting after 5 s, and keeps the original error.

  • #810 366766d Thanks @okwasniewski! - An agent step whose model answers a forced complete_step turn with another tool no longer fails as MODEL_PROVIDER_FAILED. The call goes back to the model as an error and the turn is asked again within the step's turn budget; a model that never concludes fails the step with STEP_NO_CONCLUSION.

  • #811 8b552c2 Thanks @okwasniewski! - An error an engine throws with a runner code, such as INVALID_LOCATOR for an unsupported selector, keeps its code and category when the engine is loaded from e2e.config.ts. It was reported as an infrastructure ENGINE_FAILURE.

  • #809 9995932 Thanks @okwasniewski! - A run that executes in the host process, such as e2e explore, no longer crashes that process when a test leaves a promise rejection or an exception uncaught. It handles them as a worker process does: a rejection fails the test running when it surfaces, or is recorded as UNHANDLED_REJECTION between tests. An uncaught exception, or a rejection that surfaces with no test running before any test has finished, is a run error that fails the test on its way with WORKER_CRASH and skips the rest of its file. The handlers are removed when the run ends.

  • #911 7aafa00 Thanks @okwasniewski! - agent.assert and agent.waitFor fail when the value they check is shown more than once and one place contradicts it, such as a correct order summary total next to a wrong pay button total. A claim about some item among several, such as a todo is marked done, still holds when one item matches.

  • #815 79497a7 Thanks @okwasniewski! - e2e mcp now redacts secret values from everything open_session and close_session return and from its log lines. Before, an engine or app error that carried a configured secret, in a failed open or in a close_session "Cleanup:" line, reached the client and stderr verbatim.

  • #894 9ae674e Thanks @rudycelekli! - Honor project tools' toModelOutput renderers for string results and preserve rendered error outputs as MCP error results.

  • #826 ac1c610 Thanks @okwasniewski! - e2e mcp now redacts secret values from what your code prints through console, process.stdout, or process.stderr, such as a console.log in a project tool or in the config's top-level code. Before, it reached stderr verbatim. Output printed while a config loads appears once the config has loaded; if the load fails, that output is withheld, since the config's secrets are unknown. An uncaught error or unhandled rejection is logged redacted and the server shuts down its sessions and exits with code 1, instead of crashing with the raw error.

  • #847 2e26ec6 Thanks @agammann! - Include npm's argument separator in CLI hints so flags such as --headed reach the installed e2e binary.

  • #814 78e135a Thanks @okwasniewski! - A secret value a test passes as a plain string (spelled into an app.open URL, typed with fill) no longer stays in the Playwright trace. Traces and text downloads are now rewritten whenever the session knows a secret value (every static one, and a provider's once resolved), not only after a secret fill or an engine-held secret, so they are labeled redaction: "complete" instead of not-required or incomplete. Screencast frames are still dropped only after a secret fill. Like any secret trace, a rewritten one masks unrelated text that shares 8 characters with a value.

  • #902 032825f Thanks @rudycelekli! - Preserve environment and client settings on existing e2e MCP registrations when rerunning init.

  • #820 a561f06 Thanks @okwasniewski! - Replaying a repeated scroll on a list that filled the screen, when the list can no longer be found, waits for it once and then scrolls the screen for every remaining repeat. It used to wait out the full relocation backoff (about 14 seconds) before each repeat, so a recorded 4x scroll took about a minute to replay.

  • #837 338378e Thanks @okwasniewski! - A worker that crashes during a retry no longer drops the attempts before it. Before, a test whose first attempt failed and whose retry crashed the worker showed a single attempt 0 with WORKER_CRASH, and the first attempt's error was lost. The report now keeps every finished attempt and adds the crash as the next one. A crash after the last attempt (in an afterAll) is recorded on that attempt instead of as a retry. For a serial group, the finished group attempts and the members that finished in the crashed attempt stay in the report, the member that was running fails with WORKER_CRASH, and a crash after a member finished fails the group attempt without blaming that member. A forced interrupt keeps the attempts that finished and the verdict they reach, flaky included.

  • #829 01b88d3 Thanks @okwasniewski! - e2e run redacts secret values from what the config's top-level code, a test file's top level, and reporters print, as it already did for tests, including what a timer or a reporter the run stopped waiting for prints after the run. Output printed while the config loads appears once it has loaded, and is withheld if the load fails. With the list reporter, output printed during the run prints under stdout | runner or stderr | runner, on stdout like a test's output, so the live view no longer paints over it.

  • #813 87e75ae Thanks @okwasniewski! - A serial group whose session fails to launch, or whose file fails to load, now fails the run. Before, every member was skipped and the run passed with exit code 0. The first member now fails with the launch error and the rest skip with cause serial-predecessor-failed, so the list reporter, summary.md, and junit.xml show the failure. A retry that fails to launch keeps the members' verdicts from the attempt before it, so a member that failed there still fails. An infrastructure error in a serial group, at launch or in a member, now exits 3 and sets the run status to error, as it does for any other test, instead of exiting 1. When a worker crashes during a serial group, the member that was running fails with WORKER_CRASH instead of being skipped as if it never started.

  • #827 6f528be Thanks @okwasniewski! - After a secret fill, an agent step whose screen can only be read from a fallback screenshot (act, or a judgment with vision: true) now fails with POLICY_DENIED naming the secret fill, instead of the engine's timeout.

  • #888 5e032d9 Thanks @okwasniewski! - Telemetry no longer sends a project id outside git or in a shallow clone, and a coding agent that sets CI outside a CI vendor counts as the machine it runs on. EAS Build, Bitrise, Codemagic, and Xcode Cloud are recognized as CI vendors.

  • #828 c83b86f Thanks @okwasniewski! - A page whose script never yields no longer holds a web test until its test timeout: a tap, a locate, or a navigation on it now fails with ACTION_FAILED at its action or navigation timeout, also while a trace records. A tap or keystroke cut off that way may have reached the page and is never repeated by a replay. expect(browser) matchers on such a page end at their own timeout instead of the action timeout.

  • #824 37806d7 Thanks @okwasniewski! - A test that blocks its worker's event loop (while (true) {}) no longer hangs the run until Ctrl-C. When the worker has not responded cleanupTimeout (at least 5 s) after the test timeout, the runner kills it, reports the test timed-out with TEST_TIMEOUT, and runs the rest of the file on a new worker. A worker with a debugger attached when the test starts (an editor's auto-attach, or NODE_OPTIONS=--inspect=0) is never killed this way. Runs with an inline config or in-memory tests run in the runner's own process and still hang.

Source: README.md, updated 2026-10-06