2023-11-22 11:49:51 +00:00
|
|
|
/*
|
|
|
|
Copyright 2023 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2023-11-29 13:50:13 +00:00
|
|
|
import { test as base, expect, Locator } from "@playwright/test";
|
2023-11-23 09:09:32 +00:00
|
|
|
import AxeBuilder from "@axe-core/playwright";
|
2023-11-23 10:27:11 +00:00
|
|
|
import _ from "lodash";
|
2023-11-22 11:49:51 +00:00
|
|
|
|
2023-11-23 09:09:32 +00:00
|
|
|
import type mailhog from "mailhog";
|
|
|
|
import type { IConfigOptions } from "../src/IConfigOptions";
|
2023-11-27 14:40:45 +00:00
|
|
|
import { Credentials, Homeserver, HomeserverInstance, StartHomeserverOpts } from "./plugins/homeserver";
|
|
|
|
import { Synapse } from "./plugins/homeserver/synapse";
|
|
|
|
import { Dendrite, Pinecone } from "./plugins/homeserver/dendrite";
|
2023-11-23 09:09:32 +00:00
|
|
|
import { Instance } from "./plugins/mailhog";
|
2023-11-27 12:11:00 +00:00
|
|
|
import { ElementAppPage } from "./pages/ElementAppPage";
|
2023-11-23 10:27:11 +00:00
|
|
|
import { OAuthServer } from "./plugins/oauth_server";
|
2023-11-28 12:08:05 +00:00
|
|
|
import { Crypto } from "./pages/crypto";
|
2023-11-27 10:00:16 +00:00
|
|
|
import { Toasts } from "./pages/toasts";
|
2023-11-22 11:49:51 +00:00
|
|
|
|
2023-11-23 09:09:32 +00:00
|
|
|
const CONFIG_JSON: Partial<IConfigOptions> = {
|
2023-11-22 11:49:51 +00:00
|
|
|
// This is deliberately quite a minimal config.json, so that we can test that the default settings
|
|
|
|
// actually work.
|
|
|
|
//
|
|
|
|
// 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",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// the location tests want a map style url.
|
|
|
|
map_style_url: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
|
|
|
|
};
|
|
|
|
|
2023-11-22 13:20:58 +00:00
|
|
|
export type TestOptions = {
|
2023-11-28 12:08:05 +00:00
|
|
|
cryptoBackend: "legacy" | "rust";
|
2023-11-22 13:20:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export const test = base.extend<
|
|
|
|
TestOptions & {
|
2023-11-23 09:09:32 +00:00
|
|
|
axe: AxeBuilder;
|
|
|
|
checkA11y: () => Promise<void>;
|
2023-11-23 10:27:11 +00:00
|
|
|
// The contents of the config.json to send
|
2023-11-22 13:20:58 +00:00
|
|
|
config: typeof CONFIG_JSON;
|
2023-11-23 10:27:11 +00:00
|
|
|
// The options with which to run the `homeserver` fixture
|
2023-11-22 13:20:58 +00:00
|
|
|
startHomeserverOpts: StartHomeserverOpts | string;
|
|
|
|
homeserver: HomeserverInstance;
|
2023-11-23 10:27:11 +00:00
|
|
|
oAuthServer: { port: number };
|
2023-11-28 11:02:50 +00:00
|
|
|
user: Credentials;
|
2023-11-23 10:27:11 +00:00
|
|
|
displayName?: string;
|
2023-11-27 12:11:00 +00:00
|
|
|
app: ElementAppPage;
|
2023-11-23 09:09:32 +00:00
|
|
|
mailhog?: { api: mailhog.API; instance: Instance };
|
2023-11-28 12:08:05 +00:00
|
|
|
crypto: Crypto;
|
2023-11-28 13:52:09 +00:00
|
|
|
room?: { roomId: string };
|
2023-11-27 10:00:16 +00:00
|
|
|
toasts: Toasts;
|
2023-11-29 13:50:13 +00:00
|
|
|
uut?: Locator; // Unit Under Test, useful place to refer a prepared locator
|
2023-11-22 13:20:58 +00:00
|
|
|
}
|
|
|
|
>({
|
2023-11-28 12:08:05 +00:00
|
|
|
cryptoBackend: ["legacy", { option: true }],
|
2023-11-22 13:20:58 +00:00
|
|
|
config: CONFIG_JSON,
|
2023-11-28 12:08:05 +00:00
|
|
|
page: async ({ context, page, config, cryptoBackend }, use) => {
|
2023-11-22 11:49:51 +00:00
|
|
|
await context.route(`http://localhost:8080/config.json*`, async (route) => {
|
2023-11-23 10:27:11 +00:00
|
|
|
const json = { ...CONFIG_JSON, ...config };
|
2023-11-28 12:08:05 +00:00
|
|
|
if (cryptoBackend === "rust") {
|
2023-11-22 13:20:58 +00:00
|
|
|
json["features"] = {
|
|
|
|
...json["features"],
|
|
|
|
feature_rust_crypto: true,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
await route.fulfill({ json });
|
2023-11-22 11:49:51 +00:00
|
|
|
});
|
2023-11-23 10:27:11 +00:00
|
|
|
|
2023-11-22 11:49:51 +00:00
|
|
|
await use(page);
|
|
|
|
},
|
|
|
|
|
|
|
|
startHomeserverOpts: "default",
|
|
|
|
homeserver: async ({ request, startHomeserverOpts: opts }, use) => {
|
|
|
|
if (typeof opts === "string") {
|
|
|
|
opts = { template: opts };
|
|
|
|
}
|
|
|
|
|
2023-11-27 14:40:45 +00:00
|
|
|
let server: Homeserver;
|
|
|
|
const homeserverName = process.env["PLAYWRIGHT_HOMESERVER"];
|
|
|
|
switch (homeserverName) {
|
|
|
|
case "dendrite":
|
|
|
|
server = new Dendrite(request);
|
|
|
|
break;
|
|
|
|
case "pinecone":
|
|
|
|
server = new Pinecone(request);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
server = new Synapse(request);
|
|
|
|
}
|
|
|
|
|
2023-11-22 11:49:51 +00:00
|
|
|
await use(await server.start(opts));
|
|
|
|
await server.stop();
|
|
|
|
},
|
2023-11-23 10:27:11 +00:00
|
|
|
// eslint-disable-next-line no-empty-pattern
|
|
|
|
oAuthServer: async ({}, use) => {
|
|
|
|
const server = new OAuthServer();
|
|
|
|
const port = server.start();
|
|
|
|
await use({ port });
|
|
|
|
server.stop();
|
|
|
|
},
|
|
|
|
|
|
|
|
displayName: undefined,
|
|
|
|
user: async ({ page, homeserver, displayName: testDisplayName }, use) => {
|
|
|
|
const names = ["Alice", "Bob", "Charlie", "Daniel", "Eve", "Frank", "Grace", "Hannah", "Isaac", "Judy"];
|
|
|
|
const username = _.uniqueId("user_");
|
|
|
|
const password = _.uniqueId("password_");
|
|
|
|
const displayName = testDisplayName ?? _.sample(names)!;
|
|
|
|
|
|
|
|
const credentials = await homeserver.registerUser(username, password, displayName);
|
|
|
|
console.log(`Registered test user ${username} with displayname ${displayName}`);
|
|
|
|
|
|
|
|
await page.addInitScript(
|
|
|
|
({ baseUrl, credentials }) => {
|
|
|
|
// Seed the localStorage with the required credentials
|
|
|
|
window.localStorage.setItem("mx_hs_url", baseUrl);
|
|
|
|
window.localStorage.setItem("mx_user_id", credentials.userId);
|
|
|
|
window.localStorage.setItem("mx_access_token", credentials.accessToken);
|
|
|
|
window.localStorage.setItem("mx_device_id", credentials.deviceId);
|
|
|
|
window.localStorage.setItem("mx_is_guest", "false");
|
|
|
|
window.localStorage.setItem("mx_has_pickle_key", "false");
|
|
|
|
window.localStorage.setItem("mx_has_access_token", "true");
|
|
|
|
|
|
|
|
// Ensure the language is set to a consistent value
|
|
|
|
window.localStorage.setItem("mx_local_settings", '{"language":"en"}');
|
|
|
|
},
|
|
|
|
{ baseUrl: homeserver.config.baseUrl, credentials },
|
|
|
|
);
|
|
|
|
await page.goto("/");
|
|
|
|
|
|
|
|
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
|
|
|
|
|
2023-11-28 11:02:50 +00:00
|
|
|
await use(credentials);
|
2023-11-23 10:27:11 +00:00
|
|
|
},
|
2023-11-23 09:09:32 +00:00
|
|
|
|
|
|
|
axe: async ({ page }, use) => {
|
|
|
|
await use(new AxeBuilder({ page }));
|
|
|
|
},
|
|
|
|
checkA11y: async ({ axe }, use, testInfo) =>
|
|
|
|
use(async () => {
|
|
|
|
const results = await axe.analyze();
|
|
|
|
|
|
|
|
await testInfo.attach("accessibility-scan-results", {
|
|
|
|
body: JSON.stringify(results, null, 2),
|
|
|
|
contentType: "application/json",
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(results.violations).toEqual([]);
|
|
|
|
}),
|
2023-11-27 10:00:16 +00:00
|
|
|
|
2023-11-27 12:11:00 +00:00
|
|
|
app: async ({ page }, use) => {
|
|
|
|
await use(new ElementAppPage(page));
|
|
|
|
},
|
2023-11-28 12:08:05 +00:00
|
|
|
crypto: async ({ page, homeserver, request }, use) => {
|
|
|
|
await use(new Crypto(page, homeserver, request));
|
|
|
|
},
|
2023-11-27 10:00:16 +00:00
|
|
|
toasts: async ({ page }, use) => {
|
|
|
|
await use(new Toasts(page));
|
|
|
|
},
|
2023-11-22 11:49:51 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test.use({});
|
|
|
|
|
2023-11-23 10:27:11 +00:00
|
|
|
export { expect };
|