You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

101 lines
3.9 KiB

import { test, expect, Page } from '@playwright/test';
import { importUser } from './testUtils';
import { createPerformanceCollector, attachPerformanceData, assertPerformanceMetrics } from './performanceUtils';
async function testProjectGive(page: Page, selector: string, testInfo: any) {
// STEP 1: Initialize the performance collector
const perfCollector = await createPerformanceCollector(page);
// STEP 2: Generate unique test data
const randomString = Math.random().toString(36).substring(2, 6);
const randomNonZeroNumber = Math.floor(Math.random() * 99) + 1;
const standardTitle = 'Gift ';
const finalTitle = standardTitle + randomString;
// STEP 3: Import user and navigate to discover
await perfCollector.measureUserAction('import-user-account', async () => {
await importUser(page, '00');
});
await perfCollector.measureUserAction('navigate-to-discover', async () => {
await page.goto('./discover');
});
const initialMetrics = await perfCollector.collectNavigationMetrics('discover-page-load');
await testInfo.attach('initial-page-load-metrics', {
contentType: 'application/json',
body: JSON.stringify(initialMetrics, null, 2)
});
await perfCollector.measureUserAction('close-onboarding', async () => {
await page.getByTestId('closeOnboardingAndFinish').click();
});
await perfCollector.measureUserAction('select-first-project', async () => {
await page.locator('ul#listDiscoverResults li:first-child a').click();
});
// STEP 4: Wait for project page to load
await perfCollector.measureUserAction('wait-for-project-load', async () => {
await page.waitForLoadState('networkidle');
});
// STEP 5: Handle dialog overlays
await perfCollector.measureUserAction('close-dialog-overlays', async () => {
await page.waitForTimeout(1000);
const closeButtons = page.locator('button[aria-label*="close"], button[aria-label*="Close"], .dialog-overlay button, [role="dialog"] button');
const count = await closeButtons.count();
for (let i = 0; i < count; i++) {
try {
await closeButtons.nth(i).click({ timeout: 2000 });
} catch (e) {
// Ignore errors if button is not clickable
}
}
await page.waitForTimeout(500);
});
// STEP 6: Record gift
await perfCollector.measureUserAction('click-give-button', async () => {
await page.getByTestId(selector).locator('div:first-child div button').click();
});
await perfCollector.measureUserAction('fill-gift-details', async () => {
await page.getByPlaceholder('What was given').fill(finalTitle);
await page.getByRole('spinbutton').fill(randomNonZeroNumber.toString());
});
await perfCollector.measureUserAction('submit-gift', async () => {
await page.getByRole('button', { name: 'Sign & Send' }).click();
await expect(page.getByText('That gift was recorded.')).toBeVisible();
await page.locator('div[role="alert"] button > svg.fa-xmark').click();
});
// STEP 7: Verify gift appears in list
await perfCollector.measureUserAction('refresh-page', async () => {
await page.reload();
});
await perfCollector.measureUserAction('verify-gift-in-list', async () => {
await page
.getByTestId(selector)
.locator('div ul li:first-child')
.filter({ hasText: finalTitle })
.isVisible();
});
// STEP 8: Attach and validate performance data
const { webVitals, performanceReport, summary } = await attachPerformanceData(testInfo, perfCollector);
const avgNavigationTime = perfCollector.navigationMetrics.reduce((sum, nav) =>
sum + nav.metrics.loadComplete, 0) / perfCollector.navigationMetrics.length;
assertPerformanceMetrics(webVitals, initialMetrics, avgNavigationTime);
}
test('Record a give to a project', async ({ page }, testInfo) => {
await testProjectGive(page, 'gives-to', testInfo);
});
test('Record a give from a project', async ({ page }, testInfo) => {
await testProjectGive(page, 'gives-from', testInfo);
});