first commit
This commit is contained in:
97
calcom/apps/web/playwright/auth/auth-index.e2e.ts
Normal file
97
calcom/apps/web/playwright/auth/auth-index.e2e.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { test } from "../lib/fixtures";
|
||||
|
||||
test.describe("Can signup from a team invite", async () => {
|
||||
test.beforeEach(async ({ users }) => {
|
||||
const proUser = await users.create();
|
||||
await proUser.apiLogin();
|
||||
});
|
||||
test.afterEach(async ({ users }) => users.deleteAll());
|
||||
|
||||
test("Team invites validations work and can accept invite", async ({ browser, page, users, prisma }) => {
|
||||
const [proUser] = users.get();
|
||||
const teamName = `${proUser.username}'s Team`;
|
||||
const testUser = {
|
||||
username: `${proUser.username}-member`,
|
||||
password: `${proUser.username}-member`,
|
||||
email: `${proUser.username}-member@example.com`,
|
||||
};
|
||||
await page.goto("/settings/teams/new");
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
// Create a new team
|
||||
await page.locator('input[name="name"]').fill(teamName);
|
||||
await page.locator('input[name="slug"]').fill(teamName);
|
||||
await page.locator('button[type="submit"]').click();
|
||||
|
||||
// Add new member to team
|
||||
await page.click('[data-testid="new-member-button"]');
|
||||
await page.fill('input[id="inviteUser"]', testUser.email);
|
||||
await page.click('[data-testid="invite-new-member-button"]');
|
||||
|
||||
// TODO: Adapt to new flow
|
||||
|
||||
// Wait for the invite to be sent
|
||||
/*await page.waitForSelector(`[data-testid="member-email"][data-email="${testUser.email}"]`);
|
||||
|
||||
const tokenObj = await prisma.verificationToken.findFirstOrThrow({
|
||||
where: { identifier: testUser.email },
|
||||
select: { token: true },
|
||||
});
|
||||
|
||||
if (!proUser.username) throw Error("Test username is null, can't continue");
|
||||
|
||||
// Open a new user window to accept the invite
|
||||
const newPage = await browser.newPage();
|
||||
await newPage.goto(`/auth/signup?token=${tokenObj.token}&callbackUrl=${WEBAPP_URL}/settings/teams`);
|
||||
|
||||
// Fill in form
|
||||
await newPage.fill('input[name="username"]', proUser.username); // Invalid username
|
||||
await newPage.fill('input[name="email"]', testUser.email);
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
|
||||
await expect(newPage.locator('text="Username already taken"')).toBeVisible();
|
||||
|
||||
// Email address is already registered
|
||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||
await newPage.reload();
|
||||
await newPage.fill('input[name="username"]', testUser.username);
|
||||
await newPage.fill('input[name="email"]', `${proUser.username}@example.com`); // Taken email
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
await expect(newPage.locator('text="Email address is already registered"')).toBeVisible();
|
||||
|
||||
// Successful signup
|
||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||
await newPage.reload();
|
||||
await newPage.fill('input[name="username"]', testUser.username);
|
||||
await newPage.fill('input[name="email"]', testUser.email);
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
await expect(newPage.locator(`[data-testid="login-form"]`)).toBeVisible();
|
||||
|
||||
// We don't need the new browser anymore
|
||||
await newPage.close();
|
||||
|
||||
const createdUser = await prisma.user.findUniqueOrThrow({
|
||||
where: { email: testUser.email },
|
||||
include: { teams: { include: { team: true } } },
|
||||
});
|
||||
|
||||
console.log("createdUser", createdUser);
|
||||
|
||||
// Check that the user was created
|
||||
expect(createdUser).not.toBeNull();
|
||||
expect(createdUser.username).toBe(testUser.username);
|
||||
expect(createdUser.password).not.toBeNull();
|
||||
expect(createdUser.emailVerified).not.toBeNull();
|
||||
// Check that the user accepted the team invite
|
||||
expect(createdUser.teams).toHaveLength(1);
|
||||
expect(createdUser.teams[0].team.name).toBe(teamName);
|
||||
expect(createdUser.teams[0].role).toBe("MEMBER");
|
||||
expect(createdUser.teams[0].accepted).toBe(true);*/
|
||||
});
|
||||
});
|
||||
28
calcom/apps/web/playwright/auth/delete-account.e2e.ts
Normal file
28
calcom/apps/web/playwright/auth/delete-account.e2e.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { test } from "../lib/fixtures";
|
||||
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
test("Can delete user account", async ({ page, users }) => {
|
||||
const user = await users.create({
|
||||
username: "delete-me",
|
||||
});
|
||||
await user.apiLogin();
|
||||
await page.goto(`/settings/my-account/profile`);
|
||||
await page.waitForSelector("[data-testid=dashboard-shell]");
|
||||
|
||||
await page.click("[data-testid=delete-account]");
|
||||
|
||||
expect(user.username).toBeTruthy();
|
||||
|
||||
const $passwordField = page.locator("[data-testid=password]");
|
||||
await $passwordField.fill(String(user.username));
|
||||
|
||||
await Promise.all([
|
||||
page.waitForURL((url) => url.pathname === "/auth/logout"),
|
||||
page.click("text=Delete my account"),
|
||||
]);
|
||||
|
||||
await expect(page.locator(`[id="modal-title"]`)).toHaveText("You've been logged out");
|
||||
});
|
||||
97
calcom/apps/web/playwright/auth/forgot-password.e2e.ts
Normal file
97
calcom/apps/web/playwright/auth/forgot-password.e2e.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { uuid } from "short-uuid";
|
||||
|
||||
import { verifyPassword } from "@calcom/features/auth/lib/verifyPassword";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { test } from "../lib/fixtures";
|
||||
import { testBothFutureAndLegacyRoutes } from "../lib/future-legacy-routes";
|
||||
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
testBothFutureAndLegacyRoutes.describe("Forgot password", async () => {
|
||||
test("Can reset forgotten password", async ({ page, users }) => {
|
||||
const user = await users.create();
|
||||
|
||||
// Got to reset password flow
|
||||
await page.goto("/auth/forgot-password");
|
||||
|
||||
await page.fill('input[name="email"]', `${user.username}@example.com`);
|
||||
await page.press('input[name="email"]', "Enter");
|
||||
|
||||
// wait for confirm page.
|
||||
await page.waitForSelector("text=Reset link sent");
|
||||
|
||||
// As a workaround, we query the db for the last created password request
|
||||
// there should be one, otherwise we throw
|
||||
const { id } = await prisma.resetPasswordRequest.findFirstOrThrow({
|
||||
where: {
|
||||
email: user.email,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
});
|
||||
|
||||
// Test when a user changes his email after starting the password reset flow
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
email: user.email,
|
||||
},
|
||||
data: {
|
||||
email: `${user.username}-2@example.com`,
|
||||
},
|
||||
});
|
||||
|
||||
await page.goto(`/auth/forgot-password/${id}`);
|
||||
|
||||
await page.waitForSelector("text=That request is expired.");
|
||||
|
||||
// Change the email back to continue testing.
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
email: `${user.username}-2@example.com`,
|
||||
},
|
||||
data: {
|
||||
email: user.email,
|
||||
},
|
||||
});
|
||||
|
||||
await page.goto(`/auth/forgot-password/${id}`);
|
||||
|
||||
const newPassword = `${user.username}-123CAL-${uuid().toString()}`; // To match the password policy
|
||||
|
||||
// Wait for page to fully load
|
||||
await page.waitForSelector("text=Reset Password");
|
||||
|
||||
await page.fill('input[name="new_password"]', newPassword);
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
await page.waitForSelector("text=Password updated");
|
||||
|
||||
await expect(page.locator(`text=Password updated`)).toBeVisible();
|
||||
// now we check our DB to confirm the password was indeed updated.
|
||||
// we're not logging in to the UI to speed up test performance.
|
||||
const updatedUser = await prisma.user.findUniqueOrThrow({
|
||||
where: {
|
||||
email: user.email,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
password: true,
|
||||
},
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const updatedPassword = updatedUser.password!.hash;
|
||||
expect(await verifyPassword(newPassword, updatedPassword)).toBeTruthy();
|
||||
|
||||
// finally, make sure the same URL cannot be used to reset the password again, as it should be expired.
|
||||
await page.goto(`/auth/forgot-password/${id}`);
|
||||
|
||||
await expect(page.locator(`text=Whoops`)).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user