191 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
| /*
 | |
| Copyright 2024 New Vector Ltd.
 | |
| Copyright 2023 Suguru Hirahara
 | |
| 
 | |
| SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
 | |
| Please see LICENSE files in the repository root for full details.
 | |
| */
 | |
| 
 | |
| import { test, expect } from "../../element-web-test";
 | |
| 
 | |
| const USER_NAME = "Bob";
 | |
| const USER_NAME_NEW = "Alice";
 | |
| 
 | |
| test.describe("Account user settings tab", () => {
 | |
|     test.use({
 | |
|         displayName: USER_NAME,
 | |
|         config: {
 | |
|             default_country_code: "US", // For checking the international country calling code
 | |
|         },
 | |
|         uut: async ({ app, user }, use) => {
 | |
|             const locator = await app.settings.openUserSettings("Account");
 | |
|             await use(locator);
 | |
|         },
 | |
|     });
 | |
| 
 | |
|     test("should be rendered properly", async ({ uut, user }) => {
 | |
|         await expect(uut).toMatchScreenshot("account.png");
 | |
| 
 | |
|         // Assert that the top heading is rendered
 | |
|         await expect(uut.getByRole("heading", { name: "Account", exact: true })).toBeVisible();
 | |
| 
 | |
|         const profile = uut.locator(".mx_UserProfileSettings_profile");
 | |
|         await profile.scrollIntoViewIfNeeded();
 | |
|         await expect(profile.getByRole("textbox", { name: "Display Name" })).toHaveValue(USER_NAME);
 | |
| 
 | |
|         // Assert that a userId is rendered
 | |
|         expect(uut.getByLabel("Username")).toHaveText(user.userId);
 | |
| 
 | |
|         // Wait until spinners disappear
 | |
|         await expect(uut.getByTestId("accountSection").locator(".mx_Spinner")).not.toBeVisible();
 | |
|         await expect(uut.getByTestId("discoverySection").locator(".mx_Spinner")).not.toBeVisible();
 | |
| 
 | |
|         const accountSection = uut.getByTestId("accountSection");
 | |
|         accountSection.scrollIntoViewIfNeeded();
 | |
|         // Assert that input areas for changing a password exists
 | |
|         await expect(accountSection.getByLabel("Current password")).toBeVisible();
 | |
|         await expect(accountSection.getByLabel("New Password")).toBeVisible();
 | |
|         await expect(accountSection.getByLabel("Confirm password")).toBeVisible();
 | |
| 
 | |
|         // Check email addresses area
 | |
|         const emailAddresses = uut.getByTestId("mx_AccountEmailAddresses");
 | |
|         await emailAddresses.scrollIntoViewIfNeeded();
 | |
|         // Assert that an input area for a new email address is rendered
 | |
|         await expect(emailAddresses.getByRole("textbox", { name: "Email Address" })).toBeVisible();
 | |
|         // Assert the add button is visible
 | |
|         await expect(emailAddresses.getByRole("button", { name: "Add" })).toBeVisible();
 | |
| 
 | |
|         // Check phone numbers area
 | |
|         const phoneNumbers = uut.getByTestId("mx_AccountPhoneNumbers");
 | |
|         await phoneNumbers.scrollIntoViewIfNeeded();
 | |
|         // Assert that an input area for a new phone number is rendered
 | |
|         await expect(phoneNumbers.getByRole("textbox", { name: "Phone Number" })).toBeVisible();
 | |
|         // Assert that the add button is rendered
 | |
|         await expect(phoneNumbers.getByRole("button", { name: "Add" })).toBeVisible();
 | |
| 
 | |
|         // Assert the account deactivation button is displayed
 | |
|         const accountManagementSection = uut.getByTestId("account-management-section");
 | |
|         await accountManagementSection.scrollIntoViewIfNeeded();
 | |
|         await expect(accountManagementSection.getByRole("button", { name: "Deactivate Account" })).toHaveClass(
 | |
|             /mx_AccessibleButton_kind_danger/,
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     test("should respond to small screen sizes", async ({ page, uut }) => {
 | |
|         await page.setViewportSize({ width: 700, height: 600 });
 | |
|         await expect(uut).toMatchScreenshot("account-smallscreen.png");
 | |
|     });
 | |
| 
 | |
|     test("should show tooltips on narrow screen", async ({ page, uut }) => {
 | |
|         await page.setViewportSize({ width: 700, height: 600 });
 | |
|         await page.getByRole("tab", { name: "Account" }).hover();
 | |
|         await expect(page.getByRole("tooltip")).toHaveText("Account");
 | |
|     });
 | |
| 
 | |
|     test("should support adding and removing a profile picture", async ({ uut, page }) => {
 | |
|         const profileSettings = uut.locator(".mx_UserProfileSettings");
 | |
|         // Upload a picture
 | |
|         await profileSettings.getByAltText("Upload").setInputFiles("playwright/sample-files/riot.png");
 | |
| 
 | |
|         // Image should be visible
 | |
|         await expect(profileSettings.locator(".mx_AvatarSetting_avatar img")).toBeVisible();
 | |
| 
 | |
|         // Open the menu & click remove
 | |
|         await profileSettings.getByRole("button", { name: "Profile Picture" }).click();
 | |
|         await page.getByRole("menuitem", { name: "Remove" }).click();
 | |
| 
 | |
|         // Assert that the image disappeared
 | |
|         await expect(profileSettings.locator(".mx_AvatarSetting_avatar img")).not.toBeVisible();
 | |
|     });
 | |
| 
 | |
|     test("should set a country calling code based on default_country_code", async ({ uut }) => {
 | |
|         // Check phone numbers area
 | |
|         const accountPhoneNumbers = uut.getByTestId("mx_AccountPhoneNumbers");
 | |
|         await accountPhoneNumbers.scrollIntoViewIfNeeded();
 | |
|         // Assert that an input area for a new phone number is rendered
 | |
|         await expect(accountPhoneNumbers.getByRole("textbox", { name: "Phone Number" })).toBeVisible();
 | |
| 
 | |
|         // Check a new phone number dropdown menu
 | |
|         const dropdown = accountPhoneNumbers.locator(".mx_PhoneNumbers_country");
 | |
|         await dropdown.scrollIntoViewIfNeeded();
 | |
|         // Assert that the country calling code of the United States is visible
 | |
|         await expect(dropdown.getByText(/\+1/)).toBeVisible();
 | |
| 
 | |
|         // Click the button to display the dropdown menu
 | |
|         await dropdown.getByRole("button", { name: "Country Dropdown" }).click();
 | |
| 
 | |
|         // Assert that the option for calling code of the United Kingdom is visible
 | |
|         await expect(dropdown.getByRole("option", { name: /United Kingdom/ })).toBeVisible();
 | |
| 
 | |
|         // Click again to close the dropdown
 | |
|         await dropdown.getByRole("button", { name: "Country Dropdown" }).click();
 | |
| 
 | |
|         // Assert that the default value is rendered again
 | |
|         await expect(dropdown.getByText(/\+1/)).toBeVisible();
 | |
| 
 | |
|         await expect(accountPhoneNumbers.getByRole("button", { name: "Add" })).toBeVisible();
 | |
|     });
 | |
| 
 | |
|     test("should support changing a display name", async ({ uut, page, app }) => {
 | |
|         // Change the diaplay name to USER_NAME_NEW
 | |
|         const displayNameInput = uut
 | |
|             .locator(".mx_SettingsTab .mx_UserProfileSettings")
 | |
|             .getByRole("textbox", { name: "Display Name" });
 | |
|         await displayNameInput.fill(USER_NAME_NEW);
 | |
|         await displayNameInput.press("Enter");
 | |
| 
 | |
|         await app.closeDialog();
 | |
| 
 | |
|         // Assert the avatar's initial characters are set
 | |
|         await expect(page.locator(".mx_UserMenu .mx_BaseAvatar").getByText("A")).toBeVisible(); // Alice
 | |
|         await expect(page.locator(".mx_RoomView_wrapper .mx_BaseAvatar").getByText("A")).toBeVisible(); // Alice
 | |
|     });
 | |
| 
 | |
|     // ported to a playwright test because the jest test was very flakey for no obvious reason
 | |
|     test("should display an error if the code is incorrect when adding a phone number", async ({ uut, page }) => {
 | |
|         const dummyUrl = "https://nowhere.dummy/_matrix/client/unstable/add_threepid/msisdn/submit_token";
 | |
| 
 | |
|         await page.route(
 | |
|             `**/_matrix/client/v3/account/3pid/msisdn/requestToken`,
 | |
|             async (route) => {
 | |
|                 await route.fulfill({
 | |
|                     json: {
 | |
|                         success: true,
 | |
|                         sid: "1",
 | |
|                         msisdn: "447700900000",
 | |
|                         intl_fmt: "+44 7700 900000",
 | |
|                         submit_url: dummyUrl,
 | |
|                     },
 | |
|                 });
 | |
|             },
 | |
|             { times: 1 },
 | |
|         );
 | |
| 
 | |
|         await page.route(
 | |
|             dummyUrl,
 | |
|             async (route) => {
 | |
|                 await route.fulfill({
 | |
|                     status: 400,
 | |
|                     json: {
 | |
|                         errcode: "M_THREEPID_AUTH_FAILED",
 | |
|                         error: "That code is definitely wrong",
 | |
|                     },
 | |
|                 });
 | |
|             },
 | |
|             { times: 1 },
 | |
|         );
 | |
| 
 | |
|         const phoneSection = page.getByTestId("mx_AccountPhoneNumbers");
 | |
|         await phoneSection.getByRole("textbox", { name: "Phone Number" }).fill("07700900000");
 | |
|         await phoneSection.getByRole("button", { name: "Add" }).click();
 | |
| 
 | |
|         await phoneSection
 | |
|             .getByRole("textbox", { name: "Verification code" })
 | |
|             .fill("A small eurasian field mouse dancing the paso doble");
 | |
| 
 | |
|         await phoneSection.getByRole("button", { name: "Continue" }).click();
 | |
| 
 | |
|         await expect(page.getByRole("heading", { name: "Unable to verify phone number." })).toBeVisible();
 | |
|     });
 | |
| });
 |