Run Playwright tests against Dendrite & Pinecone periodically

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
t3chguy/playwright-homeservers
Michael Telatynski 2025-01-07 09:09:53 +00:00
parent 0410574b20
commit 40d755af6c
No known key found for this signature in database
GPG Key ID: A2B008A5F49F5D0D
6 changed files with 84 additions and 49 deletions

View File

@ -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:

View File

@ -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<Options>({
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 },

View File

@ -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);

View File

@ -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<Fixture, {}, Fixture> = {
_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";
}

View File

@ -42,3 +42,5 @@ export interface Credentials {
password: string | null; // null for password-less users
displayName?: string;
}
export type HomeserverType = "synapse" | "dendrite" | "pinecone";

View File

@ -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<any>;
homeserver: StartedHomeserverContainer;
mas?: StartedMatrixAuthenticationServiceContainer;
}
export const test = base.extend<Services>({
export interface Options {
synapseConfigOptions: SynapseConfigOptions;
homeserverType: HomeserverType;
}
export const test = base.extend<Services & Options>({
// eslint-disable-next-line no-empty-pattern
logger: async ({}, use, testInfo) => {
const logger = new ContainerLogger();
@ -85,16 +91,40 @@ export const test = base.extend<Services>({
},
synapseConfigOptions: [{}, { option: true }],
_homeserver: async ({ request }, use) => {
const container = new SynapseContainer(request);
homeserverType: ["synapse", { option: true }],
_homeserver: async ({ homeserverType, request }, use) => {
let container: HomeserverContainer<any>;
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);