/** * E2E: the deployment owner's onboarding asks before scanning the fixture home folder the * harness configures, then adds only the projects and facts the user picks. */ import type { Page } from "@playwright/test"; import { expect, test } from "@playwright/test"; import type { SpaceNavigation, UserProfileState } from "@rakazo/contracts"; import { captureScreenshot, rpc, signup } from "./helpers"; const api = process.env.API_URL ?? "http://127.0.0.1:3110"; /** Advances whichever wizard step is showing until the scan step is reached. */ async function walkToScanStep(page: Page) { const surface = page.locator('[data-rakazo-surface="onboarding"]'); await expect(async () => { if ((await surface.getAttribute("data-onboarding-step")) === "scan") return; const skip = page.getByRole("button", { name: /^Skip/ }).first(); const next = (await skip.isVisible()) ? skip : page.getByRole("button", { name: "Continue", exact: true }); await next.click({ timeout: 2_000 }); await expect(surface).toHaveAttribute("data-onboarding-step", "scan", { timeout: 1_000 }); }).toPass({ timeout: 60_000 }); } test("asks before looking for projects and adds only what the user picks", async ({ page, }, testInfo) => { const email = `discovery-${Date.now()}@rakazo.test`; await signup(page, email, "password12", "Discovery"); await page.waitForURL(/\/onboarding/, { timeout: 20_000 }); // The harness starts without a deployment owner; this spec takes the seat for its run. const owner = await page.request.post(`${api}/__e2e/deployment-owner`, { data: { email } }); expect(owner.ok()).toBe(true); const { previousOwnerUserId } = (await owner.json()) as { previousOwnerUserId: string | null }; try { await page.goto("/onboarding", { waitUntil: "domcontentloaded" }); await walkToScanStep(page); await expect(page.getByRole("heading", { name: "Look for projects here?" })).toBeVisible(); await expect(page.getByText(/rakazo-e2e-scan-home-/)).toBeVisible(); await captureScreenshot(page, testInfo, "onboarding-discovery-consent"); await page.getByRole("button", { name: "Look", exact: true }).click(); const projects = page.getByRole("group", { name: "Add as projects" }); await expect(projects.getByRole("checkbox")).toHaveCount(2); const atlas = projects.getByRole("checkbox", { name: /atlas/ }); await expect(atlas).not.toBeChecked(); await expect(projects.getByRole("checkbox", { name: /garden/ })).not.toBeChecked(); await atlas.check(); const facts = page.getByRole("group", { name: "Add to About you" }); await expect(facts.getByRole("checkbox", { name: "TypeScript" })).toBeChecked(); await facts.getByRole("checkbox", { name: "Python" }).uncheck(); await captureScreenshot(page, testInfo, "onboarding-discovery-results"); await page.getByRole("button", { name: "Add", exact: true }).click(); await page.waitForURL(/\/app\/g\/[^/]+$/, { timeout: 30_000 }); const navigation = await rpc(page, "spaces/list", {}); const names = navigation.spaces.map((space) => space.name); expect(names).toContain("atlas"); expect(names).not.toContain("garden"); expect(navigation.spaces.find((space) => space.name === "atlas")?.workspace?.path).toMatch( /code\/atlas$/, ); const values = (await rpc(page, "profile/get", {})).facts.map( (fact) => fact.value, ); expect(values).toEqual( expect.arrayContaining(["Codes in TypeScript", "Uses Docker", "Uses GitHub Actions"]), ); expect(values).not.toContain("Codes in Python"); } finally { await page.request.post(`${api}/__e2e/deployment-owner`, { data: { userId: previousOwnerUserId }, }); } });