diff --git a/cypress/e2e/invite/invite-dialog.spec.ts b/cypress/e2e/invite/invite-dialog.spec.ts deleted file mode 100644 index 683cdecd85..0000000000 --- a/cypress/e2e/invite/invite-dialog.spec.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* -Copyright 2023 Suguru Hirahara - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import type { MatrixClient } from "matrix-js-sdk/src/matrix"; -import { HomeserverInstance } from "../../plugins/utils/homeserver"; - -describe("Invite dialog", function () { - let homeserver: HomeserverInstance; - let bot: MatrixClient; - const botName = "BotAlice"; - - beforeEach(() => { - cy.startHomeserver("default").then((data) => { - homeserver = data; - cy.initTestUser(homeserver, "Hanako"); - - cy.getBot(homeserver, { displayName: botName, autoAcceptInvites: true }).then((_bot) => { - bot = _bot; - }); - }); - }); - - afterEach(() => { - cy.stopHomeserver(homeserver); - }); - - it("should support inviting a user to a room", () => { - // Create and view a room - cy.createRoom({ name: "Test Room" }).viewRoomByName("Test Room"); - - // Assert that the room was configured - cy.findByText("Hanako created and configured the room.").should("exist"); - - // Open the room info panel - cy.findByRole("button", { name: "Room info" }).click(); - - cy.get(".mx_BaseCard").within(() => { - cy.findByRole("menuitem", { name: "Invite" }).click(); - }); - - cy.get(".mx_InviteDialog_other").within(() => { - cy.get(".mx_Dialog_header .mx_Dialog_title").within(() => { - // Assert that the header is rendered - cy.findByText("Invite to Test Room").should("exist"); - }); - - // Assert that the bar is rendered - cy.get(".mx_InviteDialog_addressBar").should("exist"); - }); - - // TODO: unhide userId - const percyCSS = ".mx_InviteDialog_helpText_userId { visibility: hidden !important; }"; - - // Take a snapshot of the invite dialog including its wrapper - cy.get(".mx_Dialog_wrapper").percySnapshotElement("Invite Dialog - Room (without a user)", { percyCSS }); - - cy.get(".mx_InviteDialog_other").within(() => { - cy.get(".mx_InviteDialog_identityServer").should("not.exist"); - - cy.findByTestId("invite-dialog-input").type(bot.getUserId()); - - // Assert that notification about identity servers appears after typing userId - cy.get(".mx_InviteDialog_identityServer").should("exist"); - - cy.get(".mx_InviteDialog_tile_nameStack").within(() => { - cy.get(".mx_InviteDialog_tile_nameStack_userId").within(() => { - // Assert that the bot id is rendered properly - cy.findByText(bot.getUserId()).should("exist"); - }); - - cy.get(".mx_InviteDialog_tile_nameStack_name").within(() => { - cy.findByText(botName).click(); - }); - }); - - cy.get(".mx_InviteDialog_userTile_pill .mx_InviteDialog_userTile_name").within(() => { - cy.findByText(botName).should("exist"); - }); - }); - - // Take a snapshot of the invite dialog with a user pill - cy.get(".mx_Dialog_wrapper").percySnapshotElement("Invite Dialog - Room (with a user pill)", { percyCSS }); - - cy.get(".mx_InviteDialog_other").within(() => { - // Invite the bot - cy.findByRole("button", { name: "Invite" }).click(); - }); - - // Assert that the invite dialog disappears - cy.get(".mx_InviteDialog_other").should("not.exist"); - - // Assert that they were invited and joined - cy.findByText(`${botName} joined the room`).should("exist"); - }); - - it("should support inviting a user to Direct Messages", () => { - cy.get(".mx_RoomList").within(() => { - cy.findByRole("button", { name: "Start chat" }).click(); - }); - - cy.get(".mx_InviteDialog_other").within(() => { - cy.get(".mx_Dialog_header .mx_Dialog_title").within(() => { - // Assert that the header is rendered - cy.findByText("Direct Messages").should("exist"); - }); - - // Assert that the bar is rendered - cy.get(".mx_InviteDialog_addressBar").should("exist"); - }); - - // TODO: unhide userId and invite link - const percyCSS = - ".mx_InviteDialog_footer_link, .mx_InviteDialog_helpText_userId { visibility: hidden !important; }"; - - // Take a snapshot of the invite dialog including its wrapper - cy.get(".mx_Dialog_wrapper").percySnapshotElement("Invite Dialog - Direct Messages (without a user)", { - percyCSS, - }); - - cy.get(".mx_InviteDialog_other").within(() => { - cy.findByTestId("invite-dialog-input").type(bot.getUserId()); - - cy.get(".mx_InviteDialog_tile_nameStack").within(() => { - cy.findByText(bot.getUserId()).should("exist"); - cy.findByText(botName).click(); - }); - - cy.get(".mx_InviteDialog_userTile_pill .mx_InviteDialog_userTile_name").within(() => { - cy.findByText(botName).should("exist"); - }); - }); - - // Take a snapshot of the invite dialog with a user pill - cy.get(".mx_Dialog_wrapper").percySnapshotElement("Invite Dialog - Direct Messages (with a user pill)", { - percyCSS, - }); - - cy.get(".mx_InviteDialog_other").within(() => { - // Open a direct message UI - cy.findByRole("button", { name: "Go" }).click(); - }); - - // Assert that the invite dialog disappears - cy.get(".mx_InviteDialog_other").should("not.exist"); - - // Assert that the hovered user name on invitation UI does not have background color - // TODO: implement the test on room-header.spec.ts - cy.get(".mx_LegacyRoomHeader").within(() => { - cy.get(".mx_LegacyRoomHeader_name--textonly") - .realHover() - .should("have.css", "background-color", "rgba(0, 0, 0, 0)"); - }); - - // Send a message to invite the bots - cy.getComposer().type("Hello{enter}"); - - // Assert that they were invited and joined - cy.findByText(`${botName} joined the room`).should("exist"); - - // Assert that the message is displayed at the bottom - cy.get(".mx_EventTile_last").findByText("Hello").should("exist"); - }); -}); diff --git a/playwright/e2e/invite/invite-dialog.spec.ts b/playwright/e2e/invite/invite-dialog.spec.ts new file mode 100644 index 0000000000..197b686318 --- /dev/null +++ b/playwright/e2e/invite/invite-dialog.spec.ts @@ -0,0 +1,143 @@ +/* +Copyright 2023 Suguru Hirahara +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { test, expect } from "../../element-web-test"; + +test.describe("Invite dialog", function () { + test.use({ + displayName: "Hanako", + botCreateOpts: { + displayName: "BotAlice", + }, + }); + + const botName = "BotAlice"; + + test("should support inviting a user to a room", async ({ page, app, user, bot }) => { + // Create and view a room + await app.client.createRoom({ name: "Test Room" }); + await app.viewRoomByName("Test Room"); + + // Assert that the room was configured + await expect(page.getByText("Hanako created and configured the room.")).toBeVisible(); + + // Open the room info panel + await page.getByRole("button", { name: "Room info" }).click(); + + await page.locator(".mx_BaseCard").getByRole("menuitem", { name: "Invite" }).click(); + + const other = page.locator(".mx_InviteDialog_other"); + // Assert that the header is rendered + await expect( + other.locator(".mx_Dialog_header .mx_Dialog_title").getByText("Invite to Test Room"), + ).toBeVisible(); + // Assert that the bar is rendered + await expect(other.locator(".mx_InviteDialog_addressBar")).toBeVisible(); + + await expect(page.locator(".mx_Dialog")).toMatchScreenshot("invite-dialog-room-without-user.png", { + mask: [page.locator(".mx_InviteDialog_helpText_userId")], + }); + + await expect(other.locator(".mx_InviteDialog_identityServer")).not.toBeVisible(); + + 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.locator(".mx_InviteDialog_tile_nameStack_userId").getByText(bot.credentials.userId), + ).toBeVisible(); + + await other.locator(".mx_InviteDialog_tile_nameStack_name").getByText(botName).click(); + + await expect( + other.locator(".mx_InviteDialog_userTile_pill .mx_InviteDialog_userTile_name").getByText(botName), + ).toBeVisible(); + + // Take a snapshot of the invite dialog with a user pill + await expect(page.locator(".mx_Dialog")).toMatchScreenshot("invite-dialog-room-with-user-pill.png", { + mask: [page.locator(".mx_InviteDialog_helpText_userId")], + }); + + // Invite the bot + await other.getByRole("button", { name: "Invite" }).click(); + + // Assert that the invite dialog disappears + await expect(page.locator(".mx_InviteDialog_other")).not.toBeVisible(); + + // Assert that they were invited and joined + await expect(page.getByText(`${botName} joined the room`)).toBeVisible(); + }); + + test("should support inviting a user to Direct Messages", async ({ page, app, user, bot }) => { + await page.locator(".mx_RoomList").getByRole("button", { name: "Start chat" }).click(); + + const other = page.locator(".mx_InviteDialog_other"); + // Assert that the header is rendered + await expect(other.locator(".mx_Dialog_header .mx_Dialog_title").getByText("Direct Messages")).toBeVisible(); + + // Assert that the bar is rendered + await expect(other.locator(".mx_InviteDialog_addressBar")).toBeVisible(); + + // Take a snapshot of the invite dialog + await expect(page.locator(".mx_Dialog")).toMatchScreenshot("invite-dialog-dm-without-user.png", { + mask: [page.locator(".mx_InviteDialog_footer_link, .mx_InviteDialog_helpText a")], + }); + + await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId); + + await expect(other.locator(".mx_InviteDialog_tile_nameStack").getByText(bot.credentials.userId)).toBeVisible(); + await other.locator(".mx_InviteDialog_tile_nameStack").getByText(botName).click(); + + await expect( + other.locator(".mx_InviteDialog_userTile_pill .mx_InviteDialog_userTile_name").getByText(botName), + ).toBeVisible(); + + // Take a snapshot of the invite dialog with a user pill + await expect(page.locator(".mx_Dialog")).toMatchScreenshot("invite-dialog-dm-with-user-pill.png", { + mask: [page.locator(".mx_InviteDialog_footer_link, .mx_InviteDialog_helpText a")], + }); + + // Open a direct message UI + await other.getByRole("button", { name: "Go" }).click(); + + // Assert that the invite dialog disappears + await expect(page.locator(".mx_InviteDialog_other")).not.toBeVisible(); + + // Assert that the hovered user name on invitation UI does not have background color + // TODO: implement the test on room-header.spec.ts + const roomHeader = page.locator(".mx_LegacyRoomHeader"); + await roomHeader.locator(".mx_LegacyRoomHeader_name--textonly").hover(); + await expect(roomHeader.locator(".mx_LegacyRoomHeader_name--textonly")).toHaveCSS( + "background-color", + "rgba(0, 0, 0, 0)", + ); + + // Send a message to invite the bots + const composer = app.getComposer().locator("[contenteditable]"); + await composer.fill("Hello}"); + await composer.press("Enter"); + + // Assert that they were invited and joined + await expect(page.getByText(`${botName} joined the room`)).toBeVisible(); + + // Assert that the message is displayed at the bottom + await expect(page.locator(".mx_EventTile_last").getByText("Hello")).toBeVisible(); + }); +}); diff --git a/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-with-user-pill-linux.png b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-with-user-pill-linux.png new file mode 100644 index 0000000000..291c14aba2 Binary files /dev/null and b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-with-user-pill-linux.png differ diff --git a/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-without-user-linux.png b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-without-user-linux.png new file mode 100644 index 0000000000..b9c770d574 Binary files /dev/null and b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-dm-without-user-linux.png differ diff --git a/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-with-user-pill-linux.png b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-with-user-pill-linux.png new file mode 100644 index 0000000000..4cc8edbe92 Binary files /dev/null and b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-with-user-pill-linux.png differ diff --git a/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-without-user-linux.png b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-without-user-linux.png new file mode 100644 index 0000000000..3dfcb57737 Binary files /dev/null and b/playwright/snapshots/invite/invite-dialog.spec.ts/invite-dialog-room-without-user-linux.png differ