Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and stabilise sliding sync playwright tests #28809

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 70 additions & 40 deletions playwright/e2e/sliding-sync/sliding-sync.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*

Check failure on line 1 in playwright/e2e/sliding-sync/sliding-sync.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 5/6

[Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z

1) [Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z Test timeout of 30000ms exceeded.

Check failure on line 1 in playwright/e2e/sliding-sync/sliding-sync.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 5/6

[Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z

1) [Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Test timeout of 30000ms exceeded.

Check failure on line 1 in playwright/e2e/sliding-sync/sliding-sync.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 5/6

[Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z

1) [Chrome] › sliding-sync/sliding-sync.spec.ts:78:5 › Sliding Sync › should render the Rooms list in reverse chronological order by default and allowing sorting A-Z Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── Test timeout of 30000ms exceeded.

Check failure on line 1 in playwright/e2e/sliding-sync/sliding-sync.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 5/6

[Chrome] › sliding-sync/sliding-sync.spec.ts:104:5 › Sliding Sync › should move rooms around as new events arrive

2) [Chrome] › sliding-sync/sliding-sync.spec.ts:104:5 › Sliding Sync › should move rooms around as new events arrive Test timeout of 30000ms exceeded.

Check failure on line 1 in playwright/e2e/sliding-sync/sliding-sync.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 5/6

[Chrome] › sliding-sync/sliding-sync.spec.ts:104:5 › Sliding Sync › should move rooms around as new events arrive

2) [Chrome] › sliding-sync/sliding-sync.spec.ts:104:5 › Sliding Sync › should move rooms around as new events arrive Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Test timeout of 30000ms exceeded.
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.

Expand All @@ -8,17 +8,57 @@

import { Page, Request } from "@playwright/test";

import { test, expect } from "../../element-web-test";
import { test as base, expect } from "../../element-web-test";
import type { ElementAppPage } from "../../pages/ElementAppPage";
import type { Bot } from "../../pages/bot";
import { ProxyInstance, SlidingSyncProxy } from "../../plugins/sliding-sync-proxy";

const test = base.extend<{
slidingSyncProxy: ProxyInstance;
testRoom: { roomId: string; name: string };
joinedBot: Bot;
}>({
slidingSyncProxy: async ({ context, page, homeserver }, use) => {
const proxy = new SlidingSyncProxy(homeserver.config.dockerUrl, context);
const proxyInstance = await proxy.start();
const proxyAddress = `http://localhost:${proxyInstance.port}`;
await page.addInitScript((proxyAddress) => {
window.localStorage.setItem(
"mx_local_settings",
JSON.stringify({
feature_sliding_sync_proxy_url: proxyAddress,
}),
);
window.localStorage.setItem("mx_labs_feature_feature_sliding_sync", "true");
}, proxyAddress);
await use(proxyInstance);
await proxy.stop();
},
// Ensure slidingSyncProxy is set up before the user fixture as it relies on an init script
credentials: async ({ slidingSyncProxy, credentials }, use) => {
await use(credentials);
},
testRoom: async ({ user, app }, use) => {
const name = "Test Room";
const roomId = await app.client.createRoom({ name });
await use({ roomId, name });
},
joinedBot: async ({ app, bot, testRoom }, use) => {
const roomId = testRoom.roomId;
await bot.prepareClient();
const bobUserId = await bot.evaluate((client) => client.getUserId());
await app.client.evaluate(
async (client, { bobUserId, roomId }) => {
await client.invite(roomId, bobUserId);
},
{ bobUserId, roomId },
);
await bot.joinRoom(roomId);
await use(bot);
},
});

test.describe("Sliding Sync", () => {
let roomId: string;

test.beforeEach(async ({ slidingSyncProxy, page, user, app }) => {
roomId = await app.client.createRoom({ name: "Test Room" });
});

const checkOrder = async (wantOrder: string[], page: Page) => {
await expect(page.getByRole("group", { name: "Rooms" }).locator(".mx_RoomTile_title")).toHaveText(wantOrder);
};
Expand All @@ -32,20 +72,10 @@
});
};

const createAndJoinBot = async (app: ElementAppPage, bot: Bot): Promise<Bot> => {
await bot.prepareClient();
const bobUserId = await bot.evaluate((client) => client.getUserId());
await app.client.evaluate(
async (client, { bobUserId, roomId }) => {
await client.invite(roomId, bobUserId);
},
{ bobUserId, roomId },
);
await bot.joinRoom(roomId);
return bot;
};
// Load the user fixture for all tests
test.beforeEach(({ user }) => {});

test.skip("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", async ({
test("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", async ({
page,
app,
}) => {
Expand All @@ -71,7 +101,7 @@
await checkOrder(["Apple", "Orange", "Pineapple", "Test Room"], page);
});

test.skip("should move rooms around as new events arrive", async ({ page, app }) => {
test("should move rooms around as new events arrive", async ({ page, app }) => {
// create rooms and check room names are correct
const roomIds: string[] = [];
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
Expand All @@ -94,7 +124,7 @@
await checkOrder(["Pineapple", "Orange", "Apple", "Test Room"], page);
});

test.skip("should not move the selected room: it should be sticky", async ({ page, app }) => {
test("should not move the selected room: it should be sticky", async ({ page, app }) => {
// create rooms and check room names are correct
const roomIds: string[] = [];
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
Expand Down Expand Up @@ -122,11 +152,9 @@
await checkOrder(["Apple", "Orange", "Pineapple", "Test Room"], page);
});

test.skip("should show the right unread notifications", async ({ page, app, user, bot }) => {
const bob = await createAndJoinBot(app, bot);

test("should show the right unread notifications", async ({ page, app, user, joinedBot: bob, testRoom }) => {
// send a message in the test room: unread notification count should increment
await bob.sendMessage(roomId, "Hello World");
await bob.sendMessage(testRoom.roomId, "Hello World");

const treeItemLocator1 = page.getByRole("treeitem", { name: "Test Room 1 unread message." });
await expect(treeItemLocator1.locator(".mx_NotificationBadge_count")).toHaveText("1");
Expand All @@ -136,7 +164,7 @@
);

// send an @mention: highlight count (red) should be 2.
await bob.sendMessage(roomId, `Hello ${user.displayName}`);
await bob.sendMessage(testRoom.roomId, `Hello ${user.displayName}`);
const treeItemLocator2 = page.getByRole("treeitem", {
name: "Test Room 2 unread messages including mentions.",
});
Expand All @@ -150,9 +178,8 @@
).not.toBeAttached();
});

test.skip("should not show unread indicators", async ({ page, app, bot }) => {
test("should not show unread indicators", async ({ page, app, joinedBot: bot, testRoom }) => {
// TODO: for now. Later we should.
await createAndJoinBot(app, bot);

// disable notifs in this room (TODO: CS API call?)
const locator = page.getByRole("treeitem", { name: "Test Room" });
Expand All @@ -165,7 +192,7 @@

await checkOrder(["Dummy", "Test Room"], page);

await bot.sendMessage(roomId, "Do you read me?");
await bot.sendMessage(testRoom.roomId, "Do you read me?");

// wait for this message to arrive, tell by the room list resorting
await checkOrder(["Test Room", "Dummy"], page);
Expand All @@ -184,9 +211,12 @@
expect(locator.locator(".mx_ToggleSwitch_on")).toBeAttached();
});

test.skip("should show and be able to accept/reject/rescind invites", async ({ page, app, bot }) => {
await createAndJoinBot(app, bot);

test("should show and be able to accept/reject/rescind invites", async ({
page,
app,
joinedBot: bot,
testRoom,
}) => {
const clientUserId = await app.client.evaluate((client) => client.getUserId());

// invite bot into 3 rooms:
Expand Down Expand Up @@ -262,10 +292,10 @@

// Regression test for a bug in SS mode, but would be useful to have in non-SS mode too.
// This ensures we are setting RoomViewStore state correctly.
test.skip("should clear the reply to field when swapping rooms", async ({ page, app }) => {
test("should clear the reply to field when swapping rooms", async ({ page, app, testRoom }) => {
await app.client.createRoom({ name: "Other Room" });
await expect(page.getByRole("treeitem", { name: "Other Room" })).toBeVisible();
await app.client.sendMessage(roomId, "Hello world");
await app.client.sendMessage(testRoom.roomId, "Hello world");

// select the room
await page.getByRole("treeitem", { name: "Test Room" }).click();
Expand Down Expand Up @@ -294,11 +324,11 @@
});

// Regression test for https://github.com/vector-im/element-web/issues/21462
test.skip("should not cancel replies when permalinks are clicked", async ({ page, app }) => {
test("should not cancel replies when permalinks are clicked", async ({ page, app, testRoom }) => {
// we require a first message as you cannot click the permalink text with the avatar in the way
await app.client.sendMessage(roomId, "First message");
await app.client.sendMessage(roomId, "Permalink me");
await app.client.sendMessage(roomId, "Reply to me");
await app.client.sendMessage(testRoom.roomId, "First message");
await app.client.sendMessage(testRoom.roomId, "Permalink me");
await app.client.sendMessage(testRoom.roomId, "Reply to me");

// select the room
await page.getByRole("treeitem", { name: "Test Room" }).click();
Expand All @@ -322,7 +352,7 @@
await expect(page.locator(".mx_ReplyPreview")).toBeVisible();
});

test.skip("should send unsubscribe_rooms for every room switch", async ({ page, app }) => {
test("should send unsubscribe_rooms for every room switch", async ({ page, app }) => {
// create rooms and check room names are correct
const roomIds: string[] = [];
for (const fruit of ["Apple", "Pineapple", "Orange"]) {
Expand Down
21 changes: 0 additions & 21 deletions playwright/element-web-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { OAuthServer } from "./plugins/oauth_server";
import { Crypto } from "./pages/crypto";
import { Toasts } from "./pages/toasts";
import { Bot, CreateBotOpts } from "./pages/bot";
import { ProxyInstance, SlidingSyncProxy } from "./plugins/sliding-sync-proxy";
import { Webserver } from "./plugins/webserver";

// Enable experimental service worker support
Expand Down Expand Up @@ -121,7 +120,6 @@ export interface Fixtures {
uut?: Locator; // Unit Under Test, useful place to refer a prepared locator
botCreateOpts: CreateBotOpts;
bot: Bot;
slidingSyncProxy: ProxyInstance;
labsFlags: string[];
webserver: Webserver;
}
Expand Down Expand Up @@ -274,25 +272,6 @@ export const test = base.extend<Fixtures>({
await mailhog.stop();
},

slidingSyncProxy: async ({ page, user, homeserver }, use) => {
const proxy = new SlidingSyncProxy(homeserver.config.dockerUrl);
const proxyInstance = await proxy.start();
const proxyAddress = `http://localhost:${proxyInstance.port}`;
await page.addInitScript((proxyAddress) => {
window.localStorage.setItem(
"mx_local_settings",
JSON.stringify({
feature_sliding_sync_proxy_url: proxyAddress,
}),
);
window.localStorage.setItem("mx_labs_feature_feature_sliding_sync", "true");
}, proxyAddress);
await page.goto("/");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
await use(proxyInstance);
await proxy.stop();
},

// eslint-disable-next-line no-empty-pattern
webserver: async ({}, use) => {
const webserver = new Webserver();
Expand Down
13 changes: 12 additions & 1 deletion playwright/plugins/sliding-sync-proxy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/

import type { BrowserContext } from "@playwright/test";
import { getFreePort } from "../utils/port";
import { Docker } from "../docker";
import { PG_PASSWORD, PostgresDocker } from "../postgres";
Expand All @@ -24,7 +25,10 @@ export class SlidingSyncProxy {
private readonly postgresDocker = new PostgresDocker("sliding-sync");
private instance: ProxyInstance;

constructor(private synapseIp: string) {}
constructor(
private synapseIp: string,
private context: BrowserContext,
) {}

async start(): Promise<ProxyInstance> {
console.log(new Date(), "Starting sliding sync proxy...");
Expand All @@ -49,6 +53,13 @@ export class SlidingSyncProxy {
});
console.log(new Date(), "started!");

const baseUrl = `http://localhost:${port}`;
await this.context.route("**/_matrix/client/unstable/org.matrix.msc3575/sync**", async (route) => {
await route.continue({
url: new URL(route.request().url().split("/").slice(3).join("/"), baseUrl).href,
});
});

this.instance = { containerId, postgresId, port };
return this.instance;
}
Expand Down
Loading