Feature/goal reduce flaky tests (#4247)
* Wait for current_password input to be visible * Login flow remove duplication + small fix change-password * Made hash-my-url more robust * Wait until locale is ready to resolve test flackiness * Added waitForSelector before trying to fill inputs
This commit is contained in:
1 parent
de54d75cd3
commit
d36d925788
4 files changed
+97
-82
No files matched your search
@@ -1,17 +1,20 @@
|
||||
import React, { SyntheticEvent, useState } from "react";
|
||||
|
||||
import { ErrorCode } from "@calcom/lib/auth";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import showToast from "@calcom/lib/notification";
|
||||
import Button from "@calcom/ui/Button";
|
||||
|
||||
import { ErrorCode } from "@lib/auth";
|
||||
import { useLocale } from "@lib/hooks/useLocale";
|
||||
|
||||
const ChangePasswordSection = () => {
|
||||
const [oldPassword, setOldPassword] = useState("");
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const { t } = useLocale();
|
||||
const { t, isLocaleReady } = useLocale();
|
||||
// hold display until the locale is loaded
|
||||
if (!isLocaleReady) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const errorMessages: { [key: string]: string } = {
|
||||
[ErrorCode.IncorrectPassword]: t("current_incorrect_password"),
|
||||
|
||||
@@ -4,7 +4,7 @@ import { test } from "./lib/fixtures";
|
||||
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
test.describe("Change Passsword Test", () => {
|
||||
test.describe("Change Password Test", () => {
|
||||
test("change password", async ({ page, users }) => {
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
@@ -14,6 +14,7 @@ test.describe("Change Passsword Test", () => {
|
||||
if (!pro.username) throw Error("Test user doesn't have a username");
|
||||
|
||||
// Fill form
|
||||
await page.waitForSelector('[name="current_password"]');
|
||||
await page.fill('[name="current_password"]', pro.username);
|
||||
await page.fill('[name="new_password"]', `${pro.username}1111`);
|
||||
await page.press('[name="new_password"]', "Enter");
|
||||
|
||||
@@ -18,25 +18,20 @@ test.describe("hash my url", () => {
|
||||
await page.goto("/event-types");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
await page.click('//ul[@data-testid="event-types"]/li[1]');
|
||||
await page.locator('//ul[@data-testid="event-types"]/li[1]').click();
|
||||
// We wait for the page to load
|
||||
await page.waitForSelector('//*[@data-testid="show-advanced-settings"]');
|
||||
await page.click('//*[@data-testid="show-advanced-settings"]');
|
||||
// we wait for the hashedLink setting to load
|
||||
await page.waitForSelector('//*[@id="hashedLinkCheck"]');
|
||||
await page.locator('//*[@data-testid="show-advanced-settings"]').click();
|
||||
// ignore if it is already checked, and click if unchecked
|
||||
const isChecked = await page.isChecked('//*[@id="hashedLinkCheck"]');
|
||||
!isChecked && (await page.click('//*[@id="hashedLinkCheck"]'));
|
||||
// we wait for the hashedLink setting to load
|
||||
await page.waitForSelector('//*[@data-testid="generated-hash-url"]');
|
||||
const $url = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
|
||||
// click update
|
||||
await page.focus('//button[@type="submit"]');
|
||||
await page.keyboard.press("Enter");
|
||||
const hashedLinkCheck = await page.locator('[id="hashedLinkCheck"]');
|
||||
|
||||
// To prevent an early 404
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
!(await hashedLinkCheck.isChecked()) && (await hashedLinkCheck.click());
|
||||
|
||||
// we wait for the hashedLink setting to load
|
||||
const $url = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
|
||||
|
||||
// click update
|
||||
await page.locator('[data-testid="update-eventtype"]').press("Enter");
|
||||
await page.waitForURL("/event-types");
|
||||
|
||||
// book using generated url hash
|
||||
await page.goto($url);
|
||||
@@ -51,10 +46,8 @@ test.describe("hash my url", () => {
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
await page.click('//ul[@data-testid="event-types"]/li[1]');
|
||||
// We wait for the page to load
|
||||
await page.waitForSelector('//*[@data-testid="show-advanced-settings"]');
|
||||
await page.click('//*[@data-testid="show-advanced-settings"]');
|
||||
await page.locator('//*[@data-testid="show-advanced-settings"]').click();
|
||||
// we wait for the hashedLink setting to load
|
||||
await page.waitForSelector('//*[@data-testid="generated-hash-url"]');
|
||||
const $newUrl = await page.locator('//*[@data-testid="generated-hash-url"]').inputValue();
|
||||
expect($url !== $newUrl).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -7,12 +7,67 @@ import { localize } from "./lib/testUtils";
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Login and logout tests", () => {
|
||||
test.afterEach(async ({ users }) => {
|
||||
// a test to logout requires both a succesfull login as logout, to prevent
|
||||
// a doubling of tests failing on logout & logout, we can group them.
|
||||
test.describe("user can login & logout succesfully", async () => {
|
||||
test.afterAll(async ({ users }) => {
|
||||
await users.deleteAll();
|
||||
});
|
||||
test("login flow TRAIL user & logout using dashboard", async ({ page, users }) => {
|
||||
// log in trail user
|
||||
await test.step("Log in", async () => {
|
||||
const user = await users.create({ plan: UserPlan.TRIAL });
|
||||
await user.login();
|
||||
|
||||
const shellLocator = page.locator(`[data-testid=dashboard-shell]`);
|
||||
|
||||
// expects the home page for an authorized user
|
||||
await page.goto("/");
|
||||
await expect(shellLocator).toBeVisible();
|
||||
|
||||
// Asserts to read the tested plan
|
||||
const planLocator = shellLocator.locator(`[data-testid=plan-trial]`);
|
||||
await expect(planLocator).toBeVisible();
|
||||
await expect(planLocator).toHaveText("-TRIAL");
|
||||
|
||||
await expect(page.locator(`[data-testid=trial-banner]`)).toBeVisible();
|
||||
});
|
||||
|
||||
//
|
||||
await test.step("Log out", async () => {
|
||||
const signOutLabel = (await localize("en"))("sign_out");
|
||||
const userDropdownDisclose = async () => page.locator("[data-testid=user-dropdown-trigger]").click();
|
||||
|
||||
// disclose and click the sign out button from the user dropdown
|
||||
await userDropdownDisclose();
|
||||
const signOutBtn = await page.locator(`text=${signOutLabel}`);
|
||||
await signOutBtn.click();
|
||||
|
||||
// 2s of delay to assure the session is cleared
|
||||
await page.waitForURL("/auth/logout");
|
||||
|
||||
// Reroute to the home page to check if the login form shows up
|
||||
await page.goto("/");
|
||||
await expect(page.locator(`[data-testid=login-form]`)).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Login and logout tests", () => {
|
||||
test.afterAll(async ({ users }) => {
|
||||
await users.deleteAll();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ users, page }) => {
|
||||
await users.logout();
|
||||
|
||||
// check if we are at the login page
|
||||
await page.goto("/");
|
||||
await expect(page.locator(`[data-testid=login-form]`)).toBeVisible();
|
||||
});
|
||||
|
||||
// Test login with all plans
|
||||
const plans = [UserPlan.PRO, UserPlan.FREE, UserPlan.TRIAL];
|
||||
const plans = [UserPlan.PRO, UserPlan.FREE];
|
||||
plans.forEach((plan) => {
|
||||
test(`Should login with a ${plan} account`, async ({ page, users }) => {
|
||||
// Create user and login
|
||||
@@ -29,68 +84,31 @@ test.describe("Login and logout tests", () => {
|
||||
const planLocator = shellLocator.locator(`[data-testid=plan-${plan.toLowerCase()}]`);
|
||||
await expect(planLocator).toBeVisible();
|
||||
await expect(planLocator).toHaveText(`-${plan}`);
|
||||
|
||||
// When TRIAL check if the TRIAL banner is visible
|
||||
if (plan === UserPlan.TRIAL) {
|
||||
await expect(page.locator(`[data-testid=trial-banner]`)).toBeVisible();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("Should warn when user does not exist", async ({ page }) => {
|
||||
const alertMessage = (await localize("en"))("no_account_exists");
|
||||
test.describe("Login flow validations", async () => {
|
||||
test("Should warn when user does not exist", async ({ page }) => {
|
||||
const alertMessage = (await localize("en"))("no_account_exists");
|
||||
|
||||
// Login with a non-existent user
|
||||
const never = "never";
|
||||
await login({ username: never }, page);
|
||||
// Login with a non-existent user
|
||||
const never = "never";
|
||||
await login({ username: never }, page);
|
||||
|
||||
// assert for the visibility of the localized alert message
|
||||
await expect(page.locator(`text=${alertMessage}`)).toBeVisible();
|
||||
});
|
||||
// assert for the visibility of the localized alert message
|
||||
await expect(page.locator(`text=${alertMessage}`)).toBeVisible();
|
||||
});
|
||||
|
||||
test("Should warn when password is incorrect", async ({ page, users }) => {
|
||||
const alertMessage = (await localize("en"))("incorrect_password");
|
||||
// by default password===username with the users fixture
|
||||
const pro = await users.create({ username: "pro" });
|
||||
test("Should warn when password is incorrect", async ({ page, users }) => {
|
||||
const alertMessage = (await localize("en"))("incorrect_password");
|
||||
// by default password===username with the users fixture
|
||||
const pro = await users.create({ username: "pro" });
|
||||
|
||||
// login with a wrong password
|
||||
await login({ username: pro.username, password: "wrong" }, page);
|
||||
// login with a wrong password
|
||||
await login({ username: pro.username, password: "wrong" }, page);
|
||||
|
||||
// assert for the visibility of the localized alert message
|
||||
await expect(page.locator(`text=${alertMessage}`)).toBeVisible();
|
||||
});
|
||||
|
||||
test("Should logout", async ({ page, users }) => {
|
||||
const signOutLabel = (await localize("en"))("sign_out");
|
||||
const userDropdownDisclose = async () => page.locator("[data-testid=user-dropdown-trigger]").click();
|
||||
|
||||
// creates a user and login
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
|
||||
// disclose and click the sign out button from the user dropdown
|
||||
await userDropdownDisclose();
|
||||
const signOutBtn = page.locator(`text=${signOutLabel}`);
|
||||
await signOutBtn.click();
|
||||
|
||||
// 2s of delay to assure the session is cleared
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Reroute to the home page to check if the login form shows up
|
||||
await page.goto("/");
|
||||
await expect(page.locator(`[data-testid=login-form]`)).toBeVisible();
|
||||
});
|
||||
|
||||
test("Should logout using the logout route", async ({ page, users }) => {
|
||||
// creates a user and login
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
|
||||
// users.logout() action uses the logout route "/auth/logout" to clear the session
|
||||
await users.logout();
|
||||
|
||||
// check if we are at the login page
|
||||
await page.goto("/");
|
||||
await expect(page.locator(`[data-testid=login-form]`)).toBeVisible();
|
||||
// assert for the visibility of the localized alert message
|
||||
await expect(page.locator(`text=${alertMessage}`)).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user