Fix flaky playwright tests (#28975)
* Fix flaky tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix flaky tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix mas config Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix another flaky test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
671d6de805
commit
2cddb16a9f
@@ -62,8 +62,7 @@ test.describe("Key backup reset from elsewhere", () => {
|
|||||||
await page.getByRole("textbox", { name: "Name" }).fill("test room");
|
await page.getByRole("textbox", { name: "Name" }).fill("test room");
|
||||||
await page.getByRole("button", { name: "Create room" }).click();
|
await page.getByRole("button", { name: "Create room" }).click();
|
||||||
|
|
||||||
// @ts-ignore - this runs in the browser scope where mxMatrixClientPeg is a thing. Here, it is not.
|
const accessToken = await page.evaluate(() => window.mxMatrixClientPeg.get().getAccessToken());
|
||||||
const accessToken = await page.evaluate(() => mxMatrixClientPeg.get().getAccessToken());
|
|
||||||
|
|
||||||
const csAPI = new TestClientServerAPI(request, homeserver, accessToken);
|
const csAPI = new TestClientServerAPI(request, homeserver, accessToken);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ test.use({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
context: async ({ context, homeserver }, use) => {
|
||||||
|
// Restart the homeserver to wipe its in-memory db so we can reuse the same user ID without cross-signing prompts
|
||||||
|
await homeserver.restart();
|
||||||
|
await use(context);
|
||||||
|
},
|
||||||
credentials: async ({ context, homeserver }, use) => {
|
credentials: async ({ context, homeserver }, use) => {
|
||||||
const displayName = "Dave";
|
const displayName = "Dave";
|
||||||
const credentials = await homeserver.registerUser(username, password, displayName);
|
const credentials = await homeserver.registerUser(username, password, displayName);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ test.describe("RightPanel", () => {
|
|||||||
// Set a local room address
|
// Set a local room address
|
||||||
const localAddresses = page.locator(".mx_SettingsFieldset", { hasText: "Local Addresses" });
|
const localAddresses = page.locator(".mx_SettingsFieldset", { hasText: "Local Addresses" });
|
||||||
await localAddresses.getByRole("textbox").fill(ROOM_ADDRESS_LONG);
|
await localAddresses.getByRole("textbox").fill(ROOM_ADDRESS_LONG);
|
||||||
|
await expect(page.getByText("This address is available to use")).toBeVisible();
|
||||||
await localAddresses.getByRole("button", { name: "Add" }).click();
|
await localAddresses.getByRole("button", { name: "Add" }).click();
|
||||||
await expect(localAddresses.getByText(`#${ROOM_ADDRESS_LONG}:localhost`)).toHaveClass(
|
await expect(localAddresses.getByText(`#${ROOM_ADDRESS_LONG}:localhost`)).toHaveClass(
|
||||||
"mx_EditableItem_item",
|
"mx_EditableItem_item",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ test.describe("Room Directory", () => {
|
|||||||
// First add a local address `gaming`
|
// First add a local address `gaming`
|
||||||
const localAddresses = page.locator(".mx_SettingsFieldset", { hasText: "Local Addresses" });
|
const localAddresses = page.locator(".mx_SettingsFieldset", { hasText: "Local Addresses" });
|
||||||
await localAddresses.getByRole("textbox").fill("gaming");
|
await localAddresses.getByRole("textbox").fill("gaming");
|
||||||
|
await expect(page.getByText("This address is available to use")).toBeVisible();
|
||||||
await localAddresses.getByRole("button", { name: "Add" }).click();
|
await localAddresses.getByRole("button", { name: "Add" }).click();
|
||||||
await expect(localAddresses.getByText("#gaming:localhost")).toHaveClass("mx_EditableItem_item");
|
await expect(localAddresses.getByText("#gaming:localhost")).toHaveClass("mx_EditableItem_item");
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ test.describe("General room settings tab", () => {
|
|||||||
// 1. Set the room-address to be a really long string
|
// 1. Set the room-address to be a really long string
|
||||||
const longString = "abcasdhjasjhdaj1jh1asdhasjdhajsdhjavhjksd".repeat(4);
|
const longString = "abcasdhjasjhdaj1jh1asdhasjdhajsdhjavhjksd".repeat(4);
|
||||||
await settings.locator("#roomAliases input[label='Room address']").fill(longString);
|
await settings.locator("#roomAliases input[label='Room address']").fill(longString);
|
||||||
|
await expect(page.getByText("This address is available to use")).toBeVisible();
|
||||||
await settings.locator("#roomAliases").getByText("Add", { exact: true }).click();
|
await settings.locator("#roomAliases").getByText("Add", { exact: true }).click();
|
||||||
|
|
||||||
// 2. wait for the new setting to apply ...
|
// 2. wait for the new setting to apply ...
|
||||||
|
|||||||
@@ -179,7 +179,9 @@ export class Client {
|
|||||||
public async createRoom(options: ICreateRoomOpts): Promise<string> {
|
public async createRoom(options: ICreateRoomOpts): Promise<string> {
|
||||||
const client = await this.prepareClient();
|
const client = await this.prepareClient();
|
||||||
return await client.evaluate(async (cli, options) => {
|
return await client.evaluate(async (cli, options) => {
|
||||||
const roomPromise = new Promise<void>((resolve) => {
|
const { room_id: roomId } = await cli.createRoom(options);
|
||||||
|
if (!cli.getRoom(roomId)) {
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
const onRoom = (room: Room) => {
|
const onRoom = (room: Room) => {
|
||||||
if (room.roomId === roomId) {
|
if (room.roomId === roomId) {
|
||||||
cli.off(window.matrixcs.ClientEvent.Room, onRoom);
|
cli.off(window.matrixcs.ClientEvent.Room, onRoom);
|
||||||
@@ -188,9 +190,6 @@ export class Client {
|
|||||||
};
|
};
|
||||||
cli.on(window.matrixcs.ClientEvent.Room, onRoom);
|
cli.on(window.matrixcs.ClientEvent.Room, onRoom);
|
||||||
});
|
});
|
||||||
const { room_id: roomId } = await cli.createRoom(options);
|
|
||||||
if (!cli.getRoom(roomId)) {
|
|
||||||
await roomPromise;
|
|
||||||
}
|
}
|
||||||
return roomId;
|
return roomId;
|
||||||
}, options);
|
}, options);
|
||||||
|
|||||||
@@ -130,10 +130,11 @@ export const test = base.extend<TestFixtures, Services>({
|
|||||||
{ scope: "worker" },
|
{ scope: "worker" },
|
||||||
],
|
],
|
||||||
|
|
||||||
context: async ({ logger, context, request, homeserver }, use, testInfo) => {
|
context: async ({ logger, context, request, homeserver, mailhogClient }, use, testInfo) => {
|
||||||
homeserver.setRequest(request);
|
homeserver.setRequest(request);
|
||||||
await logger.onTestStarted(context);
|
await logger.onTestStarted(context);
|
||||||
await use(context);
|
await use(context);
|
||||||
await logger.onTestFinished(testInfo);
|
await logger.onTestFinished(testInfo);
|
||||||
|
await mailhogClient.deleteAll();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ const snapshotRoot = path.join(__dirname, "snapshots");
|
|||||||
|
|
||||||
class StaleScreenshotReporter implements Reporter {
|
class StaleScreenshotReporter implements Reporter {
|
||||||
private screenshots = new Set<string>();
|
private screenshots = new Set<string>();
|
||||||
|
private failing = false;
|
||||||
private success = true;
|
private success = true;
|
||||||
|
|
||||||
public onTestEnd(test: TestCase): void {
|
public onTestEnd(test: TestCase): void {
|
||||||
if (!test.ok()) return;
|
if (!test.ok()) {
|
||||||
|
this.failing = true;
|
||||||
|
}
|
||||||
for (const annotation of test.annotations) {
|
for (const annotation of test.annotations) {
|
||||||
if (annotation.type === "_screenshot") {
|
if (annotation.type === "_screenshot") {
|
||||||
this.screenshots.add(annotation.description);
|
this.screenshots.add(annotation.description);
|
||||||
@@ -40,6 +43,7 @@ class StaleScreenshotReporter implements Reporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async onExit(): Promise<void> {
|
public async onExit(): Promise<void> {
|
||||||
|
if (this.failing) return;
|
||||||
const screenshotFiles = new Set(await glob(`**/*.png`, { cwd: snapshotRoot }));
|
const screenshotFiles = new Set(await glob(`**/*.png`, { cwd: snapshotRoot }));
|
||||||
for (const screenshot of screenshotFiles) {
|
for (const screenshot of screenshotFiles) {
|
||||||
if (screenshot.split("-").at(-1) !== "linux.png") {
|
if (screenshot.split("-").at(-1) !== "linux.png") {
|
||||||
|
|||||||
@@ -168,6 +168,16 @@ const DEFAULT_CONFIG = {
|
|||||||
access_token_ttl: 300,
|
access_token_ttl: 300,
|
||||||
compat_token_ttl: 300,
|
compat_token_ttl: 300,
|
||||||
},
|
},
|
||||||
|
rate_limiting: {
|
||||||
|
login: {
|
||||||
|
burst: 10,
|
||||||
|
per_second: 1,
|
||||||
|
},
|
||||||
|
registration: {
|
||||||
|
burst: 10,
|
||||||
|
per_second: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MatrixAuthenticationServiceContainer extends GenericContainer {
|
export class MatrixAuthenticationServiceContainer extends GenericContainer {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AbstractStartedContainer, GenericContainer, StartedTestContainer, Wait } from "testcontainers";
|
import { AbstractStartedContainer, GenericContainer, RestartOptions, StartedTestContainer, Wait } from "testcontainers";
|
||||||
import { APIRequestContext } from "@playwright/test";
|
import { APIRequestContext } from "@playwright/test";
|
||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import * as YAML from "yaml";
|
import * as YAML from "yaml";
|
||||||
@@ -239,6 +239,11 @@ export class StartedSynapseContainer extends AbstractStartedContainer implements
|
|||||||
super(container);
|
super(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public restart(options?: Partial<RestartOptions>): Promise<void> {
|
||||||
|
this.adminToken = undefined;
|
||||||
|
return super.restart(options);
|
||||||
|
}
|
||||||
|
|
||||||
public setRequest(request: APIRequestContext): void {
|
public setRequest(request: APIRequestContext): void {
|
||||||
this.request = request;
|
this.request = request;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user