import { expect, test } from "@playwright/test"; import { captureBrowserFailures, gotoLiveView, loginWithPassword, markerKinds, } from "../tests/helpers"; const phase = requiredEnv("CROSS_CLIENT_PHASE"); const requesterEmail = requiredEnv("CROSS_CLIENT_REQUESTER_EMAIL"); const fixturePassword = requiredEnv("CROSS_CLIENT_PASSWORD"); const requestPath = requiredEnv("CROSS_CLIENT_REQUEST_PATH"); const androidMessage = requiredEnv("CROSS_CLIENT_ANDROID_MESSAGE"); const browserReply = requiredEnv("CROSS_CLIENT_BROWSER_REPLY"); test("browser and Android share chat and live tracking state", async ({ browser }) => { const requester = await loginWithPassword(browser, requesterEmail, fixturePassword); const assertClean = captureBrowserFailures(requester.page); await gotoLiveView(requester.page, requestPath); await expect( requester.page.getByRole("heading", { name: "Private match chat" }), ).toBeVisible(); await expect(requester.page.getByText(androidMessage, { exact: true })).toBeVisible(); if (phase === "observe_android") { await expect.poll(() => markerKinds(requester.page)).toContain("Shared live location"); await requester.page .getByPlaceholder("Write a safe coordination message…") .fill(browserReply); await requester.page.getByRole("button", { name: "Send", exact: true }).click(); await expect(requester.page.getByText(browserReply, { exact: true })).toBeVisible(); } else if (phase === "observe_stopped") { await expect(requester.page.getByText(browserReply, { exact: true })).toBeVisible(); await expect.poll(() => markerKinds(requester.page)).not.toContain("Shared live location"); } else { throw new Error(`Unsupported CROSS_CLIENT_PHASE: ${phase}`); } assertClean(); await requester.context.close(); }); function requiredEnv(name: string): string { const value = process.env[name]; if (!value) { throw new Error(`${name} is required`); } return value; }