Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 102 additions & 102 deletions playwright/e2e/crypto/event-shields.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,108 +58,108 @@
await app.client.network.setupRoute();
});

test("should show the correct shield on e2e events", async ({
page,
app,
bot: bob,
homeserver,
}, workerInfo) => {
// Bob has a second, not cross-signed, device
const bobSecondDevice = await createSecondBotDevice(page, homeserver, bob);

// Dismiss the toasts nagging us, otherwise they get in the way of clicking the room list
await page.getByRole("button", { name: "Dismiss" }).click();
await page.getByRole("button", { name: "Yes, dismiss" }).click();

await bob.sendEvent(testRoomId, null, "m.room.encrypted", {
algorithm: "m.megolm.v1.aes-sha2",
ciphertext: "the bird is in the hand",
});

const last = page.locator(".mx_EventTile_last");
await expect(last).toContainText("Unable to decrypt message");
const lastE2eIcon = last.locator(".mx_EventTile_e2eIcon");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_decryption_failure/);
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
"This message could not be decrypted",
);

/* Should show a red padlock for an unencrypted message in an e2e room */
await bob.evaluate(
(cli, testRoomId) =>
cli.http.authedRequest(
window.matrixcs.Method.Put,
`/rooms/${encodeURIComponent(testRoomId)}/send/m.room.message/test_txn_1`,
undefined,
{
msgtype: "m.text",
body: "test unencrypted",
},
),
testRoomId,
);

await expect(last).toContainText("test unencrypted");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText("Not encrypted");

/* Should show no padlock for an unverified user */
// bob sends a valid event
await bob.sendMessage(testRoomId, "test encrypted 1");

// the message should appear, decrypted, with no warning, but also no "verified"
const lastTile = page.locator(".mx_EventTile_last");
const lastTileE2eIcon = lastTile.locator(".mx_EventTile_e2eIcon");
await expect(lastTile).toContainText("test encrypted 1");
// no e2e icon
await expect(lastTileE2eIcon).not.toBeVisible();

/* Now verify Bob */
await verify(app, bob);

/* Existing message should be updated when user is verified. */
await expect(last).toContainText("test encrypted 1");
// still no e2e icon
await expect(last.locator(".mx_EventTile_e2eIcon")).not.toBeVisible();

/* should show no padlock, and be verified, for a message from a verified device */
await bob.sendMessage(testRoomId, "test encrypted 2");

await expect(lastTile).toContainText("test encrypted 2");
// no e2e icon
await expect(lastTileE2eIcon).not.toBeVisible();

/* should show red padlock for a message from an unverified device */
await bobSecondDevice.sendMessage(testRoomId, "test encrypted from unverified");
await expect(lastTile).toContainText("test encrypted from unverified");
await expect(lastTileE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await lastTileE2eIcon.focus();
await expect(await app.getTooltipForElement(lastTileE2eIcon)).toContainText(
"Encrypted by a device not verified by its owner.",
);

/* Should show a red padlock for a message from an unverified device.
* Rust crypto remembers the verification state of the sending device, so it will know that the device was
* unverified, even if it gets deleted. */
// bob deletes his second device
await bobSecondDevice.evaluate((cli) => cli.logout(true));

// wait for the logout to propagate.
await waitForDevices(app, bob.credentials.userId, 1);

// close and reopen the room, to get the shield to update.
await app.viewRoomByName("Bob");
await app.viewRoomByName("TestRoom");

await expect(last).toContainText("test encrypted from unverified");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
"Encrypted by a device not verified by its owner.",
);
});
test(
"should show the correct shield on e2e events",
{ tag: "@screenshot" },
async ({ page, app, bot: bob, homeserver }, workerInfo) => {
// Bob has a second, not cross-signed, device
const bobSecondDevice = await createSecondBotDevice(page, homeserver, bob);

// Dismiss the toasts nagging us, otherwise they get in the way of clicking the room list
await page.getByRole("button", { name: "Dismiss" }).click();
await page.getByRole("button", { name: "Yes, dismiss" }).click();

await bob.sendEvent(testRoomId, null, "m.room.encrypted", {
algorithm: "m.megolm.v1.aes-sha2",
ciphertext: "the bird is in the hand",
});

const last = page.locator(".mx_EventTile_last");
await expect(last).toContainText("Unable to decrypt message");
const lastE2eIcon = last.locator(".mx_EventTile_e2eIcon");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_decryption_failure/);
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
"This message could not be decrypted",
);

/* Should show a red padlock for an unencrypted message in an e2e room */
await bob.evaluate(
(cli, testRoomId) =>
cli.http.authedRequest(
window.matrixcs.Method.Put,
`/rooms/${encodeURIComponent(testRoomId)}/send/m.room.message/test_txn_1`,
undefined,
{
msgtype: "m.text",
body: "test unencrypted",
},
),
testRoomId,
);

await expect(last).toContainText("test unencrypted");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await expect(lastE2eIcon).toMatchScreenshot("event-shield-warning.png");
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText("Not encrypted");

/* Should show no padlock for an unverified user */
// bob sends a valid event
await bob.sendMessage(testRoomId, "test encrypted 1");

// the message should appear, decrypted, with no warning, but also no "verified"
const lastTile = page.locator(".mx_EventTile_last");
const lastTileE2eIcon = lastTile.locator(".mx_EventTile_e2eIcon");
await expect(lastTile).toContainText("test encrypted 1");
// no e2e icon
await expect(lastTileE2eIcon).not.toBeVisible();

/* Now verify Bob */
await verify(app, bob);

/* Existing message should be updated when user is verified. */
await expect(last).toContainText("test encrypted 1");
// still no e2e icon
await expect(last.locator(".mx_EventTile_e2eIcon")).not.toBeVisible();

/* should show no padlock, and be verified, for a message from a verified device */
await bob.sendMessage(testRoomId, "test encrypted 2");

await expect(lastTile).toContainText("test encrypted 2");
// no e2e icon
await expect(lastTileE2eIcon).not.toBeVisible();

/* should show red padlock for a message from an unverified device */
await bobSecondDevice.sendMessage(testRoomId, "test encrypted from unverified");
await expect(lastTile).toContainText("test encrypted from unverified");
await expect(lastTileE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await lastTileE2eIcon.focus();
await expect(await app.getTooltipForElement(lastTileE2eIcon)).toContainText(
"Encrypted by a device not verified by its owner.",
);

/* Should show a red padlock for a message from an unverified device.
* Rust crypto remembers the verification state of the sending device, so it will know that the device was
* unverified, even if it gets deleted. */
// bob deletes his second device
await bobSecondDevice.evaluate((cli) => cli.logout(true));

// wait for the logout to propagate.
await waitForDevices(app, bob.credentials.userId, 1);

// close and reopen the room, to get the shield to update.
await app.viewRoomByName("Bob");
await app.viewRoomByName("TestRoom");

await expect(last).toContainText("test encrypted from unverified");
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
await lastE2eIcon.focus();
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
"Encrypted by a device not verified by its owner.",
);
},
);

test("Should show a grey padlock for a key restored from backup", async ({
page,
Expand Down Expand Up @@ -199,7 +199,7 @@

/* go back to the test room and find Bob's message again */
await app.viewRoomById(testRoomId);
await expect(lastTile).toContainText("test encrypted 1");

Check failure on line 202 in playwright/e2e/crypto/event-shields.spec.ts

View workflow job for this annotation

GitHub Actions / Run Tests [Chrome] 1/6

[Chrome] › playwright/e2e/crypto/event-shields.spec.ts:164:13 › Cryptography › event shields › Should show a grey padlock for a key restored from backup

2) [Chrome] › playwright/e2e/crypto/event-shields.spec.ts:164:13 › Cryptography › event shields › Should show a grey padlock for a key restored from backup Error: Timed out 5000ms waiting for expect(locator).toContainText(expected) Locator: locator('.mx_EventTile_last') Expected string: "test encrypted 1" Received: <element(s) not found> Call log: - Expect "toContainText" with timeout 5000ms - waiting for locator('.mx_EventTile_last') 200 | /* go back to the test room and find Bob's message again */ 201 | await app.viewRoomById(testRoomId); > 202 | await expect(lastTile).toContainText("test encrypted 1"); | ^ 203 | // The gray shield would be a mx_EventTile_e2eIcon_normal. The red shield would be a mx_EventTile_e2eIcon_warning. 204 | // No shield would have no div mx_EventTile_e2eIcon at all. 205 | await expect(lastTileE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_normal/); at /home/runner/work/element-web/element-web/playwright/e2e/crypto/event-shields.spec.ts:202:36
// The gray shield would be a mx_EventTile_e2eIcon_normal. The red shield would be a mx_EventTile_e2eIcon_warning.
// No shield would have no div mx_EventTile_e2eIcon at all.
await expect(lastTileE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_normal/);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion res/css/views/rooms/_E2EIcon.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ Please see LICENSE files in the repository root for full details.
background-color: var(--cpd-color-icon-tertiary);
}

.mx_E2EIcon_verified {
.mx_E2EIcon_verified,
.mx_E2EIcon_warning {
.mx_E2EIcon_normal::after {
background-color: white;
}
Expand Down
Loading