Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions fixtures/vitest-pool-workers-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
"scripts": {
"check:type": "node tsc-all.mjs",
"list": "vitest --config vitest.workers.config.ts list",
"puppeteer:initialize": "pnpx puppeteer browsers install chrome",
"pretest": "npm run puppeteer:initialize",
"test": "vitest --config vitest.workers.config.ts --reporter basic",
"pretest:ci": "npm run puppeteer:initialize",
"test:ci": "run-script-os",
"test:ci:default": "vitest run --config vitest.workers.config.ts --reporter basic",
"test:ci:win32": "vitest run --config vitest.workers.config.ts --reporter basic --exclude test/sqlite-in-do.test.ts"
},
"devDependencies": {
"@cloudflare/puppeteer": "^0.0.14",
"@cloudflare/vitest-pool-workers": "workspace:*",
"@cloudflare/workers-types": "^4.20241004.0",
"@types/node": "20.8.3",
"ext-dep": "file:./internal-module-resolution/vendor/ext-dep",
"jose": "^5.2.2",
"miniflare": "workspace:*",
"puppeteer": "^23.5.3",
"run-script-os": "^1.1.6",
"toucan-js": "^3.3.1",
"typescript": "^5.5.2",
Expand Down
8 changes: 8 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# ✅ Puppeteer

This Worker contains tests which are run with [Puppeteer](https://pptr.dev/). This is a useful tool for testing applications which use [static assets](https://developers.cloudflare.com/workers/static-assets/), (in particular, [full-stack frameworks](https://developers.cloudflare.com/workers/frameworks/)).

| Test | Overview |
| --------------------------------------------- | ----------------------------------------------------------------- |
| [puppeteer.test.ts](./test/globalSetup.ts) | A setup and teardown file for initializing the Puppeteer browser. |
| [puppeteer.test.ts](./test/puppeteer.test.ts) | A test using Puppeteer and `SELF` dispatches. |
11 changes: 11 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/public/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Blog | Hello World</title>
</head>
<body>
<h1>Blog | Hello World</h1>
<p>This is a blog post.</p>
</body>
</html>
26 changes: 26 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export function greet(request: Request): string {
return `👋 ${request.url}`;
}

export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);

if (url.pathname === "/api/date") {
return new Response(new Date().toISOString());
}

if (url.pathname === "/binding") {
const response = await env.ASSETS.fetch(request);
return new HTMLRewriter()
.on("h1", {
element(element) {
element.setInnerContent("Intercept!");
},
})
.transform(response);
}

return env.ASSETS.fetch(request);
},
} satisfies ExportedHandler<{ ASSETS: Fetcher }>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.workerd.json",
"include": ["./**/*.ts"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import puppeteer, { Browser } from "puppeteer";
import type { GlobalSetupContext } from "vitest/node";

let browser: Browser;

export default async function setup({ provide }: GlobalSetupContext) {
browser = await puppeteer.launch({
args: [`--no-sandbox`, `--disable-setuid-sandbox`], // DISABLING THESE SANDBOXES IS PROBABLY NOT REQUIRED IN YOUR PROJECT
});
provide("browserWSEndpoint", browser.wsEndpoint());
}

export async function teardown() {
await browser.close();
}

declare module "vitest" {
export interface ProvidedContext {
browserWSEndpoint: string;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import puppeteer from "@cloudflare/puppeteer";
import { SELF } from "cloudflare:test";
import { beforeAll, describe, expect, inject, it } from "vitest";
import type { Browser, HTTPRequest } from "@cloudflare/puppeteer";

const interceptRequest = async (request: HTTPRequest) => {
const miniflareRequest = new Request(request.url(), {
method: request.method(),
body: request.postData(),
});
const response = await SELF.fetch(miniflareRequest);
const arrayBuffer = await response.arrayBuffer();

await request.respond({
body: Buffer.from(arrayBuffer),
headers: Object.fromEntries(response.headers.entries()),
status: response.status,
});
};

describe("Puppeteer", () => {
let browser: Browser;

beforeAll(async () => {
browser = await puppeteer.connect({
browserWSEndpoint: inject("browserWSEndpoint"),
});
});

it("can fetch static assets", async () => {
const page = await browser.newPage();

page.setRequestInterception(true);
page.on("request", interceptRequest);

await page.goto("http://fakehost/blog/hello-world");

const contentSelector = await page.locator("text/blog post").waitHandle();
const content = await contentSelector?.evaluate((el) => el.textContent);
expect(content).toMatchInlineSnapshot(`"This is a blog post."`);
});

it("can fetch a Worker", async () => {
const page = await browser.newPage();

page.setRequestInterception(true);
page.on("request", interceptRequest);

await page.goto("http://fakehost/api/date");

expect(await page.content()).toMatch(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/
);

// Alternatively...

const response = await SELF.fetch("http://fakehost/api/date");

expect(await response.text()).toMatch(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/
);
});

it("can fetch a Worker which binds to assets", async () => {
const page = await browser.newPage();

page.setRequestInterception(true);
page.on("request", interceptRequest);

await page.goto("http://fakehost/intercept");

const contentSelector = await page.locator("text/blog post").waitHandle();
const content = await contentSelector?.evaluate((el) => el.textContent);
expect(content).toMatchInlineSnapshot(`"This is a blog post."`);

const titleSelector = await page.locator("text/Intercept").waitHandle();
const title = await titleSelector?.evaluate((el) => el.textContent);
expect(title).toMatchInlineSnapshot(`"Intercept!"`);
});

it("can fetch and 404 correctly", async () => {
const page = await browser.newPage();

page.setRequestInterception(true);
page.on("request", interceptRequest);

await page.goto("http://fakehost/non-existent");

const titleSelector = await page.locator("text/404").waitHandle();
const title = await titleSelector?.evaluate((el) => el.textContent);
expect(title).toMatchInlineSnapshot(`"404 Not Found"`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.workerd-test.json",
"include": ["./**/*.ts"]
}
4 changes: 4 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../tsconfig.node.json",
"include": ["./*.ts"]
}
14 changes: 14 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineWorkersProject } from "@cloudflare/vitest-pool-workers/config";

export default defineWorkersProject({
test: {
globalSetup: ["./test/globalSetup.ts"],
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler.toml",
},
},
},
},
});
9 changes: 9 additions & 0 deletions fixtures/vitest-pool-workers-examples/puppeteer/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "puppeteer"
main = "./src/index.ts"
compatibility_date = "2024-10-14"
compatibility_flags = ["nodejs_compat"]

[assets]
directory = "./public/"
binding = "ASSETS"
not_found_handling = "404-page"
Loading
Loading