@e2e-dev/web

中文文档
0.16.0发布于 2026/11/13Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 214.7万

Web engine for e2e agentic end-to-end testing, built on Playwright

原始使用文档
文档目录6 节
  1. Install
  2. Attaching to a remote browser ( connect )
  3. Leasing hosted browsers ( browser )
  4. The browser fixture
  5. Browsers
  6. Documentation

@e2e-dev/web

The browser engine for e2e, built on Playwright.

e2e ships no engine of its own: every target names the engine that drives it, and this package is the one for browsers. It implements the public e2e/engine contract, so a device or desktop engine plugs into the same seam with no privilege either way.

Install

npm install --save-dev e2e @e2e-dev/web

This package depends on playwright-core pinned to an exact version, so the engine always runs the Playwright it was tested against. An app that depends on Playwright itself keeps its own copy; the two share a browser cache only when their versions match.

import type { E2EConfig } from 'e2e';
import { web } from '@e2e-dev/web';

export default {
  targets: [{ name: 'web', engine: web(), app: { url: 'http://localhost:3000' } }],
} satisfies E2EConfig;

The target declares the app; the engine only drives it. The target's app takes url (the base URL app.open() opens; required on a web() target), command (a process the runner starts before the run and stops after it, with readyUrl to poll, default url), environment (test, staging, production; inferred from the host), and identity (a stable cache and session key when the origin is ephemeral). web({ url }) and the other old app options are INVALID_CONFIG. A target with app.url is a browser target, so a test can requires: ['browser']. Browser options: browser (chromium, firefox, webkit; default chromium; or a BrowserProvider that leases hosted browsers, see below), viewport ({ width, height }; default 1280x720), testIdAttribute (the attribute getByTestId and a node's testId read; default data-testid), userAgent (the User-Agent every attempt sends and navigator.userAgent reports), locale and timezoneId (the language and time zone every attempt runs in, such as de-DE and Europe/Berlin), colorScheme and reducedMotion (the prefers-color-scheme and prefers-reduced-motion every page reports, from first paint; browser.emulateMedia changes them in a test), initScripts (scripts every document runs before the page's own), and connect — attach to a remote browser over CDP instead of launching a local one.

Attaching to a remote browser (connect)

Set connect.cdpEndpoint to attach over the Chrome DevTools Protocol rather than launch. The resolver is async and called at worker init, and again at the start of any attempt that finds the session dropped, so a hosted browser whose endpoint is provisioned per run — a cloud session URL that is not known at config load — resolves each time it is needed. The resolver receives an AbortSignal that fires when the init or attempt is cancelled or exceeds its budget; a browser that connects after that is detached, never used. CDP attach is chromium-only, and disposing the engine detaches the session without killing the remote process the host owns.

engine: web({
  connect: { cdpEndpoint: async () => acquireCloudBrowserSession() },
});

For transport recovery, add connect.reconnectEndpoint(signal). This opts into the remote browser's persistent default context. cdpEndpoint then provisions a fresh, dedicated browser for every attempt, including retries; reconnectEndpoint must return that same browser after a disconnect. The engine verifies the default context ID and active page target ID, clears stale references, and never repeats a dispatched operation. A missing target fails the attempt. The host owns deleting the remote browser after cleanup.

This mode does not support headers, basicAuth, userAgent, locale, timezoneId, context reset, or session state capture and restore. Recording resumes after reconnect, but a segment lost during the disconnect remains unavailable. See the Playwright reference for the lifecycle and ownership contract.

Leasing hosted browsers (browser)

connect has no lifecycle: nothing tells the host when to delete the browser it provisioned. Pass a BrowserProvider as browser instead and the engine asks for a browser when one is needed and gives it back when its scope ends, on every exit path. scope: 'worker' (the default) leases one browser per worker slot in prepare and releases them in finish; a worker whose browser drops leases a replacement itself. scope: 'attempt' leases a fresh browser in every startAttempt and releases it in endAttempt, reattaching through the lease's reconnectEndpoint after a transport drop, with the limits of connect.reconnectEndpoint. A provider implies chromium and excludes connect; no vendor ships in the package. See Hosted browsers for the contract and an example against a generic session API.

engine: web({
  browser: {
    name: 'hosted-browsers',
    acquire: async (request) => ({ id: session.id, cdpEndpoint: session.cdpUrl }),
    release: async (lease) => stopSession(lease.id),
  },
});

The browser fixture

The engine contributes browser: navigation, routes, cookies, dialogs, frames, downloads, keyboard and mouse, plus expect(browser).toHaveURL() and toHaveTitle() and toHaveClass(). Import test from this package to have it typed; it is the same runtime test as e2e's.

import { test } from '@e2e-dev/web';
import { expect } from 'e2e';

test('signs in', async ({ app, screen, browser }) => {
  await app.open('/login');
  await screen.getByLabel('Email').fill('[email protected]');
  await expect(browser).toHaveURL('/dashboard');
});

Browsers

A missing browser is downloaded once per run, in the runner process, after the tests are collected and before the app starts: the progress prints in the run log, the run's clock starts only once the download is done, and no launch or test timeout ever includes it. Workers launch the browser the runner installed.

In CI, install browsers as their own step instead, so the cost is visible and cacheable:

npx @e2e-dev/web install chromium --with-deps

It downloads the browsers for the Playwright version this package pins, the ones the engine launches. Under pnpm, run the bin by name: pnpm exec e2e-web install chromium --with-deps.

--with-deps also installs the system libraries a slim container image lacks.

Documentation

Full documentation lives at e2e.com/docs.

版本与发布记录

@e2e-dev/web 共发布 52 个版本,首次发布于 2026/09/29;过去 12 个月发布了 52 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.16.0latest2026/11/13今天
0.16.0-nightly-20261113123338nightly2026/11/13今天
0.16.0-nightly-202611130943592026/11/13今天
0.16.0-nightly-202611130302072026/11/13今天
0.15.6-nightly-202611120302002026/11/121 天前
0.15.6-nightly-202611100302172026/11/103 天前

其他发布通道:canary → 0.11.0-canary-20260929180659,nightly → 0.16.0-nightly-20261113123338。

关于 @e2e-dev/web 的常见问题

@e2e-dev/web 是什么?

Web engine for e2e agentic end-to-end testing, built on Playwright

如何安装 @e2e-dev/web?

在项目目录运行 npm install @e2e-dev/web,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:e2e(>=0.23.1 <1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 e2e-web,可以用 npx e2e-web 直接运行。

@e2e-dev/web 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@e2e-dev/web 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@e2e-dev/web 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.22.3 || >=24.8.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@e2e-dev/web 可以商用吗?

@e2e-dev/web 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@e2e-dev/web 的下载量有多少?

根据 npm 官方下载统计,@e2e-dev/web 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,146,695 次,日均约 71,557 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@e2e-dev/web 还在维护吗?

最新版本 0.16.0 发布于 2026/11/13(今天);至今共发布 52 个版本,其中过去 12 个月发布了 52 个;首次发布于 2026/09/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。