Switch to mailpit for Playwright tests

as mailhog is unsupported and lacks arm64 support

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-01-27 12:13:26 +00:00
parent b8a3468485
commit d09fe8bd4f
12 changed files with 61 additions and 49 deletions

View File

@@ -19,19 +19,19 @@ test.use(masHomeserver);
test.describe("Encryption state after registration", () => {
test.skip(isDendrite, "does not yet support MAS");
test("Key backup is enabled by default", async ({ page, mailhogClient, app }, testInfo) => {
test("Key backup is enabled by default", async ({ page, mailpitClient, app }, testInfo) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, `alice_${testInfo.testId}`, "alice@email.com", "Pa$sW0rD!");
await registerAccountMas(page, mailpitClient, `alice_${testInfo.testId}`, "alice@email.com", "Pa$sW0rD!");
await app.settings.openUserSettings("Security & Privacy");
await expect(page.getByText("This session is backing up your keys.")).toBeVisible();
});
test("user is prompted to set up recovery", async ({ page, mailhogClient, app }, testInfo) => {
test("user is prompted to set up recovery", async ({ page, mailpitClient, app }, testInfo) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, `alice_${testInfo.testId}`, "alice@email.com", "Pa$sW0rD!");
await registerAccountMas(page, mailpitClient, `alice_${testInfo.testId}`, "alice@email.com", "Pa$sW0rD!");
await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();
@@ -47,7 +47,7 @@ test.describe("Key backup reset from elsewhere", () => {
test("Key backup is disabled when reset from elsewhere", async ({
page,
mailhogClient,
mailpitClient,
request,
homeserver,
}, testInfo) => {
@@ -60,7 +60,7 @@ test.describe("Key backup reset from elsewhere", () => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, testUsername, "alice@email.com", testPassword);
await registerAccountMas(page, mailpitClient, testUsername, "alice@email.com", testPassword);
await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();

View File

@@ -6,14 +6,14 @@ 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 { API, Messages } from "mailhog";
import { MailpitClient, MailpitMessagesSummaryResponse } from "mailpit-api";
import { Page } from "@playwright/test";
import { expect } from "../../element-web-test";
export async function registerAccountMas(
page: Page,
mailhog: API,
mailpit: MailpitClient,
username: string,
email: string,
password: string,
@@ -27,13 +27,15 @@ export async function registerAccountMas(
await page.getByRole("textbox", { name: "Confirm Password" }).fill(password);
await page.getByRole("button", { name: "Continue" }).click();
let messages: Messages;
let summary: MailpitMessagesSummaryResponse;
await expect(async () => {
messages = await mailhog.messages();
expect(messages.items).toHaveLength(1);
summary = await mailpit.listMessages();
expect(summary.messages_count).toBe(1);
}).toPass();
expect(messages.items[0].to).toEqual(`${username} <${email}>`);
const [, code] = messages.items[0].text.match(/Your verification code to confirm this email address is: (\d{6})/);
expect(summary.messages[0].To).toEqual(`${username} <${email}>`);
const [, code] = summary.messages[0].Snippet.match(
/Your verification code to confirm this email address is: (\d{6})/,
);
await page.getByRole("textbox", { name: "6-digit code" }).fill(code);
await page.getByRole("button", { name: "Continue" }).click();

View File

@@ -19,7 +19,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
context,
page,
homeserver,
mailhogClient,
mailpitClient,
mas,
}, testInfo) => {
await page.clock.install();
@@ -33,7 +33,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
await page.getByRole("button", { name: "Continue" }).click();
const userId = `alice_${testInfo.testId}`;
await registerAccountMas(page, mailhogClient, userId, "alice@email.com", "Pa$sW0rD!");
await registerAccountMas(page, mailpitClient, userId, "alice@email.com", "Pa$sW0rD!");
// Eventually, we should end up at the home screen.
await expect(page).toHaveURL(/\/#\/home$/, { timeout: 10000 });

View File

@@ -34,7 +34,7 @@ test.describe("Email Registration", async () => {
test(
"registers an account and lands on the home page",
{ tag: "@screenshot" },
async ({ page, mailhogClient, request, checkA11y }) => {
async ({ page, mailpitClient, request, checkA11y }) => {
await expect(page.getByRole("textbox", { name: "Username" })).toBeVisible();
// Hide the server text as it contains the randomly allocated Homeserver port
const screenshotOptions = { mask: [page.locator(".mx_ServerPicker_server")] };
@@ -51,10 +51,10 @@ test.describe("Email Registration", async () => {
await expect(page.getByText("An error was encountered when sending the email")).not.toBeVisible();
const messages = await mailhogClient.messages();
expect(messages.items).toHaveLength(1);
expect(messages.items[0].to).toEqual("alice@email.com");
const [emailLink] = messages.items[0].text.match(/http.+/);
const summary = await mailpitClient.listMessages();
expect(summary.messages_count).toBe(1);
expect(summary.messages[0].To).toEqual("alice@email.com");
const [emailLink] = summary.messages[0].Snippet.match(/http.+/);
await request.get(emailLink); // "Click" the link in the email
await expect(page.getByText("Welcome alice")).toBeVisible();

View File

@@ -10,7 +10,7 @@ import { Fixtures } from "../../../element-web-test.ts";
export const consentHomeserver: Fixtures = {
_homeserver: [
async ({ _homeserver: container, mailhog }, use) => {
async ({ _homeserver: container, mailpit }, use) => {
container
.withCopyDirectoriesToContainer([
{ source: "playwright/plugins/homeserver/synapse/res", target: "/data/res" },
@@ -18,7 +18,7 @@ export const consentHomeserver: Fixtures = {
.withConfig({
email: {
enable_notifs: false,
smtp_host: "mailhog",
smtp_host: "mailpit",
smtp_port: 1025,
smtp_user: "username",
smtp_pass: "password",

View File

@@ -10,13 +10,13 @@ import { Fixtures } from "../../../element-web-test.ts";
export const emailHomeserver: Fixtures = {
_homeserver: [
async ({ _homeserver: container, mailhog }, use) => {
async ({ _homeserver: container, mailpit }, use) => {
container.withConfig({
enable_registration_without_verification: undefined,
disable_msisdn_registration: undefined,
registrations_require_3pid: ["email"],
email: {
smtp_host: "mailhog",
smtp_host: "mailpit",
smtp_port: 1025,
notif_from: "Your Friendly %(app)s homeserver <noreply@example.com>",
app_name: "my_branded_matrix_server",

View File

@@ -11,7 +11,7 @@ import { Fixtures } from "../../../element-web-test.ts";
export const masHomeserver: Fixtures = {
mas: [
async ({ _homeserver: homeserver, logger, network, postgres, mailhog }, use) => {
async ({ _homeserver: homeserver, logger, network, postgres, mailpit }, use) => {
const config = {
clients: [
{

View File

@@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details.
*/
import { test as base } from "@playwright/test";
import mailhog from "mailhog";
import { MailpitClient } from "mailpit-api";
import { Network, StartedNetwork } from "testcontainers";
import { PostgreSqlContainer, StartedPostgreSqlContainer } from "@testcontainers/postgresql";
@@ -14,13 +14,13 @@ import { SynapseConfig, SynapseContainer } from "./testcontainers/synapse.ts";
import { Logger } from "./logger.ts";
import { StartedMatrixAuthenticationServiceContainer } from "./testcontainers/mas.ts";
import { HomeserverContainer, StartedHomeserverContainer } from "./testcontainers/HomeserverContainer.ts";
import { MailhogContainer, StartedMailhogContainer } from "./testcontainers/mailhog.ts";
import { MailhogContainer, StartedMailhogContainer } from "./testcontainers/mailpit.ts";
import { OAuthServer } from "./plugins/oauth_server";
import { DendriteContainer, PineconeContainer } from "./testcontainers/dendrite.ts";
import { HomeserverType } from "./plugins/homeserver";
export interface TestFixtures {
mailhogClient: mailhog.API;
mailpitClient: MailpitClient;
}
export interface Services {
@@ -28,7 +28,7 @@ export interface Services {
network: StartedNetwork;
postgres: StartedPostgreSqlContainer;
mailhog: StartedMailhogContainer;
mailpit: StartedMailhogContainer;
synapseConfig: SynapseConfig;
_homeserver: HomeserverContainer<any>;
@@ -90,20 +90,20 @@ export const test = base.extend<TestFixtures, Services & Options>({
{ scope: "worker" },
],
mailhog: [
mailpit: [
async ({ logger, network }, use) => {
const container = await new MailhogContainer()
.withNetwork(network)
.withNetworkAliases("mailhog")
.withLogConsumer(logger.getConsumer("mailhog"))
.withNetworkAliases("mailpit")
.withLogConsumer(logger.getConsumer("mailpit"))
.start();
await use(container);
await container.stop();
},
{ scope: "worker" },
],
mailhogClient: async ({ mailhog: container }, use) => {
await container.client.deleteAll();
mailpitClient: async ({ mailpit: container }, use) => {
await container.client.deleteMessages();
await use(container.client);
},

View File

@@ -6,11 +6,11 @@ Please see LICENSE files in the repository root for full details.
*/
import { AbstractStartedContainer, GenericContainer, StartedTestContainer, Wait } from "testcontainers";
import mailhog from "mailhog";
import { MailpitClient } from "mailpit-api";
export class MailhogContainer extends GenericContainer {
constructor() {
super("mailhog/mailhog:latest");
super("axllent/mailpit:latest");
this.withExposedPorts(8025).withWaitStrategy(Wait.forListeningPorts());
}
@@ -21,10 +21,10 @@ export class MailhogContainer extends GenericContainer {
}
export class StartedMailhogContainer extends AbstractStartedContainer {
public readonly client: mailhog.API;
public readonly client: MailpitClient;
constructor(container: StartedTestContainer) {
super(container);
this.client = mailhog({ host: container.getHost(), port: container.getMappedPort(8025) });
this.client = new MailpitClient(`http://${container.getHost()}:${container.getMappedPort(8025)}`);
}
}

View File

@@ -92,7 +92,7 @@ const DEFAULT_CONFIG = {
reply_to: '"Authentication Service" <root@localhost>',
transport: "smtp",
mode: "plain",
hostname: "mailhog",
hostname: "mailpit",
port: 1025,
username: "username",
password: "password",