Make apps/web/playwright comply with strict mode (#34403)
* Make apps/web/playwright comply with strict mode Otherwise it sometimes fails to compile matrix-js-sdk as strict mode & noImplicitAny both impact how overloads are asserted * Iterate
This commit is contained in:
@@ -65,7 +65,7 @@ test.describe("Landmark navigation tests", () => {
|
||||
await cli.invite(bobRoom.room_id, bob);
|
||||
},
|
||||
{
|
||||
bob: bob.credentials.userId,
|
||||
bob: bob.credentials!.userId,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -118,7 +118,7 @@ test.describe("Landmark navigation tests", () => {
|
||||
await cli.invite(bobRoom.room_id, bob);
|
||||
},
|
||||
{
|
||||
bob: bob.credentials.userId,
|
||||
bob: bob.credentials!.userId,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -313,7 +313,9 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await expect(tile.locator(".mx_ReplyChain")).toHaveCount(2);
|
||||
|
||||
// Assert that one line contains the user name
|
||||
await expect(tile.locator(".mx_ReplyChain .mx_ReplyTile_sender").getByText(user.displayName)).toBeVisible();
|
||||
await expect(
|
||||
tile.locator(".mx_ReplyChain .mx_ReplyTile_sender").getByText(user.displayName!),
|
||||
).toBeVisible();
|
||||
|
||||
// Assert that the other line contains the file button
|
||||
await expect(tile.locator(".mx_ReplyChain .mx_MFileBody")).toBeVisible();
|
||||
|
||||
@@ -99,9 +99,12 @@ test.describe("HTML Export", () => {
|
||||
|
||||
// Send a bunch of messages to populate the room
|
||||
for (let i = 1; i < 10; i++) {
|
||||
const respone = await app.client.sendMessage(room.roomId, { body: `Testing ${i}`, msgtype: "m.text" });
|
||||
const response = await app.client.sendMessage(room!.roomId, {
|
||||
body: `Testing ${i}`,
|
||||
msgtype: "m.text",
|
||||
});
|
||||
if (i == 1) {
|
||||
await app.client.reactToMessage(room.roomId, null, respone.event_id, "🙃");
|
||||
await app.client.reactToMessage(room!.roomId, null, response.event_id, "🙃");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ test.describe("Composer", () => {
|
||||
// Set up a private room so we have another user to mention
|
||||
await app.client.createRoom({
|
||||
is_direct: true,
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
await app.viewRoomByName("Bob");
|
||||
|
||||
@@ -194,7 +194,7 @@ test.describe("Composer", () => {
|
||||
|
||||
// Note that we include the user ID here as the room tile is also an 'option' role
|
||||
// with text 'Bob'
|
||||
await page.getByRole("option", { name: `Bob ${bot.credentials.userId}` }).click();
|
||||
await page.getByRole("option", { name: `Bob ${bot.credentials!.userId}` }).click();
|
||||
await expect(composer.getByText("Bob")).toBeVisible();
|
||||
await expect(composer).toMatchScreenshot("mention.png");
|
||||
await composer.press("Enter");
|
||||
|
||||
@@ -100,7 +100,7 @@ test.describe("Composer", () => {
|
||||
// Set up a private room so we have another user to mention
|
||||
await app.client.createRoom({
|
||||
is_direct: true,
|
||||
invite: [bob.credentials.userId],
|
||||
invite: [bob.credentials!.userId],
|
||||
});
|
||||
await app.viewRoomByName("Bob");
|
||||
|
||||
@@ -113,11 +113,11 @@ test.describe("Composer", () => {
|
||||
await expect(page.getByTestId("autocomplete-wrapper")).toBeEmpty();
|
||||
|
||||
// Entering the first letter of the other user's name opens the autocomplete...
|
||||
await page.getByRole("textbox").pressSequentially(bob.credentials.displayName.slice(0, 1));
|
||||
await page.getByRole("textbox").pressSequentially(bob.credentials!.displayName!.slice(0, 1));
|
||||
// ...with the other user name visible, and clicking that username...
|
||||
await page.getByTestId("autocomplete-wrapper").getByText(bob.credentials.displayName).click();
|
||||
await page.getByTestId("autocomplete-wrapper").getByText(bob.credentials!.displayName!).click();
|
||||
// ...inserts the username into the composer
|
||||
const pill = page.getByRole("textbox").getByText(bob.credentials.displayName, { exact: false });
|
||||
const pill = page.getByRole("textbox").getByText(bob.credentials!.displayName!, { exact: false });
|
||||
await expect(pill).toHaveAttribute("contenteditable", "false");
|
||||
await expect(pill).toHaveAttribute("data-mention-type", "user");
|
||||
|
||||
@@ -125,7 +125,7 @@ test.describe("Composer", () => {
|
||||
await page.getByRole("button", { name: "Send message" }).click();
|
||||
|
||||
// Typing an @, then other user's name, then trailing space closes the autocomplete
|
||||
await page.getByRole("textbox").pressSequentially(`@${bob.credentials.displayName} `);
|
||||
await page.getByRole("textbox").pressSequentially(`@${bob.credentials!.displayName!} `);
|
||||
await expect(page.getByTestId("autocomplete-wrapper")).toBeEmpty();
|
||||
|
||||
// Send the message to clear the composer
|
||||
@@ -134,7 +134,7 @@ test.describe("Composer", () => {
|
||||
// Moving the cursor back to an "incomplete" mention opens the autocomplete
|
||||
await page
|
||||
.getByRole("textbox")
|
||||
.pressSequentially(`initial text @${bob.credentials.displayName.slice(0, 1)} abc`);
|
||||
.pressSequentially(`initial text @${bob.credentials!.displayName!.slice(0, 1)} abc`);
|
||||
await expect(page.getByTestId("autocomplete-wrapper")).toBeEmpty();
|
||||
// Move the cursor left by 4 to put it to: `@B| abc`, check autocomplete displays
|
||||
await page.getByRole("textbox").press("ArrowLeft");
|
||||
@@ -145,7 +145,7 @@ test.describe("Composer", () => {
|
||||
|
||||
// Selecting the autocomplete option using Enter inserts it into the composer
|
||||
await page.getByRole("textbox").press("Enter");
|
||||
const pill2 = page.getByRole("textbox").getByText(bob.credentials.displayName, { exact: false });
|
||||
const pill2 = page.getByRole("textbox").getByText(bob.credentials!.displayName!, { exact: false });
|
||||
await expect(pill2).toHaveAttribute("contenteditable", "false");
|
||||
await expect(pill2).toHaveAttribute("data-mention-type", "user");
|
||||
});
|
||||
|
||||
@@ -89,13 +89,13 @@ test.describe("Key backup reset from elsewhere", () => {
|
||||
await page.getByRole("textbox", { name: "Name" }).fill("test room");
|
||||
await page.getByRole("button", { name: "Create room" }).click();
|
||||
|
||||
const accessToken = await page.evaluate(() => window.mxMatrixClientPeg.get().getAccessToken());
|
||||
const accessToken = await page.evaluate(() => window.mxMatrixClientPeg.get().getAccessToken()!);
|
||||
|
||||
const csAPI = new TestClientServerAPI(request, homeserver, accessToken);
|
||||
|
||||
const backupInfo = await csAPI.getCurrentBackupInfo();
|
||||
|
||||
await csAPI.deleteBackupVersion(backupInfo.version);
|
||||
await csAPI.deleteBackupVersion(backupInfo!.version);
|
||||
|
||||
await page.getByRole("textbox", { name: "Send a message…" }).fill("/discardsession");
|
||||
await page.getByRole("button", { name: "Send message" }).click();
|
||||
|
||||
@@ -25,8 +25,8 @@ const checkDMRoom = async (page: Page) => {
|
||||
const startDMWithBob = async (page: Page, bob: Bot) => {
|
||||
await page.getByRole("navigation", { name: "Room list" }).getByRole("button", { name: "New conversation" }).click();
|
||||
await page.getByRole("menuitem", { name: "Start chat" }).click();
|
||||
await page.getByTestId("invite-dialog-input").fill(bob.credentials.userId);
|
||||
await page.getByRole("option", { name: bob.credentials.displayName }).click();
|
||||
await page.getByTestId("invite-dialog-input").fill(bob.credentials!.userId);
|
||||
await page.getByRole("option", { name: bob.credentials!.displayName! }).click();
|
||||
await expect(page.getByTestId("invite-dialog-input-wrapper").getByText("Bob")).toBeVisible();
|
||||
await page.getByRole("button", { name: "Go" }).click();
|
||||
|
||||
@@ -82,14 +82,14 @@ test.describe("Cryptography", function () {
|
||||
* @param keyType
|
||||
*/
|
||||
async function verifyKey(app: ElementAppPage, keyType: "master" | "self_signing" | "user_signing") {
|
||||
const accountData: { encrypted: Record<string, Record<string, string>> } = await app.client.evaluate(
|
||||
const accountData = await app.client.evaluate(
|
||||
(cli, keyType) => cli.getAccountDataFromServer(`m.cross_signing.${keyType}`),
|
||||
keyType,
|
||||
);
|
||||
|
||||
expect(accountData.encrypted).toBeDefined();
|
||||
const keys = Object.keys(accountData.encrypted);
|
||||
const key = accountData.encrypted[keys[0]];
|
||||
expect(accountData?.encrypted).toBeDefined();
|
||||
const keys = Object.keys(accountData!.encrypted);
|
||||
const key = accountData!.encrypted[keys[0]];
|
||||
expect(key.ciphertext).toBeDefined();
|
||||
expect(key.iv).toBeDefined();
|
||||
expect(key.mac).toBeDefined();
|
||||
@@ -119,9 +119,9 @@ test.describe("Cryptography", function () {
|
||||
async function fetchMasterKey() {
|
||||
return await test.step("Fetch master key from server", async () => {
|
||||
const k = await app.client.evaluate(async (cli) => {
|
||||
const userId = cli.getUserId();
|
||||
const userId = cli.getSafeUserId();
|
||||
const keys = await cli.downloadKeysForUsers([userId]);
|
||||
return Object.values(keys.master_keys[userId].keys)[0];
|
||||
return Object.values(keys.master_keys![userId].keys)[0];
|
||||
});
|
||||
console.log(`fetchMasterKey: ${k}`);
|
||||
return k;
|
||||
@@ -138,7 +138,7 @@ test.describe("Cryptography", function () {
|
||||
await encryptionTab.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Enter the password
|
||||
await page.getByPlaceholder("Password").fill(aliceCredentials.password);
|
||||
await page.getByPlaceholder("Password").fill(aliceCredentials.password!);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
await expect(async () => {
|
||||
@@ -163,7 +163,7 @@ test.describe("Cryptography", function () {
|
||||
await encryptionTab.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Enter the password
|
||||
await page.getByPlaceholder("Password").fill(aliceCredentials.password);
|
||||
await page.getByPlaceholder("Password").fill(aliceCredentials.password!);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// Key storage should now be enabled
|
||||
@@ -209,7 +209,7 @@ test.describe("Cryptography", function () {
|
||||
await autoJoin(bob);
|
||||
|
||||
// we need to have a room with the other user present, so we can open the verification panel
|
||||
await createSharedRoomWithUser(app, bob.credentials.userId);
|
||||
await createSharedRoomWithUser(app, bob.credentials!.userId);
|
||||
await verify(app, bob);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ test.describe("Device dehydration, on a MAS-enabled homeserver", () => {
|
||||
await autoJoin(bob);
|
||||
|
||||
// Create an encrypted room, and wait for Bob to join it.
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials.userId);
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials!.userId);
|
||||
|
||||
// Even though Alice has seen Bob's join event, Bob may not have done so yet. Wait for the sync to arrive.
|
||||
await bob.awaitRoomMembership(testRoomId);
|
||||
|
||||
@@ -77,7 +77,7 @@ test.describe("Dehydration", () => {
|
||||
// Set up cross-signing and recovery
|
||||
const { botClient } = await createBot(page, homeserver, credentials);
|
||||
// ... and dehydration
|
||||
await botClient.evaluate(async (client) => await client.getCrypto().startDehydration());
|
||||
await botClient.evaluate(async (client) => await client.getCrypto()!.startDehydration());
|
||||
|
||||
const initialDehydratedDeviceIds = await getDehydratedDeviceIds(botClient);
|
||||
expect(initialDehydratedDeviceIds.length).toBe(1);
|
||||
@@ -93,7 +93,7 @@ test.describe("Dehydration", () => {
|
||||
page.getByRole("heading", { name: "Are you sure you want to reset your digital identity?" }),
|
||||
).toBeVisible();
|
||||
await page.getByRole("button", { name: "Continue", exact: true }).click();
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password!);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// And set up recovery
|
||||
@@ -141,7 +141,7 @@ test.describe("Dehydration", () => {
|
||||
await autoJoin(bob);
|
||||
|
||||
// create an encrypted room, and wait for Bob to join it.
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials.userId);
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials!.userId);
|
||||
|
||||
// Even though Alice has seen Bob's join event, Bob may not have done so yet. Wait for the sync to arrive.
|
||||
await bob.awaitRoomMembership(testRoomId);
|
||||
@@ -171,9 +171,9 @@ test.describe("Dehydration", () => {
|
||||
|
||||
async function getDehydratedDeviceIds(client: Client): Promise<string[]> {
|
||||
return await client.evaluate(async (client) => {
|
||||
const userId = client.getUserId();
|
||||
const devices = await client.getCrypto().getUserDeviceInfo([userId]);
|
||||
return Array.from(devices.get(userId).values())
|
||||
const userId = client.getSafeUserId();
|
||||
const devices = await client.getCrypto()!.getUserDeviceInfo([userId]);
|
||||
return Array.from(devices.get(userId)!.values())
|
||||
.filter((d) => d.dehydrated)
|
||||
.map((d) => d.deviceId);
|
||||
});
|
||||
|
||||
@@ -169,8 +169,8 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
await app.client.evaluate(async (cli, aliceBotCredentials) => {
|
||||
const deviceStatus = await cli
|
||||
.getCrypto()!
|
||||
.getDeviceVerificationStatus(aliceBotCredentials.userId, aliceBotCredentials.deviceId);
|
||||
if (!deviceStatus.isVerified()) {
|
||||
.getDeviceVerificationStatus(aliceBotCredentials!.userId, aliceBotCredentials!.deviceId);
|
||||
if (!deviceStatus!.isVerified()) {
|
||||
throw new Error("Bot device was not verified after QR code verification");
|
||||
}
|
||||
}, aliceBotClient.credentials);
|
||||
@@ -193,14 +193,14 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
);
|
||||
|
||||
test("Verify device with Recovery Key during login", async ({ page, app, credentials, homeserver }) => {
|
||||
const recoveryKey = (await aliceBotClient.getRecoveryKey()).encodedPrivateKey;
|
||||
const recoveryKey = (await aliceBotClient.getRecoveryKey()).encodedPrivateKey!;
|
||||
|
||||
await logIntoElement(page, credentials);
|
||||
await enterRecoveryKeyAndCheckVerified(page, app, recoveryKey);
|
||||
});
|
||||
|
||||
test("Verify device with Recovery Key from settings", async ({ page, app, credentials }) => {
|
||||
const recoveryKey = (await aliceBotClient.getRecoveryKey()).encodedPrivateKey;
|
||||
const recoveryKey = (await aliceBotClient.getRecoveryKey()).encodedPrivateKey!;
|
||||
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
@@ -277,7 +277,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
await authPage.getByRole("button", { name: "I'll verify later" }).click();
|
||||
|
||||
await page.waitForSelector(".mx_MatrixChat");
|
||||
const elementDeviceId = await page.evaluate(() => window.mxMatrixClientPeg.get().getDeviceId());
|
||||
const elementDeviceId = await page.evaluate(() => window.mxMatrixClientPeg.get().getDeviceId()!);
|
||||
|
||||
/* Create an encrypted room so the "Verify this device" toast appears */
|
||||
await app.client.createRoom({
|
||||
@@ -301,7 +301,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
/* Check the toast for the incoming request */
|
||||
const toast = await getToast(page, "Verification requested");
|
||||
// it should contain the device ID of the requesting device
|
||||
await expect(toast.getByText(`${aliceBotClient.credentials.deviceId} from `)).toBeVisible();
|
||||
await expect(toast.getByText(`${aliceBotClient.credentials!.deviceId} from `)).toBeVisible();
|
||||
// Accept
|
||||
await toast.getByRole("button", { name: "Start verification" }).click();
|
||||
|
||||
@@ -311,7 +311,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
||||
/* on the bot side, wait for the verifier to exist ... */
|
||||
const verifier = await awaitVerifier(botVerificationRequest);
|
||||
// ... confirm ...
|
||||
void botVerificationRequest.evaluate((verificationRequest) => verificationRequest.verifier.verify());
|
||||
void botVerificationRequest.evaluate((verificationRequest) => verificationRequest.verifier!.verify());
|
||||
// ... and then check the emoji match
|
||||
await doTwoWaySasVerification(page, verifier);
|
||||
|
||||
@@ -337,7 +337,7 @@ async function readQrCode(base: Locator) {
|
||||
>(async (img) => {
|
||||
// draw the image on a canvas
|
||||
const myCanvas = new OffscreenCanvas(img.width, img.height);
|
||||
const ctx = myCanvas.getContext("2d");
|
||||
const ctx = myCanvas.getContext("2d")!;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// read the image data
|
||||
@@ -352,5 +352,5 @@ async function readQrCode(base: Locator) {
|
||||
|
||||
// now we can decode the QR code.
|
||||
const result = jsQR(new Uint8ClampedArray(imageData.buffer), imageData.width, imageData.height);
|
||||
return new Uint8Array(result.binaryData);
|
||||
return new Uint8Array(result!.binaryData);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ test.describe("Cryptography", function () {
|
||||
await autoJoin(bob);
|
||||
|
||||
// create an encrypted room, and wait for Bob to join it.
|
||||
testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials.userId);
|
||||
testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials!.userId);
|
||||
|
||||
// Even though Alice has seen Bob's join event, Bob may not have done so yet. Wait for the sync to arrive.
|
||||
await bob.awaitRoomMembership(testRoomId);
|
||||
@@ -128,7 +128,7 @@ test.describe("Cryptography", function () {
|
||||
await bobSecondDevice.evaluate((cli) => cli.logout(true));
|
||||
|
||||
// wait for the logout to propagate.
|
||||
await waitForDevices(app, bob.credentials.userId, 1);
|
||||
await waitForDevices(app, bob.credentials!.userId, 1);
|
||||
|
||||
// close and reopen the room, to get the shield to update.
|
||||
await app.viewRoomByName("Bob");
|
||||
@@ -245,7 +245,7 @@ test.describe("Cryptography", function () {
|
||||
// Workaround for https://github.com/element-hq/element-web/issues/28640:
|
||||
// make sure that Alice has seen Bob's identity before she goes offline. We do this by opening
|
||||
// his user info.
|
||||
await waitForDevices(app, bob.credentials.userId, 1);
|
||||
await waitForDevices(app, bob.credentials!.userId, 1);
|
||||
|
||||
// Our app is blocked from syncing while Bob sends his messages.
|
||||
await app.client.network.goOffline();
|
||||
@@ -286,7 +286,7 @@ test.describe("Cryptography", function () {
|
||||
|
||||
// Bob logs in a new device and resets cross-signing
|
||||
const bobSecondDevice = await createSecondBotDevice(page, homeserver, bob);
|
||||
await bootstrapCrossSigningForClient(await bobSecondDevice.prepareClient(), bob.credentials, true);
|
||||
await bootstrapCrossSigningForClient(await bobSecondDevice.prepareClient(), bob.credentials!, true);
|
||||
|
||||
/* should show an error for a message from a previously verified device */
|
||||
await bobSecondDevice.sendMessage(testRoomId, "test encrypted from user that was previously verified");
|
||||
|
||||
@@ -29,14 +29,14 @@ test.describe("Invisible cryptography", () => {
|
||||
await autoJoin(bob);
|
||||
|
||||
// create an encrypted room
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials.userId);
|
||||
const testRoomId = await createSharedEncryptedRoomWithUser(app, bob.credentials!.userId);
|
||||
|
||||
// Verify Bob
|
||||
await verify(app, bob);
|
||||
|
||||
// Bob logs in a new device and resets cross-signing
|
||||
const bobSecondDevice = await createSecondBotDevice(page, homeserver, bob);
|
||||
await bootstrapCrossSigningForClient(await bobSecondDevice.prepareClient(), bob.credentials, true);
|
||||
await bootstrapCrossSigningForClient(await bobSecondDevice.prepareClient(), bob.credentials!, true);
|
||||
|
||||
/* should show an error for a message from a previously verified device */
|
||||
await bobSecondDevice.sendMessage(testRoomId, "test encrypted from user that was previously verified");
|
||||
|
||||
@@ -41,8 +41,8 @@ test.describe("migration", { tag: "@no-webkit" }, function () {
|
||||
// When the progress bar first loads, it should have a high max (one per megolm session to import), and
|
||||
// a relatively low value.
|
||||
const progressBar = page.getByRole("progressbar");
|
||||
const initialProgress = parseFloat(await progressBar.getAttribute("value"));
|
||||
const initialMax = parseFloat(await progressBar.getAttribute("max"));
|
||||
const initialProgress = parseFloat((await progressBar.getAttribute("value"))!);
|
||||
const initialMax = parseFloat((await progressBar.getAttribute("max"))!);
|
||||
expect(initialMax).toBeGreaterThan(4000);
|
||||
expect(initialProgress).toBeGreaterThanOrEqual(0);
|
||||
expect(initialProgress).toBeLessThanOrEqual(500);
|
||||
@@ -53,8 +53,8 @@ test.describe("migration", { tag: "@no-webkit" }, function () {
|
||||
async () => {
|
||||
const progressBar = page.getByRole("progressbar");
|
||||
return (
|
||||
(parseFloat(await progressBar.getAttribute("value")) * 100.0) /
|
||||
parseFloat(await progressBar.getAttribute("max"))
|
||||
(parseFloat((await progressBar.getAttribute("value"))!) * 100.0) /
|
||||
parseFloat((await progressBar.getAttribute("max"))!)
|
||||
);
|
||||
},
|
||||
{ timeout: 60000 },
|
||||
|
||||
@@ -30,7 +30,7 @@ test.describe("Key storage out of sync toast", () => {
|
||||
recoveryKey = res.recoveryKey;
|
||||
|
||||
await logIntoElement(page, credentials);
|
||||
await verifyAfterLogin(page, recoveryKey.encodedPrivateKey);
|
||||
await verifyAfterLogin(page, recoveryKey.encodedPrivateKey!);
|
||||
|
||||
await deleteCachedSecrets(page);
|
||||
});
|
||||
@@ -43,7 +43,7 @@ test.describe("Key storage out of sync toast", () => {
|
||||
|
||||
await page.getByRole("button", { name: "Enter recovery key" }).click();
|
||||
|
||||
await page.getByRole("textbox", { name: "Recovery Key" }).fill(recoveryKey.encodedPrivateKey);
|
||||
await page.getByRole("textbox", { name: "Recovery Key" }).fill(recoveryKey.encodedPrivateKey!);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
await expect(page.getByRole("button", { name: "Enter recovery key" })).not.toBeVisible();
|
||||
@@ -63,7 +63,7 @@ test.describe("Key storage out of sync toast", () => {
|
||||
});
|
||||
|
||||
test.describe("'Turn on key storage' toast", () => {
|
||||
let botClient: Bot | undefined;
|
||||
let botClient: Bot;
|
||||
|
||||
test.beforeEach(async ({ page, homeserver, credentials }) => {
|
||||
// Set up all crypto stuff. Key storage defaults to on.
|
||||
@@ -73,7 +73,7 @@ test.describe("'Turn on key storage' toast", () => {
|
||||
botClient = res.botClient;
|
||||
|
||||
await logIntoElement(page, credentials);
|
||||
await verifyAfterLogin(page, recoveryKey.encodedPrivateKey);
|
||||
await verifyAfterLogin(page, recoveryKey.encodedPrivateKey!);
|
||||
|
||||
// We won't be prompted for crypto setup unless we have an e2e room, so make one
|
||||
await page
|
||||
|
||||
@@ -39,7 +39,7 @@ test.describe("User verification", () => {
|
||||
user: aliceCredentials,
|
||||
room: { roomId: dmRoomId },
|
||||
}) => {
|
||||
await waitForDevices(app, bob.credentials.userId, 1);
|
||||
await waitForDevices(app, bob.credentials!.userId, 1);
|
||||
await expect(page.getByRole("button", { name: "Avatar" })).toBeVisible();
|
||||
const avatar = page.getByRole("button", { name: "Avatar" });
|
||||
await avatar.click();
|
||||
@@ -47,14 +47,14 @@ test.describe("User verification", () => {
|
||||
// once Alice has joined, Bob starts the verification
|
||||
const bobVerificationRequest = await bob.evaluateHandle(
|
||||
async (client, { dmRoomId, aliceCredentials }) => {
|
||||
const room = client.getRoom(dmRoomId);
|
||||
const room = client.getRoom(dmRoomId)!;
|
||||
while (room.getMember(aliceCredentials.userId)?.membership !== "join") {
|
||||
await new Promise((resolve) => {
|
||||
room.once(window.matrixcs.RoomStateEvent.Members, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
return client.getCrypto().requestVerificationDM(aliceCredentials.userId, dmRoomId);
|
||||
return client.getCrypto()!.requestVerificationDM(aliceCredentials.userId, dmRoomId);
|
||||
},
|
||||
{ dmRoomId, aliceCredentials },
|
||||
);
|
||||
@@ -62,7 +62,7 @@ test.describe("User verification", () => {
|
||||
// there should also be a toast
|
||||
const toast = await getToast(page, "Verification requested");
|
||||
// it should contain the details of the requesting user
|
||||
await expect(toast.getByText(`Bob (${bob.credentials.userId})`)).toBeVisible();
|
||||
await expect(toast.getByText(`Bob (${bob.credentials!.userId})`)).toBeVisible();
|
||||
// Accept
|
||||
await toast.getByRole("button", { name: "Verify User" }).click();
|
||||
|
||||
@@ -93,7 +93,7 @@ test.describe("User verification", () => {
|
||||
user: aliceCredentials,
|
||||
room: { roomId: dmRoomId },
|
||||
}) => {
|
||||
await waitForDevices(app, bob.credentials.userId, 1);
|
||||
await waitForDevices(app, bob.credentials!.userId, 1);
|
||||
await expect(page.getByRole("button", { name: "Avatar" })).toBeVisible();
|
||||
const avatar = page.getByRole("button", { name: "Avatar" });
|
||||
await avatar.click();
|
||||
@@ -101,14 +101,14 @@ test.describe("User verification", () => {
|
||||
// once Alice has joined, Bob starts the verification
|
||||
const bobVerificationRequest = await bob.evaluateHandle(
|
||||
async (client, { dmRoomId, aliceCredentials }) => {
|
||||
const room = client.getRoom(dmRoomId);
|
||||
const room = client.getRoom(dmRoomId)!;
|
||||
while (room.getMember(aliceCredentials.userId)?.membership !== "join") {
|
||||
await new Promise((resolve) => {
|
||||
room.once(window.matrixcs.RoomStateEvent.Members, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
return client.getCrypto().requestVerificationDM(aliceCredentials.userId, dmRoomId);
|
||||
return client.getCrypto()!.requestVerificationDM(aliceCredentials.userId, dmRoomId);
|
||||
},
|
||||
{ dmRoomId, aliceCredentials },
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function createBot(
|
||||
botClient.setCredentials(credentials);
|
||||
// Backup is prepared in the background. Poll until it is ready.
|
||||
const botClientHandle = await botClient.prepareClient();
|
||||
let expectedBackupVersion: string;
|
||||
let expectedBackupVersion: string | null;
|
||||
await expect
|
||||
.poll(async () => {
|
||||
expectedBackupVersion = await botClientHandle.evaluate((cli) =>
|
||||
@@ -63,7 +63,7 @@ export async function createBot(
|
||||
|
||||
const recoveryKey = await botClient.getRecoveryKey();
|
||||
|
||||
return { botClient, recoveryKey, expectedBackupVersion };
|
||||
return { botClient, recoveryKey, expectedBackupVersion: expectedBackupVersion! };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,13 +98,15 @@ export async function waitForVerificationRequest(client: Client): Promise<JSHand
|
||||
export function handleSasVerification(verifier: JSHandle<Verifier>): Promise<EmojiMapping[]> {
|
||||
return verifier.evaluate((verifier) => {
|
||||
const event = verifier.getShowSasCallbacks();
|
||||
if (event) return event.sas.emoji;
|
||||
if (event) {
|
||||
return event.sas.emoji!;
|
||||
}
|
||||
|
||||
return new Promise<EmojiMapping[]>((resolve) => {
|
||||
const onShowSas = (event: ShowSasCallbacks) => {
|
||||
verifier.off("show_sas" as VerifierEvent, onShowSas);
|
||||
void event.confirm();
|
||||
resolve(event.sas.emoji);
|
||||
resolve(event.sas.emoji!);
|
||||
};
|
||||
|
||||
verifier.on("show_sas" as VerifierEvent, onShowSas);
|
||||
@@ -117,24 +119,24 @@ export function handleSasVerification(verifier: JSHandle<Verifier>): Promise<Emo
|
||||
*/
|
||||
export async function checkDeviceIsCrossSigned(app: ElementAppPage): Promise<void> {
|
||||
const { userId, deviceId, keys } = await app.client.evaluate(async (cli: MatrixClient) => {
|
||||
const deviceId = cli.getDeviceId();
|
||||
const userId = cli.getUserId();
|
||||
const deviceId = cli.getDeviceId()!;
|
||||
const userId = cli.getSafeUserId();
|
||||
const keys = await cli.downloadKeysForUsers([userId]);
|
||||
|
||||
return { userId, deviceId, keys };
|
||||
});
|
||||
|
||||
// there should be three cross-signing keys
|
||||
expect(keys.master_keys[userId]).toHaveProperty("keys");
|
||||
expect(keys.self_signing_keys[userId]).toHaveProperty("keys");
|
||||
expect(keys.user_signing_keys[userId]).toHaveProperty("keys");
|
||||
expect(keys.master_keys![userId]).toHaveProperty("keys");
|
||||
expect(keys.self_signing_keys![userId]).toHaveProperty("keys");
|
||||
expect(keys.user_signing_keys![userId]).toHaveProperty("keys");
|
||||
|
||||
// and the device should be signed by the self-signing key
|
||||
const selfSigningKeyId = Object.keys(keys.self_signing_keys[userId].keys)[0];
|
||||
const selfSigningKeyId = Object.keys(keys.self_signing_keys![userId].keys)[0];
|
||||
|
||||
expect(keys.device_keys[userId][deviceId]).toBeDefined();
|
||||
|
||||
const myDeviceSignatures = keys.device_keys[userId][deviceId].signatures[userId];
|
||||
const myDeviceSignatures = keys.device_keys[userId][deviceId].signatures![userId];
|
||||
expect(myDeviceSignatures[selfSigningKeyId]).toBeDefined();
|
||||
}
|
||||
|
||||
@@ -190,7 +192,7 @@ export async function checkDeviceIsConnectedKeyBackup(
|
||||
// We have a key backup
|
||||
expect(backupInfo).toBeDefined();
|
||||
// The key backup version is as expected
|
||||
expect(backupInfo.version).toBe(expectedBackupVersion);
|
||||
expect(backupInfo!.version).toBe(expectedBackupVersion);
|
||||
// The active backup version is as expected
|
||||
expect(activeBackupVersion).toBe(expectedBackupVersion);
|
||||
// The backup key is stored in 4S
|
||||
@@ -211,7 +213,7 @@ export async function logIntoElement(page: Page, credentials: Credentials) {
|
||||
await page.goto("/#/login");
|
||||
|
||||
await page.getByRole("textbox", { name: "Username" }).fill(credentials.userId);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password!);
|
||||
await page.getByRole("button", { name: "Sign in" }).click();
|
||||
}
|
||||
|
||||
@@ -379,7 +381,7 @@ export async function completeCreateSecretStorageDialog(
|
||||
// the step is quite quick, and playwright can miss it, so we can't test for it.
|
||||
if (opts && Object.hasOwn(opts, "accountPassword")) {
|
||||
await expect(currentDialogLocator.getByRole("heading", { name: "Setting up keys" })).toBeVisible();
|
||||
await page.getByPlaceholder("Password").fill(opts!.accountPassword);
|
||||
await page.getByPlaceholder("Password").fill(opts!.accountPassword!);
|
||||
await currentDialogLocator.getByRole("button", { name: "Continue" }).click();
|
||||
}
|
||||
|
||||
@@ -595,7 +597,7 @@ export async function createSecondBotDevice(page: Page, homeserver: HomeserverIn
|
||||
bootstrapSecretStorage: false,
|
||||
bootstrapCrossSigning: false,
|
||||
});
|
||||
bobSecondDevice.setCredentials(await homeserver.loginUser(bob.credentials.userId, bob.credentials.password));
|
||||
bobSecondDevice.setCredentials(await homeserver.loginUser(bob.credentials!.userId, bob.credentials!.password!));
|
||||
await bobSecondDevice.prepareClient();
|
||||
return bobSecondDevice;
|
||||
}
|
||||
@@ -638,7 +640,7 @@ export async function waitForDevices(
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
const userDeviceMap = await cli.getCrypto()?.getUserDeviceInfo([userId], true);
|
||||
const deviceMap = userDeviceMap?.get(userId);
|
||||
if (deviceMap.size === expectedNumberOfDevices) return true;
|
||||
if (deviceMap?.size === expectedNumberOfDevices) return true;
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -362,7 +362,7 @@ test.describe("Editing", () => {
|
||||
const messageTile = page.locator(`[data-event-id="${originalEventId}"]`);
|
||||
// at this point, the edit event should still be unknown
|
||||
const timeline = await app.client.evaluate(
|
||||
(cli, { testRoomId, editEventId }) => cli.getRoom(testRoomId).getTimelineForEvent(editEventId),
|
||||
(cli, { testRoomId, editEventId }) => cli.getRoom(testRoomId)!.getTimelineForEvent(editEventId),
|
||||
{ testRoomId, editEventId },
|
||||
);
|
||||
expect(timeline).toBeNull();
|
||||
|
||||
@@ -94,7 +94,7 @@ test.describe("Rageshakes", () => {
|
||||
if (request.method() !== "POST") {
|
||||
throw Error("Expected POST");
|
||||
}
|
||||
const fields = formDataParser(request.postData(), await request.headerValue("Content-Type"));
|
||||
const fields = formDataParser(request.postData()!, await request.headerValue("Content-Type"));
|
||||
expect(fields.text).toEqual(
|
||||
"These are some notes\n\nIssue: https://github.com/element-hq/element-web/12345",
|
||||
);
|
||||
|
||||
@@ -56,7 +56,7 @@ test.describe("Forgot Password", () => {
|
||||
"renders email verification dialog properly",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, homeserver, credentials }) => {
|
||||
const user = await homeserver.registerUser(credentials.username, credentials.password);
|
||||
const user = await homeserver.registerUser(credentials.username, credentials.password!);
|
||||
|
||||
await homeserver.setThreepid(user.userId, "email", email);
|
||||
|
||||
@@ -73,8 +73,8 @@ test.describe("Forgot Password", () => {
|
||||
|
||||
await page.getByRole("button", { name: "Next" }).click();
|
||||
|
||||
await page.getByRole("textbox", { name: "New Password", exact: true }).fill(credentials.password);
|
||||
await page.getByRole("textbox", { name: "Confirm new password", exact: true }).fill(credentials.password);
|
||||
await page.getByRole("textbox", { name: "New Password", exact: true }).fill(credentials.password!);
|
||||
await page.getByRole("textbox", { name: "Confirm new password", exact: true }).fill(credentials.password!);
|
||||
|
||||
await page.getByRole("button", { name: "Reset password" }).click();
|
||||
|
||||
|
||||
@@ -148,18 +148,23 @@ test.describe("Integration Manager: Kick", () => {
|
||||
|
||||
test("should kick the target", async ({ page, app, bot: targetUser, room }) => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials!.userId);
|
||||
await expect(page.getByText(`${BOT_DISPLAY_NAME} joined the room`)).toBeVisible();
|
||||
|
||||
await openIntegrationManager(app);
|
||||
await sendActionFromIntegrationManager(page, integrationManagerUrl, room.roomId, targetUser.credentials.userId);
|
||||
await sendActionFromIntegrationManager(
|
||||
page,
|
||||
integrationManagerUrl,
|
||||
room.roomId,
|
||||
targetUser.credentials!.userId,
|
||||
);
|
||||
await closeIntegrationManager(page, integrationManagerUrl);
|
||||
await expectKickedMessage(page, true);
|
||||
});
|
||||
|
||||
test("should not kick the target if lacking permissions", async ({ page, app, user, bot: targetUser, room }) => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials!.userId);
|
||||
await expect(page.getByText(`${BOT_DISPLAY_NAME} joined the room`)).toBeVisible();
|
||||
|
||||
await app.client.sendStateEvent(room.roomId, "m.room.power_levels", {
|
||||
@@ -170,31 +175,46 @@ test.describe("Integration Manager: Kick", () => {
|
||||
});
|
||||
|
||||
await openIntegrationManager(app);
|
||||
await sendActionFromIntegrationManager(page, integrationManagerUrl, room.roomId, targetUser.credentials.userId);
|
||||
await sendActionFromIntegrationManager(
|
||||
page,
|
||||
integrationManagerUrl,
|
||||
room.roomId,
|
||||
targetUser.credentials!.userId,
|
||||
);
|
||||
await closeIntegrationManager(page, integrationManagerUrl);
|
||||
await expectKickedMessage(page, false);
|
||||
});
|
||||
|
||||
test("should no-op if the target already left", async ({ page, app, bot: targetUser, room }) => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials!.userId);
|
||||
await expect(page.getByText(`${BOT_DISPLAY_NAME} joined the room`)).toBeVisible();
|
||||
await targetUser.leave(room.roomId);
|
||||
|
||||
await openIntegrationManager(app);
|
||||
await sendActionFromIntegrationManager(page, integrationManagerUrl, room.roomId, targetUser.credentials.userId);
|
||||
await sendActionFromIntegrationManager(
|
||||
page,
|
||||
integrationManagerUrl,
|
||||
room.roomId,
|
||||
targetUser.credentials!.userId,
|
||||
);
|
||||
await closeIntegrationManager(page, integrationManagerUrl);
|
||||
await expectKickedMessage(page, false);
|
||||
});
|
||||
|
||||
test("should no-op if the target was banned", async ({ page, app, bot: targetUser, room }) => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, targetUser.credentials!.userId);
|
||||
await expect(page.getByText(`${BOT_DISPLAY_NAME} joined the room`)).toBeVisible();
|
||||
await app.client.ban(room.roomId, targetUser.credentials.userId);
|
||||
await app.client.ban(room.roomId, targetUser.credentials!.userId);
|
||||
|
||||
await openIntegrationManager(app);
|
||||
await sendActionFromIntegrationManager(page, integrationManagerUrl, room.roomId, targetUser.credentials.userId);
|
||||
await sendActionFromIntegrationManager(
|
||||
page,
|
||||
integrationManagerUrl,
|
||||
room.roomId,
|
||||
targetUser.credentials!.userId,
|
||||
);
|
||||
await closeIntegrationManager(page, integrationManagerUrl);
|
||||
await expectKickedMessage(page, false);
|
||||
});
|
||||
@@ -203,7 +223,12 @@ test.describe("Integration Manager: Kick", () => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
|
||||
await openIntegrationManager(app);
|
||||
await sendActionFromIntegrationManager(page, integrationManagerUrl, room.roomId, targetUser.credentials.userId);
|
||||
await sendActionFromIntegrationManager(
|
||||
page,
|
||||
integrationManagerUrl,
|
||||
room.roomId,
|
||||
targetUser.credentials!.userId,
|
||||
);
|
||||
await closeIntegrationManager(page, integrationManagerUrl);
|
||||
await expectKickedMessage(page, false);
|
||||
});
|
||||
|
||||
@@ -55,13 +55,13 @@ test.describe("Invite dialog", function () {
|
||||
|
||||
await expect(other.locator(".mx_InviteDialog_identityServer")).not.toBeVisible();
|
||||
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId);
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials!.userId);
|
||||
|
||||
// Assert that notification about identity servers appears after typing userId
|
||||
await expect(other.locator(".mx_InviteDialog_identityServer")).toBeVisible();
|
||||
|
||||
// Assert that the bot id is rendered properly
|
||||
await expect(other.getByRole("option", { name: botName }).getByText(bot.credentials.userId)).toBeVisible();
|
||||
await expect(other.getByRole("option", { name: botName }).getByText(bot.credentials!.userId)).toBeVisible();
|
||||
|
||||
await other.getByRole("option", { name: botName }).click();
|
||||
|
||||
@@ -112,9 +112,9 @@ test.describe("Invite dialog", function () {
|
||||
// Take a snapshot of the invite dialog
|
||||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("invite-dialog-dm-without-user.png");
|
||||
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId);
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials!.userId);
|
||||
|
||||
await expect(other.getByRole("option", { name: botName }).getByText(bot.credentials.userId)).toBeVisible();
|
||||
await expect(other.getByRole("option", { name: botName }).getByText(bot.credentials!.userId)).toBeVisible();
|
||||
await other.getByRole("option", { name: botName }).click();
|
||||
|
||||
await expect(other.getByTestId("invite-dialog-input-wrapper").getByText(botName)).toBeVisible();
|
||||
|
||||
@@ -80,8 +80,12 @@ test.describe("Lazy Loading", () => {
|
||||
async function checkPaginatedDisplayNames(app: ElementAppPage, charlies: Bot[]) {
|
||||
await app.timeline.scrollToTop();
|
||||
for (const charly of charlies) {
|
||||
await expect(await app.timeline.findEventTile(charly.credentials.displayName, charlyMsg1)).toBeAttached();
|
||||
await expect(await app.timeline.findEventTile(charly.credentials.displayName, charlyMsg2)).toBeAttached();
|
||||
await expect(
|
||||
(await app.timeline.findEventTile(charly.credentials!.displayName!, charlyMsg1))!,
|
||||
).toBeAttached();
|
||||
await expect(
|
||||
(await app.timeline.findEventTile(charly.credentials!.displayName!, charlyMsg2))!,
|
||||
).toBeAttached();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,13 +103,13 @@ test.describe("Lazy Loading", () => {
|
||||
await expect(getMemberInMemberlist(page, "Alice")).toBeAttached();
|
||||
await expect(getMemberInMemberlist(page, "Bob")).toBeAttached();
|
||||
for (const charly of charlies) {
|
||||
await expect(getMemberInMemberlist(page, charly.credentials.displayName)).toBeAttached();
|
||||
await expect(getMemberInMemberlist(page, charly.credentials!.displayName!)).toBeAttached();
|
||||
}
|
||||
}
|
||||
|
||||
async function checkMemberListLacksCharlies(page: Page, charlies: Bot[]) {
|
||||
for (const charly of charlies) {
|
||||
await expect(getMemberInMemberlist(page, charly.credentials.displayName)).not.toBeAttached();
|
||||
await expect(getMemberInMemberlist(page, charly.credentials!.displayName!)).not.toBeAttached();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ test.describe("Collapsible Room list", () => {
|
||||
const boundingBox = await leftPanelLocator.boundingBox();
|
||||
|
||||
// Move mouse 2px to the right of the left-panel, this should be region that the user drags to resize the panel.
|
||||
const mouseX = boundingBox.x + boundingBox.width + 2;
|
||||
const mouseY = boundingBox.y + boundingBox.height / 2;
|
||||
const mouseX = boundingBox!.x + boundingBox!.width + 2;
|
||||
const mouseY = boundingBox!.y + boundingBox!.height / 2;
|
||||
|
||||
await page.mouse.move(mouseX, mouseY);
|
||||
await page.mouse.down();
|
||||
@@ -50,12 +50,12 @@ test.describe("Collapsible Room list", () => {
|
||||
// Contract the panel
|
||||
let previousBoundingBox = await resize(page, -50);
|
||||
let currentBoundingBox = await leftPanelLocator.boundingBox();
|
||||
expect(currentBoundingBox.width).toBeCloseTo(previousBoundingBox.width - 50, 0);
|
||||
expect(currentBoundingBox!.width).toBeCloseTo(previousBoundingBox!.width - 50, 0);
|
||||
|
||||
// Expand the panel
|
||||
previousBoundingBox = await resize(page, 30);
|
||||
currentBoundingBox = await leftPanelLocator.boundingBox();
|
||||
expect(currentBoundingBox.width).toBeCloseTo(previousBoundingBox.width + 30, 0);
|
||||
expect(currentBoundingBox!.width).toBeCloseTo(previousBoundingBox!.width + 30, 0);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -67,7 +67,7 @@ test.describe("Collapsible Room list", () => {
|
||||
// Collapse the panel
|
||||
await resize(page, -300);
|
||||
let currentBoundingBox = await leftPanelLocator.boundingBox();
|
||||
expect(currentBoundingBox.width).toStrictEqual(0);
|
||||
expect(currentBoundingBox!.width).toStrictEqual(0);
|
||||
|
||||
// Expect te separator to be shown
|
||||
const separator = page.getByRole("separator", { name: "Click or drag to expand" });
|
||||
@@ -77,19 +77,19 @@ test.describe("Collapsible Room list", () => {
|
||||
// Should be possible to expand by clicking on the separator
|
||||
await separator.click();
|
||||
currentBoundingBox = await leftPanelLocator.boundingBox();
|
||||
expect(currentBoundingBox.width).toBeGreaterThan(365);
|
||||
expect(currentBoundingBox!.width).toBeGreaterThan(365);
|
||||
|
||||
// Collapse the panel again
|
||||
await resize(page, -300);
|
||||
|
||||
// Check that the panel can be expanded by dragging the separator
|
||||
const separatorBoundingBox = await separator.boundingBox();
|
||||
const mouseX = separatorBoundingBox.x + separatorBoundingBox.width / 2;
|
||||
const mouseY = separatorBoundingBox.y + separatorBoundingBox.height / 2;
|
||||
const mouseX = separatorBoundingBox!.x + separatorBoundingBox!.width / 2;
|
||||
const mouseY = separatorBoundingBox!.y + separatorBoundingBox!.height / 2;
|
||||
await page.mouse.move(mouseX, mouseY);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(mouseX + 400, mouseY);
|
||||
expect(currentBoundingBox.width).toBeGreaterThan(365);
|
||||
expect(currentBoundingBox!.width).toBeGreaterThan(365);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -48,7 +48,7 @@ test.describe("Room list filters and sort", () => {
|
||||
We will also send a simple message in this room.
|
||||
*/
|
||||
const oldRoomId = await app.client.createRoom({ name: "Old Room" });
|
||||
await app.client.inviteUser(oldRoomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(oldRoomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(oldRoomId);
|
||||
const response = await app.client.sendMessage(oldRoomId, "Hello!");
|
||||
|
||||
@@ -99,8 +99,8 @@ test.describe("Room list filters and sort", () => {
|
||||
});
|
||||
|
||||
test.describe("Room list", () => {
|
||||
let unReadDmId: string | undefined;
|
||||
let unReadRoomId: string | undefined;
|
||||
let unReadDmId: string;
|
||||
let unReadRoomId: string;
|
||||
|
||||
test.beforeEach(async ({ page, app, bot, user }) => {
|
||||
await app.client.createRoom({ name: "empty room" });
|
||||
@@ -114,7 +114,7 @@ test.describe("Room list filters and sort", () => {
|
||||
await bot.sendMessage(unReadDmId, "I am a robot. Beep.");
|
||||
|
||||
unReadRoomId = await app.client.createRoom({ name: "unread room" });
|
||||
await app.client.inviteUser(unReadRoomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(unReadRoomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(unReadRoomId);
|
||||
await bot.sendMessage(unReadRoomId, "I am a robot. Beep.");
|
||||
|
||||
@@ -135,7 +135,7 @@ test.describe("Room list filters and sort", () => {
|
||||
});
|
||||
|
||||
const mentionRoomId = await app.client.createRoom({ name: "room with mention" });
|
||||
await app.client.inviteUser(mentionRoomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(mentionRoomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(mentionRoomId);
|
||||
|
||||
const clientBot = await bot.prepareClient();
|
||||
|
||||
@@ -364,7 +364,7 @@ test.describe("Room list sections", () => {
|
||||
const roomList = getRoomList(page);
|
||||
|
||||
// Invite the bot and have it send a message to generate an unread
|
||||
await app.client.inviteUser(favouriteId, bot.credentials.userId);
|
||||
await app.client.inviteUser(favouriteId, bot.credentials!.userId);
|
||||
await bot.joinRoom(favouriteId);
|
||||
await bot.sendMessage(favouriteId, "Hello from bot!");
|
||||
|
||||
@@ -391,7 +391,7 @@ test.describe("Room list sections", () => {
|
||||
|
||||
// A room with a mention, landing in the Chats section
|
||||
const mentionId = await app.client.createRoom({ name: "mention room" });
|
||||
await app.client.inviteUser(mentionId, bot.credentials.userId);
|
||||
await app.client.inviteUser(mentionId, bot.credentials!.userId);
|
||||
await bot.joinRoom(mentionId);
|
||||
const clientBot = await bot.prepareClient();
|
||||
await clientBot.evaluate(
|
||||
@@ -464,13 +464,13 @@ test.describe("Room list sections", () => {
|
||||
await app.client.evaluate(async (client, roomId) => {
|
||||
await client.setRoomTag(roomId, "m.favourite");
|
||||
}, favouriteId);
|
||||
await app.client.inviteUser(favouriteId, bot.credentials.userId);
|
||||
await app.client.inviteUser(favouriteId, bot.credentials!.userId);
|
||||
await bot.joinRoom(favouriteId);
|
||||
await bot.sendMessage(favouriteId, "Hello from favourite!");
|
||||
|
||||
// Create a regular room with unread messages
|
||||
const regularId = await app.client.createRoom({ name: "regular with unread" });
|
||||
await app.client.inviteUser(regularId, bot.credentials.userId);
|
||||
await app.client.inviteUser(regularId, bot.credentials!.userId);
|
||||
await bot.joinRoom(regularId);
|
||||
await bot.sendMessage(regularId, "Hello from regular!");
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ test.describe("Room list unread activity toast", () => {
|
||||
|
||||
// A room with a real notification count, named so it sorts to the very bottom under A-Z.
|
||||
const targetId = await app.client.createRoom({ name: "zzz unread room" });
|
||||
await app.client.inviteUser(targetId, bot.credentials.userId);
|
||||
await app.client.inviteUser(targetId, bot.credentials!.userId);
|
||||
await bot.joinRoom(targetId);
|
||||
|
||||
// Enough filler rooms to push the target well below the visible area.
|
||||
@@ -100,7 +100,7 @@ test.describe("Room list unread activity toast", () => {
|
||||
// The target's unread state will only ever be an activity dot, never a notification count: set it
|
||||
// to "@mentions & keywords" so a plain (non-mention) message produces activity rather than a count.
|
||||
const targetId = await app.client.createRoom({ name: "zzz activity room" });
|
||||
await app.client.inviteUser(targetId, bot.credentials.userId);
|
||||
await app.client.inviteUser(targetId, bot.credentials!.userId);
|
||||
await bot.joinRoom(targetId);
|
||||
|
||||
await app.viewRoomById(targetId);
|
||||
@@ -148,7 +148,7 @@ test.describe("Room list unread activity toast", () => {
|
||||
|
||||
// A regular (Chats) room with a notification count.
|
||||
const notifyId = await app.client.createRoom({ name: "chats notify room" });
|
||||
await app.client.inviteUser(notifyId, bot.credentials.userId);
|
||||
await app.client.inviteUser(notifyId, bot.credentials!.userId);
|
||||
await bot.joinRoom(notifyId);
|
||||
|
||||
// A favourite room so the list renders in section mode from the start.
|
||||
|
||||
@@ -192,7 +192,7 @@ test.describe("Room list", () => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "1 notification" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot.sendMessage(roomId, "I am a robot. Beep.");
|
||||
|
||||
@@ -396,7 +396,7 @@ test.describe("Room list", () => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "2 notifications" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
await bot.sendMessage(roomId, "I am a robot. Beep.");
|
||||
@@ -412,7 +412,7 @@ test.describe("Room list", () => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "mention" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
const clientBot = await bot.prepareClient();
|
||||
@@ -445,7 +445,7 @@ test.describe("Room list", () => {
|
||||
// focus the user menu to avoid to have hover decoration
|
||||
await page.getByRole("button", { name: "User menu" }).focus();
|
||||
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot.sendMessage(roomId, "I am a robot. Beep.");
|
||||
|
||||
@@ -483,7 +483,7 @@ test.describe("Room list", () => {
|
||||
const otherRoomId = await app.client.createRoom({ name: "other room" });
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "activity" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
await app.viewRoomById(roomId);
|
||||
@@ -510,7 +510,7 @@ test.describe("Room list", () => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "mark as unread" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
const room = roomListView.getByRole("option", { name: "mark as unread" });
|
||||
@@ -527,7 +527,7 @@ test.describe("Room list", () => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "silent" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
await app.viewRoomById(roomId);
|
||||
|
||||
@@ -38,8 +38,8 @@ test.describe("permalinks", () => {
|
||||
|
||||
await app.viewRoomByName(room1Name);
|
||||
|
||||
await app.client.inviteUser(room1Id, bob.credentials.userId);
|
||||
await app.client.inviteUser(room2Id, charlotte.credentials.userId);
|
||||
await app.client.inviteUser(room1Id, bob.credentials!.userId);
|
||||
await app.client.inviteUser(room2Id, charlotte.credentials!.userId);
|
||||
|
||||
await app.client.sendMessage(room1Id, "At room mention: @room");
|
||||
|
||||
@@ -65,11 +65,11 @@ test.describe("permalinks", () => {
|
||||
|
||||
await app.client.sendMessage(
|
||||
room1Id,
|
||||
`Permalink to a user in the room: ${permalinkPrefix}${bob.credentials.userId}`,
|
||||
`Permalink to a user in the room: ${permalinkPrefix}${bob.credentials!.userId}`,
|
||||
);
|
||||
await app.client.sendMessage(
|
||||
room1Id,
|
||||
`Permalink to a user in another room: ${permalinkPrefix}${charlotte.credentials.userId}`,
|
||||
`Permalink to a user in another room: ${permalinkPrefix}${charlotte.credentials!.userId}`,
|
||||
);
|
||||
await app.client.sendMessage(
|
||||
room1Id,
|
||||
@@ -117,14 +117,14 @@ test.describe("triple-click message selection", () => {
|
||||
await bot.prepareClient();
|
||||
|
||||
const roomId = await app.client.createRoom({ name: "Test Room" });
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await app.viewRoomByName("Test Room");
|
||||
|
||||
// Send a message with user and room pills
|
||||
await app.client.sendMessage(
|
||||
roomId,
|
||||
`Testing triple-click message selection. ` +
|
||||
`User: ${permalinkPrefix}${bot.credentials.userId}, ` +
|
||||
`User: ${permalinkPrefix}${bot.credentials!.userId}, ` +
|
||||
`Room: ${permalinkPrefix}${roomId}, ` +
|
||||
`Message: ${permalinkPrefix}${roomId}/$dummy-event, ` +
|
||||
`and @room mention.`,
|
||||
|
||||
@@ -75,7 +75,7 @@ async function login(page: Page, homeserver: HomeserverInstance, credentials: Cr
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await page.getByRole("textbox", { name: "Username" }).fill(credentials.username);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password!);
|
||||
await page.getByRole("button", { name: "Sign in" }).click();
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ test.describe("Login", () => {
|
||||
await expect(axe).toHaveNoViolations();
|
||||
|
||||
await page.getByRole("textbox", { name: "Username" }).fill(credentials.username);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password!);
|
||||
await page.getByRole("button", { name: "Sign in" }).click();
|
||||
|
||||
await expect(page).toHaveURL(/\/#\/home$/);
|
||||
@@ -323,7 +323,7 @@ test.describe("Login", () => {
|
||||
|
||||
// Finally we actually continue
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password!);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
// We end up at the Home screen
|
||||
@@ -336,7 +336,7 @@ test.describe("Login", () => {
|
||||
test.describe("logout", () => {
|
||||
test("should go to welcome page on logout", async ({ page, user }) => {
|
||||
await page.getByRole("button", { name: "User menu" }).click();
|
||||
await expect(page.getByText(user.displayName, { exact: true })).toBeVisible();
|
||||
await expect(page.getByText(user.displayName!, { exact: true })).toBeVisible();
|
||||
|
||||
// Allow the outstanding requests queue to settle before logging out
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
@@ -24,7 +24,7 @@ test.use({
|
||||
test.describe("logout with logout_redirect_url", () => {
|
||||
test("should respect logout_redirect_url", async ({ page, user }) => {
|
||||
await page.getByRole("button", { name: "User menu" }).click();
|
||||
await expect(page.getByText(user.displayName, { exact: true })).toBeVisible();
|
||||
await expect(page.getByText(user.displayName!, { exact: true })).toBeVisible();
|
||||
|
||||
// give a change for the outstanding requests queue to settle before logging out
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
@@ -26,7 +26,7 @@ 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").fill(user.password!);
|
||||
await page.getByPlaceholder("Password").press("Enter");
|
||||
|
||||
// back to the welcome page
|
||||
|
||||
@@ -52,13 +52,13 @@ export async function doTokenRegistration(
|
||||
|
||||
return page.evaluate(() => ({
|
||||
homeserverBaseUrl: window.mxMatrixClientPeg.get().getHomeserverUrl(),
|
||||
accessToken: window.mxMatrixClientPeg.get().getAccessToken(),
|
||||
userId: window.mxMatrixClientPeg.get().getUserId(),
|
||||
deviceId: window.mxMatrixClientPeg.get().getDeviceId(),
|
||||
accessToken: window.mxMatrixClientPeg.get().getAccessToken()!,
|
||||
userId: window.mxMatrixClientPeg.get().getSafeUserId(),
|
||||
deviceId: window.mxMatrixClientPeg.get().getDeviceId()!,
|
||||
homeServer: window.mxMatrixClientPeg.get().getHomeserverUrl(),
|
||||
password: null,
|
||||
displayName: "Alice",
|
||||
username: window.mxMatrixClientPeg.get().getUserIdLocalpart(),
|
||||
username: window.mxMatrixClientPeg.get().getUserIdLocalpart()!,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ export async function registerAccountMas(
|
||||
await page.getByRole("textbox", { name: "Confirm Password" }).fill(password);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
let code: string;
|
||||
let code!: string;
|
||||
await expect(async () => {
|
||||
const messages = await mailpit.listMessages();
|
||||
expect(messages.messages[0].To[0].Address).toEqual(email);
|
||||
const text = await mailpit.renderMessageText(messages.messages[0].ID);
|
||||
[, code] = text.match(/Your verification code to confirm this email address is: (\d{6})/);
|
||||
[, code] = text.match(/Your verification code to confirm this email address is: (\d{6})/)!;
|
||||
}).toPass();
|
||||
|
||||
await page.getByRole("textbox", { name: "6-digit code" }).fill(code);
|
||||
|
||||
@@ -29,7 +29,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
}, testInfo) => {
|
||||
await page.clock.install();
|
||||
|
||||
const tokenUri = `${mas.baseUrl}/oauth2/token`;
|
||||
const tokenUri = `${mas!.baseUrl}/oauth2/token`;
|
||||
const tokenApiPromise = page.waitForRequest(
|
||||
(request) => request.url() === tokenUri && request.postDataJSON()["grant_type"] === "authorization_code",
|
||||
);
|
||||
@@ -66,7 +66,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await newPage.close();
|
||||
|
||||
// Assert logging out revokes both tokens
|
||||
const revokeUri = `${mas.baseUrl}/oauth2/revoke`;
|
||||
const revokeUri = `${mas!.baseUrl}/oauth2/revoke`;
|
||||
const revokeAccessTokenPromise = page.waitForRequest(
|
||||
(request) => request.url() === revokeUri && request.postDataJSON()["token_type_hint"] === "access_token",
|
||||
);
|
||||
@@ -95,7 +95,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await expect(page.getByText("Welcome")).toBeVisible();
|
||||
await page.goto("about:blank");
|
||||
|
||||
const result = await mas.manage("kill-sessions", userId);
|
||||
const result = await mas!.manage("kill-sessions", userId);
|
||||
expect(result.output).toContain("Ended 1 active OAuth 2.0 session");
|
||||
|
||||
await page.goto("http://localhost:8080");
|
||||
|
||||
@@ -12,7 +12,7 @@ import { type Credentials } from "../../plugins/homeserver";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
const test = base.extend<{
|
||||
user2?: Credentials;
|
||||
user2: Credentials;
|
||||
}>({});
|
||||
|
||||
test.describe("1:1 chat room", () => {
|
||||
@@ -38,12 +38,12 @@ test.describe("1:1 chat room", () => {
|
||||
|
||||
// wait till the room was left
|
||||
await expect(
|
||||
page.getByRole("group", { name: "Rooms" }).locator(".mx_RoomTile").getByText(user2.displayName),
|
||||
page.getByRole("group", { name: "Rooms" }).locator(".mx_RoomTile").getByText(user2.displayName!),
|
||||
).not.toBeVisible();
|
||||
await page.waitForTimeout(500); // avoid race condition with routing
|
||||
|
||||
// open new 1:1 chat room
|
||||
await page.goto(`/#/user/${user2.userId}?action=chat`);
|
||||
await expect(page.locator(".mx_RoomHeader_heading").getByText(user2.displayName)).toBeVisible();
|
||||
await expect(page.locator(".mx_RoomHeader_heading").getByText(user2.displayName!)).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ type RoomRef = { name: string; roomId: string };
|
||||
* Set up for pinned message tests.
|
||||
*/
|
||||
export const test = base.extend<{
|
||||
room1Name?: string;
|
||||
room1Name: string;
|
||||
room1: { name: string; roomId: string };
|
||||
util: Helpers;
|
||||
}>({
|
||||
@@ -28,7 +28,7 @@ export const test = base.extend<{
|
||||
|
||||
room1Name: "Room 1",
|
||||
room1: async ({ room1Name: name, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials.userId] });
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
await use({ name, roomId });
|
||||
},
|
||||
|
||||
@@ -95,7 +95,7 @@ test.describe("Poll history", () => {
|
||||
|
||||
const roomId = await app.client.createRoom({});
|
||||
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
// wait until Bob joined
|
||||
await expect(page.getByText("BotBob joined the room")).toBeAttached();
|
||||
|
||||
@@ -98,7 +98,7 @@ test.describe("Polls", () => {
|
||||
|
||||
test("should be creatable and votable", { tag: "@screenshot" }, async ({ page, app, bot, user }) => {
|
||||
const roomId: string = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
// wait until Bob joined
|
||||
await expect(page.getByText("BotBob joined the room")).toBeAttached();
|
||||
@@ -116,10 +116,10 @@ test.describe("Polls", () => {
|
||||
await createPoll(page, pollParams);
|
||||
|
||||
// Wait for message to send, get its ID and save as @pollId
|
||||
const pollId = await page
|
||||
const pollId = (await page
|
||||
.locator(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]")
|
||||
.filter({ hasText: pollParams.title })
|
||||
.getAttribute("data-scroll-tokens");
|
||||
.getAttribute("data-scroll-tokens"))!;
|
||||
await expect(getPollTile(page, pollId)).toMatchScreenshot("Polls_Timeline_tile_no_votes.png", {
|
||||
css: `
|
||||
.mx_MessageTimestamp {
|
||||
@@ -162,7 +162,7 @@ test.describe("Polls", () => {
|
||||
|
||||
test("should be editable from context menu if no votes have been cast", async ({ page, app, user, bot }) => {
|
||||
const roomId: string = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
const locator = await app.openMessageComposerOptions();
|
||||
@@ -175,10 +175,10 @@ test.describe("Polls", () => {
|
||||
await createPoll(page, pollParams);
|
||||
|
||||
// Wait for message to send, get its ID and save as @pollId
|
||||
const pollId = await page
|
||||
const pollId = (await page
|
||||
.locator(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]")
|
||||
.filter({ hasText: pollParams.title })
|
||||
.getAttribute("data-scroll-tokens");
|
||||
.getAttribute("data-scroll-tokens"))!;
|
||||
|
||||
// Open context menu
|
||||
await getPollTile(page, pollId).click({ button: "right" });
|
||||
@@ -192,7 +192,7 @@ test.describe("Polls", () => {
|
||||
|
||||
test("should not be editable from context menu if votes have been cast", async ({ page, app, user, bot }) => {
|
||||
const roomId: string = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
const locator = await app.openMessageComposerOptions();
|
||||
@@ -205,10 +205,10 @@ test.describe("Polls", () => {
|
||||
await createPoll(page, pollParams);
|
||||
|
||||
// Wait for message to send, get its ID and save as @pollId
|
||||
const pollId = await page
|
||||
const pollId = (await page
|
||||
.locator(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]")
|
||||
.filter({ hasText: pollParams.title })
|
||||
.getAttribute("data-scroll-tokens");
|
||||
.getAttribute("data-scroll-tokens"))!;
|
||||
|
||||
// Bot votes 'Maybe' in the poll
|
||||
await botVoteForOption(page, bot, roomId, pollId, pollParams.options[2]);
|
||||
@@ -234,8 +234,8 @@ test.describe("Polls", () => {
|
||||
await botCharlie.prepareClient();
|
||||
|
||||
const roomId: string = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, botCharlie.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, botCharlie.credentials!.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
// wait until the bots joined
|
||||
@@ -253,10 +253,10 @@ test.describe("Polls", () => {
|
||||
await createPoll(page, pollParams);
|
||||
|
||||
// Wait for message to send, get its ID and save as @pollId
|
||||
const pollId = await page
|
||||
const pollId = (await page
|
||||
.locator(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]")
|
||||
.filter({ hasText: pollParams.title })
|
||||
.getAttribute("data-scroll-tokens");
|
||||
.getAttribute("data-scroll-tokens"))!;
|
||||
|
||||
// Bob starts thread on the poll
|
||||
await bot.sendMessage(
|
||||
|
||||
@@ -18,7 +18,7 @@ test.describe("Presence tests", () => {
|
||||
// This is failing on CI (https://github.com/element-hq/element-web/issues/27270)
|
||||
// but not locally, so debugging this is going to be tricky. Let's disable it for now.
|
||||
test.skip("renders unreachable presence state correctly", async ({ page, app, user, bot: bob }) => {
|
||||
await app.client.createRoom({ name: "My Room", invite: [bob.credentials.userId] });
|
||||
await app.client.createRoom({ name: "My Room", invite: [bob.credentials!.userId] });
|
||||
await app.viewRoomByName("My Room");
|
||||
|
||||
await bob.evaluate(async (client) => {
|
||||
@@ -36,7 +36,7 @@ test.describe("Presence tests", () => {
|
||||
events: [
|
||||
{
|
||||
type: "m.presence",
|
||||
sender: bob.credentials.userId,
|
||||
sender: bob.credentials!.userId,
|
||||
content: {
|
||||
presence: "io.element.unreachable",
|
||||
currently_active: false,
|
||||
|
||||
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
/* See readme.md for tips on writing these tests. */
|
||||
|
||||
import { customEvent, many, test } from ".";
|
||||
import { many, test } from ".";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
@@ -20,6 +20,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
roomAlpha: room1,
|
||||
roomBeta: room2,
|
||||
util,
|
||||
msg,
|
||||
}) => {
|
||||
await util.goTo(room1);
|
||||
await util.assertRead(room2);
|
||||
@@ -29,13 +30,14 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.markAsRead(room2);
|
||||
await util.assertRead(room2);
|
||||
|
||||
await util.receiveMessages(room2, [customEvent("org.custom.event", { body: "foobar" })]);
|
||||
await util.receiveMessages(room2, [msg.customEvent("org.custom.event", { body: "foobar" })]);
|
||||
await util.assertRead(room2);
|
||||
});
|
||||
test("Sending an important event after unimportant ones makes the room unread", async ({
|
||||
roomAlpha: room1,
|
||||
roomBeta: room2,
|
||||
util,
|
||||
msg,
|
||||
}) => {
|
||||
// Given We have read the important messages
|
||||
await util.goTo(room1);
|
||||
@@ -47,7 +49,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
await util.goTo(room1);
|
||||
|
||||
// When we receive unimportant messages
|
||||
await util.receiveMessages(room2, [customEvent("org.custom.event", { body: "foobar" })]);
|
||||
await util.receiveMessages(room2, [msg.customEvent("org.custom.event", { body: "foobar" })]);
|
||||
|
||||
// Then the room is still read
|
||||
await util.assertStillRead(room2);
|
||||
@@ -62,6 +64,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
roomAlpha: room1,
|
||||
roomBeta: room2,
|
||||
util,
|
||||
msg,
|
||||
}) => {
|
||||
// Display room 1
|
||||
await util.goTo(room1);
|
||||
@@ -71,9 +74,9 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
|
||||
// We received 3 unimportant messages to room2
|
||||
await util.receiveMessages(room2, [
|
||||
customEvent("org.custom.event", { body: "foobar1" }),
|
||||
customEvent("org.custom.event", { body: "foobar2" }),
|
||||
customEvent("org.custom.event", { body: "foobar3" }),
|
||||
msg.customEvent("org.custom.event", { body: "foobar1" }),
|
||||
msg.customEvent("org.custom.event", { body: "foobar2" }),
|
||||
msg.customEvent("org.custom.event", { body: "foobar3" }),
|
||||
]);
|
||||
|
||||
// The room 2 is still read
|
||||
|
||||
@@ -23,9 +23,9 @@ type RoomRef = { name: string; roomId: string };
|
||||
* - Invite the bot to both rooms and ensure that it has joined
|
||||
*/
|
||||
export const test = base.extend<{
|
||||
roomAlphaName?: string;
|
||||
roomAlphaName: string;
|
||||
roomAlpha: RoomRef;
|
||||
roomBetaName?: string;
|
||||
roomBetaName: string;
|
||||
roomBeta: RoomRef;
|
||||
msg: MessageBuilder;
|
||||
util: Helpers;
|
||||
@@ -35,13 +35,13 @@ export const test = base.extend<{
|
||||
|
||||
roomAlphaName: "Room Alpha",
|
||||
roomAlpha: async ({ roomAlphaName: name, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials.userId] });
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
await use({ name, roomId });
|
||||
},
|
||||
roomBetaName: "Room Beta",
|
||||
roomBeta: async ({ roomBetaName: name, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials.userId] });
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
await use({ name, roomId });
|
||||
},
|
||||
@@ -159,7 +159,7 @@ export class MessageBuilder {
|
||||
ev.getRelation()?.rel_type === "m.thread"
|
||||
? {
|
||||
rel_type: "m.thread",
|
||||
event_id: ev.getRelation().event_id,
|
||||
event_id: ev.getRelation()!.event_id,
|
||||
}
|
||||
: {};
|
||||
|
||||
@@ -222,11 +222,11 @@ export class MessageBuilder {
|
||||
public async performAction(bot: Bot, room: JSHandle<Room>): Promise<void> {
|
||||
const ev = await this.messageFinder.getMessage(room, targetMessage, true);
|
||||
const { id, threadId } = await ev.evaluate((ev) => ({
|
||||
id: ev.getId(),
|
||||
id: ev.getId()!,
|
||||
threadId: !ev.isThreadRoot ? ev.threadRootId : undefined,
|
||||
}));
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
await bot.reactToMessage(roomId, threadId, id, reaction);
|
||||
await bot.reactToMessage(roomId, threadId ?? null, id, reaction);
|
||||
}
|
||||
})(this);
|
||||
}
|
||||
@@ -240,11 +240,11 @@ export class MessageBuilder {
|
||||
public async performAction(bot: Bot, room: JSHandle<Room>): Promise<void> {
|
||||
const ev = await this.messageFinder.getMessage(room, targetMessage, true);
|
||||
const { id, threadId } = await ev.evaluate((ev) => ({
|
||||
id: ev.getId(),
|
||||
id: ev.getId()!,
|
||||
threadId: !ev.isThreadRoot ? ev.threadRootId : undefined,
|
||||
}));
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
await bot.redactEvent(roomId, threadId, id);
|
||||
await bot.redactEvent(roomId, threadId!, id);
|
||||
}
|
||||
})(this);
|
||||
}
|
||||
@@ -286,6 +286,20 @@ export class MessageBuilder {
|
||||
{ event },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* BotActionSpec to send a custom event
|
||||
* @param eventType - the type of the event to send
|
||||
* @param content - the event content to send
|
||||
*/
|
||||
customEvent(eventType: string, content: Record<string, any>): BotActionSpec {
|
||||
return new (class extends BotActionSpec {
|
||||
public async performAction(cli: Client, room: JSHandle<Room>): Promise<void> {
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
await cli.sendEvent(roomId, null, eventType, content);
|
||||
}
|
||||
})(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,11 +309,7 @@ export class MessageBuilder {
|
||||
* MessageBuilder.replyTo} which creates a reply based on a previous message.
|
||||
*/
|
||||
export abstract class MessageContentSpec {
|
||||
messageFinder: MessageBuilder | null;
|
||||
|
||||
constructor(messageFinder: MessageBuilder = null) {
|
||||
this.messageFinder = messageFinder;
|
||||
}
|
||||
constructor(public readonly messageFinder: MessageBuilder) {}
|
||||
|
||||
public abstract getContent(room: JSHandle<Room>): Promise<Record<string, unknown>>;
|
||||
}
|
||||
@@ -312,11 +322,7 @@ export abstract class MessageContentSpec {
|
||||
* MessageBuilder.redactionOf} which redacts the message we are referring to.
|
||||
*/
|
||||
export abstract class BotActionSpec {
|
||||
messageFinder: MessageBuilder | null;
|
||||
|
||||
constructor(messageFinder: MessageBuilder = null) {
|
||||
this.messageFinder = messageFinder;
|
||||
}
|
||||
constructor(public readonly messageFinder: MessageBuilder) {}
|
||||
|
||||
public abstract performAction(client: Client, room: JSHandle<Room>): Promise<void>;
|
||||
}
|
||||
@@ -542,7 +548,7 @@ class Helpers {
|
||||
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomId) => {
|
||||
return cli.getRooms().find((r) => r.roomId === roomId);
|
||||
return cli.getRooms().find((r) => r.roomId === roomId)!;
|
||||
}, roomId);
|
||||
}
|
||||
|
||||
@@ -614,20 +620,6 @@ class Helpers {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BotActionSpec to send a custom event
|
||||
* @param eventType - the type of the event to send
|
||||
* @param content - the event content to send
|
||||
*/
|
||||
export function customEvent(eventType: string, content: Record<string, any>): BotActionSpec {
|
||||
return new (class extends BotActionSpec {
|
||||
public async performAction(cli: Client, room: JSHandle<Room>): Promise<void> {
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
await cli.sendEvent(roomId, null, eventType, content);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate strings with the supplied prefix, suffixed with numbers.
|
||||
*
|
||||
|
||||
@@ -64,7 +64,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
const sendThreadedReadReceipt = async (
|
||||
app: ElementAppPage,
|
||||
eventResponse: ISendEventResponse,
|
||||
threadRootEventResponse: ISendEventResponse = undefined,
|
||||
threadRootEventResponse?: ISendEventResponse,
|
||||
) => {
|
||||
await app.client.sendReadReceipt(
|
||||
await fakeEventFromSent(app, eventResponse, threadRootEventResponse?.event_id),
|
||||
@@ -93,10 +93,10 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
*/
|
||||
selectedRoomId = await app.client.createRoom({ name: selectedRoomName });
|
||||
// Invite the bot to Other room
|
||||
otherRoomId = await app.client.createRoom({ name: otherRoomName, invite: [bot.credentials.userId] });
|
||||
otherRoomId = await app.client.createRoom({ name: otherRoomName, invite: [bot.credentials!.userId] });
|
||||
|
||||
await page.goto(`/#/room/${otherRoomId}`);
|
||||
await expect(page.getByText(`${bot.credentials.displayName} joined the room`)).toBeVisible();
|
||||
await expect(page.getByText(`${bot.credentials!.displayName} joined the room`)).toBeVisible();
|
||||
|
||||
// Then go into Selected room
|
||||
await page.goto(`/#/room/${selectedRoomId}`);
|
||||
@@ -287,7 +287,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
sendMessageResponses.push(await sendMessage(bot, i));
|
||||
}
|
||||
|
||||
const lastMessageId = sendMessageResponses.at(-1).event_id;
|
||||
const lastMessageId = sendMessageResponses.at(-1)!.event_id;
|
||||
const uriEncodedLastMessageId = encodeURIComponent(lastMessageId);
|
||||
|
||||
// wait until all messages have been received
|
||||
@@ -330,7 +330,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
|
||||
const readMarkersRequest2 = await readMarkersRequestPromise2;
|
||||
expect(readMarkersRequest2.postDataJSON()).toEqual({
|
||||
["m.fully_read"]: sendMessageResponses.at(-1).event_id,
|
||||
["m.fully_read"]: sendMessageResponses.at(-1)!.event_id,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
bot,
|
||||
}) => {
|
||||
// Create a third room to navigate to
|
||||
const room3Id = await app.client.createRoom({ name: "Room Gamma", invite: [bot.credentials.userId] });
|
||||
const room3Id = await app.client.createRoom({ name: "Room Gamma", invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(room3Id);
|
||||
const room3 = { name: "Room Gamma", roomId: room3Id };
|
||||
|
||||
@@ -51,7 +51,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
bot,
|
||||
}) => {
|
||||
// Create a third room to navigate to
|
||||
const room3Id = await app.client.createRoom({ name: "Room Gamma", invite: [bot.credentials.userId] });
|
||||
const room3Id = await app.client.createRoom({ name: "Room Gamma", invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(room3Id);
|
||||
const room3 = { name: "Room Gamma", roomId: room3Id };
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ test.describe("Email Registration", async () => {
|
||||
expect(messages.messages).toHaveLength(1);
|
||||
expect(messages.messages[0].To[0].Address).toEqual("alice@email.com");
|
||||
const text = await mailpitClient.renderMessageText(messages.messages[0].ID);
|
||||
const [emailLink] = text.match(/http.+/);
|
||||
const [emailLink] = text.match(/http.+/)!;
|
||||
await request.get(emailLink); // "Click" the link in the email
|
||||
|
||||
await expect(page.getByText("Welcome alice")).toBeVisible();
|
||||
|
||||
@@ -46,7 +46,7 @@ test.describe("global retention rules", () => {
|
||||
test("should apply", async ({ app, bot, page }) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "Test",
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
await checkRetentionInRoom({ app, bot, page }, roomId);
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ test.describe("Retention", () => {
|
||||
test("should apply retention to a bunch of messages", async ({ app, homeserver, page, user, bot }) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "Test",
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
initial_state: [
|
||||
{
|
||||
state_key: "",
|
||||
@@ -66,7 +66,7 @@ test.describe("Retention", () => {
|
||||
test("retention rules should apply after restart", async ({ app, bot, page }) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "Test",
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
await bot.joinRoom(roomId);
|
||||
await app.viewRoomByName("Test");
|
||||
@@ -102,7 +102,7 @@ test.describe("Retention", () => {
|
||||
const currentTime = new Date();
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "Test",
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
initial_state: [
|
||||
{
|
||||
state_key: "",
|
||||
|
||||
@@ -147,7 +147,7 @@ test.describe("RightPanel", () => {
|
||||
async ({ page, homeserver, app }) => {
|
||||
const bobLongName = new Bot(page, homeserver, { displayName: LONG_NAME });
|
||||
await bobLongName.prepareClient();
|
||||
await app.client.inviteUser(testRoomId, bobLongName.credentials.userId);
|
||||
await app.client.inviteUser(testRoomId, bobLongName.credentials!.userId);
|
||||
await bobLongName.joinRoom(testRoomId);
|
||||
|
||||
await viewRoomSummaryByName(page, app, ROOM_NAME);
|
||||
|
||||
@@ -51,7 +51,7 @@ test.describe("Room Directory", () => {
|
||||
|
||||
const resp = await bot.publicRooms({});
|
||||
expect(resp.total_room_count_estimate).toBeGreaterThanOrEqual(1);
|
||||
expect(resp.chunk).toHaveLength(resp.total_room_count_estimate);
|
||||
expect(resp.chunk).toHaveLength(resp.total_room_count_estimate!);
|
||||
expect(resp.chunk.find((r) => r.room_id === roomId)).toBeTruthy();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -68,7 +68,7 @@ test.describe("Invites", () => {
|
||||
await app.settings.openUserSettings("Security & Privacy");
|
||||
const ignoredUsersList = page.getByRole("list", { name: "Ignored users" });
|
||||
await ignoredUsersList.scrollIntoViewIfNeeded();
|
||||
await expect(ignoredUsersList.getByRole("listitem", { name: bot.credentials.userId })).toBeVisible();
|
||||
await expect(ignoredUsersList.getByRole("listitem", { name: bot.credentials!.userId })).toBeVisible();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -161,9 +161,9 @@ test.describe("Room Status Bar", () => {
|
||||
});
|
||||
|
||||
const other = page.locator(".mx_InviteDialog_other");
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId);
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials!.userId);
|
||||
await expect(
|
||||
other.getByRole("option", { name: "Alice" }).getByText(bot.credentials.userId),
|
||||
other.getByRole("option", { name: "Alice" }).getByText(bot.credentials!.userId),
|
||||
).toBeVisible();
|
||||
await other.getByRole("option", { name: "Alice" }).click();
|
||||
await other.getByRole("button", { name: "Go" }).click();
|
||||
|
||||
@@ -34,8 +34,8 @@ test.describe("Room Directory", () => {
|
||||
});
|
||||
},
|
||||
{
|
||||
bob: bob.credentials.userId,
|
||||
charlie: charlie.credentials.userId,
|
||||
bob: bob.credentials!.userId,
|
||||
charlie: charlie.credentials!.userId,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ test.describe("Mark as Unread", () => {
|
||||
const dummyRoomId = await app.client.createRoom({
|
||||
name: "Room of no consequence",
|
||||
});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot.sendMessage(roomId, "I am a robot. Beep.");
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ test.describe("Device manager", () => {
|
||||
test.beforeEach(async ({ homeserver, user }) => {
|
||||
// create 3 extra sessions to manage
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await homeserver.loginUser(user.userId, user.password);
|
||||
await homeserver.loginUser(user.userId, user.password!);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ test.describe("Advanced section in Encryption tab", () => {
|
||||
const section = util.getEncryptionDetailsSection();
|
||||
|
||||
const deviceId = await page.evaluate(() => window.mxMatrixClientPeg.get().getDeviceId());
|
||||
await expect(section.getByText(deviceId)).toBeVisible();
|
||||
await expect(section.getByText(deviceId!)).toBeVisible();
|
||||
|
||||
await expect(section).toMatchScreenshot("encryption-details.png", {
|
||||
mask: [section.getByTestId("deviceId"), section.getByTestId("sessionKey")],
|
||||
@@ -59,7 +59,7 @@ test.describe("Advanced section in Encryption tab", () => {
|
||||
|
||||
// Fill password dialog and validate
|
||||
const dialog = page.locator(".mx_InteractiveAuthDialog");
|
||||
await dialog.getByRole("textbox", { name: "Password" }).fill(credentials.password);
|
||||
await dialog.getByRole("textbox", { name: "Password" }).fill(credentials.password!);
|
||||
await dialog.getByRole("button", { name: "Continue" }).click();
|
||||
|
||||
await expect(section.getByRole("button", { name: "Reset cryptographic identity" })).toBeVisible();
|
||||
|
||||
@@ -26,6 +26,7 @@ test.describe("Encryption tab", () => {
|
||||
test.beforeEach(async ({ page, homeserver, credentials }) => {
|
||||
// The bot bootstraps cross-signing, creates a key backup and sets up a recovery key
|
||||
const botCredentials = { ...credentials };
|
||||
// @ts-expect-error
|
||||
delete botCredentials.accessToken; // use a new login for the bot
|
||||
const res = await createBot(page, homeserver, botCredentials);
|
||||
recoveryKey = res.recoveryKey;
|
||||
@@ -71,7 +72,7 @@ test.describe("Encryption tab", () => {
|
||||
"should prompt to enter the recovery key when the secrets are not cached locally",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey);
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey!);
|
||||
// We need to delete the cached secrets
|
||||
await deleteCachedSecrets(page);
|
||||
|
||||
@@ -104,7 +105,7 @@ test.describe("Encryption tab", () => {
|
||||
app,
|
||||
util,
|
||||
}) => {
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey);
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey!);
|
||||
// We need to delete the cached secrets
|
||||
await deleteCachedSecrets(page);
|
||||
|
||||
@@ -120,7 +121,7 @@ test.describe("Encryption tab", () => {
|
||||
});
|
||||
|
||||
test("should warn before turning off key storage", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey);
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey!);
|
||||
await util.openEncryptionTab();
|
||||
|
||||
await page.getByRole("switch", { name: "Allow key storage" }).click();
|
||||
|
||||
@@ -55,7 +55,7 @@ class Helpers {
|
||||
async enterRecoveryKey(recoveryKey: GeneratedSecretStorageKey) {
|
||||
// Fill the recovery key
|
||||
const dialog = this.page.locator(".mx_Dialog");
|
||||
await dialog.getByRole("textbox").fill(recoveryKey.encodedPrivateKey);
|
||||
await dialog.getByRole("textbox").fill(recoveryKey.encodedPrivateKey!);
|
||||
await dialog.getByRole("button", { name: "Continue" }).click();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ test.describe("Recovery section in Encryption tab", () => {
|
||||
test.beforeEach(async ({ page, homeserver, credentials }) => {
|
||||
// The bot bootstraps cross-signing, creates a key backup and sets up a recovery key
|
||||
const botCredentials = { ...credentials };
|
||||
// @ts-expect-error
|
||||
delete botCredentials.accessToken; // use a new login for the bot
|
||||
const res = await createBot(page, homeserver, botCredentials);
|
||||
recoveryKey = res.recoveryKey;
|
||||
@@ -27,7 +28,7 @@ test.describe("Recovery section in Encryption tab", () => {
|
||||
"should change the recovery key",
|
||||
{ tag: ["@screenshot", "@no-webkit"] },
|
||||
async ({ page, app, homeserver, credentials, util, context }) => {
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey);
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey!);
|
||||
const dialog = await util.openEncryptionTab();
|
||||
|
||||
// The user can only change the recovery key
|
||||
@@ -54,7 +55,7 @@ test.describe("Recovery section in Encryption tab", () => {
|
||||
);
|
||||
|
||||
test("should setup the recovery key", { tag: ["@screenshot", "@no-webkit"] }, async ({ page, app, util }) => {
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey);
|
||||
await verifySession(app, recoveryKey.encodedPrivateKey!);
|
||||
await util.removeSecretStorageDefaultKeyId();
|
||||
|
||||
// The key backup is deleted and the user needs to set it up
|
||||
|
||||
@@ -54,6 +54,6 @@ test.describe("General room settings tab", () => {
|
||||
const dialogBoundingBox = await page.locator(".mx_Dialog").boundingBox();
|
||||
const inputBoundingBox = await settings.locator("#canonicalAlias").boundingBox();
|
||||
// Assert that the width of the select element is less than that of .mx_Dialog div.
|
||||
expect(inputBoundingBox.width).toBeLessThan(dialogBoundingBox.width);
|
||||
expect(inputBoundingBox!.width).toBeLessThan(dialogBoundingBox!.width);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ const test = base.extend<{
|
||||
joinedBot: async ({ app, bot, testRoom }, use) => {
|
||||
const roomId = testRoom.roomId;
|
||||
await bot.prepareClient();
|
||||
const bobUserId = await bot.evaluate((client) => client.getUserId());
|
||||
const bobUserId = await bot.evaluate((client) => client.getSafeUserId());
|
||||
await app.client.evaluate(
|
||||
async (client, { bobUserId, roomId }) => {
|
||||
await client.invite(roomId, bobUserId);
|
||||
@@ -230,7 +230,7 @@ test.describe("Sliding Sync", () => {
|
||||
joinedBot: bot,
|
||||
testRoom,
|
||||
}) => {
|
||||
const clientUserId = await app.client.evaluate((client) => client.getUserId());
|
||||
const clientUserId = await app.client.evaluate((client) => client.getSafeUserId());
|
||||
|
||||
// invite bot into 3 rooms:
|
||||
// - roomJoin: will join this room
|
||||
|
||||
@@ -48,7 +48,7 @@ function spaceChildInitialState(
|
||||
serverName: string,
|
||||
roomId: string,
|
||||
order?: string,
|
||||
): ICreateRoomOpts["initial_state"]["0"] {
|
||||
): NonNullable<ICreateRoomOpts["initial_state"]>[number] {
|
||||
return {
|
||||
type: "m.space.child",
|
||||
state_key: roomId,
|
||||
@@ -240,7 +240,7 @@ test.describe("Spaces", () => {
|
||||
await shareDialog.getByRole("button", { name: "Invite people" }).click();
|
||||
|
||||
const otherSection = page.locator(".mx_InviteDialog_other");
|
||||
await otherSection.getByRole("textbox").fill(bot.credentials.userId);
|
||||
await otherSection.getByRole("textbox").fill(bot.credentials!.userId);
|
||||
await otherSection.getByRole("button", { name: "Invite" }).click();
|
||||
|
||||
await expect(page.locator(".mx_InviteDialog_other")).not.toBeVisible();
|
||||
|
||||
@@ -25,9 +25,9 @@ type RoomRef = { name: string; roomId: string };
|
||||
* - Invite the bot to both rooms and ensure that it has joined
|
||||
*/
|
||||
export const test = base.extend<{
|
||||
room1Name?: string;
|
||||
room1Name: string;
|
||||
room1: { name: string; roomId: string };
|
||||
room2Name?: string;
|
||||
room2Name: string;
|
||||
room2: { name: string; roomId: string };
|
||||
msg: MessageBuilder;
|
||||
util: Helpers;
|
||||
@@ -39,7 +39,7 @@ export const test = base.extend<{
|
||||
room1: async ({ room1Name: name, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name,
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
preset: "public_chat" as Preset,
|
||||
});
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
@@ -47,12 +47,12 @@ export const test = base.extend<{
|
||||
},
|
||||
room2Name: "Room 2",
|
||||
room2: async ({ room2Name: name, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials.userId] });
|
||||
const roomId = await app.client.createRoom({ name, invite: [bot.credentials!.userId] });
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
await use({ name, roomId });
|
||||
},
|
||||
msg: async ({ page, app, util }, use) => {
|
||||
await use(new MessageBuilder(page, app, util));
|
||||
await use(new MessageBuilder());
|
||||
},
|
||||
util: async ({ room1, room2, page, app, bot }, use) => {
|
||||
await use(new Helpers(page, app, bot));
|
||||
@@ -70,12 +70,6 @@ export const test = base.extend<{
|
||||
* which finds a message and then constructs a reply to it.
|
||||
*/
|
||||
export class MessageBuilder {
|
||||
constructor(
|
||||
private page: Page,
|
||||
private app: ElementAppPage,
|
||||
private helpers: Helpers,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Map of message content -> event.
|
||||
*/
|
||||
@@ -164,11 +158,7 @@ export class MessageBuilder {
|
||||
* MessageBuilder.replyTo} which creates a reply based on a previous message.
|
||||
*/
|
||||
export abstract class MessageContentSpec {
|
||||
messageFinder: MessageBuilder | null;
|
||||
|
||||
constructor(messageFinder: MessageBuilder = null) {
|
||||
this.messageFinder = messageFinder;
|
||||
}
|
||||
constructor(public readonly messageFinder: MessageBuilder) {}
|
||||
|
||||
public abstract getContent(room: JSHandle<Room>): Promise<Record<string, unknown>>;
|
||||
}
|
||||
@@ -230,9 +220,9 @@ export class Helpers {
|
||||
await expect(this.page.locator(".mx_ThreadView_timelinePanelWrapper")).toBeVisible();
|
||||
}
|
||||
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room | undefined>> {
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomId) => {
|
||||
return cli.getRooms().find((r) => r.roomId === roomId);
|
||||
return cli.getRooms().find((r) => r.roomId === roomId)!;
|
||||
}, roomId);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,8 +97,8 @@ test.describe("Spotlight", () => {
|
||||
|
||||
test.beforeEach(async ({ page, user, bot1, bot2, room1, room2, room3 }) => {
|
||||
await bot1.joinRoom(room1.roomId);
|
||||
await bot2.inviteUser(room2.roomId, bot1.credentials.userId);
|
||||
await bot2.inviteUser(room3.roomId, bot1.credentials.userId);
|
||||
await bot2.inviteUser(room2.roomId, bot1.credentials!.userId);
|
||||
await bot2.inviteUser(room3.roomId, bot1.credentials!.userId);
|
||||
|
||||
await page.goto(`/#/room/${room1.roomId}`);
|
||||
await expect(page.locator(".mx_RoomSublist_skeletonUI")).not.toBeAttached();
|
||||
@@ -215,12 +215,12 @@ test.describe("Spotlight", () => {
|
||||
const spotlight = await app.openSpotlight();
|
||||
await page.waitForTimeout(500); // wait for the dialog to settle
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot1.credentials.displayName);
|
||||
await spotlight.search(bot1.credentials!.displayName!);
|
||||
const resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(1);
|
||||
await expect(resultLocator.first()).toContainText(bot1.credentials.displayName);
|
||||
await expect(resultLocator.first()).toContainText(bot1.credentials!.displayName!);
|
||||
await resultLocator.first().click();
|
||||
await expect(roomHeaderName(page)).toHaveText(bot1.credentials.displayName);
|
||||
await expect(roomHeaderName(page)).toHaveText(bot1.credentials!.displayName!);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -234,30 +234,30 @@ test.describe("Spotlight", () => {
|
||||
const spotlight = await app.openSpotlight();
|
||||
await page.waitForTimeout(500); // wait for the dialog to settle
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot2.credentials.displayName);
|
||||
await spotlight.search(bot2.credentials!.displayName!);
|
||||
const resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(1);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials.displayName);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials!.displayName!);
|
||||
await resultLocator.first().click();
|
||||
await expect(roomHeaderName(page)).toHaveText(bot2.credentials.displayName);
|
||||
await expect(roomHeaderName(page)).toHaveText(bot2.credentials!.displayName!);
|
||||
});
|
||||
|
||||
test("should find group DMs by usernames or user ids", async ({ page, app, bot1, bot2, room1 }) => {
|
||||
// First we want to share a room with both bots to ensure we’ve got their usernames cached
|
||||
await app.client.inviteUser(room1.roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(room1.roomId, bot2.credentials!.userId);
|
||||
|
||||
// Starting a DM with ByteBot (will be turned into a group dm later)
|
||||
let spotlight = await app.openSpotlight();
|
||||
await page.waitForTimeout(500); // wait for the dialog to settle
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot2.credentials.displayName);
|
||||
await spotlight.search(bot2.credentials!.displayName!);
|
||||
let resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(1);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials.displayName);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials!.displayName!);
|
||||
await resultLocator.first().click();
|
||||
|
||||
// Send first message to actually start DM
|
||||
await expect(roomHeaderName(page)).toHaveText(bot2.credentials.displayName);
|
||||
await expect(roomHeaderName(page)).toHaveText(bot2.credentials!.displayName!);
|
||||
const locator = page.getByRole("textbox", { name: "Send a message…" });
|
||||
await locator.fill("Hey!");
|
||||
await locator.press("Enter");
|
||||
@@ -265,7 +265,7 @@ test.describe("Spotlight", () => {
|
||||
// Assert DM exists by checking for the first message and the room being in the room list
|
||||
await expect(page.locator(".mx_EventTile_body").filter({ hasText: "Hey!" })).toBeAttached({ timeout: 3000 });
|
||||
await expect(
|
||||
page.getByTestId("room-list").getByRole("option", { name: `Open room ${bot2.credentials.displayName}` }),
|
||||
page.getByTestId("room-list").getByRole("option", { name: `Open room ${bot2.credentials!.displayName}` }),
|
||||
).toBeVisible();
|
||||
|
||||
// Invite BotBob into existing DM with ByteBot
|
||||
@@ -273,11 +273,11 @@ test.describe("Spotlight", () => {
|
||||
const map = client
|
||||
.getAccountData("m.direct" as keyof AccountDataEvents)
|
||||
?.getContent<Record<string, string[]>>();
|
||||
return map[userId] ?? [];
|
||||
}, bot2.credentials.userId);
|
||||
return map?.[userId] ?? [];
|
||||
}, bot2.credentials!.userId);
|
||||
expect(dmRooms).toHaveLength(1);
|
||||
const groupDmName = await app.client.evaluate((client, id) => client.getRoom(id).name, dmRooms[0]);
|
||||
await app.client.inviteUser(dmRooms[0], bot1.credentials.userId);
|
||||
const groupDmName = await app.client.evaluate((client, id) => client.getRoom(id)!.name, dmRooms[0]);
|
||||
await app.client.inviteUser(dmRooms[0], bot1.credentials!.userId);
|
||||
await expect(roomHeaderName(page).first()).toContainText(groupDmName);
|
||||
await expect(
|
||||
page.getByTestId("room-list").getByRole("option", { name: `Open room ${groupDmName}` }),
|
||||
@@ -286,7 +286,7 @@ test.describe("Spotlight", () => {
|
||||
// Search for BotBob by id, should return group DM and user
|
||||
spotlight = await app.openSpotlight();
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot1.credentials.userId);
|
||||
await spotlight.search(bot1.credentials!.userId);
|
||||
await page.waitForTimeout(1000); // wait for the dialog to settle
|
||||
resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(2);
|
||||
@@ -299,7 +299,7 @@ test.describe("Spotlight", () => {
|
||||
// Search for ByteBot by id, should return group DM and user
|
||||
spotlight = await app.openSpotlight();
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot2.credentials.userId);
|
||||
await spotlight.search(bot2.credentials!.userId);
|
||||
await page.waitForTimeout(1000); // wait for the dialog to settle
|
||||
resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(2);
|
||||
@@ -324,11 +324,11 @@ test.describe("Spotlight", () => {
|
||||
// We search for user ID to trigger the profile lookup within the dialog.
|
||||
for (let i = 0; i < 2; i++) {
|
||||
console.log("Iteration: " + i);
|
||||
await spotlight.search(bot1.credentials.userId);
|
||||
await spotlight.search(bot1.credentials!.userId);
|
||||
await page.waitForTimeout(1000); // wait for the dialog to settle
|
||||
const resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(1);
|
||||
await expect(resultLocator.first()).toContainText(bot1.credentials.userId);
|
||||
await expect(resultLocator.first()).toContainText(bot1.credentials!.userId);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -336,12 +336,12 @@ test.describe("Spotlight", () => {
|
||||
const spotlight = await app.openSpotlight();
|
||||
await page.waitForTimeout(500); // wait for the dialog to settle
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot2.credentials.displayName);
|
||||
await spotlight.search(bot2.credentials!.displayName!);
|
||||
await page.waitForTimeout(3000); // wait for the dialog to settle
|
||||
|
||||
const resultLocator = spotlight.results;
|
||||
await expect(resultLocator).toHaveCount(1);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials.displayName);
|
||||
await expect(resultLocator.first()).toContainText(bot2.credentials!.displayName!);
|
||||
|
||||
await expect(spotlight.dialog.locator("#mx_SpotlightDialog_button_startGroupChat")).toContainText(
|
||||
"Start a group chat",
|
||||
@@ -351,17 +351,17 @@ test.describe("Spotlight", () => {
|
||||
});
|
||||
|
||||
test("should close spotlight after starting a DM", async ({ page, app, bot1 }) => {
|
||||
await startDM(app, page, bot1.credentials.displayName);
|
||||
await startDM(app, page, bot1.credentials!.displayName!);
|
||||
await expect(page.locator(".mx_SpotlightDialog")).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("should show the same user only once", async ({ page, app, bot1 }) => {
|
||||
await startDM(app, page, bot1.credentials.displayName);
|
||||
await startDM(app, page, bot1.credentials!.displayName!);
|
||||
await page.goto("/#/home");
|
||||
const spotlight = await app.openSpotlight();
|
||||
await page.waitForTimeout(500); // wait for the dialog to settle
|
||||
await spotlight.filter(Filter.People);
|
||||
await spotlight.search(bot1.credentials.displayName);
|
||||
await spotlight.search(bot1.credentials!.displayName!);
|
||||
await page.waitForTimeout(3000); // wait for the dialog to settle
|
||||
await expect(spotlight.dialog.locator(".mx_Spinner")).not.toBeAttached();
|
||||
const resultLocator = spotlight.results;
|
||||
|
||||
@@ -29,7 +29,7 @@ test.describe("Threads", () => {
|
||||
|
||||
test("should be usable for a conversation", { tag: "@screenshot" }, async ({ page, app, bot }) => {
|
||||
const roomId = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
@@ -436,7 +436,7 @@ test.describe("Threads", () => {
|
||||
{ tag: ["@screenshot", "@no-firefox"] },
|
||||
async ({ page, app, bot }) => {
|
||||
const roomId = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ test.describe("Event List Summary", () => {
|
||||
await app.client.sendMessage(roomId, "Saying something");
|
||||
|
||||
// When we ban the bot
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
await app.client.ban(roomId, bot.credentials!.userId);
|
||||
|
||||
// Then we say that, but the name is hidden
|
||||
await expect(
|
||||
@@ -92,8 +92,8 @@ test.describe("Event List Summary", () => {
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on it
|
||||
await app.client.kick(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.kick(roomId, bot.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary
|
||||
@@ -126,9 +126,9 @@ test.describe("Event List Summary", () => {
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on it, including a ban
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
await app.client.unban(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.ban(roomId, bot.credentials!.userId);
|
||||
await app.client.unban(roomId, bot.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary, with the name hidden
|
||||
@@ -158,7 +158,7 @@ test.describe("Event List Summary", () => {
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot2.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials!.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot2...");
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
@@ -169,10 +169,10 @@ test.describe("Event List Summary", () => {
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on both bots
|
||||
await app.client.kick(roomId, bot.credentials.userId);
|
||||
await app.client.kick(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.kick(roomId, bot.credentials!.userId);
|
||||
await app.client.kick(roomId, bot2.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
|
||||
@@ -227,7 +227,7 @@ test.describe("Event List Summary", () => {
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot2.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials!.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot2...");
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
@@ -238,11 +238,11 @@ test.describe("Event List Summary", () => {
|
||||
).toBeVisible();
|
||||
|
||||
// When we ban bot1 but not bot2
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
await app.client.unban(roomId, bot.credentials.userId);
|
||||
await app.client.kick(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.ban(roomId, bot.credentials!.userId);
|
||||
await app.client.unban(roomId, bot.credentials!.userId);
|
||||
await app.client.kick(roomId, bot2.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials!.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
|
||||
@@ -318,7 +318,7 @@ async function setupRoom(app: ElementAppPage, homeserver: StartedHomeserverConta
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials!.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot...");
|
||||
|
||||
return { bot, roomId };
|
||||
@@ -336,11 +336,11 @@ async function replaceBotIds(page: Page, bot: Bot, bot2?: Bot) {
|
||||
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
||||
while (walker.nextNode()) {
|
||||
const node = walker.currentNode;
|
||||
node.textContent = node.textContent.replaceAll(bot1UserId, "<<replaced_bot1_id>>");
|
||||
node.textContent = node.textContent!.replaceAll(bot1UserId, "<<replaced_bot1_id>>");
|
||||
node.textContent = node.textContent.replaceAll(bot2UserId, "<<replaced_bot2_id>>");
|
||||
}
|
||||
}
|
||||
},
|
||||
[bot.credentials.userId, bot2?.credentials?.userId ?? "no_bot_2_to_replace"],
|
||||
[bot.credentials!.userId, bot2?.credentials?.userId ?? "no_bot_2_to_replace"],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ const expectAvatar = async (cli: Client, e: Locator, avatarUrl: string): Promise
|
||||
},
|
||||
{ avatarUrl, size, resizeMethod: AVATAR_RESIZE_METHOD },
|
||||
);
|
||||
await expect(e.locator(".mx_BaseAvatar img")).toHaveAttribute("src", url);
|
||||
await expect(e.locator(".mx_BaseAvatar img")).toHaveAttribute("src", url!);
|
||||
};
|
||||
|
||||
const sendEvent = async (client: Client, roomId: string, html = false): Promise<ISendEventResponse> => {
|
||||
@@ -917,7 +917,7 @@ test.describe("Timeline", () => {
|
||||
|
||||
const bot = new Bot(page, homeserver, {});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(room.roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, bot.credentials!.userId);
|
||||
|
||||
await sendImage(bot, room.roomId, NEW_AVATAR);
|
||||
await app.timeline.scrollToBottom();
|
||||
@@ -936,7 +936,7 @@ test.describe("Timeline", () => {
|
||||
|
||||
const bot = new Bot(page, homeserver, {});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(room.roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, bot.credentials!.userId);
|
||||
|
||||
const upload = await bot.uploadContent(VIDEO_FILE, { name: "bbb.webm", type: "video/webm" });
|
||||
await bot.sendEvent(room.roomId, null, "m.room.message" as EventType, {
|
||||
@@ -970,7 +970,7 @@ test.describe("Timeline", () => {
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(room.roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(room.roomId);
|
||||
await bot.sendMessage(room.roomId, messageFromSender);
|
||||
|
||||
@@ -1100,7 +1100,7 @@ test.describe("Timeline", () => {
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(room.roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(room.roomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(room.roomId);
|
||||
|
||||
// Make sure the bot joined the room
|
||||
@@ -1228,7 +1228,7 @@ test.describe("Timeline", () => {
|
||||
|
||||
// Create another room with a long name, invite the bot, and open the room
|
||||
const testRoomId = await app.client.createRoom({ name: LONG_STRING });
|
||||
await app.client.inviteUser(testRoomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(testRoomId, bot.credentials!.userId);
|
||||
await bot.joinRoom(testRoomId);
|
||||
await page.goto(`/#/room/${testRoomId}`);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ test.describe("User Menu", () => {
|
||||
await page.getByRole("button", { name: "User menu", exact: true }).click();
|
||||
const menu = page.getByRole("menu");
|
||||
|
||||
await expect(menu.getByText(user.displayName)).toBeVisible();
|
||||
await expect(menu.getByText(user.displayName!)).toBeVisible();
|
||||
await expect(menu.getByText(user.userId)).toBeVisible();
|
||||
await expect(menu).toMatchScreenshot("user-menu.png", screenshotOptions(page));
|
||||
});
|
||||
|
||||
@@ -15,10 +15,12 @@ test.describe("UserView", () => {
|
||||
});
|
||||
|
||||
test("should render the user view as expected", { tag: "@screenshot" }, async ({ page, homeserver, user, bot }) => {
|
||||
await page.goto(`/#/user/${bot.credentials.userId}`);
|
||||
await page.goto(`/#/user/${bot.credentials!.userId}`);
|
||||
|
||||
const rightPanel = page.locator("#mx_RightPanel");
|
||||
await expect(rightPanel.getByRole("heading", { name: bot.credentials.displayName, exact: true })).toBeVisible();
|
||||
await expect(
|
||||
rightPanel.getByRole("heading", { name: bot.credentials!.displayName, exact: true }),
|
||||
).toBeVisible();
|
||||
await expect(rightPanel).toMatchScreenshot("user-info.png", {
|
||||
mask: [page.locator(".mx_UserInfo_profile_mxid")],
|
||||
css: `
|
||||
|
||||
@@ -40,7 +40,7 @@ export async function waitForRoom(
|
||||
await client.evaluateHandle(
|
||||
(matrixClient, { roomId, predicateId }) => {
|
||||
return new Promise<Room>((resolve) => {
|
||||
const room = matrixClient.getRoom(roomId);
|
||||
const room = matrixClient.getRoom(roomId)!;
|
||||
|
||||
if ((<any>window)[predicateId](room)) {
|
||||
resolve(room);
|
||||
|
||||
@@ -63,7 +63,7 @@ async function sendRTCState(bot: Bot, roomId: string, notification?: "ring" | "n
|
||||
},
|
||||
"scope": "m.room",
|
||||
},
|
||||
`_@${bot.credentials.userId}_OiDFxsZrjz_m.call`,
|
||||
`_@${bot.credentials!.userId}_OiDFxsZrjz_m.call`,
|
||||
);
|
||||
if (!notification) {
|
||||
return;
|
||||
@@ -140,7 +140,7 @@ test.describe("Element Call", () => {
|
||||
await charlie.prepareClient();
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "TestRoom",
|
||||
invite: [bot.credentials.userId, charlie.credentials.userId],
|
||||
invite: [bot.credentials!.userId, charlie.credentials!.userId],
|
||||
});
|
||||
await use({ roomId });
|
||||
},
|
||||
@@ -155,7 +155,7 @@ test.describe("Element Call", () => {
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
// Ensure we set the correct parameters for ECall.
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
expect(hash.get("intent")).toEqual("start_call");
|
||||
@@ -180,7 +180,7 @@ test.describe("Element Call", () => {
|
||||
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
expect(hash.get("intent")).toEqual("start_call");
|
||||
@@ -192,7 +192,7 @@ test.describe("Element Call", () => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
// Allow bob to create a call
|
||||
await expect(page.getByText("Bob and one other were invited and joined")).toBeVisible();
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials.userId, 50);
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials!.userId, 50);
|
||||
// Fake a start of a call
|
||||
await sendRTCState(bot, room.roomId, undefined, callType === "voice" ? "audio" : "video");
|
||||
const button = page.getByTestId("join-call-button");
|
||||
@@ -205,7 +205,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -237,7 +237,7 @@ test.describe("Element Call", () => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
// Allow bob to create a call
|
||||
await expect(page.getByText("Bob and one other were invited and joined")).toBeVisible();
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials.userId, 50);
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials!.userId, 50);
|
||||
// Fake a start of a call
|
||||
await sendRTCState(bot, room.roomId, "notification", "video");
|
||||
const toast = page.locator(".mx_Toast_toast");
|
||||
@@ -255,7 +255,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -272,7 +272,7 @@ test.describe("Element Call", () => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
// Allow bob to create a call
|
||||
await expect(page.getByText("Bob and one other were invited and joined")).toBeVisible();
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials.userId, 50);
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials!.userId, 50);
|
||||
// Fake a start of a call
|
||||
await sendRTCState(bot, room.roomId, "notification", "audio");
|
||||
const toast = page.locator(".mx_Toast_toast");
|
||||
@@ -284,7 +284,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -299,11 +299,11 @@ test.describe("Element Call", () => {
|
||||
room: async ({ page, app, user, bot }, use) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
preset: "trusted_private_chat" as Preset.TrustedPrivateChat,
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
await bot.awaitRoomMembership(roomId);
|
||||
await app.client.setAccountData("m.direct" as EventType.Direct, {
|
||||
[bot.credentials.userId]: [roomId],
|
||||
[bot.credentials!.userId]: [roomId],
|
||||
});
|
||||
await use({ roomId });
|
||||
},
|
||||
@@ -318,7 +318,7 @@ test.describe("Element Call", () => {
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
expect(hash.get("intent")).toEqual("start_call_dm");
|
||||
@@ -336,7 +336,7 @@ test.describe("Element Call", () => {
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
expect(hash.get("intent")).toEqual("start_call_dm");
|
||||
@@ -370,7 +370,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -410,7 +410,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -444,7 +444,7 @@ test.describe("Element Call", () => {
|
||||
await button.click();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, room);
|
||||
|
||||
@@ -477,7 +477,7 @@ test.describe("Element Call", () => {
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
expect(frameUrlStr).toBeDefined();
|
||||
// Ensure we set the correct parameters for ECall.
|
||||
const url = new URL(frameUrlStr);
|
||||
const url = new URL(frameUrlStr!);
|
||||
const hash = new URLSearchParams(url.hash.slice(1));
|
||||
assertCommonCallParameters(url.searchParams, hash, user, { roomId });
|
||||
expect(hash.get("intent")).toEqual("join_existing");
|
||||
@@ -494,7 +494,7 @@ test.describe("Element Call", () => {
|
||||
await charlie.prepareClient();
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "TestRoom",
|
||||
invite: [bot.credentials.userId, charlie.credentials.userId],
|
||||
invite: [bot.credentials!.userId, charlie.credentials!.userId],
|
||||
});
|
||||
await app.client.createRoom({
|
||||
name: "OtherRoom",
|
||||
@@ -514,7 +514,7 @@ test.describe("Element Call", () => {
|
||||
const iframe = page.locator("iframe");
|
||||
await expect(iframe).toBeVisible();
|
||||
const frameUrlStr = await page.locator("iframe").getAttribute("src");
|
||||
const callFrame = page.frame({ url: frameUrlStr });
|
||||
const callFrame = page.frame({ url: frameUrlStr! })!;
|
||||
await callFrame.getByRole("button", { name: "Join Call" }).click();
|
||||
await expect(callFrame.getByText("In call", { exact: true })).toBeVisible();
|
||||
|
||||
@@ -608,7 +608,7 @@ test.describe("Element Call", () => {
|
||||
}) => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
await expect(page.getByText("Bob and one other were invited and joined")).toBeVisible();
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials.userId, 50);
|
||||
await app.client.setPowerLevel(room.roomId, bot.credentials!.userId, 50);
|
||||
|
||||
await sendRTCState(bot, room.roomId);
|
||||
await openAndJoinCall(page, true);
|
||||
@@ -654,7 +654,7 @@ test.describe("Element Call", () => {
|
||||
await charlie.prepareClient();
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "VideoRoom",
|
||||
invite: [bot.credentials.userId, charlie.credentials.userId],
|
||||
invite: [bot.credentials!.userId, charlie.credentials!.userId],
|
||||
creation_content: {
|
||||
type: "org.matrix.msc3417.call",
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ test.describe("Widget Events", () => {
|
||||
}) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: ROOM_NAME,
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
|
||||
// setup widget via state event
|
||||
|
||||
@@ -30,7 +30,7 @@ test.describe("Jitsi Calls", () => {
|
||||
test("should be able to pop out a jitsi widget", async ({ page, app, bot, bot2, context }) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: ROOM_NAME,
|
||||
invite: [bot.credentials.userId, bot2.credentials.userId],
|
||||
invite: [bot.credentials!.userId, bot2.credentials!.userId],
|
||||
});
|
||||
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
@@ -76,19 +76,19 @@ test.describe("Widget Layout", () => {
|
||||
|
||||
test("manually resize the height of the top container layout", async ({ page }) => {
|
||||
const iframe = page.locator('iframe[title="widget"]');
|
||||
expect((await iframe.boundingBox()).height).toBeLessThan(250);
|
||||
expect((await iframe.boundingBox())!.height).toBeLessThan(250);
|
||||
|
||||
await page.locator(".mx_AppsDrawer_resizer_container_handle").hover();
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(0, 550);
|
||||
await page.mouse.up();
|
||||
|
||||
expect((await iframe.boundingBox()).height).toBeGreaterThan(400);
|
||||
expect((await iframe.boundingBox())!.height).toBeGreaterThan(400);
|
||||
});
|
||||
|
||||
test("programmatically resize the height of the top container layout", async ({ page, app }) => {
|
||||
const iframe = page.locator('iframe[title="widget"]');
|
||||
expect((await iframe.boundingBox()).height).toBeLessThan(250);
|
||||
expect((await iframe.boundingBox())!.height).toBeLessThan(250);
|
||||
|
||||
await app.client.sendStateEvent(
|
||||
roomId,
|
||||
@@ -106,6 +106,6 @@ test.describe("Widget Layout", () => {
|
||||
"",
|
||||
);
|
||||
|
||||
await expect.poll(async () => (await iframe.boundingBox()).height).toBeGreaterThan(400);
|
||||
await expect.poll(async () => (await iframe.boundingBox())!.height).toBeGreaterThan(400);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,7 +56,7 @@ async function waitForRoomWidget(client: Client, widgetId: string, roomId: strin
|
||||
}
|
||||
}
|
||||
|
||||
const room = matrixClient.getRoom(roomId);
|
||||
const room = matrixClient.getRoom(roomId)!;
|
||||
|
||||
const startingWidgetEvents = room.currentState.getStateEvents("im.vector.modular.widgets");
|
||||
if (eventsInIntendedState(startingWidgetEvents)) {
|
||||
@@ -97,14 +97,14 @@ test.describe("Widget PIP", () => {
|
||||
test(`should be closed on ${userRemove}`, async ({ page, app, bot, user }) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: ROOM_NAME,
|
||||
invite: [bot.credentials.userId],
|
||||
invite: [bot.credentials!.userId],
|
||||
});
|
||||
|
||||
// sets bot to Admin and user to Moderator
|
||||
await app.client.sendStateEvent(roomId, "m.room.power_levels", {
|
||||
users: {
|
||||
[user.userId]: 50,
|
||||
[bot.credentials.userId]: 100,
|
||||
[bot.credentials!.userId]: 100,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user