Skip to content
Merged
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
21 changes: 20 additions & 1 deletion tests/browser/typeahead.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
import { test, expect } from "./source-fixture.mjs";
import { test, expect } from "./playwright-test.mjs";
import { previewFixtures } from "./vite-server.mjs";
import { watchPageErrors } from "./page-errors.mjs";

let fixtures;
// A dev server serves these fixtures as about 1,600 modules, and a worker's
// first navigation outlasted the navigation timeout on a busy runner.
test.beforeAll(async () => {
fixtures = await previewFixtures([
"tests/fixtures/emoji.html",
"tests/fixtures/mentions.html",
"tests/fixtures/messages.html",
"tests/fixtures/typeahead.html",
]);
});
test.afterAll(() => fixtures?.close());
// Journeys open the pages by path. The bundle's port is known only after
// beforeAll, which runs before each test's fixtures. Playwright also resolves
// baseURL for beforeAll itself, before the bundle exists.
// biome-ignore lint/correctness/noEmptyPattern: Playwright requires a destructured fixture argument.
test.use({ baseURL: async ({}, use) => use(fixtures?.origin) });

const open = async (page) => {
await page.goto("/tests/fixtures/mentions.html?test-controls");
return page.getByRole("textbox", { name: "Message #General" });
Expand Down
43 changes: 43 additions & 0 deletions tests/browser/vite-server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,49 @@ export const preview = (config) =>
}),
);

// A dev server transforms a page's modules on first request, so a worker's
// first navigation to a large fixture can outlast the navigation timeout on a
// busy runner. This builds the repository-relative pages once and serves the
// bundle. Development React, as a dev server serves, keeps StrictMode's checks.
// close() stops the server and removes the build.
export async function previewFixtures(pages) {
const directory = await mkdtemp(join(tmpdir(), "buzz-fixture-preview-"));
try {
const config = {
root,
configFile: false,
envDir: false,
logLevel: "error",
plugins: [react()],
define: {
"import.meta.env.DEV": "true",
"process.env.NODE_ENV": '"development"',
},
build: {
rollupOptions: { input: pages.map((page) => join(root, page)) },
outDir: join(directory, "dist"),
emptyOutDir: true,
target: "esnext",
},
};
await build(config);
const server = await preview({
...config,
preview: { host: "127.0.0.1", port: 0, strictPort: true },
});
return {
origin: `http://127.0.0.1:${server.httpServer.address().port}`,
async close() {
await new Promise((resolve) => server.httpServer.close(resolve));
await rm(directory, { recursive: true, force: true });
},
};
} catch (error) {
await rm(directory, { recursive: true, force: true });
throw error;
}
}

// Run once per test run, before any test: it scans and bundles the fixture
// dependencies so no server does that work inside a navigation budget.
export async function prepareFixtureDependencies() {
Expand Down
50 changes: 7 additions & 43 deletions tests/browser/voice-notes.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,49 +1,13 @@
import { watchPageErrors } from "./page-errors.mjs";
import { test, expect } from "./playwright-test.mjs";
import { build, preview } from "./vite-server.mjs";
import react from "@vitejs/plugin-react";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
let server, directory, url;
// A dev server serves this fixture as about 800 modules. On a busy runner,
// WebKit's first navigation took longer than the navigation timeout to load
// them, so build the page once and serve the bundle.
import { previewFixtures } from "./vite-server.mjs";
let fixtures;
// A dev server serves this fixture as about 800 modules, and WebKit's first
// navigation outlasted the navigation timeout on a busy runner.
test.beforeAll(async () => {
const root = fileURLToPath(new URL("../../", import.meta.url));
directory = await mkdtemp(join(tmpdir(), "buzz-voice-notes-"));
const config = {
root,
configFile: false,
envDir: false,
logLevel: "error",
plugins: [react()],
// Development React, as the dev server served, keeps StrictMode's checks.
define: {
"import.meta.env.DEV": "true",
"process.env.NODE_ENV": '"development"',
},
build: {
rollupOptions: {
input: join(root, "tests/fixtures/voice-notes.html"),
},
outDir: join(directory, "dist"),
emptyOutDir: true,
target: "esnext",
},
};
await build(config);
server = await preview({
...config,
preview: { host: "127.0.0.1", port: 0, strictPort: true },
});
url = `http://127.0.0.1:${server.httpServer.address().port}/tests/fixtures/voice-notes.html`;
});
test.afterAll(async () => {
if (server) await new Promise((resolve) => server.httpServer.close(resolve));
if (directory) await rm(directory, { recursive: true, force: true });
fixtures = await previewFixtures(["tests/fixtures/voice-notes.html"]);
});
test.afterAll(() => fixtures?.close());
test.beforeEach(async ({ page }) => {
await page.route("**/api/relay/media?*", async (route) => {
const url = new URL(route.request().url()).searchParams.get("url");
Expand All @@ -59,7 +23,7 @@ test.beforeEach(async ({ page }) => {
body: Buffer.from(bytes),
});
});
await page.goto(url);
await page.goto(`${fixtures.origin}/tests/fixtures/voice-notes.html`);
await page.evaluate(() => {
const mic = {
mode: "allow",
Expand Down
Loading