diff --git a/.github/workflows/end-to-end-tests.yaml b/.github/workflows/end-to-end-tests.yaml index 6afabdb1fe..8a59504429 100644 --- a/.github/workflows/end-to-end-tests.yaml +++ b/.github/workflows/end-to-end-tests.yaml @@ -114,14 +114,20 @@ jobs: - Chrome - Firefox - WebKit + - Dendrite + - Pinecone isCron: - ${{ github.event_name == 'schedule' }} - # Skip the Firefox & Safari runs unless this was a cron trigger - exclude: - - isCron: false - project: Firefox - - isCron: false - project: WebKit + # Skip the non-Chrome runs unless this was a cron trigger + # exclude: + # - isCron: false + # project: Firefox + # - isCron: false + # project: WebKit + # - isCron: false + # project: Dendrite + # - isCron: false + # project: Pinecone steps: - uses: actions/checkout@v4 with: diff --git a/playwright.config.ts b/playwright.config.ts index d317c55a6d..09bd07bb3b 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -8,19 +8,25 @@ Please see LICENSE files in the repository root for full details. import { defineConfig, devices } from "@playwright/test"; +import { Options } from "./playwright/services"; + const baseURL = process.env["BASE_URL"] ?? "http://localhost:8080"; -export default defineConfig({ +const chromeProject = { + ...devices["Desktop Chrome"], + channel: "chromium", + permissions: ["clipboard-write", "clipboard-read", "microphone"], + launchOptions: { + args: ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", "--mute-audio"], + }, +}; + +export default defineConfig({ projects: [ { name: "Chrome", use: { - ...devices["Desktop Chrome"], - channel: "chromium", - permissions: ["clipboard-write", "clipboard-read", "microphone"], - launchOptions: { - args: ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", "--mute-audio"], - }, + ...chromeProject, }, }, { @@ -48,6 +54,22 @@ export default defineConfig({ }, ignoreSnapshots: true, }, + { + name: "Dendrite", + use: { + ...chromeProject, + homeserverType: "dendrite", + }, + ignoreSnapshots: true, + }, + { + name: "Pinecone", + use: { + ...chromeProject, + homeserverType: "pinecone", + }, + ignoreSnapshots: true, + }, ], use: { viewport: { width: 1280, height: 720 }, diff --git a/playwright/e2e/crypto/backups.spec.ts b/playwright/e2e/crypto/backups.spec.ts index 6e6c3e0491..adb7db03aa 100644 --- a/playwright/e2e/crypto/backups.spec.ts +++ b/playwright/e2e/crypto/backups.spec.ts @@ -23,7 +23,7 @@ async function expectBackupVersionToBe(page: Page, version: string) { } // These tests register an account with MAS because then we go through the "normal" registration flow -// and crypto gets set up. Using the 'user' fixture create a a user an synthesizes an existing login, +// and crypto gets set up. Using the 'user' fixture create a user and synthesizes an existing login, // which is faster but leaves us without crypto set up. test.describe("Encryption state after registration", () => { test.use(masHomeserver); diff --git a/playwright/plugins/homeserver/dendrite/index.ts b/playwright/plugins/homeserver/dendrite/index.ts index c9cb3332eb..fb3537f417 100644 --- a/playwright/plugins/homeserver/dendrite/index.ts +++ b/playwright/plugins/homeserver/dendrite/index.ts @@ -6,33 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { Fixtures, PlaywrightTestArgs } from "@playwright/test"; +import { Options } from "../../../services.ts"; -import { Fixtures as BaseFixtures } from "../../../element-web-test.ts"; -import { DendriteContainer, PineconeContainer } from "../../../testcontainers/dendrite.ts"; -import { Services } from "../../../services.ts"; - -type Fixture = PlaywrightTestArgs & Services & BaseFixtures; -export const dendriteHomeserver: Fixtures = { - _homeserver: async ({ request }, use) => { - const container = - process.env["PLAYWRIGHT_HOMESERVER"] === "dendrite" - ? new DendriteContainer(request) - : new PineconeContainer(request); - await use(container); - }, - homeserver: async ({ logger, network, _homeserver: homeserver }, use) => { - const container = await homeserver - .withNetwork(network) - .withNetworkAliases("homeserver") - .withLogConsumer(logger.getConsumer("dendrite")) - .start(); - - await use(container); - await container.stop(); - }, +export const isDendrite = ({ homeserverType }: Options): boolean => { + return homeserverType === "dendrite" || homeserverType === "pinecone"; }; - -export function isDendrite(): boolean { - return process.env["PLAYWRIGHT_HOMESERVER"] === "dendrite" || process.env["PLAYWRIGHT_HOMESERVER"] === "pinecone"; -} diff --git a/playwright/plugins/homeserver/index.ts b/playwright/plugins/homeserver/index.ts index c05a5c345e..ba8a5bdb28 100644 --- a/playwright/plugins/homeserver/index.ts +++ b/playwright/plugins/homeserver/index.ts @@ -42,3 +42,5 @@ export interface Credentials { password: string | null; // null for password-less users displayName?: string; } + +export type HomeserverType = "synapse" | "dendrite" | "pinecone"; diff --git a/playwright/services.ts b/playwright/services.ts index 58fc21775e..1c34898a94 100644 --- a/playwright/services.ts +++ b/playwright/services.ts @@ -14,6 +14,8 @@ import { SynapseConfigOptions, SynapseContainer } from "./testcontainers/synapse import { ContainerLogger } from "./testcontainers/utils.ts"; import { StartedMatrixAuthenticationServiceContainer } from "./testcontainers/mas.ts"; import { HomeserverContainer, StartedHomeserverContainer } from "./testcontainers/HomeserverContainer.ts"; +import { DendriteContainer, PineconeContainer } from "./testcontainers/dendrite.ts"; +import { HomeserverType } from "./plugins/homeserver"; export interface Services { logger: ContainerLogger; @@ -24,13 +26,17 @@ export interface Services { mailhog: StartedTestContainer; mailhogClient: mailhog.API; - synapseConfigOptions: SynapseConfigOptions; _homeserver: HomeserverContainer; homeserver: StartedHomeserverContainer; mas?: StartedMatrixAuthenticationServiceContainer; } -export const test = base.extend({ +export interface Options { + synapseConfigOptions: SynapseConfigOptions; + homeserverType: HomeserverType; +} + +export const test = base.extend({ // eslint-disable-next-line no-empty-pattern logger: async ({}, use, testInfo) => { const logger = new ContainerLogger(); @@ -85,16 +91,40 @@ export const test = base.extend({ }, synapseConfigOptions: [{}, { option: true }], - _homeserver: async ({ request }, use) => { - const container = new SynapseContainer(request); + homeserverType: ["synapse", { option: true }], + _homeserver: async ({ homeserverType, request }, use) => { + let container: HomeserverContainer; + switch (homeserverType) { + case "synapse": + container = new SynapseContainer(request); + break; + case "dendrite": + container = new DendriteContainer(request); + break; + case "pinecone": + container = new PineconeContainer(request); + break; + } + await use(container); }, - homeserver: async ({ logger, network, _homeserver: homeserver, synapseConfigOptions, mas }, use) => { + homeserver: async ( + { homeserverType, logger, network, _homeserver: homeserver, synapseConfigOptions, mas }, + use, + ) => { + test.skip( + !(homeserver instanceof SynapseContainer) && Object.keys(synapseConfigOptions).length > 0, + `Test specifies Synapse config options so is unsupported with ${homeserverType}`, + ); + + if (homeserver instanceof SynapseContainer) { + homeserver.withConfig(synapseConfigOptions); + } + const container = await homeserver .withNetwork(network) .withNetworkAliases("homeserver") - .withLogConsumer(logger.getConsumer("synapse")) - .withConfig(synapseConfigOptions) + .withLogConsumer(logger.getConsumer(homeserverType)) .start(); await use(container);