← Browser Run / browser-run
Playwright
Playwright ↗ je open-source balíček vyvinutý společností Microsoft, který umí automatizovat úlohy v prohlížeči. Běžně se používá k psaní frontendových testů, vytváření snímků obrazovky nebo procházení stránek.
Tým Workers vytvořil fork verze Playwright ↗ který byl upraven tak, aby byl kompatibilní s Cloudflare Workers a Browser Run.
Naše verze je open source a najdete ji v Fork frameworku Playwright od Cloudflare ↗. Balíček npm lze nainstalovat z npmjs ↗ jako @cloudflare/playwright ↗:
npm i -D @cloudflare/playwrightPoužití Playwright ve Worker
V tomto příklad ↗, spustíte testy Playwright v Cloudflare Workeru pomocí todomvc ↗ aplikace.
Pokud chcete kroky přeskočit a rychle začít, vyberte Deploy to Cloudflare níže.
Ověřte, že máte vazba pro prohlížeč nakonfigurovaný v konfiguračním souboru Wrangler:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "cloudflare-playwright-example",
"main": "src/index.ts",
"workers_dev": true,
"compatibility_flags": ["nodejs_compat"],
// Set this to today's date
"compatibility_date": "2026-08-28",
"upload_source_maps": true,
"browser": {
"binding": "MYBROWSER",
},
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "cloudflare-playwright-example"
main = "src/index.ts"
workers_dev = true
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-28"
upload_source_maps = true
[browser]
binding = "MYBROWSER"Nainstalujte npm balíček:
npm i -D @cloudflare/playwrightPodívejme se na několik příkladů použití Playwright:
Pořízení snímku obrazovky
Pořizování snímků webových stránek pomocí automatizace prohlížeče je běžný případ použití. Tento skript prohlížeči přikáže přejít na https://demo.playwright.dev/todomvc ↗, vytvořte několik položek, pořiďte snímek obrazovky stránky a vraťte obrázek v odpovědi.
import { launch } from "@cloudflare/playwright";
export default {
async fetch(request: Request, env: Env) {
const browser = await launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://demo.playwright.dev/todomvc");
const TODO_ITEMS = [
"buy some cheese",
"feed the cat",
"book a doctors appointment",
];
const newTodo = page.getByPlaceholder("What needs to be done?");
for (const item of TODO_ITEMS) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
const img = await page.screenshot();
await browser.close();
return new Response(img, {
headers: {
"Content-Type": "image/png",
},
});
},
};Trasování
Trasování Playwright je podrobný záznam průběhu vašeho workflow, který zachycuje informace, jako jsou kliknutí uživatele a navigační akce, snímky obrazovky stránky a veškeré generované zprávy konzole využívané při ladění. Vývojáři mohou pořídit trace.zip soubor a buď jej otevřete lokálně ↗ nebo jej nahrajte do Playwright Trace Viewer ↗, grafický nástroj, který vám pomůže data prozkoumat.
Zde je příklad workeru, který generuje trasovací soubor:
import fs from "fs";
import { launch } from "@cloudflare/playwright";
export default {
async fetch(request: Request, env: Env) {
const browser = await launch(env.MYBROWSER);
const page = await browser.newPage();
// Start tracing before navigating to the page
await page.context().tracing.start({ screenshots: true, snapshots: true });
await page.goto("https://demo.playwright.dev/todomvc");
const TODO_ITEMS = [
"buy some cheese",
"feed the cat",
"book a doctors appointment",
];
const newTodo = page.getByPlaceholder("What needs to be done?");
for (const item of TODO_ITEMS) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
// Stop tracing and save the trace to a zip file
await page.context().tracing.stop({ path: "trace.zip" });
await browser.close();
const file = await fs.promises.readFile("trace.zip");
return new Response(file, {
status: 200,
headers: {
"Content-Type": "application/zip",
},
});
},
};Ověření
Jedním z nejčastějších případů použití Playwright je testování softwaru. Playwright obsahuje ve svém API funkce pro testovací assertions; viz Ověření ↗ v dokumentaci Playwright. Zde je příklad workeru, který provádí expect() testovacích tvrzení nástroje todomvc ↗ demo stránka:
import { launch } from "@cloudflare/playwright";
import { expect } from "@cloudflare/playwright/test";
export default {
async fetch(request: Request, env: Env) {
const browser = await launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto("https://demo.playwright.dev/todomvc");
const TODO_ITEMS = [
"buy some cheese",
"feed the cat",
"book a doctors appointment",
];
const newTodo = page.getByPlaceholder("What needs to be done?");
for (const item of TODO_ITEMS) {
await newTodo.fill(item);
await newTodo.press("Enter");
}
await expect(page.getByTestId("todo-title")).toHaveCount(TODO_ITEMS.length);
await Promise.all(
TODO_ITEMS.map((value, index) =>
expect(page.getByTestId("todo-title").nth(index)).toHaveText(value),
),
);
},
};Stav úložiště
Playwright podporuje stav úložiště ↗ k získání a trvalému uložení cookies a dalších úložných dat. V tomto příkladu použijete storage state k trvalému uložení cookies a dalších úložných dat v Workers KV.
Nejprve se ujistěte, že máte obor názvů KV. Nový můžete vytvořit pomocí:
npx wrangler kv namespace create KVPoté přidejte KV namespace do svého konfiguračního souboru Wrangler:
{
"name": "storage-state-examples",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"],
// Set this to today's date
"compatibility_date": "2026-08-28",
"browser": {
"binding": "MYBROWSER",
},
"kv_namespaces": [
{
"binding": "KV",
"id": "<YOUR-KV-NAMESPACE-ID>",
},
],
}name = "storage-state-examples"
main = "src/index.ts"
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-28"
[browser]
binding = "MYBROWSER"
[[kv_namespaces]]
binding = "KV"
id = "<YOUR-KV-NAMESPACE-ID>"Nyní můžete pomocí storage state trvale uložit cookies a další úložná data do KV:
// gets persisted storage state from KV or undefined if it does not exist
const storageStateJson = await env.KV.get("storageState");
const storageState = storageStateJson
? ((await JSON.parse(
storageStateJson,
)) as BrowserContextOptions["storageState"])
: undefined;
await using browser = await launch(env.MYBROWSER);
// creates a new context with storage state persisted in KV
await using context = await browser.newContext({ storageState });
await using page = await context.newPage();
// do some actions on the page that may update client-side storage
// gets updated storage state: cookies, localStorage, and IndexedDB
const updatedStorageState = await context.storageState({ indexedDB: true });
// persists updated storage state in KV
await env.KV.put("storageState", JSON.stringify(updatedStorageState));Keep Alive
Pokud uživatelé vynechají browser.close() příkaz, instance prohlížeče zůstane otevřená, připravená k opětovnému připojení a znovu použité ve výchozím nastavení se však po 1 minutě nečinnosti automaticky uzavře. Uživatelé mohou tuto dobu nečinnosti volitelně prodloužit až na 10 minut pomocí keep_alive nastavenou v milisekundách:
const browser = await playwright.launch(env.MYBROWSER, { keep_alive: 600000 });Při použití výše uvedeného zůstane prohlížeč otevřený až 10 minut, i když je nečinný.
Opakované využití relace
Nejlepší způsob, jak zlepšit výkon vašeho Workeru pro Browser Run, je znovu využívat relace: prohlížeč po dokončení práce ponechte otevřený a při každém novém požadavku se připojte ke stejné relaci. Playwright řeší browser.close ↗ jinak než Puppeteer. V Playwrightu, pokud byl prohlížeč získán pomocí connect relace, relace se odpojí. Pokud byl prohlížeč získán pomocí launch relace, relace se uzavře.
import { env } from "cloudflare:workers";
import { acquire, connect } from "@cloudflare/playwright";
async function reuseSameSession() {
// acquires a new session
const { sessionId } = await acquire(env.BROWSER);
for (let i = 0; i < 5; i++) {
// connects to the session that was previously acquired
const browser = await connect(env.BROWSER, sessionId);
// ...
// this will disconnect the browser from the session, but the session will be kept alive
await browser.close();
}
}Nastavení vlastního user-agenta
Chcete-li v Playwright zadat vlastní user agent, nastavte ho v možnostech při vytváření nového kontextu prohlížeče pomocí browser.newContext(). Všechny stránky následně vytvořené z tohoto kontextu budou používat nový user agent. To je užitečné, pokud cílový web poskytuje odlišný obsah podle user agenta.
const context = await browser.newContext({
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
});Místní ladění v režimu headful (experimentální)
Při lokálním vývoji s wrangler dev nebo vite dev, Chrome ve výchozím nastavení běží v režimu headless. Chcete-li spustit Chrome ve viditelném režimu (headful), nastavte X_BROWSER_HEADFUL proměnnou prostředí:
X_BROWSER_HEADFUL=true npx wrangler devNebo pomocí Cloudflare Vite plugin:
X_BROWSER_HEADFUL=true npx vite devTím se otevře okno prohlížeče, takže můžete v reálném čase sledovat svou automatizaci v Playwright, což usnadňuje ladění navigace, výběru prvků a interakcí se stránkou.
Správa relací
Abychom usnadnili správu relací prohlížeče, rozšířili jsme Playwright API o nové metody:
Vypište otevřené relace
playwright.sessions() zobrazí aktuálně spuštěné relace. Vrátí výstup podobný tomuto:
[
{
"connectionId": "2a2246fa-e234-4dc1-8433-87e6cee80145",
"connectionStartTime": 1711621704607,
"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
"startTime": 1711621703708
},
{
"sessionId": "565e05fb-4d2a-402b-869b-5b65b1381db7",
"startTime": 1711621703808
}
]Všimněte si, že relace 478f4d7d-e943-40f6-a414-837d3736a1dc má aktivní připojení workeru (connectionId=2a2246fa-e234-4dc1-8433-87e6cee80145), zatímco relace 565e05fb-4d2a-402b-869b-5b65b1381db7 je zdarma. Dokud je připojení aktivní, nemůže se k dané relaci připojit žádný jiný worker.
Vypište nedávné relace
playwright.history() zobrazí seznam nedávných relací, otevřených i uzavřených. Je to užitečné pro získání přehledu o vašem aktuálním využití.
[
{
"closeReason": 2,
"closeReasonText": "BrowserIdle",
"endTime": 1711621769485,
"sessionId": "478f4d7d-e943-40f6-a414-837d3736a1dc",
"startTime": 1711621703708
},
{
"closeReason": 1,
"closeReasonText": "NormalClosure",
"endTime": 1711123501771,
"sessionId": "2be00a21-9fb6-4bb2-9861-8cd48e40e771",
"startTime": 1711123430918
}
]Relace 2be00a21-9fb6-4bb2-9861-8cd48e40e771 byla výslovně uzavřena pomocí browser.close() klientem, zatímco relace 478f4d7d-e943-40f6-a414-837d3736a1dc byla uzavřena kvůli dosažení maximální doby nečinnosti (ověřte limity).
Tyto informace byste měli vidět i v dashboardu, i když s mírným zpožděním.
Aktivní limity
playwright.limits() zobrazí vaše aktivní limity:
{
"activeSessions": [
{ "id": "478f4d7d-e943-40f6-a414-837d3736a1dc" },
{ "id": "565e05fb-4d2a-402b-869b-5b65b1381db7" }
],
"allowedBrowserAcquisitions": 1,
"maxConcurrentSessions": 2,
"timeUntilNextAllowedBrowserAcquisition": 0
}activeSessionszobrazí ID aktuálně otevřených relací.maxConcurrentSessionsurčuje, kolik prohlížečů může být otevřeno současně.allowedBrowserAcquisitionsurčuje, zda lze otevřít novou relaci prohlížeče podle limitu četnosti limity na místě.timeUntilNextAllowedBrowserAcquisitionurčuje čekací dobu, než lze spustit nový prohlížeč.
Playwright API
Úplné API Playwright najdete na Dokumentace Playwright API ↗.
Následující funkce zatím nejsou plně podporovány, ale aktivně na nich pracujeme:
- Playwright Test ↗ kromě Ověření ↗
- Komponenty ↗
- Firefox ↗, Android ↗ a Electron ↗, i různé verze Chrome
- Videa ↗
Toto je nejde o vyčerpávající seznam : očekávejte rychlé změny, protože pracujeme na širší paritě s původní sadou funkcí. Můžete se také podívat na nejnovější výsledky testů ↗ podrobný a aktuální seznam plně podporovaných funkcí.