/** * @file Bulk Project Creation Test Suite * @description Tests TimeSafari's project creation functionality under load by creating multiple projects in sequence * * This test verifies: * 1. Scalability * - System can handle creation of multiple projects (10) * - Performance remains stable across iterations * - No data corruption during bulk operations * * 2. Data Integrity * - Each project has unique identifiers * - All projects are properly stored and retrievable * - No cross-contamination between project data * * 3. UI Responsiveness * - Interface remains responsive during bulk operations * - Feedback is provided for each creation * - No memory leaks or performance degradation * * Test Flow: * 1. Setup Phase * - Generate array of unique identifiers * - Prepare standard text templates * - Calculate common date/time values * - Import test user (User 00) * * 2. Bulk Creation (10 iterations) * - Navigate to projects page * - Handle first-time onboarding dialog * - Create project with unique data * - Verify project creation success * - Confirm project details display correctly * * Test Data: * - Project Count: 10 projects * - Title Format: "Idea [unique-string]" * - Description Format: "Description of Idea [unique-string]" * - Website: https://example.com (common across all) * - Start Date: Current date + 30 days * - Start Time: Current time + 1 hour * * Key Selectors: * - Project title: 'h2' * - Project content: '#Content' * - New project button: 'button > svg.fa-plus' * - Onboarding close: 'div > svg.fa-xmark' * * Performance Considerations: * - Uses test.slow() to extend timeout * - Handles potential UI lag between operations * - Manages memory usage during bulk operations * * Error Handling: * - Closes onboarding dialog only on first iteration * - Verifies each project individually * - Maintains operation even if individual creations fail * * Related Files: * - Project utilities: ./testUtils * - JWT handling: sw_scripts/safari-notifications.js * - Project view: src/views/ProjectView.vue * * @see Documentation in usage-guide.md for project creation workflows * @requires @playwright/test * @requires ./testUtils - For user management and string generation * * @example * ```typescript * // Generate unique strings for multiple projects * const uniqueStrings = await createUniqueStringsArray(10); * * // Create projects in sequence * for (let i = 0; i < projectCount; i++) { * await page.goto('./projects'); * await page.locator('button > svg.fa-plus').click(); * await page.getByPlaceholder('Idea Name').fill(`Idea ${uniqueStrings[i]}`); * } * ``` */ import { test, expect } from '@playwright/test'; import { createUniqueStringsArray, importUser } from './testUtils'; test('Create 10 new projects', async ({ page }) => { test.slow(); // Set timeout longer since it often fails at 30 seconds const projectCount = 10; // Standard texts const standardTitle = "Idea "; const standardDescription = "Description of Idea "; const standardWebsite = 'https://example.com'; // Title and description arrays const finalTitles = []; const finalDescriptions = []; // Create an array of unique strings const uniqueStrings = await createUniqueStringsArray(projectCount); // Populate arrays with titles and descriptions for (let i = 0; i < projectCount; i++) { let loopTitle = standardTitle + uniqueStrings[i]; finalTitles.push(loopTitle); let loopDescription = standardDescription + uniqueStrings[i]; finalDescriptions.push(loopDescription); } // Set date const today = new Date(); const oneMonthAhead = new Date(today.setDate(today.getDate() + 30)); const standardDate = oneMonthAhead.toISOString().split('T')[0]; // Set time const now = new Date(); const futureTime = new Date(now.setHours(now.getHours() + 1)); const standardHour = futureTime.getHours().toString().padStart(2, '0'); const standardMinute = futureTime.getMinutes().toString().padStart(2, '0'); const standardTime = `${standardHour}:${standardMinute}`; // Import user 00 await importUser(page, '00'); // Create new projects for (let i = 0; i < projectCount; i++) { await page.goto('./projects'); if (i === 0) { // close onboarding, but not with a click to go to the main screen await page.locator('div > svg.fa-xmark').click(); } await page.locator('button > svg.fa-plus').click(); await page.getByPlaceholder('Idea Name').fill(finalTitles[i]); // Add random suffix await page.getByPlaceholder('Description').fill(finalDescriptions[i]); await page.getByPlaceholder('Website').fill(standardWebsite); await page.getByPlaceholder('Start Date').fill(standardDate); await page.getByPlaceholder('Start Time').fill(standardTime); await page.getByRole('button', { name: 'Save Project' }).click(); // Check texts await expect(page.locator('h2')).toContainText(finalTitles[i]); await expect(page.locator('#Content')).toContainText(finalDescriptions[i]); } });