diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2ef4dc04..518226fb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -46,7 +46,8 @@ jobs: run: yarn playwright install --with-deps - name: Run backend components run: | - docker compose -f playwright-backend-docker-compose.yml up -d + docker compose -f playwright-backend-docker-compose.yml -f playwright-backend-docker-compose.override.yml pull + docker compose -f playwright-backend-docker-compose.yml -f playwright-backend-docker-compose.override.yml up -d docker ps - name: Copy config file run: cp config/config.devenv.json public/config.json diff --git a/package.json b/package.json index e1e27185..3dc634f8 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test": "vitest", "test:coverage": "vitest --coverage", "backend": "docker-compose -f dev-backend-docker-compose.yml up", + "backend-playwright": "docker-compose -f playwright-backend-docker-compose.yml -f playwright-backend-docker-compose.override.yml up", "test:playwright": "playwright test", "test:playwright:open": "yarn test:playwright --ui", "links:enable": "mv .links.disabled.yaml .links.yaml & touch .links.yaml", diff --git a/playwright/fixtures/widget-user.ts b/playwright/fixtures/widget-user.ts index d1412bd8..9caef91d 100644 --- a/playwright/fixtures/widget-user.ts +++ b/playwright/fixtures/widget-user.ts @@ -5,7 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { type Page, test, expect, type JSHandle } from "@playwright/test"; +import { + type Browser, + type Page, + test, + expect, + type JSHandle, +} from "@playwright/test"; import type { MatrixClient } from "matrix-js-sdk"; @@ -30,8 +36,8 @@ const PASSWORD = "foobarbaz1!"; const CONFIG_JSON = { default_server_config: { "m.homeserver": { - base_url: "http://synapse.localhost:8008", - server_name: "synapse.localhost", + base_url: "https://synapse.m.localhost", + server_name: "synapse.m.localhost", }, }, @@ -74,6 +80,52 @@ async function setDevToolElementCallDevUrl(page: Page): Promise { }); } +/** + * Registers a new user and returns page, clientHandle and mxId. + */ +async function registerUser( + browser: Browser, + username: string, +): Promise<{ page: Page; clientHandle: JSHandle; mxId: string }> { + const userContext = await browser.newContext({ + reducedMotion: "reduce", + }); + const page = await userContext.newPage(); + await page.goto("http://localhost:8081/#/welcome"); + await page.getByRole("link", { name: "Create Account" }).click(); + await page.getByRole("textbox", { name: "Username" }).fill(username); + await page + .getByRole("textbox", { name: "Password", exact: true }) + .fill(PASSWORD); + await page.getByRole("textbox", { name: "Confirm password" }).click(); + await page.getByRole("textbox", { name: "Confirm password" }).fill(PASSWORD); + await page.getByRole("button", { name: "Register" }).click(); + const continueButton = page.getByRole("button", { name: "Continue" }); + try { + await expect(continueButton).toBeVisible({ timeout: 5000 }); + await page + .getByRole("textbox", { name: "Password", exact: true }) + .fill(PASSWORD); + await continueButton.click(); + } catch { + // continueButton not visible, continue as normal + } + await expect( + page.getByRole("heading", { name: `Welcome ${username}` }), + ).toBeVisible(); + await setDevToolElementCallDevUrl(page); + + const clientHandle = await page.evaluateHandle(() => + window.mxMatrixClientPeg.get(), + ); + const mxId = (await clientHandle.evaluate( + (cli: MatrixClient) => cli.getUserId(), + clientHandle, + ))!; + + return { page, clientHandle, mxId }; +} + export const widgetTest = test.extend({ asWidget: async ({ browser, context }, pUse) => { await context.route(`http://localhost:8081/config.json*`, async (route) => { @@ -83,61 +135,17 @@ export const widgetTest = test.extend({ const userA = `brooks_${Date.now()}`; const userB = `whistler_${Date.now()}`; - const user1Context = await browser.newContext({ - reducedMotion: "reduce", - }); - const ewPage1 = await user1Context.newPage(); - // Register the first user - await ewPage1.goto("http://localhost:8081/#/welcome"); - await ewPage1.getByRole("link", { name: "Create Account" }).click(); - await ewPage1.getByRole("textbox", { name: "Username" }).fill(userA); - await ewPage1 - .getByRole("textbox", { name: "Password", exact: true }) - .fill(PASSWORD); - await ewPage1.getByRole("textbox", { name: "Confirm password" }).click(); - await ewPage1 - .getByRole("textbox", { name: "Confirm password" }) - .fill(PASSWORD); - await ewPage1.getByRole("button", { name: "Register" }).click(); - await expect( - ewPage1.getByRole("heading", { name: `Welcome ${userA}` }), - ).toBeVisible(); - await setDevToolElementCallDevUrl(ewPage1); - - const brooksClientHandle = await ewPage1.evaluateHandle(() => - window.mxMatrixClientPeg.get(), - ); - const brooksMxId = (await brooksClientHandle.evaluate((cli) => { - return cli.getUserId(); - }, brooksClientHandle))!; - - const user2Context = await browser.newContext({ - reducedMotion: "reduce", - }); - const ewPage2 = await user2Context.newPage(); - // Register the second user - await ewPage2.goto("http://localhost:8081/#/welcome"); - await ewPage2.getByRole("link", { name: "Create Account" }).click(); - await ewPage2.getByRole("textbox", { name: "Username" }).fill(userB); - await ewPage2 - .getByRole("textbox", { name: "Password", exact: true }) - .fill(PASSWORD); - await ewPage2.getByRole("textbox", { name: "Confirm password" }).click(); - await ewPage2 - .getByRole("textbox", { name: "Confirm password" }) - .fill(PASSWORD); - await ewPage2.getByRole("button", { name: "Register" }).click(); - await expect( - ewPage2.getByRole("heading", { name: `Welcome ${userB}` }), - ).toBeVisible(); - await setDevToolElementCallDevUrl(ewPage2); - - const whistlerClientHandle = await ewPage2.evaluateHandle(() => - window.mxMatrixClientPeg.get(), - ); - const whistlerMxId = (await whistlerClientHandle.evaluate((cli) => { - return cli.getUserId(); - }, whistlerClientHandle))!; + // Register users + const { + page: ewPage1, + clientHandle: brooksClientHandle, + mxId: brooksMxId, + } = await registerUser(browser, userA); + const { + page: ewPage2, + clientHandle: whistlerClientHandle, + mxId: whistlerMxId, + } = await registerUser(browser, userB); // Invite the second user await ewPage1.getByRole("button", { name: "Add room" }).click(); diff --git a/playwright/widget/simple-create.spec.ts b/playwright/widget/simple-create.spec.ts index 3712f5c4..00d5c658 100644 --- a/playwright/widget/simple-create.spec.ts +++ b/playwright/widget/simple-create.spec.ts @@ -9,11 +9,14 @@ import { expect, test } from "@playwright/test"; import { widgetTest } from "../fixtures/widget-user.ts"; +// Skip test, including Fixtures +widgetTest.skip( + ({ browserName }) => browserName === "firefox", + "This test is not working on firefox, after hangup brooks is locked in a strange state with a blank widget", +); + widgetTest("Start a new call as widget", async ({ asWidget, browserName }) => { - test.skip( - browserName === "firefox", - "This test is not working on firefox, after hangup brooks is locked in a strange state with a blank widget", - ); + test.slow(); // Triples the timeout const { brooks, whistler } = asWidget;