Repository navigation
e2e@0.21.0
Minor Changes
-
#1132
c82a03aThanks @okwasniewski! -app.command.inheritEnvpasses host variables to the app by name or trailing-*prefix (['DATABASE_URL', 'STRIPE_*']), copying each one only when it is set, so a host can hand the app per-run values without listing them in the config or spreadingprocess.env.command.envwins over an inherited value, and inherited values are redacted from a quoted startup failure likecommand.env. A bare*and a*anywhere but the end areINVALID_CONFIG. -
#1134
8497c06Thanks @okwasniewski! -E2E_CACHE_DIRande2e run --cache-dir <dir>(also one2e cache) replacecache.dir, so checkouts and worktrees of one project can share a replay cache without editing the config. The flag wins over the variable, both resolve from the project root with~or a leading~/as the home directory, and the cache mode stays as configured. With a customcache.store,--cache-diris an error andE2E_CACHE_DIRis ignored. -
#1137
27a6ed0Thanks @okwasniewski! -e2e feedbacknow asks for reports the e2e team can act on. A--type bugreport needs--repro, steps that reproduce it every time. Without it, the command sends nothing and prints a prefilled GitHub issue instead, so the team can ask you for a reproduction there. When the registry confirms the installed e2e is older than the latest release, the report exits 2 and sends nothing, since the problem may already be fixed; upgrade and check again, or pass--allow-outdated. The new--error-codeflag takes the e2e error code involved, and--task,--expected,--actual, and--approachnow take at most 1500 characters. -
#1135
78655e1Thanks @okwasniewski! -e2e inittakes a flag per wizard question:--engine,--gateway,--endpoint,--skills,--mcp, and--install/--no-install. A flag skips its prompt; with--yes, an omitted flag keeps its default. Without a terminal, pass--yes.--endpointimplies--gateway openai-compatible.--skillsand--mcptake comma-separated locations ornone. An unknown value exits 2 before any write and lists the valid ones.npx e2e init --yes --gateway openrouter --skills .agents/skills --mcp .mcp.json --install
-
#1097
a869c06Thanks @okwasniewski! -textContent(),inputValue(),getAttribute(),isEnabled(),isDisabled(),isChecked(), andboundingBox()now wait for their one match until the action timeout, as actions and Playwright's reads do, instead of failing at once withLOCATOR_NOT_FOUNDwhen the node is still rendering.isVisible(),isHidden(),count(),all(), andallTextContents()still answer from the current screen. A read of a node that never appears fails after the action timeout. -
#1131
babae32Thanks @okwasniewski! -e2e run --max-duration <ms>and the config keymaxDurationstop a run once it has spent that long running tests: nothing more is dispatched, the running tests end asinterrupted, the rest are skipped with the new causetime-limit, and the run records aRUN_TIMEOUTerror and exits 1.--last-failedruns the interrupted and skipped tests next. The report schema's skip causes gaintime-limit. -
#980
3a53fbdThanks @bheemreddy181! - AddopenHost<Fixtures>()toe2e/runnerfor other test runners. A worker-lifetime host prepares the target, starts app processes, and initializes its engine once.host.openSession({ name, timeout, signal, agent, onStep })opens a fresh test-lifetime attempt with typed fixtures, its own deadline, steps, and artifacts. Only one hosted attempt can be opening, live, or closing per process; a host can open sessions sequentially.A session's
timeoutis enforced: when it passes, every operation still running fails withTEST_TIMEOUT, the session is timed out, andclose()reports it. A launch that fails or is cancelled leaves the host usable for the next session; only a session whose engine cleanup failed closes the host.Closing a session writes a redacted
trace.mdunder a safe, uniqueresults/host/directory, available through the absolutetracePathfor attachments.close()returns soft expectation and cleanup failures; async disposal throws anAggregateErrorwhen failures exist. Closing the host cancels any pending or active session, then disposes and releases its worker resources once. Both close methods are idempotent.configaccepts a path or anE2EConfigvalue. The one-shot MCP attempt stays internal.
Patch Changes
-
#1130
2536ed3Thanks @kacperkapusciak! - Update dependencies: the web engine drives Playwright 1.64.0 (and the Chromium it installs), and smol machines boot the matchingmcr.microsoft.com/playwright:v1.64.0-nobleimage. The runner moves tooxc-parser,oxc-transform, and@oxc-project/runtime0.153.0,@modelcontextprotocol/server2.3.1, and@ai-sdk/provider4.0.26. -
#1058
a91b6fbThanks @HEOJUNFO! - Anend-mismatchcache detail now says which part of the end check failed: recorded nodes that did not show (missing alert "Acme Notes"), nodes that should have gone but are still there (still showing ...), alerts the recording never saw (unrecorded alert ...), or an outcome that already showed before the replay acted. It used to print the first two recorded nodes, whether or not they were on screen. -
#1093
0feaefbThanks @okwasniewski! - The list reporter badges ane2e explore --target <name>run with the explored target rather than the first configured one. -
#1092
6b1e524Thanks @okwasniewski! - A judgment (agent.assert,agent.waitFor,agent.extract) on a screen denser than the observation budget now cuts the screen by its instruction's measured size, so a long instruction, ore2e explore's planner once its record of earlier steps has grown, no longer fails the adapter's pre-flight withSTEP_BUDGET_EXHAUSTED: model input upper bound N exceeds the agent's maxInputTokens Mand aborts the run before any request is sent. -
#1111
c4d8706Thanks @kacperkapusciak! - A TypeScript import of a directory through a package subpath or a#import now loads the directory'smainorindex.ts, the way TypeScript resolves it. A workspace package withoutexportsimported as@acme/db/enums, anexportsentry naming a directory, and a#import mapped to one used to fail collection withERR_UNSUPPORTED_DIR_IMPORT. A relative directory import already worked. Under Yarn PnP, a package subpath that names a directory still fails: PnP's resolver does not say which directory it found. -
#1107
dbdec70Thanks @KrzysztofMoch! - Make the bundled agent skill work alongside the shared Codex and Claude plugin, document project-local Codex MCP setup, register the MCP server with Claude Code at project scope in the CLI hints, and ask before sending feedback. -
#1103
292cd05Thanks @hasandenizuk! - MCPlocateno longer sends astatus,alert, orlistitemname that matches nothing back to the observation as an accessible name. It says thatobserveshows those roles by their text and names thegetByRole(role).filter({ hasText })andgetByTextcalls that match that text. A query that already hasexact: falseis no longer told to loosen the match withexact: false. -
#1098
a5bb4dbThanks @TMisiukiewicz! -e2e loginprints the sign-in URL on a line of its own instead of inside a box, so copying it no longer picks up the box's borders. -
#1021
33cb8d3Thanks @Yi-111-a! -e2e models opencode-consolelists models throughOPENCODE_API_KEYwhen it is set, the keyopencodeConsole()uses in place of the stored login.e2e modelswith no provider includes OpenCode Console when only the key is set, and with no credential the error names bothnpx e2e login opencode-consoleandOPENCODE_API_KEY. -
#1018
dec61afThanks @fecolinhares! -opencodeConsole()asks for an explicit output cap on the models the workspace config serves over Anthropic. Those ids are unknown to the Anthropic SDK, which limits a call that sets nomaxOutputTokensto 4096 tokens and only warns: a long answer ended withfinishReason: 'length'and nothing in the result said why. The provider now asks for 8192, the cap the runner already allows a judgment, and a caller's ownmaxOutputTokensis left untouched. -
#1073
14b77d3Thanks @thymikee! - The mobile engine now bounds each input (a tap or other node action, a point action, typing, a key,back, a keyboard dismissal) by its budget (actionTimeout, or the call'stimeout). An input that outlived it used to hold the step until the test timeout. Now an input sent that does not answer in time fails withACTION_MAY_HAVE_COMMITTED, which the runner never repeats, as on the web engine; one sent with almost no budget left still gets 250 ms to answer. An input the budget ran out before, while its target was still settling, is not sent and fails withOPERATION_TIMEOUT. A long press or timed swipe that holds at least as long as the budget left is refused before it is sent, naming the hold and the time left. Reads (observe, locate, the relocation before a tap), launches, artifacts, anddevice.*fixture calls are unchanged: a locator poll still lets its last read finish. TheOperationContext.signaldocs ine2e/enginenow say what it does: it aborts with the attempt or the running hook, not attimeoutMs. -
#1104
762f7deThanks @DeryFerd! - The bundled agent skill's limrun note on iOS keyboard actions no longer names an agent-device version, which had gone stale. -
#1108
b965c10Thanks @kacperkapusciak! - The bundled agent skill and the docs now define an atomicagent.actgoal: one outcome that one check confirms. Core concepts shows a bad instruction that joins three goals next to the good version, threeactcalls each followed by its check, and the examples that joined two checkable outcomes in oneactare split. -
#1096
37fee75Thanks @okwasniewski! - The run telemetry event now counts agent steps by entry point (steps_agent_act,steps_agent_assert,steps_agent_extract,steps_agent_waitfor) and how many executed tests ran any agent step and how many of those ranagent.act(tests_with_agent_steps,tests_with_act), so the share of tests that are deterministic end to end can be read off a run.