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

Use homeserver in a worker-scoped fixture #28848

Merged
merged 52 commits into from
Jan 8, 2025
Merged
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
bba55a7
Use homeserver in a worker-scoped fixture
t3chguy Jan 2, 2025
c3316a8
Iterate
t3chguy Jan 2, 2025
0764106
Iterate
t3chguy Jan 2, 2025
00b25f5
Switch to TestContainers for manging services in Playwright
t3chguy Jan 3, 2025
87a0acb
Iterate
t3chguy Jan 3, 2025
7ba1d3e
Flip fixture dependency order
t3chguy Jan 3, 2025
c0337f1
Remove mas dep
t3chguy Jan 6, 2025
a4ba79a
Iterate
t3chguy Jan 6, 2025
94697fe
Iterate
t3chguy Jan 6, 2025
9c52986
Iterate
t3chguy Jan 6, 2025
f176473
Iterate
t3chguy Jan 6, 2025
75ba4f2
Iterate
t3chguy Jan 6, 2025
99af4a4
Merge branch 'develop' of https://github.com/vector-im/element-web in…
t3chguy Jan 6, 2025
4fce001
Iterate
t3chguy Jan 6, 2025
4eefa27
Update matrix-authentication-service in Playwright tests
t3chguy Jan 6, 2025
1cd1dcd
delint
t3chguy Jan 6, 2025
f1c392d
Fix SMTP port
t3chguy Jan 6, 2025
84126e8
Iterate
t3chguy Jan 6, 2025
eaca3f8
Comments
t3chguy Jan 6, 2025
edefe02
Strip ansi from playwright logs to make them more readable
t3chguy Jan 6, 2025
d506dec
Actually do the update
t3chguy Jan 6, 2025
63e855e
Iterate
t3chguy Jan 6, 2025
8e1372b
Remove access to homeserver.config.baseUrl field in favour of homeser…
t3chguy Jan 6, 2025
d80ad9d
Use sane default_server_config and specify server.invalid in the spec…
t3chguy Jan 6, 2025
4cacb83
Fix mas run
t3chguy Jan 6, 2025
08bb07e
break cycle
t3chguy Jan 6, 2025
7104429
Merge branch 't3chguy/playwright-update-mas' of https://github.com/ve…
t3chguy Jan 6, 2025
e7b62c3
Merge branch 't3chguy/prepare-playwright-testcontainers' of https://g…
t3chguy Jan 6, 2025
f6ea850
Iterate
t3chguy Jan 6, 2025
b2fb036
typo
t3chguy Jan 6, 2025
1368dc0
Iterate
t3chguy Jan 6, 2025
27652d0
Iterate
t3chguy Jan 6, 2025
ac53bab
Merge branch 'develop' of https://github.com/vector-im/element-web in…
t3chguy Jan 6, 2025
69723c5
Merge branch 't3chguy/prepare-playwright-testcontainers' of https://g…
t3chguy Jan 6, 2025
9ba9f1c
Iterate
t3chguy Jan 6, 2025
ea61320
prettier
t3chguy Jan 6, 2025
7ceced6
Merge branch 'develop' of https://github.com/vector-im/element-web in…
t3chguy Jan 6, 2025
fd44732
Merge branch 't3chguy/prepare-playwright-testcontainers' of https://g…
t3chguy Jan 6, 2025
0410574
Wire up basics of dendriteHomeserver
t3chguy Jan 6, 2025
96d1812
Merge branch 'develop' of https://github.com/vector-im/element-web in…
t3chguy Jan 7, 2025
6e6c70f
Merge branch 't3chguy/playwright-testcontainers' of https://github.co…
t3chguy Jan 7, 2025
90a05cd
Iterate
t3chguy Jan 7, 2025
0785dec
Iterate
t3chguy Jan 7, 2025
36b8d3c
Iterate
t3chguy Jan 7, 2025
dd494dc
Fix types
t3chguy Jan 7, 2025
a29956e
Iterate
t3chguy Jan 7, 2025
f770ba6
Iterate
t3chguy Jan 7, 2025
da0b0c9
Discard changes to playwright/e2e/settings/device-management.spec.ts
t3chguy Jan 7, 2025
c2682a3
Merge branch 'develop' of https://github.com/vector-im/element-web in…
t3chguy Jan 8, 2025
b346763
Merge branch 't3chguy/worker-scoped-fixtures' of https://github.com/v…
t3chguy Jan 8, 2025
ca7c303
Iterate
t3chguy Jan 8, 2025
70aa6e1
Fix bad merge
t3chguy Jan 8, 2025
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
Prev Previous commit
Next Next commit
Iterate
Signed-off-by: Michael Telatynski <[email protected]>
  • Loading branch information
t3chguy committed Jan 7, 2025
commit 90a05cdae7627d739bf09fe39106d94848759488
3 changes: 1 addition & 2 deletions playwright/e2e/crypto/backups.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*

Check failure on line 1 in playwright/e2e/crypto/backups.spec.ts

GitHub Actions / Run Tests [Chrome] 6/6

[Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create

1) [Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create, delete and recreate a keys backup @no-webkit { errcode: 'M_UNRECOGNIZED', error: 'Unrecognized request' }

Check failure on line 1 in playwright/e2e/crypto/backups.spec.ts

GitHub Actions / Run Tests [Chrome] 6/6

[Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create

1) [Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create, delete and recreate a keys backup @no-webkit Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── { errcode: 'M_UNRECOGNIZED', error: 'Unrecognized request' }

Check failure on line 1 in playwright/e2e/crypto/backups.spec.ts

GitHub Actions / Run Tests [Chrome] 6/6

[Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create

1) [Chrome] › crypto/backups.spec.ts:108:9 › Backups › Create, delete and recreate a keys backup @no-webkit Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── { errcode: 'M_UNRECOGNIZED', error: 'Unrecognized request' }
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.

@@ -25,8 +25,8 @@
// 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,
// which is faster but leaves us without crypto set up.
test.use(masHomeserver);
test.describe("Encryption state after registration", () => {
test.use(masHomeserver);
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is enabled by default", async ({ page, mailhogClient, app }) => {
@@ -53,7 +53,6 @@
});

test.describe("Key backup reset from elsewhere", () => {
test.use(masHomeserver);
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is disabled when reset from elsewhere", async ({ page, mailhogClient, request, homeserver }) => {
44 changes: 22 additions & 22 deletions playwright/e2e/crypto/dehydration.spec.ts
Original file line number Diff line number Diff line change
@@ -19,30 +19,30 @@ function getMemberTileByName(page: Page, name: string): Locator {
return page.locator(`.mx_EntityTile, [title="${name}"]`);
}

test.describe("Dehydration", () => {
test.skip(isDendrite, "does not yet support dehydration v2");

test.use({
displayName: NAME,
synapseConfigOptions: {
experimental_features: {
msc2697_enabled: false,
msc3814_enabled: true,
},
test.use({
displayName: NAME,
synapseConfigOptions: {
experimental_features: {
msc2697_enabled: false,
msc3814_enabled: true,
},
config: async ({ config, context }, use) => {
const wellKnown = {
...config.default_server_config,
"org.matrix.msc3814": true,
};

await context.route("https://localhost/.well-known/matrix/client", async (route) => {
await route.fulfill({ json: wellKnown });
});
},
config: async ({ config, context }, use) => {
const wellKnown = {
...config.default_server_config,
"org.matrix.msc3814": true,
};

await context.route("https://localhost/.well-known/matrix/client", async (route) => {
await route.fulfill({ json: wellKnown });
});

await use(config);
},
});

await use(config);
},
});
test.describe("Dehydration", () => {
test.skip(isDendrite, "does not yet support dehydration v2");

test("Create dehydrated device", async ({ page, user, app }, workerInfo) => {
// Create a backup (which will create SSSS, and dehydrated device)
114 changes: 15 additions & 99 deletions playwright/e2e/login/soft_logout.spec.ts
Original file line number Diff line number Diff line change
@@ -6,12 +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 { Page } from "@playwright/test";

import { test, expect } from "../../element-web-test";
import { doTokenRegistration } from "./utils";
import { Credentials } from "../../plugins/homeserver";
import { legacyOAuthHomeserver } from "../../plugins/homeserver/synapse/legacyOAuthHomeserver.ts";
import { interceptRequestsWithSoftLogout } from "./utils";

test.use({
displayName: "Alice",
@@ -26,102 +22,22 @@ test.use({
},
});

test.describe("Soft logout", () => {
test.describe("with password user", () => {
test("shows the soft-logout page when a request fails, and allows a re-login", async ({ page, user }) => {
await interceptRequestsWithSoftLogout(page, user);
await expect(page.getByText("You're signed out")).toBeVisible();
await page.getByPlaceholder("Password").fill(user.password);
await page.getByPlaceholder("Password").press("Enter");

// back to the welcome page
await expect(page).toHaveURL(/\/#\/home/);
await expect(
page.getByRole("heading", { name: "Now, let's help you get started", exact: true }),
).toBeVisible();
});
test.describe("Soft logout with password user", () => {
test("shows the soft-logout page when a request fails, and allows a re-login", async ({ page, user }) => {
await interceptRequestsWithSoftLogout(page, user);
await expect(page.getByText("You're signed out")).toBeVisible();
await page.getByPlaceholder("Password").fill(user.password);
await page.getByPlaceholder("Password").press("Enter");

test("still shows the soft-logout page when the page is reloaded after a soft-logout", async ({
page,
user,
}) => {
await interceptRequestsWithSoftLogout(page, user);
await expect(page.getByText("You're signed out")).toBeVisible();
await page.reload();
await expect(page.getByText("You're signed out")).toBeVisible();
});
// back to the welcome page
await expect(page).toHaveURL(/\/#\/home/);
await expect(page.getByRole("heading", { name: "Now, let's help you get started", exact: true })).toBeVisible();
});

test.describe("with SSO user", () => {
test.use(legacyOAuthHomeserver);
test.use({
user: async ({ page, homeserver }, use) => {
const user = await doTokenRegistration(page, homeserver);

// Eventually, we should end up at the home screen.
await expect(page).toHaveURL(/\/#\/home$/);
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();

await use(user);
},
});

test("shows the soft-logout page when a request fails, and allows a re-login", async ({ page, user }) => {
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();

await interceptRequestsWithSoftLogout(page, user);

await expect(page.getByText("You're signed out")).toBeVisible();
await page.getByRole("button", { name: "Continue with OAuth test" }).click();

// click the submit button
await page.getByRole("button", { name: "Submit" }).click();

// Synapse prompts us to grant permission to Element
await expect(page.getByRole("heading", { name: "Continue to your account" })).toBeVisible();
await page.getByRole("link", { name: "Continue" }).click();

// back to the welcome page
await expect(page).toHaveURL(/\/#\/home$/);
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();
});
test("still shows the soft-logout page when the page is reloaded after a soft-logout", async ({ page, user }) => {
await interceptRequestsWithSoftLogout(page, user);
await expect(page.getByText("You're signed out")).toBeVisible();
await page.reload();
await expect(page.getByText("You're signed out")).toBeVisible();
});
});

/**
* Intercept calls to /sync and have them fail with a soft-logout
*
* Any further requests to /sync with the same access token are blocked.
*/
async function interceptRequestsWithSoftLogout(page: Page, user: Credentials): Promise<void> {
await page.route("**/_matrix/client/*/sync*", async (route, req) => {
const accessToken = await req.headerValue("Authorization");

// now, if the access token on this request matches the expired one, block it
if (accessToken === `Bearer ${user.accessToken}`) {
console.log("Intercepting request with soft-logged-out access token");
await route.fulfill({
status: 401,
json: {
errcode: "M_UNKNOWN_TOKEN",
error: "Soft logout",
soft_logout: true,
},
});
return;
}

// otherwise, pass through as normal
await route.continue();
});

const promise = page.waitForResponse((resp) => resp.url().includes("/sync") && resp.status() === 401);

// do something to make the active /sync return: create a new room
await page.evaluate(() => {
// don't wait for this to complete: it probably won't, because of the broken sync
window.mxMatrixClientPeg.get().createRoom({});
});

await promise;
}
59 changes: 59 additions & 0 deletions playwright/e2e/login/soft_logout_oauth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.

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 { test, expect } from "../../element-web-test";
import { doTokenRegistration, interceptRequestsWithSoftLogout } from "./utils";
import { legacyOAuthHomeserver } from "../../plugins/homeserver/synapse/legacyOAuthHomeserver.ts";

test.use({
displayName: "Alice",
config: {
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
// We point that to a guaranteed-invalid domain.
default_server_config: {
"m.homeserver": {
base_url: "https://server.invalid",
},
},
},
});

test.use(legacyOAuthHomeserver);
test.describe("Soft logout with SSO user", () => {
test.use({
user: async ({ page, homeserver }, use) => {
const user = await doTokenRegistration(page, homeserver);

// Eventually, we should end up at the home screen.
await expect(page).toHaveURL(/\/#\/home$/);
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();

await use(user);
},
});

test("shows the soft-logout page when a request fails, and allows a re-login", async ({ page, user }) => {
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();

await interceptRequestsWithSoftLogout(page, user);

await expect(page.getByText("You're signed out")).toBeVisible();
await page.getByRole("button", { name: "Continue with OAuth test" }).click();

// click the submit button
await page.getByRole("button", { name: "Submit" }).click();

// Synapse prompts us to grant permission to Element
await expect(page.getByRole("heading", { name: "Continue to your account" })).toBeVisible();
await page.getByRole("link", { name: "Continue" }).click();

// back to the welcome page
await expect(page).toHaveURL(/\/#\/home$/);
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();
});
});
38 changes: 38 additions & 0 deletions playwright/e2e/login/utils.ts
Original file line number Diff line number Diff line change
@@ -58,3 +58,41 @@ export async function doTokenRegistration(
displayName: "Alice",
}));
}

/**
* Intercept calls to /sync and have them fail with a soft-logout
*
* Any further requests to /sync with the same access token are blocked.
*/
export async function interceptRequestsWithSoftLogout(page: Page, user: Credentials): Promise<void> {
await page.route("**/_matrix/client/*/sync*", async (route, req) => {
const accessToken = await req.headerValue("Authorization");

// now, if the access token on this request matches the expired one, block it
if (accessToken === `Bearer ${user.accessToken}`) {
console.log("Intercepting request with soft-logged-out access token");
await route.fulfill({
status: 401,
json: {
errcode: "M_UNKNOWN_TOKEN",
error: "Soft logout",
soft_logout: true,
},
});
return;
}

// otherwise, pass through as normal
await route.continue();
});

const promise = page.waitForResponse((resp) => resp.url().includes("/sync") && resp.status() === 401);

// do something to make the active /sync return: create a new room
await page.evaluate(() => {
// don't wait for this to complete: it probably won't, because of the broken sync
window.mxMatrixClientPeg.get().createRoom({});
});

await promise;
}
2 changes: 1 addition & 1 deletion playwright/e2e/oidc/oidc-native.spec.ts
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ import { ElementAppPage } from "../../pages/ElementAppPage.ts";
import { isDendrite } from "../../plugins/homeserver/dendrite";
import { masHomeserver } from "../../plugins/homeserver/synapse/masHomeserver.ts";

test.use(masHomeserver);
test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
test.use(masHomeserver);
test.skip(isDendrite, "does not yet support MAS");
test.slow(); // trace recording takes a while here

Loading