e073cbd5ea
* fix: resolve flaky team-management E2E test
Fix two failure modes in the 'Can create teams via Wizard' test:
1. Strict mode violation: locator('[data-testid=new-team-btn]') resolves to
2 elements during Next.js streaming/hydration. Fixed by using .first().
2. Race condition in disband assertion: raw .count() check doesn't wait for
UI to update after team deletion. Replaced with Playwright's auto-retrying
toBeHidden() assertion with a 10s timeout.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* chore: remove explanatory comments per review feedback
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
import { expect } from "@playwright/test";
|
|
|
|
import { IS_TEAM_BILLING_ENABLED } from "@calcom/lib/constants";
|
|
import { prisma } from "@calcom/prisma";
|
|
import { MembershipRole } from "@calcom/prisma/enums";
|
|
|
|
import { test } from "../lib/fixtures";
|
|
import { fillStripeTestCheckout } from "../lib/testUtils";
|
|
|
|
test.describe("Teams", () => {
|
|
test.afterEach(({ orgs, users }) => {
|
|
orgs.deleteAll();
|
|
users.deleteAll();
|
|
});
|
|
|
|
test("Can create teams via Wizard", async ({ page, users, orgs }) => {
|
|
const org = await orgs.create({
|
|
name: "TestOrg",
|
|
});
|
|
const user = await users.create(
|
|
{
|
|
organizationId: org.id,
|
|
roleInOrganization: MembershipRole.ADMIN,
|
|
},
|
|
{ hasTeam: true }
|
|
);
|
|
const inviteeEmail = `${user.username}+invitee@example.com`;
|
|
await user.apiLogin();
|
|
await page.goto("/teams");
|
|
|
|
await test.step("Can create team", async () => {
|
|
await page.locator("[data-testid=new-team-btn]").first().click();
|
|
await page.waitForLoadState("networkidle");
|
|
// Fill team name input (new onboarding-v3 style flow)
|
|
await page.locator('[data-testid="team-name-input"]').fill(`${user.username}'s Team`);
|
|
// Click text=Continue
|
|
await page.click("[type=submit]");
|
|
// TODO: Figure out a way to make this more reliable
|
|
// eslint-disable-next-line playwright/no-conditional-in-test
|
|
if (IS_TEAM_BILLING_ENABLED) await fillStripeTestCheckout(page);
|
|
// Wait for the invite email page (new flow)
|
|
await expect(page).toHaveURL(/\/settings\/teams\/new\/invite\/email.*$/i);
|
|
await page.waitForLoadState("networkidle");
|
|
});
|
|
|
|
await test.step("Can add members via email invite", async () => {
|
|
// Add member via email invite form
|
|
await page.locator('input[type="email"]').first().fill(inviteeEmail);
|
|
await page.click("[type=submit]");
|
|
await page.waitForLoadState("networkidle");
|
|
// Wait for redirect to teams page
|
|
await expect(page).toHaveURL(/\/teams$/i);
|
|
});
|
|
|
|
await test.step("Can navigate to team settings", async () => {
|
|
// Click on the team to go to settings
|
|
await page.locator(`text=${user.username}'s Team`).click();
|
|
await page.waitForURL(/\/settings\/teams\/(\d+)\/profile$/i);
|
|
});
|
|
|
|
await test.step("Can disband team", async () => {
|
|
await page.getByTestId("disband-team-button").click();
|
|
await page.getByTestId("dialog-confirmation").click();
|
|
await page.waitForURL("/teams");
|
|
await expect(page.locator(`text=${user.username}'s Team`)).toBeHidden({ timeout: 10000 });
|
|
|
|
// Cleanup the invited user since they were created without our fixtures
|
|
const invitedUser = await prisma.user.findUnique({ where: { email: inviteeEmail } });
|
|
// eslint-disable-next-line playwright/no-conditional-in-test
|
|
if (invitedUser) {
|
|
await prisma.user.delete({ where: { email: inviteeEmail } });
|
|
}
|
|
});
|
|
});
|
|
});
|