INTEGRITY Dokumentace

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/playwright

Použ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.

Deploy to Cloudflare

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/playwright

Podí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 KV

Poté 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:

src/index.ts
// 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 dev

Nebo pomocí Cloudflare Vite plugin:

X_BROWSER_HEADFUL=true npx vite dev

Tí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
}

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:

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í.