# Phoenix Playwright Test Examples Complete examples from the Phoenix test suite. ## Example 1: Basic CRUD Test (Prompt Management) ```typescript import { expect, test } from "@playwright/test"; import { randomUUID } from "crypto"; test.describe("Prompt Management", () => { test.beforeEach(async ({ page }) => { page.goto(`/login`); await page.getByLabel("Email").fill("admin@localhost"); await page.getByLabel("Password").fill("admin123"); await page.getByRole("button", { name: "Log In", exact: true }).click(); await page.waitForURL("**/projects"); }); test("can create a prompt", async ({ page }) => { await page.goto("/prompts"); await page.waitForURL("**/prompts"); await page.getByRole("link", { name: "New Prompt" }).click(); await page.waitForURL("**/playground"); await page .getByText("You are a chatbot") .fill("You are a helpful assistant"); await page.getByRole("button", { name: "Save Prompt" }).click(); await page.getByPlaceholder("Select or enter new prompt").click(); const promptName = `chatbot-${randomUUID()}`; await page.getByPlaceholder("Select or enter new prompt").fill(promptName); await page.getByLabel("Prompt Description").click(); await page.getByLabel("Prompt Description").fill("very kind chatbot"); await page.getByRole("button", { name: "Create Prompt" }).click(); await page.getByRole("button", { name: "View Prompt" }).click(); await expect(page.getByRole("heading", { name: promptName })).toBeVisible(); await expect( page.getByText("You are a helpful assistant").first() ).toBeVisible(); }); }); ``` ## Example 2: User Management (Admin Actions) ```typescript import { expect, test } from "@playwright/test"; import { randomUUID } from "crypto"; test.beforeEach(async ({ page }) => { page.goto(`/login`); await page.getByLabel("Email").fill("admin@localhost"); await page.getByLabel("Password").fill("admin123"); await page.getByRole("button", { name: "Log In", exact: true }).click(); await page.waitForURL("**/projects"); }); test("can create a user", async ({ page }) => { await page.goto("/settings/general"); await page.waitForURL("**/settings/general"); await page.getByRole("button", { name: "Add User" }).click(); const email = `member-${randomUUID()}@localhost.com`; await page.getByLabel("Email").fill(email); await page.getByLabel("Username").fill(email); await page.getByLabel("Password", { exact: true }).fill("member123"); await page.getByLabel("Confirm Password").fill("member123"); await page.getByRole("dialog").getByLabel("member", { exact: true }).click(); await page .getByRole("dialog") .getByRole("option", { name: "member" }) .click(); await page .getByRole("dialog") .getByRole("button", { name: "Add User" }) .click(); await expect(page.getByRole("cell", { name: email })).toBeVisible(); }); ``` ## Example 3: Serial Tests with Shared State (Evaluators) ```typescript import { expect, test } from "@playwright/test"; import { randomUUID } from "crypto"; test.describe.serial("Server Evaluators", () => { const datasetName = `test-dataset-${randomUUID()}`; const customEvaluatorName = `custom-eval-${randomUUID().slice(0, 8)}`; const updatedDescription = "Updated description for testing"; test.beforeEach(async ({ page }) => { await page.goto(`/login`); await page.getByLabel("Email").fill("admin@localhost"); await page.getByLabel("Password").fill("admin123"); await page.getByRole("button", { name: "Log In", exact: true }).click(); await page.waitForURL("**/projects"); }); test("can create a dataset", async ({ page }) => { await page.goto("/datasets"); await page.waitForURL("**/datasets"); await page.getByRole("button", { name: "New Dataset" }).click(); await page.getByRole("menuitem", { name: "New Dataset" }).click(); await page.getByLabel("Dataset Name").clear(); await page.getByLabel("Dataset Name").fill(datasetName); await page.getByLabel("Description").fill("Test dataset for evaluators"); await page.getByRole("button", { name: "Create Dataset" }).click(); await expect(page.getByRole("dialog")).not.toBeVisible({ timeout: 10000 }); await expect(page.getByRole("link", { name: datasetName })).toBeVisible({ timeout: 10000, }); }); test("can create a custom LLM evaluator", async ({ page }) => { await page.goto("/datasets"); await page.getByRole("link", { name: datasetName }).click(); await page.waitForURL("**/datasets/**/examples"); await page.getByRole("tab", { name: /Evaluators/i }).click(); await page.waitForURL("**/evaluators"); await page.getByRole("button", { name: "Add evaluator" }).click(); await page .getByRole("menuitem", { name: "Create new LLM evaluator" }) .click(); await expect( page.getByRole("heading", { name: "Create Evaluator" }) ).toBeVisible(); await page .getByRole("textbox", { name: "Name" }) .first() .fill(customEvaluatorName); await page .getByRole("textbox", { name: /Description/i }) .fill("Initial description for custom evaluator"); const systemSection = page.locator( 'button:has-text("System"):not([role="menuitem"])' ); const systemTextbox = systemSection .locator("..") .locator("..") .getByRole("textbox"); await systemTextbox.fill("You are an evaluator."); const userSection = page.locator( 'button:has-text("User"):not([role="menuitem"])' ); const userTextbox = userSection .locator("..") .locator("..") .getByRole("textbox"); await userTextbox.fill("Evaluate: {{output}}"); await page.getByRole("button", { name: "Create" }).click(); await expect(page.getByRole("dialog")).not.toBeVisible({ timeout: 10000 }); await expect( page.getByRole("cell", { name: customEvaluatorName }) ).toBeVisible(); }); test("can edit an LLM evaluator", async ({ page }) => { await page.goto("/datasets"); await page.getByRole("link", { name: datasetName }).click(); await page.waitForURL("**/datasets/**/examples"); await page.getByRole("tab", { name: /Evaluators/i }).click(); await page.waitForURL("**/evaluators"); const evaluatorRow = page.getByRole("row").filter({ has: page.getByRole("cell", { name: customEvaluatorName }), }); await evaluatorRow.getByRole("button").last().click(); await page.getByRole("menuitem", { name: "Edit" }).click(); await expect( page.getByRole("heading", { name: "Edit Evaluator" }) ).toBeVisible(); const descriptionInput = page.getByRole("textbox", { name: /Description/i, }); await descriptionInput.clear(); await descriptionInput.fill(updatedDescription); await page.getByRole("button", { name: "Update" }).click(); await expect(page.getByRole("dialog")).not.toBeVisible({ timeout: 10000 }); await expect( page.getByRole("cell", { name: customEvaluatorName }) ).toBeVisible(); }); test("can verify edits were saved", async ({ page }) => { await page.goto("/datasets"); await page.getByRole("link", { name: datasetName }).click(); await page.waitForURL("**/datasets/**/examples"); await page.getByRole("tab", { name: /Evaluators/i }).click(); await page.waitForURL("**/evaluators"); const evaluatorRow = page.getByRole("row").filter({ has: page.getByRole("cell", { name: customEvaluatorName }), }); await evaluatorRow.getByRole("button").last().click(); await page.getByRole("menuitem", { name: "Edit" }).click(); const descriptionInput = page.getByRole("textbox", { name: /Description/i, }); await expect(descriptionInput).toHaveValue(updatedDescription); await page.getByRole("button", { name: "Cancel" }).click(); }); }); ``` ## Example 4: Role-Based Access Control ```typescript import { expect, test } from "@playwright/test"; test.describe("Viewer Access", () => { test.beforeEach(async ({ page }) => { page.goto(`/login`); await page.getByLabel("Email").fill("viewer@localhost.com"); await page.getByLabel("Password").fill("viewer123"); await page.getByRole("button", { name: "Log In", exact: true }).click(); await page.waitForURL("**/projects"); }); test("viewer cannot access settings", async ({ page }) => { await page.goto("/settings/general"); // Viewer should be redirected or see access denied await expect(page.getByText("Access Denied")).toBeVisible(); }); }); ``` ## Example 5: Testing with Playground Integration ```typescript test("evaluators are visible in playground when dataset is selected", async ({ page, }) => { await page.goto("/datasets"); await page.getByRole("link", { name: datasetName }).click(); await page.waitForURL("**/datasets/**/examples"); const datasetUrl = page.url(); const datasetIdMatch = datasetUrl.match(/datasets\/([^/]+)/); const datasetIdForUrl = datasetIdMatch ? datasetIdMatch[1] : ""; await page.goto(`/playground?datasetId=${datasetIdForUrl}`); await page.waitForURL("**/playground**"); await expect( page.getByRole("button", { name: new RegExp(datasetName) }) ).toBeVisible(); await expect(page.getByRole("heading", { name: "Experiment" })).toBeVisible(); const experimentSection = page.locator("text=Experiment").locator(".."); await expect( experimentSection.getByRole("button", { name: "Evaluators" }) ).toBeVisible(); }); ```