|
|
|
/**
|
|
|
|
* @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]);
|
|
|
|
}
|
|
|
|
});
|