Enhance E2E Tests and Configuration (#358)
* Enhance E2E Tests and Configuration - Updated `.gitignore` to exclude `.auth/` directory for cleaner test environment. - Added `test:fast` script in `package.json` for faster Playwright test execution. - Configured Playwright to include a setup project for initializing tests. - Introduced `AUTH_STATES` utility for managing authentication states in tests. - Created `auth.setup.ts` for user authentication tests, ensuring proper login flows. - Refactored various test files to utilize the new authentication state management, improving test reliability and maintainability. - Adjusted team and user billing tests to streamline setup and enhance clarity. - Refactored some dialogs
This commit is contained in:
committed by
GitHub
parent
f157cc7f3e
commit
02e2502dcc
@@ -15,11 +15,24 @@ export class TeamAccountsPageObject {
|
||||
}
|
||||
|
||||
async setup(params = this.createTeamName()) {
|
||||
const { email } = await this.auth.signUpFlow('/home');
|
||||
const auth = new AuthPageObject(this.page);
|
||||
|
||||
const email = auth.createRandomEmail();
|
||||
|
||||
await auth.bootstrapUser({
|
||||
email,
|
||||
name: 'Test User',
|
||||
});
|
||||
|
||||
await auth.loginAsUser({ email });
|
||||
|
||||
await this.createTeam(params);
|
||||
|
||||
return { email, teamName: params.teamName, slug: params.slug };
|
||||
return {
|
||||
email: email,
|
||||
teamName: params.teamName,
|
||||
slug: params.slug,
|
||||
};
|
||||
}
|
||||
|
||||
getTeamFromSelector(teamName: string) {
|
||||
@@ -81,11 +94,12 @@ export class TeamAccountsPageObject {
|
||||
async tryCreateTeam(teamName: string) {
|
||||
await this.page.locator('[data-test="create-team-form"] input').fill('');
|
||||
await this.page.waitForTimeout(200);
|
||||
await this.page.locator('[data-test="create-team-form"] input').fill(teamName);
|
||||
|
||||
return this.page.click(
|
||||
'[data-test="create-team-form"] button:last-child',
|
||||
);
|
||||
await this.page
|
||||
.locator('[data-test="create-team-form"] input')
|
||||
.fill(teamName);
|
||||
|
||||
return this.page.click('[data-test="create-team-form"] button:last-child');
|
||||
}
|
||||
|
||||
async createTeam({ teamName, slug } = this.createTeamName()) {
|
||||
@@ -150,13 +164,13 @@ export class TeamAccountsPageObject {
|
||||
await this.page.click('[data-test="role-selector-trigger"]');
|
||||
await this.page.click(`[data-test="role-option-${newRole}"]`);
|
||||
|
||||
// Click the confirm button
|
||||
const click = this.page.click('[data-test="confirm-update-member-role"]');
|
||||
|
||||
// Wait for the update to complete and page to reload
|
||||
const response = this.page.waitForURL('**/home/*/members');
|
||||
const response = this.page.waitForResponse('**/members');
|
||||
|
||||
return Promise.all([click, response]);
|
||||
return Promise.all([
|
||||
this.page.click('[data-test="confirm-update-member-role"]'),
|
||||
response,
|
||||
]);
|
||||
}).toPass();
|
||||
}
|
||||
|
||||
@@ -172,15 +186,13 @@ export class TeamAccountsPageObject {
|
||||
// Complete OTP verification
|
||||
await this.otp.completeOtpVerification(ownerEmail);
|
||||
|
||||
// Click the confirm button
|
||||
const click = this.page.click(
|
||||
'[data-test="confirm-transfer-ownership-button"]',
|
||||
);
|
||||
|
||||
// Wait for the transfer to complete and page to reload
|
||||
const response = this.page.waitForURL('**/home/*/members');
|
||||
const response = this.page.waitForResponse('**/members');
|
||||
|
||||
return Promise.all([click, response]);
|
||||
return Promise.all([
|
||||
this.page.click('[data-test="confirm-transfer-ownership-button"]'),
|
||||
response,
|
||||
]);
|
||||
}).toPass();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,13 +56,11 @@ async function setupTeamWithMember(page: Page, memberRole = 'member') {
|
||||
|
||||
await page.goto('/auth/sign-in');
|
||||
|
||||
await invitations.auth.signIn({
|
||||
await invitations.auth.loginAsUser({
|
||||
email: ownerEmail,
|
||||
password: 'password',
|
||||
next: '/home',
|
||||
});
|
||||
|
||||
await page.waitForURL('/home');
|
||||
|
||||
// Navigate to the team members page
|
||||
await page.goto(`/home/${slug}/members`);
|
||||
|
||||
@@ -70,17 +68,13 @@ async function setupTeamWithMember(page: Page, memberRole = 'member') {
|
||||
}
|
||||
|
||||
test.describe('Team Accounts', () => {
|
||||
let page: Page;
|
||||
let teamAccounts: TeamAccountsPageObject;
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
teamAccounts = new TeamAccountsPageObject(page);
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
await teamAccounts.setup();
|
||||
});
|
||||
|
||||
test('user can update their team name (and slug)', async () => {
|
||||
await teamAccounts.setup();
|
||||
|
||||
test('user can update their team name (and slug)', async ({ page }) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
const { teamName, slug } = teamAccounts.createTeamName();
|
||||
|
||||
await teamAccounts.goToSettings();
|
||||
@@ -101,7 +95,7 @@ test.describe('Team Accounts', () => {
|
||||
page,
|
||||
}) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
await teamAccounts.setup();
|
||||
await teamAccounts.createTeam();
|
||||
|
||||
await teamAccounts.openAccountsSelector();
|
||||
await page.click('[data-test="create-team-account-trigger"]');
|
||||
@@ -132,16 +126,16 @@ test.describe('Team Accounts', () => {
|
||||
await teamAccounts.tryCreateTeam('Test,Name');
|
||||
await expectError();
|
||||
|
||||
await teamAccounts.tryCreateTeam('Test Name/')
|
||||
await teamAccounts.tryCreateTeam('Test Name/');
|
||||
await expectError();
|
||||
|
||||
await teamAccounts.tryCreateTeam('Test Name\\')
|
||||
await teamAccounts.tryCreateTeam('Test Name\\');
|
||||
await expectError();
|
||||
|
||||
await teamAccounts.tryCreateTeam('Test Name:')
|
||||
await teamAccounts.tryCreateTeam('Test Name:');
|
||||
await expectError();
|
||||
|
||||
await teamAccounts.tryCreateTeam('Test Name;')
|
||||
await teamAccounts.tryCreateTeam('Test Name;');
|
||||
await expectError();
|
||||
|
||||
await teamAccounts.tryCreateTeam('Test Name=');
|
||||
@@ -225,14 +219,11 @@ test.describe('Team Member Role Management', () => {
|
||||
// Update the member's role to admin
|
||||
await teamAccounts.updateMemberRole(memberEmail, 'owner');
|
||||
|
||||
// Wait for the page to fully load after the update
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Verify the role was updated successfully
|
||||
const updatedRoleBadge = page
|
||||
.getByRole('row', { name: memberEmail })
|
||||
.locator('[data-test="member-role-badge"]');
|
||||
await expect(updatedRoleBadge).toHaveText('Owner');
|
||||
await expect(
|
||||
page
|
||||
.getByRole('row', { name: memberEmail })
|
||||
.locator('[data-test="member-role-badge"]'),
|
||||
).toHaveText('Owner');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -250,7 +241,7 @@ test.describe('Team Ownership Transfer', () => {
|
||||
await teamAccounts.transferOwnership(memberEmail, ownerEmail);
|
||||
|
||||
// Wait for the page to fully load after the transfer
|
||||
await page.waitForTimeout(1000);
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Verify the transfer was successful by checking if the primary owner badge
|
||||
// is now on the new owner's row
|
||||
|
||||
@@ -4,8 +4,6 @@ import { AuthPageObject } from '../authentication/auth.po';
|
||||
import { InvitationsPageObject } from '../invitations/invitations.po';
|
||||
import { TeamAccountsPageObject } from './team-accounts.po';
|
||||
|
||||
const MFA_KEY = 'NHOHJVGPO3R3LKVPRMNIYLCDMBHUM2SE';
|
||||
|
||||
test.describe('Team Invitation with MFA Flow', () => {
|
||||
test('complete flow: test@makerkit.dev creates team, invites super-admin@makerkit.dev who accepts after MFA', async ({
|
||||
page,
|
||||
@@ -14,18 +12,12 @@ test.describe('Team Invitation with MFA Flow', () => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
const invitations = new InvitationsPageObject(page);
|
||||
|
||||
const teamName = `test-team-${Math.random().toString(36).substring(2, 15)}`;
|
||||
const teamSlug = teamName.toLowerCase().replace(/ /g, '-');
|
||||
|
||||
// Step 1: test@makerkit.dev creates a team and sends invitation
|
||||
await page.goto('/auth/sign-in');
|
||||
|
||||
await auth.signIn({
|
||||
await auth.loginAsUser({
|
||||
email: 'test@makerkit.dev',
|
||||
password: 'testingpassword',
|
||||
});
|
||||
|
||||
await page.waitForURL('/home');
|
||||
const teamName = `test-team-${Math.random().toString(36).substring(2, 15)}`;
|
||||
const teamSlug = teamName.toLowerCase().replace(/ /g, '-');
|
||||
|
||||
// Create a new team
|
||||
await teamAccounts.createTeam({
|
||||
@@ -46,19 +38,24 @@ test.describe('Team Invitation with MFA Flow', () => {
|
||||
|
||||
// Verify invitation was sent
|
||||
await expect(invitations.getInvitations()).toHaveCount(1);
|
||||
|
||||
const invitationRow = invitations.getInvitationRow(
|
||||
'super-admin@makerkit.dev',
|
||||
);
|
||||
|
||||
await expect(invitationRow).toBeVisible();
|
||||
|
||||
// Sign out test@makerkit.dev
|
||||
await auth.signOut();
|
||||
await page.waitForURL('/');
|
||||
await expect(async () => {
|
||||
// Sign out test@makerkit.dev
|
||||
await auth.signOut();
|
||||
|
||||
// Step 2: super-admin@makerkit.dev signs in with MFA
|
||||
await page.context().clearCookies();
|
||||
await page.waitForURL('/', {
|
||||
timeout: 5_000,
|
||||
});
|
||||
}).toPass();
|
||||
|
||||
await auth.visitConfirmEmailLink('super-admin@makerkit.dev');
|
||||
|
||||
await page
|
||||
.locator('[data-test="existing-account-hint"]')
|
||||
.getByRole('link', { name: 'Already have an account?' })
|
||||
@@ -71,7 +68,7 @@ test.describe('Team Invitation with MFA Flow', () => {
|
||||
|
||||
// Complete MFA verification
|
||||
await expect(async () => {
|
||||
await auth.submitMFAVerification(MFA_KEY);
|
||||
await auth.submitMFAVerification(AuthPageObject.MFA_KEY);
|
||||
}).toPass({
|
||||
intervals: [
|
||||
500, 2500, 5000, 7500, 10_000, 15_000, 20_000, 25_000, 30_000, 35_000,
|
||||
@@ -91,6 +88,7 @@ test.describe('Team Invitation with MFA Flow', () => {
|
||||
// Step 4: Verify membership was successful
|
||||
// Open account selector to verify team is available
|
||||
await teamAccounts.openAccountsSelector();
|
||||
|
||||
const team = teamAccounts.getTeamFromSelector(teamName);
|
||||
|
||||
await expect(team).toBeVisible();
|
||||
|
||||
Reference in New Issue
Block a user