From 701c0191a5404688e2712c96d0d4c957926d05e1 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 09:29:32 +0100 Subject: [PATCH 1/9] Use real interface type for SynapseConfig --- .../src/testcontainers/synapse.ts | 225 +++++++++++++----- 1 file changed, 170 insertions(+), 55 deletions(-) diff --git a/packages/playwright-common/src/testcontainers/synapse.ts b/packages/playwright-common/src/testcontainers/synapse.ts index 65d92c0ab98..9b4e164330f 100644 --- a/packages/playwright-common/src/testcontainers/synapse.ts +++ b/packages/playwright-common/src/testcontainers/synapse.ts @@ -25,7 +25,169 @@ import { type StartedMatrixAuthenticationServiceContainer } from "./mas.js"; import { Api, ClientServerApi, type Verb, type Credentials } from "../utils/api.js"; import { type StartedMailpitContainer } from "./mailpit.js"; -const DEFAULT_CONFIG = { +/** + * Incomplete type describing the configuration for a Synapse homeserver + */ +export interface SynapseConfig { + server_name: string; + public_baseurl: string; + pid_file: string; + web_client: boolean; + soft_file_limit: number; + log_config: string; + listeners: Array<{ + port: number; + tls: boolean; + bind_addresses: string[]; + type: string; + x_forwarded: boolean; + resources: Array<{ + names: string[]; + compress: boolean; + }>; + }>; + database: { + name: string; + args: { + database: string; + }; + }; + rc_messages_per_second: number; + rc_message_burst_count: number; + rc_registration: { + per_second: number; + burst_count: number; + }; + rc_joins: { + local: { + per_second: number; + burst_count: number; + }; + remote: { + per_second: number; + burst_count: number; + }; + }; + rc_joins_per_room: { + per_second: number; + burst_count: number; + }; + rc_3pid_validation: { + per_second: number; + burst_count: number; + }; + rc_invites: { + per_room: { + per_second: number; + burst_count: number; + }; + per_user: { + per_second: number; + burst_count: number; + }; + }; + rc_login: { + address: { + per_second: number; + burst_count: number; + }; + account: { + per_second: number; + burst_count: number; + }; + failed_attempts: { + per_second: number; + burst_count: number; + }; + }; + rc_room_creation: { + per_second: number; + burst_count: number; + }; + media_store_path: string; + max_upload_size: string; + max_image_pixels: string; + dynamic_thumbnails: boolean; + enable_registration: boolean; + enable_registration_without_verification: boolean; + disable_msisdn_registration: boolean; + registrations_require_3pid: string[]; + enable_metrics: boolean; + report_stats: boolean; + registration_shared_secret: string; + macaroon_secret_key: string; + form_secret: string; + signing_key_path: string; + trusted_key_servers: unknown[]; + password_config: { + enabled: boolean; + }; + ui_auth: Record; + background_updates: { + min_batch_size: number; + sleep_duration_ms: number; + }; + enable_authenticated_media: boolean; + email: + | undefined + | { + enable_notifs: boolean; + smtp_host: string; + smtp_port: number; + smtp_user: string; + smtp_pass: string; + require_transport_security: false; + notif_from: string; + app_name: string; + notif_template_html: string; + notif_template_text: string; + notif_for_new_users: boolean; + client_base_url: string; + }; + user_consent: + | undefined + | { + template_dir: string; + version: string; + server_notice_content: Record; + send_server_notice_to_guests: boolean; + block_events_error: string; + require_at_registration: boolean; + }; + server_notices: + | undefined + | { + system_mxid_localpart: string; + system_mxid_display_name: string; + system_mxid_avatar_url: string; + room_name: string; + }; + allow_guest_access: boolean; + experimental_features: Record; + matrix_rtc: + | undefined + | { + transports: Array<{ type: string; [field: string]: string }>; + }; + oidc_providers: unknown[]; + serve_server_wellknown: boolean; + presence: { + enabled: boolean; + include_offline_users_on_sync: boolean; + }; + room_list_publication_rules: Array<{ action: string }>; + modules: Array<{ module: string; config?: Record }>; + matrix_authentication_service: + | undefined + | { + enabled?: boolean; + endpoint?: string; + secret?: string | null; + secret_path?: string | null; + }; +} + +const DEFAULT_CONFIG: SynapseConfig = { server_name: "localhost", public_baseurl: "", // set by start method pid_file: "/homeserver.pid", @@ -135,47 +297,12 @@ const DEFAULT_CONFIG = { sleep_duration_ms: 100000, }, enable_authenticated_media: true, - email: undefined as - | undefined - | { - enable_notifs: boolean; - smtp_host: string; - smtp_port: number; - smtp_user: string; - smtp_pass: string; - require_transport_security: false; - notif_from: string; - app_name: string; - notif_template_html: string; - notif_template_text: string; - notif_for_new_users: boolean; - client_base_url: string; - }, - user_consent: undefined as - | undefined - | { - template_dir: string; - version: string; - server_notice_content: Record; - send_server_notice_to_guests: boolean; - block_events_error: string; - require_at_registration: boolean; - }, - server_notices: undefined as - | undefined - | { - system_mxid_localpart: string; - system_mxid_display_name: string; - system_mxid_avatar_url: string; - room_name: string; - }, + email: undefined, + user_consent: undefined, + server_notices: undefined, allow_guest_access: false, - experimental_features: {} as Record, - matrix_rtc: undefined as - | undefined - | { - transports: Array<{ type: string; [field: string]: string }>; - }, + experimental_features: {}, + matrix_rtc: undefined, oidc_providers: [], serve_server_wellknown: true, presence: { @@ -183,22 +310,10 @@ const DEFAULT_CONFIG = { include_offline_users_on_sync: true, }, room_list_publication_rules: [{ action: "allow" }], - modules: [] as Array<{ module: string; config?: Record }>, - matrix_authentication_service: undefined as - | undefined - | { - enabled?: boolean; - endpoint?: string; - secret?: string | null; - secret_path?: string | null; - }, + modules: [], + matrix_authentication_service: undefined, }; -/** - * Incomplete type describing the configuration for a Synapse homeserver - */ -export type SynapseConfig = typeof DEFAULT_CONFIG; - /** * A Synapse testcontainer * From e40ca1c352e5a161d87b55be3e971a3514dfa5da Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 10:05:51 +0100 Subject: [PATCH 2/9] Reconfigure for Synapse retention config --- .../e2e/retention/retention-global.spec.ts | 45 ++++++++ .../e2e/retention/retention.spec.ts | 46 +++----- apps/web/playwright/testcontainers/synapse.ts | 2 +- .../src/testcontainers/synapse.ts | 108 +++++++++--------- 4 files changed, 119 insertions(+), 82 deletions(-) create mode 100644 apps/web/playwright/e2e/retention/retention-global.spec.ts diff --git a/apps/web/playwright/e2e/retention/retention-global.spec.ts b/apps/web/playwright/e2e/retention/retention-global.spec.ts new file mode 100644 index 00000000000..1bbecc3ffc2 --- /dev/null +++ b/apps/web/playwright/e2e/retention/retention-global.spec.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { isDendrite } from "../../plugins/homeserver/dendrite"; +import { checkRetentionInRoom } from "./retention.spec.ts"; +import { test } from "../../element-web-test"; + +const ONE_MINUTE_STR = "60s"; + +test.use({ + synapseConfig: { + retention: { + enabled: true, + default_policy: { + max_lifetime: ONE_MINUTE_STR, + }, + allowed_lifetime_min: ONE_MINUTE_STR, + allowed_lifetime_max: ONE_MINUTE_STR, + }, + experimental_features: { + "msc1763_enabled": true, + } + }, +}); +test.describe("global retention rules", () => { + test.skip(isDendrite, "dendrite does not support retention"); + test.use({ + displayName: "Tom", + botCreateOpts: { + displayName: "Bob", + }, + labsFlags: ["feature_retention"], + }); + test("should apply", async ({ app, bot, page }) => { + const roomId = await app.client.createRoom({ + name: "Test", + invite: [bot.credentials.userId], + }); + await checkRetentionInRoom({ app, bot, page }, roomId); + }); +}); diff --git a/apps/web/playwright/e2e/retention/retention.spec.ts b/apps/web/playwright/e2e/retention/retention.spec.ts index f1440e4c4e1..69ce4728b00 100644 --- a/apps/web/playwright/e2e/retention/retention.spec.ts +++ b/apps/web/playwright/e2e/retention/retention.spec.ts @@ -7,12 +7,14 @@ import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; +import { isDendrite } from "../../plugins/homeserver/dendrite"; import { test, expect, type TestFixtures } from "../../element-web-test"; import type { Page } from "@playwright/test"; const ONE_MINUTE = 60 * 1000; +const ONE_MINUTE_STR = "60s"; -async function checkRetentionInRoom( +export async function checkRetentionInRoom( { bot, app, page }: Pick & { page: Page }, roomId: string, ) { @@ -30,7 +32,23 @@ async function checkRetentionInRoom( } } + +test.use({ + synapseConfig: { + retention: { + enabled: true, + // deliberately no default policy. + allowed_lifetime_min: ONE_MINUTE_STR, + allowed_lifetime_max: ONE_MINUTE_STR, + }, + experimental_features: { + "msc1763_enabled": true, + } + }, +}); + test.describe("Retention", () => { + test.skip(isDendrite, "dendrite does not support retention"); test.use({ displayName: "Tom", botCreateOpts: { @@ -65,32 +83,6 @@ test.describe("Retention", () => { await checkRetentionInRoom({ app, bot, page }, roomId); }); - test.describe("global retention rules", () => { - test.use({ - page: async ({ page }, runFixture) => { - await page.route("**/_matrix/client/unstable/org.matrix.msc1763/retention/configuration", (route) => { - return route.fulfill({ - json: { - policies: { - "*": { - max_lifetime: ONE_MINUTE, - }, - }, - }, - }); - }); - await runFixture(page); - }, - }); - test("should apply", async ({ app, bot, page }) => { - const roomId = await app.client.createRoom({ - name: "Test", - invite: [bot.credentials.userId], - }); - await checkRetentionInRoom({ app, bot, page }, roomId); - }); - }); - test("retention rules should apply after restart", async ({ app, bot, page }) => { const roomId = await app.client.createRoom({ name: "Test", diff --git a/apps/web/playwright/testcontainers/synapse.ts b/apps/web/playwright/testcontainers/synapse.ts index a8e7bd761b7..2f110d2d252 100644 --- a/apps/web/playwright/testcontainers/synapse.ts +++ b/apps/web/playwright/testcontainers/synapse.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { SynapseContainer as BaseSynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers/index.js"; const DOCKER_IMAGE = - "ghcr.io/element-hq/synapse:develop@sha256:9ec4c58ea1384d3a854cd4b25a56b5a9e98b7b0c36844c8e3a442f2a9aa0c5bc"; + "ghcr.io/element-hq/synapse:develop@sha256:34656f82f110460b44c4ec7b77830b04ee325f0f7dc423ec2f95810737ba357e"; /** * SynapseContainer which freezes the docker digest to stabilise tests, diff --git a/packages/playwright-common/src/testcontainers/synapse.ts b/packages/playwright-common/src/testcontainers/synapse.ts index 9b4e164330f..e4f563a953d 100644 --- a/packages/playwright-common/src/testcontainers/synapse.ts +++ b/packages/playwright-common/src/testcontainers/synapse.ts @@ -118,57 +118,51 @@ export interface SynapseConfig { macaroon_secret_key: string; form_secret: string; signing_key_path: string; - trusted_key_servers: unknown[]; + trusted_key_servers: never[]; password_config: { enabled: boolean; }; - ui_auth: Record; + ui_auth?: { + session_timeout: `{number}s`, + } background_updates: { min_batch_size: number; sleep_duration_ms: number; }; enable_authenticated_media: boolean; - email: - | undefined - | { - enable_notifs: boolean; - smtp_host: string; - smtp_port: number; - smtp_user: string; - smtp_pass: string; - require_transport_security: false; - notif_from: string; - app_name: string; - notif_template_html: string; - notif_template_text: string; - notif_for_new_users: boolean; - client_base_url: string; - }; - user_consent: - | undefined - | { - template_dir: string; - version: string; - server_notice_content: Record; - send_server_notice_to_guests: boolean; - block_events_error: string; - require_at_registration: boolean; - }; - server_notices: - | undefined - | { - system_mxid_localpart: string; - system_mxid_display_name: string; - system_mxid_avatar_url: string; - room_name: string; - }; + email?: { + enable_notifs: boolean; + smtp_host: string; + smtp_port: number; + smtp_user: string; + smtp_pass: string; + require_transport_security: false; + notif_from: string; + app_name: string; + notif_template_html: string; + notif_template_text: string; + notif_for_new_users: boolean; + client_base_url: string; + }; + user_consent?: { + template_dir: string; + version: string; + server_notice_content: Record; + send_server_notice_to_guests: boolean; + block_events_error: string; + require_at_registration: boolean; + }; + server_notices?: { + system_mxid_localpart: string; + system_mxid_display_name: string; + system_mxid_avatar_url: string; + room_name: string; + }; allow_guest_access: boolean; experimental_features: Record; - matrix_rtc: - | undefined - | { - transports: Array<{ type: string; [field: string]: string }>; - }; + matrix_rtc?: { + transports: Array<{ type: string;[field: string]: string }>; + }; oidc_providers: unknown[]; serve_server_wellknown: boolean; presence: { @@ -177,14 +171,25 @@ export interface SynapseConfig { }; room_list_publication_rules: Array<{ action: string }>; modules: Array<{ module: string; config?: Record }>; - matrix_authentication_service: - | undefined - | { - enabled?: boolean; - endpoint?: string; - secret?: string | null; - secret_path?: string | null; - }; + matrix_authentication_service?: { + enabled?: boolean; + endpoint?: string; + secret?: string | null; + secret_path?: string | null; + }; + /** + * Server-wide retention rules. + * @see https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=retent#retention + */ + retention?: { + enabled: boolean; + default_policy?: { + min_lifetime?: string; + max_lifetime?: string; + }; + allowed_lifetime_min?: string; + allowed_lifetime_max?: string; + }; } const DEFAULT_CONFIG: SynapseConfig = { @@ -290,16 +295,12 @@ const DEFAULT_CONFIG: SynapseConfig = { password_config: { enabled: true, }, - ui_auth: {}, background_updates: { // Inhibit background updates as this Synapse isn't long-lived min_batch_size: 100000, sleep_duration_ms: 100000, }, enable_authenticated_media: true, - email: undefined, - user_consent: undefined, - server_notices: undefined, allow_guest_access: false, experimental_features: {}, matrix_rtc: undefined, @@ -311,7 +312,6 @@ const DEFAULT_CONFIG: SynapseConfig = { }, room_list_publication_rules: [{ action: "allow" }], modules: [], - matrix_authentication_service: undefined, }; /** From 701abcf42c76c7d140286fb65d8ca84a24a5406b Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 10:07:20 +0100 Subject: [PATCH 3/9] Add beforeEach --- apps/web/playwright/e2e/retention/retention-global.spec.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/web/playwright/e2e/retention/retention-global.spec.ts b/apps/web/playwright/e2e/retention/retention-global.spec.ts index 1bbecc3ffc2..afaf351bed9 100644 --- a/apps/web/playwright/e2e/retention/retention-global.spec.ts +++ b/apps/web/playwright/e2e/retention/retention-global.spec.ts @@ -8,6 +8,7 @@ import { isDendrite } from "../../plugins/homeserver/dendrite"; import { checkRetentionInRoom } from "./retention.spec.ts"; import { test } from "../../element-web-test"; +import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; const ONE_MINUTE_STR = "60s"; @@ -35,6 +36,12 @@ test.describe("global retention rules", () => { }, labsFlags: ["feature_retention"], }); + test.beforeEach(async ({ app, homeserver, page, user }) => { + await rejectToastIfExists(page, "Verify this device"); + await rejectToastIfExists(page, "Notifications"); + await page.clock.install(); + }); + test("should apply", async ({ app, bot, page }) => { const roomId = await app.client.createRoom({ name: "Test", From 4aa5e5c7d660016c8fd5f47fad1dbe493fb9f7c4 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 11:37:44 +0100 Subject: [PATCH 4/9] fix import --- apps/web/playwright/e2e/retention/retention-global.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/playwright/e2e/retention/retention-global.spec.ts b/apps/web/playwright/e2e/retention/retention-global.spec.ts index afaf351bed9..89574614235 100644 --- a/apps/web/playwright/e2e/retention/retention-global.spec.ts +++ b/apps/web/playwright/e2e/retention/retention-global.spec.ts @@ -5,10 +5,11 @@ * Please see LICENSE files in the repository root for full details. */ +import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; + import { isDendrite } from "../../plugins/homeserver/dendrite"; import { checkRetentionInRoom } from "./retention.spec.ts"; import { test } from "../../element-web-test"; -import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; const ONE_MINUTE_STR = "60s"; From bebc712fbe24b428f53bda4898e290041ca43e67 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 11:38:29 +0100 Subject: [PATCH 5/9] lint lint --- apps/web/playwright/e2e/retention/retention-global.spec.ts | 4 ++-- apps/web/playwright/e2e/retention/retention.spec.ts | 5 ++--- packages/playwright-common/src/testcontainers/synapse.ts | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/web/playwright/e2e/retention/retention-global.spec.ts b/apps/web/playwright/e2e/retention/retention-global.spec.ts index 89574614235..3b5e9775ad4 100644 --- a/apps/web/playwright/e2e/retention/retention-global.spec.ts +++ b/apps/web/playwright/e2e/retention/retention-global.spec.ts @@ -24,8 +24,8 @@ test.use({ allowed_lifetime_max: ONE_MINUTE_STR, }, experimental_features: { - "msc1763_enabled": true, - } + msc1763_enabled: true, + }, }, }); test.describe("global retention rules", () => { diff --git a/apps/web/playwright/e2e/retention/retention.spec.ts b/apps/web/playwright/e2e/retention/retention.spec.ts index 69ce4728b00..89079fbd9e8 100644 --- a/apps/web/playwright/e2e/retention/retention.spec.ts +++ b/apps/web/playwright/e2e/retention/retention.spec.ts @@ -32,7 +32,6 @@ export async function checkRetentionInRoom( } } - test.use({ synapseConfig: { retention: { @@ -42,8 +41,8 @@ test.use({ allowed_lifetime_max: ONE_MINUTE_STR, }, experimental_features: { - "msc1763_enabled": true, - } + msc1763_enabled: true, + }, }, }); diff --git a/packages/playwright-common/src/testcontainers/synapse.ts b/packages/playwright-common/src/testcontainers/synapse.ts index e4f563a953d..499121cb3fa 100644 --- a/packages/playwright-common/src/testcontainers/synapse.ts +++ b/packages/playwright-common/src/testcontainers/synapse.ts @@ -123,8 +123,8 @@ export interface SynapseConfig { enabled: boolean; }; ui_auth?: { - session_timeout: `{number}s`, - } + session_timeout: `{number}s`; + }; background_updates: { min_batch_size: number; sleep_duration_ms: number; @@ -161,7 +161,7 @@ export interface SynapseConfig { allow_guest_access: boolean; experimental_features: Record; matrix_rtc?: { - transports: Array<{ type: string;[field: string]: string }>; + transports: Array<{ type: string; [field: string]: string }>; }; oidc_providers: unknown[]; serve_server_wellknown: boolean; From 7bbf4c2aacbd20b8f0619149829586ddd95e7324 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 15:24:32 +0100 Subject: [PATCH 6/9] fix number type --- packages/playwright-common/src/testcontainers/synapse.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/playwright-common/src/testcontainers/synapse.ts b/packages/playwright-common/src/testcontainers/synapse.ts index 499121cb3fa..f6119711183 100644 --- a/packages/playwright-common/src/testcontainers/synapse.ts +++ b/packages/playwright-common/src/testcontainers/synapse.ts @@ -123,7 +123,7 @@ export interface SynapseConfig { enabled: boolean; }; ui_auth?: { - session_timeout: `{number}s`; + session_timeout: `${number}s`; }; background_updates: { min_batch_size: number; @@ -161,7 +161,7 @@ export interface SynapseConfig { allow_guest_access: boolean; experimental_features: Record; matrix_rtc?: { - transports: Array<{ type: string; [field: string]: string }>; + transports: Array<{ type: string;[field: string]: string }>; }; oidc_providers: unknown[]; serve_server_wellknown: boolean; From 791fb2c7a504f0dd44a981eb21ac715c09605964 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 15:28:14 +0100 Subject: [PATCH 7/9] fix --- packages/playwright-common/src/testcontainers/synapse.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/playwright-common/src/testcontainers/synapse.ts b/packages/playwright-common/src/testcontainers/synapse.ts index f6119711183..eecb1bbbeaf 100644 --- a/packages/playwright-common/src/testcontainers/synapse.ts +++ b/packages/playwright-common/src/testcontainers/synapse.ts @@ -161,7 +161,7 @@ export interface SynapseConfig { allow_guest_access: boolean; experimental_features: Record; matrix_rtc?: { - transports: Array<{ type: string;[field: string]: string }>; + transports: Array<{ type: string; [field: string]: string }>; }; oidc_providers: unknown[]; serve_server_wellknown: boolean; From 611e0c214b183e8210eb4d9f999e342e5220db31 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 15:35:12 +0100 Subject: [PATCH 8/9] cleanup --- .../e2e/retention/retention-global.spec.ts | 2 +- .../e2e/retention/retention.spec.ts | 24 ++------------- apps/web/playwright/e2e/retention/utils.ts | 30 +++++++++++++++++++ 3 files changed, 34 insertions(+), 22 deletions(-) create mode 100644 apps/web/playwright/e2e/retention/utils.ts diff --git a/apps/web/playwright/e2e/retention/retention-global.spec.ts b/apps/web/playwright/e2e/retention/retention-global.spec.ts index 3b5e9775ad4..3ff37ce49a6 100644 --- a/apps/web/playwright/e2e/retention/retention-global.spec.ts +++ b/apps/web/playwright/e2e/retention/retention-global.spec.ts @@ -8,7 +8,7 @@ import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; import { isDendrite } from "../../plugins/homeserver/dendrite"; -import { checkRetentionInRoom } from "./retention.spec.ts"; +import { checkRetentionInRoom } from "./utils"; import { test } from "../../element-web-test"; const ONE_MINUTE_STR = "60s"; diff --git a/apps/web/playwright/e2e/retention/retention.spec.ts b/apps/web/playwright/e2e/retention/retention.spec.ts index 89079fbd9e8..b6a902dbfec 100644 --- a/apps/web/playwright/e2e/retention/retention.spec.ts +++ b/apps/web/playwright/e2e/retention/retention.spec.ts @@ -8,29 +8,11 @@ import { rejectToastIfExists } from "@element-hq/element-web-playwright-common"; import { isDendrite } from "../../plugins/homeserver/dendrite"; -import { test, expect, type TestFixtures } from "../../element-web-test"; -import type { Page } from "@playwright/test"; +import { test, expect } from "../../element-web-test"; +import { checkRetentionInRoom, ONE_MINUTE } from "./utils"; -const ONE_MINUTE = 60 * 1000; -const ONE_MINUTE_STR = "60s"; -export async function checkRetentionInRoom( - { bot, app, page }: Pick & { page: Page }, - roomId: string, -) { - await bot.joinRoom(roomId); - await app.viewRoomById(roomId); - const tiles = ( - await Promise.all(Array.from({ length: 5 }).map((_o, index) => bot.sendMessage(roomId, `Message ${index}`))) - ).map(({ event_id: evtId }) => page.locator(`.mx_RoomView_MessageList .mx_EventTile[data-event-id='${evtId}']`)); - for (const tile of tiles) { - await expect(tile).toBeVisible(); - } - await page.clock.fastForward(ONE_MINUTE + 1); - for (const tile of tiles) { - await expect(tile).toBeHidden(); - } -} +const ONE_MINUTE_STR = "60s"; test.use({ synapseConfig: { diff --git a/apps/web/playwright/e2e/retention/utils.ts b/apps/web/playwright/e2e/retention/utils.ts new file mode 100644 index 00000000000..216a40d8535 --- /dev/null +++ b/apps/web/playwright/e2e/retention/utils.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { expect, type TestFixtures } from "../../element-web-test"; +import type { Page } from "@playwright/test"; + + +export const ONE_MINUTE = 60 * 1000; + +export async function checkRetentionInRoom( + { bot, app, page }: Pick & { page: Page }, + roomId: string, +) { + await bot.joinRoom(roomId); + await app.viewRoomById(roomId); + const tiles = ( + await Promise.all(Array.from({ length: 5 }).map((_o, index) => bot.sendMessage(roomId, `Message ${index}`))) + ).map(({ event_id: evtId }) => page.locator(`.mx_RoomView_MessageList .mx_EventTile[data-event-id='${evtId}']`)); + for (const tile of tiles) { + await expect(tile).toBeVisible(); + } + await page.clock.fastForward(ONE_MINUTE + 1); + for (const tile of tiles) { + await expect(tile).toBeHidden(); + } +} From 60548a357cdc102a96469a0ca07fdeaff4a34317 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 19 Jun 2026 15:37:08 +0100 Subject: [PATCH 9/9] formatted --- apps/web/playwright/e2e/retention/retention.spec.ts | 1 - apps/web/playwright/e2e/retention/utils.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/web/playwright/e2e/retention/retention.spec.ts b/apps/web/playwright/e2e/retention/retention.spec.ts index b6a902dbfec..9988e57412b 100644 --- a/apps/web/playwright/e2e/retention/retention.spec.ts +++ b/apps/web/playwright/e2e/retention/retention.spec.ts @@ -11,7 +11,6 @@ import { isDendrite } from "../../plugins/homeserver/dendrite"; import { test, expect } from "../../element-web-test"; import { checkRetentionInRoom, ONE_MINUTE } from "./utils"; - const ONE_MINUTE_STR = "60s"; test.use({ diff --git a/apps/web/playwright/e2e/retention/utils.ts b/apps/web/playwright/e2e/retention/utils.ts index 216a40d8535..d94167dd8c1 100644 --- a/apps/web/playwright/e2e/retention/utils.ts +++ b/apps/web/playwright/e2e/retention/utils.ts @@ -8,7 +8,6 @@ import { expect, type TestFixtures } from "../../element-web-test"; import type { Page } from "@playwright/test"; - export const ONE_MINUTE = 60 * 1000; export async function checkRetentionInRoom(