chore: add saml signup test / improve signup e2e test (#16849)

* add comment to signup-view

* add a basic test for saml button in signup

* add a test for cookie consent checkbox

* refactor and remove duplicates

* rename data-testid for saml button

* add test for saml

* remove code not needed

* better naming

* improve

* address code nit

* skip saml test when needed

* fix flag

* improve

* improve more

* refactor

* refactor

* refactor

* fix and add 1 more test

* remove tag

* remove unneeded code

* fix

* fix test

* it needs to be parallel mode

* reduce code

* simplify

* fix

* fix flake

* fix another flake

* add comments + refactor

---------

Co-authored-by: unknown <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
Benny Joo
2024-10-01 09:34:20 +01:00
committed by GitHub
co-authored by unknown Anik Dhabal Babu
parent 2b1cb9f878
commit 5ff52e1239
3 changed files with 167 additions and 51 deletions
+9 -4
View File
@@ -206,10 +206,10 @@ export default function Signup({
}
}, [redirectUrl]);
const [COOKIE_CONSENT, setCOOKIE_CONSENT] = useState(false);
const [userConsentToCookie, setUserConsentToCookie] = useState(false); // No need to be checked for user to proceed
function handleConsentChange(consent: boolean) {
setCOOKIE_CONSENT(!consent);
setUserConsentToCookie(!consent);
}
const loadingSubmitState = isSubmitSuccessful || isSubmitting;
@@ -297,7 +297,7 @@ export default function Signup({
return (
<>
{IS_CALCOM && (!IS_EUROPE || COOKIE_CONSENT) ? (
{IS_CALCOM && (!IS_EUROPE || userConsentToCookie) ? (
<>
{process.env.NEXT_PUBLIC_GTM_ID && (
<>
@@ -342,6 +342,7 @@ export default function Signup({
color="minimal"
className="hover:bg-subtle todesktop:mt-10 mb-6 flex h-6 max-h-6 w-full items-center rounded-md px-3 py-2"
StartIcon="arrow-left"
data-testid="signup-back-button"
onClick={() => {
setDisplayEmailForm(false);
setIsSamlSignup(false);
@@ -432,7 +433,8 @@ export default function Signup({
) : null}
<CheckboxField
onChange={() => handleConsentChange(COOKIE_CONSENT)}
data-testid="signup-cookie-content-checkbox"
onChange={() => handleConsentChange(userConsentToCookie)}
description={t("cookie_consent_checkbox")}
/>
{errors.apiError && (
@@ -445,6 +447,7 @@ export default function Signup({
)}
{isSamlSignup ? (
<Button
data-testid="saml-submit-button"
color="primary"
disabled={
!!formMethods.formState.errors.username ||
@@ -457,6 +460,7 @@ export default function Signup({
onClick={() => {
const username = formMethods.getValues("username");
if (!username) {
// should not be reached but needed to bypass type errors
showToast("error", t("username_required"));
return;
}
@@ -572,6 +576,7 @@ export default function Signup({
</Button>
{isSAMLLoginEnabled && (
<Button
data-testid="continue-with-saml-button"
color="minimal"
disabled={isGoogleLoading}
className={classNames("w-full justify-center rounded-md text-center")}
+66 -2
View File
@@ -1,17 +1,81 @@
import { IS_SAML_LOGIN_ENABLED } from "../server/lib/constants";
import { expect } from "@playwright/test";
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
import { IS_PREMIUM_USERNAME_ENABLED } from "@calcom/lib/constants";
import { login } from "./fixtures/users";
import { test } from "./lib/fixtures";
test.describe.configure({ mode: "parallel" });
test.describe("SAML tests", () => {
// eslint-disable-next-line playwright/no-skipped-test
test.skip(!isSAMLLoginEnabled, "Skipping due to SAML login being disabled");
test("test SAML configuration UI with pro@example.com", async ({ page }) => {
// TODO: Figure out a way to use the users from fixtures here, right now we cannot set
// the SAML_ADMINS env variables dynamically
await login({ username: "pro", email: "pro@example.com", password: "pro" }, page);
// eslint-disable-next-line playwright/no-skipped-test
test.skip(!IS_SAML_LOGIN_ENABLED, "It should only run if SAML is enabled");
// Try to go Security page
await page.goto("/settings/security/sso");
// It should redirect you to the event-types page
// await page.waitForSelector("[data-testid=saml_config]");
});
test.describe("SAML Signup Flow Test", async () => {
test.beforeEach(async ({ page }) => {
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible(); // this prevents flaky test
await page.getByTestId("continue-with-saml-button").click();
await page.waitForSelector('[data-testid="saml-submit-button"]');
});
test("Submit button should be disabled without username", async ({ page }) => {
await page.locator('input[name="email"]').fill("tester123@example.com");
const submitButton = page.getByTestId("saml-submit-button");
await expect(submitButton).toBeVisible();
await expect(submitButton).toBeDisabled();
});
test("Submit button should be disabled without email", async ({ page }) => {
await page.locator('input[name="username"]').fill("tester123");
const submitButton = page.getByTestId("saml-submit-button");
await expect(submitButton).toBeVisible();
await expect(submitButton).toBeDisabled();
});
test("Password input should not exist", async ({ page }) => {
await expect(page.locator('input[name="password"]')).toBeHidden();
});
test("Checkbox for cookie consent does not need to be checked", async ({ page }) => {
// Fill form
await page.locator('input[name="username"]').fill("tester123");
await page.locator('input[name="email"]').fill("tester123@example.com");
const submitButton = page.getByTestId("saml-submit-button");
const checkbox = page.getByTestId("signup-cookie-content-checkbox");
await checkbox.check();
await expect(submitButton).toBeEnabled();
// the cookie consent checkbox does not need to be checked for user to proceed
await checkbox.uncheck();
await expect(submitButton).toBeEnabled();
});
test("Submit button should be disabled with a premium username", async ({ page }) => {
// eslint-disable-next-line playwright/no-skipped-test
test.skip(!IS_PREMIUM_USERNAME_ENABLED, "Only run on Cal.com");
// Fill form
await page.locator('input[name="username"]').fill("pro");
await page.locator('input[name="email"]').fill("pro@example.com");
// Submit form
const submitButton = page.getByTestId("saml-submit-button");
await expect(submitButton).toBeDisabled();
});
});
});
+92 -45
View File
@@ -1,4 +1,4 @@
import { expect } from "@playwright/test";
import { expect, Page } from "@playwright/test";
import { randomBytes } from "crypto";
import { APP_NAME, IS_PREMIUM_USERNAME_ENABLED, IS_MAILHOG_ENABLED } from "@calcom/lib/constants";
@@ -10,23 +10,38 @@ import { expectInvitationEmailToBeReceived } from "./team/expects";
test.describe.configure({ mode: "parallel" });
const preventFlakyTest = async (page: Page) => {
await expect(page.locator("text=Create your account")).toBeVisible();
};
test.describe("Signup Main Page Test", async () => {
test.beforeEach(async ({ features }) => {
features.reset();
test.beforeEach(async ({ page }) => {
await page.goto("/signup");
await preventFlakyTest(page);
});
test("Continue with email button must exist / work", async ({ page }) => {
await page.goto("/signup");
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
const button = page.getByTestId("continue-with-email-button");
await expect(button).toBeVisible();
await expect(button).toBeEnabled();
await button.click();
await expect(page.getByTestId("signup-back-button")).toBeVisible();
});
test("Continue with google button must exist / work", async ({ page }) => {
await page.goto("/signup");
await expect(page.locator('[data-testid="continue-with-google-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-google-button"]').click();
const button = page.getByTestId("continue-with-google-button");
await expect(button).toBeVisible();
await expect(button).toBeEnabled();
await button.click();
await page.waitForURL("/auth/sso/google");
});
test("Continue with SAML button must exist / work", async ({ page }) => {
const button = page.getByTestId("continue-with-saml-button");
await expect(button).toBeVisible();
await expect(button).toBeEnabled();
await button.click();
await expect(page.getByTestId("signup-back-button")).toBeVisible();
});
});
test.describe("Email Signup Flow Test", async () => {
@@ -44,10 +59,10 @@ test.describe("Email Signup Flow Test", async () => {
});
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
const alertMessage = "Username or email is already taken";
@@ -57,7 +72,8 @@ test.describe("Email Signup Flow Test", async () => {
await page.locator('input[name="password"]').fill("Password99!");
// Submit form
await page.click('button[type="submit"]');
const submitButton = page.getByTestId("signup-submit-button");
await submitButton.click();
const alert = await page.waitForSelector('[data-testid="alert"]');
const alertMessageInner = await alert.innerText();
@@ -74,10 +90,10 @@ test.describe("Email Signup Flow Test", async () => {
});
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
const alertMessage = "Username or email is already taken";
@@ -87,8 +103,9 @@ test.describe("Email Signup Flow Test", async () => {
await page.locator('input[name="password"]').fill("Password99!");
// Submit form
const submitButton = page.getByTestId("signup-submit-button");
await submitButton.click();
await page.click('button[type="submit"]');
const alert = await page.waitForSelector('[data-testid="alert"]');
const alertMessageInner = await alert.innerText();
@@ -108,17 +125,19 @@ test.describe("Email Signup Flow Test", async () => {
// Signup with premium username name
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
// Fill form
await page.locator('input[name="username"]').fill("rock");
await page.locator('input[name="email"]').fill(userToCreate.email);
await page.locator('input[name="password"]').fill(userToCreate.password);
await page.click('button[type="submit"]');
// Submit form
const submitButton = page.getByTestId("signup-submit-button");
await submitButton.click();
// Check that stripe checkout is present
const expectedUrl = "https://checkout.stripe.com";
@@ -130,7 +149,7 @@ test.describe("Email Signup Flow Test", async () => {
expect(url).toContain(expectedUrl);
// TODO: complete the stripe checkout flow
});
test("Signup with valid (non premium) username", async ({ page, users, features }) => {
test("Signup with valid (non premium) username", async ({ page, users }) => {
const userToCreate = users.buildForSignup({
username: "rick-jones",
password: "Password99!",
@@ -139,17 +158,20 @@ test.describe("Email Signup Flow Test", async () => {
});
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
// Fill form
await page.locator('input[name="username"]').fill(userToCreate.username);
await page.locator('input[name="email"]').fill(userToCreate.email);
await page.locator('input[name="password"]').fill(userToCreate.password);
await page.click('button[type="submit"]');
// Submit form
const submitButton = page.getByTestId("signup-submit-button");
await submitButton.click();
await page.waitForURL("/auth/verify-email**");
// Check that the URL matches the expected URL
@@ -161,10 +183,11 @@ test.describe("Email Signup Flow Test", async () => {
test("Signup fields prefilled with query params", async ({ page, users }) => {
const signupUrlWithParams = "/signup?username=rick-jones&email=rick-jones%40example.com";
await page.goto(signupUrlWithParams);
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
await expect(page.getByTestId("signup-submit-button")).toBeVisible();
// Fill form
const usernameInput = page.locator('input[name="username"]');
@@ -214,8 +237,8 @@ test.describe("Email Signup Flow Test", async () => {
const signupUrlWithToken = `/signup?token=${token}`;
await page.goto(signupUrlWithToken);
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
await expect(page.getByTestId("signup-submit-button")).toBeVisible();
const usernameField = page.locator('input[name="username"]');
const emailField = page.locator('input[name="email"]');
@@ -246,18 +269,18 @@ test.describe("Email Signup Flow Test", async () => {
});
await page.goto("/signup");
await expect(page.locator("text=Create your account")).toBeVisible();
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
await preventFlakyTest(page);
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
// Fill form
await page.locator('input[name="username"]').fill(userToCreate.username);
await page.locator('input[name="email"]').fill(userToCreate.email);
await page.locator('input[name="password"]').fill(userToCreate.password);
const submitButton = page.locator('button[type="submit"]');
await expect(submitButton).toBeEnabled();
// Submit form
const submitButton = page.getByTestId("signup-submit-button");
await submitButton.click();
await page.waitForURL((url) => url.pathname.includes("/auth/verify-email"));
@@ -320,9 +343,10 @@ test.describe("Email Signup Flow Test", async () => {
const url = new URL(newPage.url());
expect(url.pathname).toBe("/signup");
await expect(page.locator('[data-testid="continue-with-email-button"]')).toBeVisible();
await page.locator('[data-testid="continue-with-email-button"]').click();
await expect(page.locator('[data-testid="signup-submit-button"]')).toBeVisible();
const continueWithEmailButton = page.getByTestId("continue-with-email-button");
await expect(continueWithEmailButton).toBeVisible();
await continueWithEmailButton.click();
await expect(page.getByTestId("signup-submit-button")).toBeVisible();
// Check required fields
await newPage.locator("input[name=password]").fill(`P4ssw0rd!`);
await newPage.locator("button[type=submit]").click();
@@ -331,4 +355,27 @@ test.describe("Email Signup Flow Test", async () => {
await context.close();
});
});
test("Checkbox for cookie consent does not need to be checked", async ({ page, users }) => {
await page.goto("/signup");
await preventFlakyTest(page);
// Navigate to email form
await page.getByTestId("continue-with-email-button").click();
// Fill form
await page.locator('input[name="username"]').fill("pro");
await page.locator('input[name="email"]').fill("pro@example.com");
await page.locator('input[name="password"]').fill("Password99!");
const submitButton = page.getByTestId("signup-submit-button");
const checkbox = page.getByTestId("signup-cookie-content-checkbox");
await checkbox.check();
await expect(submitButton).toBeEnabled();
// the cookie consent checkbox does not need to be checked for user to proceed
await checkbox.uncheck();
await expect(submitButton).toBeEnabled();
});
});