|
1 |
| -# Workers version of Playwright |
| 1 | +# Playwright for Browser Rendering |
2 | 2 |
|
3 |
| -This repo is an experimental work-in-progress fork of [Playwright](https://playwright.dev/) that has been modified to be compatible with Cloudflare Workers and [Browser Rendering](https://developers.cloudflare.com/browser-rendering/). For installation and usage instructions specific to this fork, see our [Developer Documentation](./packages/playwright-cloudflare/README.md). |
| 3 | +Fork of [Playwright](https://github.com/microsoft/playwright/) that was modified to be compatible with [Cloudflare Workers](https://developers.cloudflare.com/workers/) and [Browser Rendering](https://developers.cloudflare.com/browser-rendering/). |
4 | 4 |
|
5 |
| -Original README follows: |
| 5 | +## Getting Started |
6 | 6 |
|
7 |
| -# 🎭 Playwright |
| 7 | +Create a [Cloudflare Worker](https://developers.cloudflare.com/workers/get-started/guide/_) |
8 | 8 |
|
9 |
| -[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop --> [](https://aka.ms/playwright/discord) |
10 |
| - |
11 |
| -## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright) |
12 |
| - |
13 |
| -Playwright is a framework for Web Testing and Automation. It allows testing [Chromium](https://www.chromium.org/Home), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [WebKit](https://webkit.org/) with a single API. Playwright is built to enable cross-browser web automation that is **ever-green**, **capable**, **reliable** and **fast**. |
14 |
| - |
15 |
| -| | Linux | macOS | Windows | |
16 |
| -| :--- | :---: | :---: | :---: | |
17 |
| -| Chromium <!-- GEN:chromium-version -->135.0.7049.28<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
18 |
| -| WebKit <!-- GEN:webkit-version -->18.4<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
19 |
| -| Firefox <!-- GEN:firefox-version -->136.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
20 |
| - |
21 |
| -Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details. |
22 |
| - |
23 |
| -Looking for Playwright for [Python](https://playwright.dev/python/docs/intro), [.NET](https://playwright.dev/dotnet/docs/intro), or [Java](https://playwright.dev/java/docs/intro)? |
| 9 | +```Shell |
| 10 | +npm create cloudflare@latest -- cf-playwright-worker |
| 11 | +``` |
24 | 12 |
|
25 | 13 | ## Installation
|
26 | 14 |
|
27 |
| -Playwright has its own test runner for end-to-end tests, we call it Playwright Test. |
28 |
| - |
29 |
| -### Using init command |
30 |
| - |
31 |
| -The easiest way to get started with Playwright Test is to run the init command. |
| 15 | +This package is released on npmjs.com at [@cloudflare/playwright](https://www.npmjs.com/package/@cloudflare/playwright). To install it in your project: |
32 | 16 |
|
33 | 17 | ```Shell
|
34 |
| -# Run from your project's root directory |
35 |
| -npm init playwright@latest |
36 |
| -# Or create a new project |
37 |
| -npm init playwright@latest new-project |
| 18 | +npm i -s @cloudflare/playwright |
38 | 19 | ```
|
39 | 20 |
|
40 |
| -This will create a configuration file, optionally add examples, a GitHub Action workflow and a first test example.spec.ts. You can now jump directly to writing assertions section. |
41 |
| - |
42 |
| -### Manually |
| 21 | +## Configuration |
43 | 22 |
|
44 |
| -Add dependency and install browsers. |
| 23 | +📄 **Place this in `wrangler.toml`** |
45 | 24 |
|
46 |
| -```Shell |
47 |
| -npm i -D @playwright/test |
48 |
| -# install supported browsers |
49 |
| -npx playwright install |
| 25 | +```toml |
| 26 | +compatibility_flags = [ "nodejs_compat" ] |
| 27 | +browser = { binding = "MYBROWSER" } |
50 | 28 | ```
|
51 | 29 |
|
52 |
| -You can optionally install only selected browsers, see [install browsers](https://playwright.dev/docs/cli#install-browsers) for more details. Or you can install no browsers at all and use existing [browser channels](https://playwright.dev/docs/browsers). |
| 30 | +## Example |
53 | 31 |
|
54 |
| -* [Getting started](https://playwright.dev/docs/intro) |
55 |
| -* [API reference](https://playwright.dev/docs/api/class-playwright) |
| 32 | +You can find a full running example here [Cloudflare Playwright running example](https://github.com/cloudflare/playwright/tree/main/packages/playwright-cloudflare/examples/todomvc) |
56 | 33 |
|
57 |
| -## Capabilities |
| 34 | +### Screenshot |
58 | 35 |
|
59 |
| -### Resilient • No flaky tests |
| 36 | +```js |
| 37 | +import { launch } from '@cloudflare/playwright'; |
60 | 38 |
|
61 |
| -**Auto-wait**. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - a primary cause of flaky tests. |
| 39 | +const todos = searchParams.getAll('todo'); |
62 | 40 |
|
63 |
| -**Web-first assertions**. Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met. |
| 41 | +const browser = await launch(env.MYBROWSER); |
| 42 | +const page = await browser.newPage(); |
64 | 43 |
|
65 |
| -**Tracing**. Configure test retry strategy, capture execution trace, videos and screenshots to eliminate flakes. |
| 44 | +await page.goto('https://demo.playwright.dev/todomvc'); |
66 | 45 |
|
67 |
| -### No trade-offs • No limits |
| 46 | +const TODO_ITEMS = todos.length > 0 ? todos : [ |
| 47 | + 'buy some cheese', |
| 48 | + 'feed the cat', |
| 49 | + 'book a doctors appointment' |
| 50 | +]; |
68 | 51 |
|
69 |
| -Browsers run web content belonging to different origins in different processes. Playwright is aligned with the architecture of the modern browsers and runs tests out-of-process. This makes Playwright free of the typical in-process test runner limitations. |
| 52 | +const newTodo = page.getByPlaceholder('What needs to be done?'); |
| 53 | +for (const item of TODO_ITEMS) { |
| 54 | + await newTodo.fill(item); |
| 55 | + await newTodo.press('Enter'); |
| 56 | +} |
70 | 57 |
|
71 |
| -**Multiple everything**. Test scenarios that span multiple tabs, multiple origins and multiple users. Create scenarios with different contexts for different users and run them against your server, all in one test. |
| 58 | +const img = await page.screenshot(); |
| 59 | + await browser.close(); |
72 | 60 |
|
73 |
| -**Trusted events**. Hover elements, interact with dynamic controls and produce trusted events. Playwright uses real browser input pipeline indistinguishable from the real user. |
| 61 | + return new Response(img, { |
| 62 | + headers: { |
| 63 | + 'Content-Type': 'image/png', |
| 64 | + }, |
| 65 | + }); |
| 66 | +``` |
74 | 67 |
|
75 |
| -Test frames, pierce Shadow DOM. Playwright selectors pierce shadow DOM and allow entering frames seamlessly. |
| 68 | +### Trace |
76 | 69 |
|
77 |
| -### Full isolation • Fast execution |
| 70 | +```js |
| 71 | +import { launch } from '@cloudflare/playwright'; |
| 72 | +import fs from "@cloudflare/playwright/fs"; |
78 | 73 |
|
79 |
| -**Browser contexts**. Playwright creates a browser context for each test. Browser context is equivalent to a brand new browser profile. This delivers full test isolation with zero overhead. Creating a new browser context only takes a handful of milliseconds. |
| 74 | +const browser = await launch(env.MYBROWSER); |
| 75 | +const page = await browser.newPage(); |
80 | 76 |
|
81 |
| -**Log in once**. Save the authentication state of the context and reuse it in all the tests. This bypasses repetitive log-in operations in each test, yet delivers full isolation of independent tests. |
| 77 | +await page.context().tracing.start({ screenshots: true, snapshots: true }); |
82 | 78 |
|
83 |
| -### Powerful Tooling |
| 79 | +// ... do something, screenshot for example |
84 | 80 |
|
85 |
| -**[Codegen](https://playwright.dev/docs/codegen)**. Generate tests by recording your actions. Save them into any language. |
| 81 | +await page.context().tracing.stop({ path: 'trace.zip' }); |
| 82 | +await browser.close(); |
| 83 | +const file = await fs.promises.readFile('trace.zip'); |
86 | 84 |
|
87 |
| -**[Playwright inspector](https://playwright.dev/docs/inspector)**. Inspect page, generate selectors, step through the test execution, see click points and explore execution logs. |
| 85 | +return new Response(file, { |
| 86 | + status: 200, |
| 87 | + headers: { |
| 88 | + 'Content-Type': 'application/zip', |
| 89 | + }, |
| 90 | +}); |
| 91 | +``` |
88 | 92 |
|
89 |
| -**[Trace Viewer](https://playwright.dev/docs/trace-viewer)**. Capture all the information to investigate the test failure. Playwright trace contains test execution screencast, live DOM snapshots, action explorer, test source and many more. |
| 93 | +### Assertions |
90 | 94 |
|
91 |
| -Looking for Playwright for [TypeScript](https://playwright.dev/docs/intro), [JavaScript](https://playwright.dev/docs/intro), [Python](https://playwright.dev/python/docs/intro), [.NET](https://playwright.dev/dotnet/docs/intro), or [Java](https://playwright.dev/java/docs/intro)? |
| 95 | +```js |
| 96 | +import { launch } from '@cloudflare/playwright'; |
| 97 | +import { expect } from '@cloudflare/playwright/test'; |
92 | 98 |
|
93 |
| -## Examples |
| 99 | +const browser = await launch(env.MYBROWSER); |
| 100 | +const page = await browser.newPage(); |
94 | 101 |
|
95 |
| -To learn how to run these Playwright Test examples, check out our [getting started docs](https://playwright.dev/docs/intro). |
| 102 | +await page.goto('https://demo.playwright.dev/todomvc'); |
96 | 103 |
|
97 |
| -#### Page screenshot |
| 104 | +const TODO_ITEMS = todos.length > 0 ? todos : [ |
| 105 | + 'buy some cheese', |
| 106 | + 'feed the cat', |
| 107 | + 'book a doctors appointment' |
| 108 | +]; |
98 | 109 |
|
99 |
| -This code snippet navigates to Playwright homepage and saves a screenshot. |
| 110 | +const newTodo = page.getByPlaceholder('What needs to be done?'); |
| 111 | +for (const item of TODO_ITEMS) { |
| 112 | + await newTodo.fill(item); |
| 113 | + await newTodo.press('Enter'); |
| 114 | +} |
100 | 115 |
|
101 |
| -```TypeScript |
102 |
| -import { test } from '@playwright/test'; |
| 116 | +await expect(page.getByTestId('todo-title')).toHaveCount(TODO_ITEMS.length); |
103 | 117 |
|
104 |
| -test('Page Screenshot', async ({ page }) => { |
105 |
| - await page.goto('https://playwright.dev/'); |
106 |
| - await page.screenshot({ path: `example.png` }); |
107 |
| -}); |
| 118 | +await Promise.all(TODO_ITEMS.map( |
| 119 | + (value, index) => expect(page.getByTestId('todo-title').nth(index)).toHaveText(value) |
| 120 | +)); |
108 | 121 | ```
|
109 | 122 |
|
110 |
| -#### Mobile and geolocation |
| 123 | +# Contribute |
111 | 124 |
|
112 |
| -This snippet emulates Mobile Safari on a device at given geolocation, navigates to maps.google.com, performs the action and takes a screenshot. |
| 125 | +## Build |
113 | 126 |
|
114 |
| -```TypeScript |
115 |
| -import { test, devices } from '@playwright/test'; |
| 127 | +To build Playwright for Cloudflare: |
116 | 128 |
|
117 |
| -test.use({ |
118 |
| - ...devices['iPhone 13 Pro'], |
119 |
| - locale: 'en-US', |
120 |
| - geolocation: { longitude: 12.492507, latitude: 41.889938 }, |
121 |
| - permissions: ['geolocation'], |
122 |
| -}) |
123 |
| - |
124 |
| -test('Mobile and geolocation', async ({ page }) => { |
125 |
| - await page.goto('https://maps.google.com'); |
126 |
| - await page.getByText('Your location').click(); |
127 |
| - await page.waitForRequest(/.*preview\/pwa/); |
128 |
| - await page.screenshot({ path: 'colosseum-iphone.png' }); |
129 |
| -}); |
| 129 | +```sh |
| 130 | +npm ci |
| 131 | +cd packages/playwright-cloudflare |
| 132 | +npm run build |
130 | 133 | ```
|
131 | 134 |
|
132 |
| -#### Evaluate in browser context |
| 135 | +## Run |
133 | 136 |
|
134 |
| -This code snippet navigates to example.com, and executes a script in the page context. |
| 137 | +To run the TodoMVC example: |
135 | 138 |
|
136 |
| -```TypeScript |
137 |
| -import { test } from '@playwright/test'; |
| 139 | +- launch it with `wrangler`: |
138 | 140 |
|
139 |
| -test('Evaluate in browser context', async ({ page }) => { |
140 |
| - await page.goto('https://www.example.com/'); |
141 |
| - const dimensions = await page.evaluate(() => { |
142 |
| - return { |
143 |
| - width: document.documentElement.clientWidth, |
144 |
| - height: document.documentElement.clientHeight, |
145 |
| - deviceScaleFactor: window.devicePixelRatio |
146 |
| - } |
147 |
| - }); |
148 |
| - console.log(dimensions); |
149 |
| -}); |
| 141 | +```sh |
| 142 | +cd packages/playwright-cloudflare/examples/todomvc |
| 143 | +npm ci |
| 144 | +npx wrangler dev --remote |
150 | 145 | ```
|
151 | 146 |
|
152 |
| -#### Intercept network requests |
| 147 | +- press `b` to open the browser |
153 | 148 |
|
154 |
| -This code snippet sets up request routing for a page to log all network requests. |
| 149 | +## 🚧 Currently Unsupported Features |
155 | 150 |
|
156 |
| -```TypeScript |
157 |
| -import { test } from '@playwright/test'; |
| 151 | +The following capabilities are not yet fully supported, but we’re actively working on them. |
158 | 152 |
|
159 |
| -test('Intercept network requests', async ({ page }) => { |
160 |
| - // Log and continue all network requests |
161 |
| - await page.route('**', route => { |
162 |
| - console.log(route.request().url()); |
163 |
| - route.continue(); |
164 |
| - }); |
165 |
| - await page.goto('http://todomvc.com'); |
166 |
| -}); |
167 |
| -``` |
| 153 | +- [API Testing](https://playwright.dev/docs/api-testing) |
| 154 | +- [Playwright Test](https://playwright.dev/docs/test-configuration) except [Assertions](https://playwright.dev/docs/test-assertions) |
| 155 | +- [Components](https://playwright.dev/docs/test-components) |
| 156 | +- [Firefox](https://playwright.dev/docs/api/class-playwright#playwright-firefox), [Android](https://playwright.dev/docs/api/class-android) and [Electron](https://playwright.dev/docs/api/class-electron), as well as different versions of Chrome |
| 157 | +- [Network](https://playwright.dev/docs/next/network#network) |
| 158 | +- [Videos](https://playwright.dev/docs/next/videos) |
168 | 159 |
|
169 |
| -## Resources |
| 160 | +This is **not an exhaustive list** — expect rapid changes as we work toward broader parity with the original feature set. You can also check [latest test results](https://playwright-full-test-report.pages.dev/) for a granular up to date list of the features that are fully supported |
170 | 161 |
|
171 |
| -* [Documentation](https://playwright.dev) |
172 |
| -* [API reference](https://playwright.dev/docs/api/class-playwright/) |
173 |
| -* [Contribution guide](CONTRIBUTING.md) |
174 |
| -* [Changelog](https://github.com/microsoft/playwright/releases) |
0 commit comments