必须额外执行 playwright-install 下载浏览器,否则无法启动;PHPUnit 集成需 PHPUnit 10.0 及以上;CI 或新机器上需加 --with-deps 安装系统依赖。

playwright
playwright-phpMIT活跃维护PHP 版的 Playwright 浏览器自动化库,用 PHP 就能驱动浏览器做导航、E2E 测试、断言和截图,省去在 PHP 项目里另搭一套自动化工具链。
Playwright PHP library for browser automation: navigation, E2E tests, assertions, screenshots, and so much more!
composer require --dev playwright-php/playwright
vendor/bin/playwright-install --browsersREADME 未说明显存或 GPU 要求;运行环境需 PHP 8.2+ 与 Node.js 20+,浏览器由 playwright-install 下载。
在 PHP 里直接驱动 Chromium、Firefox、WebKit 做 E2E 测试与网页抓取,无需自己管理 Node 服务
PHP 版的 Playwright 浏览器自动化库,用 PHP 就能驱动浏览器做导航、E2E 测试、断言和截图,省去在 PHP 项目里另搭一套自动化工具链。
核心能力
- 用 browser/context/page/locator 模型操作浏览器
- 交互自动等待,减少手写 sleep
- 内置 PHPUnit trait 与 expect() 流式断言
- 包内自带 Node 服务,无需单独启动服务器
- 支持 storageState 复用登录态与上下文
容易踩的坑
- v1.6.0最新正式版2026-11-07 · 2026-11-07 23:07 UTC
Added
- Report missing Playwright dependencies with installation commands and include redacted Node stderr when the process exits (#130)
toHaveScreenshot()onPageAssertionsInterface,LocatorAssertionsInterface, andExpectInterfacecompares screenshots against PNG or lossless WebP baselines (#174)- Launching a browser from a custom path through
withExecutablePath()andPW_EXECUTABLE_PATH(#191) PageInterface::pageErrors()exposes recorded JavaScript errors (#179)- Remote browser configuration through
PlaywrightConfig::wsEndpoint,withWsEndpoint()and thePW_WS_ENDPOINT/PLAYWRIGHT_WS_ENDPOINTenvironment variables (#195)
Changed
Playwrightstatic browser launch helpers throwInvalidArgumentExceptionfor unsupported options that were previously ignored (#200)
Fixed
- Use
PlaywrightConfig::loggerfor page and locator diagnostics, with redacted navigation URLs and command errors (#83) - Preserve Playwright's default Chromium feature flags so cross-site iframes can access storage (#199)
New Contributors
- @aik099 made their first contribution in https://github.com/playwright-php/playwright/pull/191
Full Changelog: https://github.com/playwright-php/playwright/compare/v1.5.1...v1.6.0
- v1.5.12026-11-06 · 2026-11-06 21:01 UTC
查看更新说明
Fixed
- Handle commands from one stdin chunk concurrently by @bjalt in https://github.com/playwright-php/playwright/pull/184
- Follow navigation redirects with Playwright 1.64 by @kbond in https://github.com/playwright-php/playwright/pull/186
- Reduce CI duplication and cache Composer dependencies by @kbond in https://github.com/playwright-php/playwright/pull/197
- Redact URL query secrets and complete authorization tokens by @smnandre in https://github.com/playwright-php/playwright/pull/175
- Clean up context resources when closing a browser by @smnandre in https://github.com/playwright-php/playwright/pull/176
- Preserve native popup wait errors by @smnandre in https://github.com/playwright-php/playwright/pull/177
- Respect operation timeouts when expiring coordinated commands by @smnandre in https://github.com/playwright-php/playwright/pull/178
- Release closed browser contexts by @Jean-Beru in https://github.com/playwright-php/playwright/pull/181
- Dispatch route events to the handler that registered them by @Mir-Zairan in https://github.com/playwright-php/playwright/pull/182
- Settle requests before rethrowing route handler errors by @kbond in https://github.com/playwright-php/playwright/pull/185
- Use existing browser context when connecting over CDP by @EdwinHoksberg in https://github.com/playwright-php/playwright/pull/100
- Expose existing pages when connecting over CDP by @kbond in https://github.com/playwright-php/playwright/pull/198
- Send
isNavigationRequestin the route request payload by @kbond in https://github.com/playwright-php/playwright/pull/124 - Rely on native Playwright action waiting by @Toflar in https://github.com/playwright-php/playwright/pull/172
New Contributors
- @bjalt made their first contribution in https://github.com/playwright-php/playwright/pull/184
- @Jean-Beru made their first contribution in https://github.com/playwright-php/playwright/pull/181
- @Mir-Zairan made their first contribution in https://github.com/playwright-php/playwright/pull/182
- @EdwinHoksberg made their first contribution in https://github.com/playwright-php/playwright/pull/100
Full Changelog: https://github.com/playwright-php/playwright/compare/v1.5.0...v1.5.1
- v1.5.02026-09-20 · 2026-09-20 12:55 UTC
查看更新说明
Added
- Targeted browser installation through
playwright-install [browser...](#165) - Package manager selection from the consuming project's
packageManagerdeclaration or--package-manager-bin(#168)
Fixed
- Browser-context API requests preserve response status, headers, binary bodies, cookies, storage state and tracing (#163)
- API request tracing and HAR recording use the correct request tracer with Playwright 1.63 and newer (#166)
Route::fulfill()decodes base64 response bodies (#162)playwright-installkeeps pnpm dependencies and lockfiles isolated from enclosing workspaces (#167)- Failure screenshots are named after the failing test again on PHPUnit 10 and newer (#169)
New Contributors
- @Kocal made their first contribution in https://github.com/playwright-php/playwright/pull/167
- @jacekzlotnicki made their first contribution in https://github.com/playwright-php/playwright/pull/169
- @Toflar made their first contribution in https://github.com/playwright-php/playwright/pull/168
Full Changelog: https://github.com/playwright-php/playwright/compare/v1.4.0...v1.5.0
- Targeted browser installation through
- v1.4.02026-08-10 · 2026-08-10 19:42 UTC
查看更新说明
What's Changed
- Standardize on bin/.gitignore for bin/ artifacts by @kbond in https://github.com/playwright-php/playwright/pull/131
- Enforce $this-> for PHPUnit assertion calls by @smnandre in https://github.com/playwright-php/playwright/pull/132
- Declare interface methods instead of annotating them by @smnandre in https://github.com/playwright-php/playwright/pull/136
- Match the class attribute exactly in toHaveClass by @smnandre in https://github.com/playwright-php/playwright/pull/137
- Add internal navigation redirect handling by @smnandre in https://github.com/playwright-php/playwright/pull/135
- Merge splitted unit tests into one by @smnandre in https://github.com/playwright-php/playwright/pull/134
- Add browser type and context browser by @smnandre in https://github.com/playwright-php/playwright/pull/133
- Add console message metadata by @smnandre in https://github.com/playwright-php/playwright/pull/140
- Add browser context timeouts and extra headers by @smnandre in https://github.com/playwright-php/playwright/pull/141
- Add direct locator APIs by @smnandre in https://github.com/playwright-php/playwright/pull/142
- Add DOM locator assertions by @smnandre in https://github.com/playwright-php/playwright/pull/139
- Add page init scripts, drag and drop and headers by @smnandre in https://github.com/playwright-php/playwright/pull/138
- Add frame evaluation and title by @smnandre in https://github.com/playwright-php/playwright/pull/143
- Cover the parity additions left untested by @smnandre in https://github.com/playwright-php/playwright/pull/144
- Add accessible text and ARIA snapshot assertions by @smnandre in https://github.com/playwright-php/playwright/pull/146
- Consolidate assertion implementations by @smnandre in https://github.com/playwright-php/playwright/pull/154
- Add frame navigation and evaluation by @smnandre in https://github.com/playwright-php/playwright/pull/145
- Add observability features by @smnandre in https://github.com/playwright-php/playwright/pull/147
- Add evaluation parity by @smnandre in https://github.com/playwright-php/playwright/pull/148
- Add WebStorage, Credentials and Screencast support by @smnandre in https://github.com/playwright-php/playwright/pull/149
- Add Network parity by @smnandre in https://github.com/playwright-php/playwright/pull/150
- Add surface parity by @smnandre in https://github.com/playwright-php/playwright/pull/151
- Add Browser bind and unbind by @smnandre in https://github.com/playwright-php/playwright/pull/152
- Add HAR recording & API tracing by @smnandre in https://github.com/playwright-php/playwright/pull/153
- Add missing runtime resource docblocks by @smnandre in https://github.com/playwright-php/playwright/pull/156
- Add missing core API docblocks by @smnandre in https://github.com/playwright-php/playwright/pull/155
New Contributors
- @kbond made their first contribution in https://github.com/playwright-php/playwright/pull/131
Full Changelog: https://github.com/playwright-php/playwright/compare/v1.3.1...v1.4.0
- v1.3.12026-08-04 · 2026-08-04 21:17 UTC
查看更新说明
What's Changed
- Resolve input file paths before sending by @smnandre in https://github.com/playwright-php/playwright/pull/127
- Redact credentials from connect logs by @smnandre in https://github.com/playwright-php/playwright/pull/128
Full Changelog: https://github.com/playwright-php/playwright/compare/v1.3.0...v1.3.1
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Playwright PHP
Automate Chromium, Firefox, and WebKit from PHP for browser testing, scraping, screenshots, and other browser-driven workflows.
- Familiar browser, context, page, and locator model
- Auto-waiting interactions
- PHPUnit integration with fluent
expect()assertions - No separate server to manage: the package starts its bundled Node server
Requirements:
- PHP 8.2+
- Node.js 20+ (used by the bundled Playwright server and browsers)
Installation
Add the library to your project:
composer require --dev playwright-php/playwright
Install the Playwright browsers (Chromium, Firefox, WebKit):
# Run after composer install in your application or in this repository
vendor/bin/playwright-install --browsers
# Or install only the browser targets your project uses
vendor/bin/playwright-install chromium
# On fresh machines/CI where you need Playwright's OS dependencies too
vendor/bin/playwright-install --with-deps
# Preview commands without changes
vendor/bin/playwright-install --dry-run --with-deps
For targeted installation, browser cache location, and Chrome or Edge channels, see Browsers, Browser Types, and Channels.
Quick Start
Open a page and print its title:
<?php
require __DIR__.'/vendor/autoload.php';
use Playwright\Playwright;
$context = Playwright::chromium(['headless' => true]);
$page = $context->newPage();
$page->goto('https://example.com');
echo $page->title().PHP_EOL; // Example Domain
$context->close();
Documentation
Usage
Browser
- Choose a browser:
Playwright::chromium(),Playwright::firefox(), orPlaywright::webkit(). Playwright::safari()is an alias ofwebkit().- Supported launch options:
headless(bool),slowMo(ms),args(array of CLI args), and an optionalcontextarray with context options.
$context = Playwright::webkit([
'headless' => false,
'slowMo' => 200,
'args' => ['--no-sandbox'],
// 'context' => [ ... context options ... ],
]);
Unknown launch option names throw InvalidArgumentException. For options such as channel and proxy, use PlaywrightConfigBuilder with PlaywrightFactory.
Page
Create pages, navigate, evaluate scripts, and take screenshots:
$page = $context->newPage();
$page->goto('https://example.com');
$html = $page->content();
$title = $page->title();
$path = $page->screenshot(__DIR__.'/screenshot.png');
Locators and interactions
$button = $page->locator('text=Sign in');
$button->click();
$username = $page->locator('#username');
$username->fill('[email protected]');
$password = $page->locator('#password');
$password->fill('s3cret');
$password->press('Enter');
Storage state and context reuse
$context->storageState(__DIR__.'/state.json');
// Later in another process
$ctx = Playwright::chromium([
'context' => ['storageState' => __DIR__.'/state.json'],
]);
PHPUnit integration
The package provides a testing trait and fluent expect() assertions to write robust E2E tests.
Requirements: PHPUnit 10.0 or higher is required to use the PlaywrightTestCaseTrait.
Minimal example:
<?php
use PHPUnit\Framework\TestCase;
use Playwright\Testing\PlaywrightTestCaseTrait;
final class HomePageTest extends TestCase
{
use PlaywrightTestCaseTrait;
protected function setUp(): void
{
parent::setUp();
$this->setUpPlaywright();
}
protected function tearDown(): void
{
$this->tearDownPlaywright();
parent::tearDown();
}
public function test_title_is_correct(): void
{
$this->page->goto('https://example.com');
$this->expect($this->page)->toHaveTitle('Example Domain');
}
}
Notes:
- The trait provides
$this->playwright,$this->browser,$this->context, and$this->pageproperties. - Call
setUpPlaywright()insetUp()andtearDownPlaywright()intearDown()for proper lifecycle management. - Use
$this->expect($locator)or$this->expect($page)for fluent assertions with auto-waiting. - If you prefer full control, you can skip the trait and use the static
Playwrightfacade directly.
GitHub Actions
Example workflow snippet:
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: composer install --no-interaction --prefer-dist
# Install browsers for Playwright PHP
- run: vendor/bin/playwright-install --with-deps
- run: vendor/bin/phpunit --colors=always
Tips:
- Cache Node and Composer if you need faster builds.
- You can also cache Playwright browsers under
~/.cache/ms-playwright.
Contributing
Include tests for behavior changes and update documentation or examples when their public behavior changes. Set up the repository with:
composer install # installs PHP deps and the bundled Playwright server
bin/playwright-install --with-deps # downloads browsers + optional system deps
make ci # runs code style, static analysis, and tests
See docs/contributing/testing.md for more details on the local workflow.
License
This package is released by the Playwright PHP project under the MIT License. See the LICENSE file for details.