Table of Contents
Open Table of Contents
Why This Repo, Why Now
Checking github.com/trending today, the top repository is tester-army/e2e, described by its maintainers as “an end-to-end testing framework for web and mobile apps.” Instead of writing a script of selectors and waits, a test describes a goal in natural language — agent.act('upgrade the workspace to the Pro plan') — and an agent drives the running app to reach it, while the same test still checks the outcome with ordinary locators and assertions.
The pitch behind the trending spike is straightforward: UI changes break selector-based E2E suites constantly, and maintaining them eats time engineers would rather spend shipping. e2e lets an agent adapt to UI changes while a verified act step gets recorded into a replay cache, so the next run replays the recorded actions with no further model calls — tests with no agent steps need no model at all. The project also ships engines for both Playwright-driven web testing and iOS/Android testing through agent-device, plus a documented MCP-adjacent coding-agent workflow that lets tools like Claude Code or Cursor set up, run, and debug its tests. As always, a trending position reflects visibility and momentum, not a verdict on quality, security, or production-readiness — those are reviewed independently below.
What the Technology Actually Is
Per the repository’s README and documentation, e2e is a TypeScript monorepo built around a pluggable “engine” architecture, managed with pnpm workspaces and released with Changesets.
Documented architectural pieces:
e2e(npm) — the core SDK, test runner, and CLI (npx e2e init,npx e2e run).@e2e-dev/web— the browser engine, driving Chromium, Firefox, and WebKit through Playwright.@e2e-dev/mobile— the iOS/Android engine, driving simulators and emulators through agent-device.@e2e-dev/github— a reporter that posts run results as a pull request comment.@e2e-dev/kerneland@e2e-dev/eas— hosted browser and hosted iOS/Android simulator backends for the web and mobile engines, respectively.@e2e-dev/decision— executors for “decision models” (bounded, non-LLM action/assertion models such as Clef or Jev), per docs/decision-models.mdx.
At a high level, a test runs once per configured target (for example Chromium, or an iPhone simulator). Deterministic steps (locator, expect) never touch a model. Agent steps (agent.act, agent.assert, agent.waitFor, agent.extract) send the current screen — quoted to the model as untrusted evidence, never as instructions — through the AI SDK to whichever model you’ve configured (a subscription, an API key, or a local/self-hosted endpoint), per docs/models.mdx. A verified act step is cached and replayed on later runs without a model call, per docs/cache.mdx, which is the project’s documented answer to the token cost and flakiness of agent-only E2E suites.
Purpose and Use Cases
Per the README and linked docs, e2e’s primary purpose is covering real user flows on web and mobile without hand-maintaining brittle selector scripts for every UI change, while keeping an explicit “code-trust” vs. “untrusted model input” boundary so agent steps don’t gain more authority than a human reviewer would grant a test.
Documented use cases and target users:
- Web app teams — testing flows like checkout or billing upgrades with Chromium/Firefox/WebKit via Playwright, mixing agent goals with deterministic locator checks in the same test.
- Mobile teams — testing iOS and Android apps on simulators/emulators via
agent-device, including physical-device workflows. - CI/CD pipelines — a documented GitHub Actions workflow runs deterministic and agent tests in the same job, supports sharding, rerunning only failed tests, and posting results as a PR comment via
@e2e-dev/github. - Coding-agent–assisted development — per docs/coding-agents.mdx,
e2e initinstalls an “e2e skill” so a coding agent (Claude Code, Codex, Cursor) can scaffold, run, and debug tests from a single setup prompt. - Teams without an AI budget — the README states explicitly that “tests without agent steps need no model,” so the framework also works as a plain deterministic Playwright/mobile runner.
Installation
Per the project’s Quickstart. The project documents one primary path — the init wizard — run through npm, pnpm, or bun.
Prerequisites
- Node.js 24.8 or newer (22.22.3 or newer on Node.js 22). On Windows, run inside WSL.
- Mobile testing additionally needs Xcode with an iOS simulator runtime, or the Android SDK with an emulator (
npx agent-device doctorchecks this). - A model provider if you want agent steps: an existing subscription (ChatGPT Plus/Pro, GitHub Copilot, OpenCode Console, SuperGrok/X Premium+), an API key for an AI SDK provider, or a local/self-hosted OpenAI-compatible endpoint. Tests with no agent steps need no model.
Recommended: the init wizard
# npm
npx e2e init
# pnpm
pnpm dlx e2e init
# bun
bunx e2e init
The wizard asks for Web (Playwright) or Mobile (iOS/Android), then a subscription or model provider (or None for tests without AI), and writes a config, an example test, and adds dependencies — existing files are left intact.
Example web config written by the wizard (Vercel AI Gateway):
import type { E2EConfig } from "e2e";
import { web } from "@e2e-dev/web";
import { gateway } from "ai";
export default {
agents: { default: { model: gateway("openai/gpt-6-luna-fast") } },
targets: [{ engine: web(), app: { url: "http://localhost:3000" } }],
} satisfies E2EConfig;
Run the example test
# npm
npx e2e run
# pnpm
pnpm exec e2e run
# bun
bunx e2e run
This downloads a browser (or boots the simulator/emulator), checks that the app opens, and writes .e2e/report.json — no model calls, so no sign-in or API key is needed for this step.
Minimal getting-started example: an agent step
import { test } from "@e2e-dev/web";
import { expect } from "e2e";
test("a visitor signs up for a trial", async ({ app, agent, screen }) => {
await app.open("/");
await agent.act("sign up for a free trial as {name} with email {email}", {
params: { name: "Ada Lovelace", email: "ada@example.test" },
});
await agent.assert("the welcome screen greets Ada by name");
await expect(screen.getByRole("status")).toContainText("trial");
});
npx e2e run tests/agent.e2e.ts
To use a subscription instead of an API key, sign in once, e.g. npx e2e login github-copilot, per docs/subscriptions.mdx.
Quick Verification
Based on the documented commands:
- Example test passes with no model —
npx e2e runafterinitshould complete, open the app, and write.e2e/report.json, with no sign-in required. - Agent step runs — after configuring a model or running
npx e2e login,npx e2e run tests/agent.e2e.ts(or your own agent test) should pass; add--headedto watch a web run visually. - Mobile environment check —
npx agent-device doctorreports whether Xcode/Android SDK and a simulator/emulator are correctly set up before running mobile tests. - CI reproduction locally —
CI=1 npx e2e runreproduces CI defaults (serial workers, one retry, read-only cache) for debugging CI-only failures. - Telemetry opt-out check —
npx e2e telemetry disableor settingE2E_TELEMETRY_DISABLED=1/DO_NOT_TRACK=1should stop the documentedeu.i.posthog.comtelemetry requests, per docs/telemetry.mdx.
Security Review
Verified from the repository itself (SECURITY.md and docs/security.mdx):
- The project maintains a documented security policy with a private disclosure process — GitHub Security Advisories (preferred) or email (
security@tester.army) — with a stated acknowledgment window (3 business days) and a fix or written plan within 30 days. - Only the latest published
0.xminor of each package receives security fixes until1.0ships; older minors are not patched. - SECURITY.md describes an explicit trust model distinguishing “code-trust” (test files, config, custom tools — run with full OS authority, no sandbox) from “untrusted model input” (page content, quoted to the model as evidence, never executed as code, selectors, shell, or config). The project explicitly recommends running pull-request code from untrusted contributors in an external sandbox with no secrets and no write tokens.
- A documented secrets-handling design: a configured
Secretis never passed to model input, logs, reports, or artifacts; once a secret is filled, the viewport is “pixel-tainted” for the rest of the attempt, and the stored Playwright trace is rewritten so every credential value is replaced with<secret:name>before being saved — a trace that can’t be rewritten is deleted instead. - A detailed, itemized list of every outbound network connection a run can make (telemetry to
eu.i.posthog.com, the configured model endpoint, app-under-test readiness probes, one-time Playwright browser downloads, and whatever the tested app itself loads) — there is no crash reporting and no update check. - Telemetry is documented field-by-field in docs/telemetry.mdx: the CLI sends anonymized command/engine/error-code usage data but never test titles, file paths, URLs, instructions, observations, stack traces, environment variables, or credentials;
$geoip_disable: trueis set on every event. - The repository carries a dependabot.yml for dependency update automation and multiple CI workflows (
spec.yml,agent.yml,mobile.yml,benchmark.yml) exercising the suite on pull requests. - The project is licensed Apache-2.0 (LICENSE).
- Release cadence is very active: multiple packages (
e2e,@e2e-dev/web,@e2e-dev/mobile,@e2e-dev/github,@e2e-dev/kernel,@e2e-dev/eas) are independently versioned via Changesets, with several tagged releases each and commits landing on the day this article was written. - No published GitHub Security Advisories were found against this repository at the time of writing; absence of advisories is not proof of absence of vulnerabilities.
Security considerations to weigh yourself (documented factors, not verified vulnerabilities):
- Per the documented trust model, there is no sandbox around test code, config, or custom tools — they run with full OS authority. A malicious or compromised test file, dependency, or committed replay-cache entry is a code-trust risk the framework does not mitigate by itself.
- On the web engine there is no origin allowlist for navigation or secret fills; the docs explain this is a deliberate design choice (a click, redirect, or popup can reach another origin the same as a typed URL would), so a test whose target app can navigate elsewhere should be treated as one whose secrets can follow it there.
command.logand service logs are captured verbatim as the process writes them — the runner does not redact these, so secrets must be kept out of your app’s stdout/stderr.- CI secrets (e.g., model provider API keys) are readable by any code running in the job, including test code and dependencies — the docs explicitly recommend running untrusted/fork-PR code without secrets or write tokens.
Practical recommendations:
- Pin an exact published version of each package you depend on rather than tracking a floating range, given the active, fast-moving release cadence.
- Review third-party test files, custom tools, and any committed replay cache before trusting them, per the project’s own code-trust model — they execute with full OS authority.
- Keep CI secrets out of forked-PR workflows, as GitHub already withholds secrets from fork pull requests by default; don’t work around that.
- Disable telemetry (
E2E_TELEMETRY_DISABLED=1) in CI environments if your policy requires no outbound calls beyond the app under test and the configured model provider. - Test in an isolated environment first, especially before wiring agent-driven tests into a pipeline that has write access to production credentials or infrastructure.
Should You Use It?
Strengths: a clearly documented, itemized trust and secrets-handling model (code-trust vs. untrusted model input, pixel-tainting, trace redaction) that is unusually explicit for a project of this age; a replay-cache design that directly targets the real cost problem of agent-driven testing (token spend and model latency on every run); first-class web and mobile engines in one framework; a documented GitHub Actions CI workflow with sharding, failure-only reruns, and PR-comment reporting; and a very active commit/release cadence.
Limitations: the project is explicitly pre-1.0 (“APIs and config can still change between minor releases”), so upgrades may require config changes; agent steps still depend on an external model provider’s availability, cost, and non-determinism for anything not yet cached; there is no sandboxing of test code or dependencies, so the security of a suite still depends heavily on how carefully you vet what you run; and as a fast-moving framework spanning web, mobile, CI, and MCP-adjacent agent tooling, the configuration surface is large enough that getting model, secret, and CI settings right takes some upfront reading.
Good fit for: teams maintaining web or mobile E2E suites that break often on UI changes and want agent-driven goals instead of brittle selector scripts; teams that already use Playwright or mobile simulators/emulators and want to add agent steps incrementally, mixed with deterministic assertions; and teams building coding-agent-assisted development workflows that want tests an agent can read, run, and debug on its own.
Evaluate alternatives if: you need a stable, versioned-1.0 API for a large existing test suite; your organization cannot send any screen content to an external model provider, even redacted; or you need strong sandboxing guarantees around third-party or fork-contributed test code out of the box.
Primary sources used: GitHub repository · README · SECURITY.md · Documentation home · Quickstart · Models · Continuous integration · Cache · Telemetry · Coding agents · LICENSE