Frontend Labs
⋯

tests/fixtures.js

// Shared fixtures (§76): page objects and helpers every spec can ask for by
// name. Playwright builds them lazily, only for the tests that use them.
import { test as base, expect } from "@playwright/test";

export const USERS = {
  alice: { email: "alice@example.com", password: "correct-horse-1" },
  bob: { email: "bob@example.com", password: "battery-staple-2" },
};

// A page object: the one place that knows how the chat UI is built.
// Tests talk in user intent ("ask", "lastReply"), not CSS selectors.
export class ChatPage {
  constructor(page) {
    this.page = page;
    this.input = page.getByRole("textbox", { name: "Message" });
    this.send = page.getByRole("button", { name: "Send" });
    this.stop = page.getByRole("button", { name: "Stop" });
    this.log = page.getByRole("log", { name: "Conversation" });
    this.orders = page.getByRole("list", { name: "Your orders" });
  }
  async goto() {
    await this.page.goto("/");
    await expect(this.input).toBeVisible();
  }
  async ask(text) {
    await this.input.fill(text);
    await this.send.click();
  }
  lastReply() {
    return this.log.locator('[data-role="assistant"]').last();
  }
  async waitForReply() {
    // aria-busy flips back to false when the stream ends.
    await expect(this.log).toHaveAttribute("aria-busy", "false");
  }
}

export async function login(page, { email, password }) {
  await page.goto("/");
  await page.getByLabel("Email").fill(email);
  await page.getByLabel("Password").fill(password);
  await page.getByRole("button", { name: "Sign in" }).click();
}

// Build an SSE body by hand, for tests that mock the agent (§77).
export const sse = (...events) => events.map((e) => `data: ${JSON.stringify(e)}\n\n`).join("");

export const test = base.extend({
  chat: async ({ page }, use) => {
    const chat = new ChatPage(page);
    await chat.goto();
    await use(chat);
  },
  // seedOrder({ item, total }) -> a fresh order owned by the signed-in user.
  seedOrder: async ({ page }, use) => {
    await use(async (order = {}) => {
      const res = await page.request.post("/__test__/orders", { data: order });
      expect(res.status()).toBe(201);
      return res.json();
    });
  },
});

export { expect };

Generated from SOURCE.md · 8 Oct 2026 16:36