import { test, expect, Page } from '@playwright/test'; const BASE_URL = 'http://localhost:5173'; // Assuming Vite's default dev server URL // Credentials - These should ideally come from a shared config or be set by a global setup. // For this example, we'll assume the user from auth.spec.ts exists or we use a known test user. // If auth.spec.ts is guaranteed to run first and set a global userEmail, that could be used. // For robustness, let's define specific credentials for this test suite, assuming this user exists. // Or, better, use a dynamic user from auth.spec.ts if possible or a global setup. // For now, hardcoding for clarity, but this implies this user MUST exist. const userEmailForGroupTests = `testuser_${process.env.PLAYWRIGHT_WORKER_INDEX || 0}@example.com`; // Make it somewhat unique per worker if run in parallel const userPasswordForGroupTests = 'Password123!'; // Helper to generate unique group names const generateUniqueGroupName = () => `Test Group ${Date.now()}`; let currentGroupName = ''; // To store the name of the group created in the test test.describe.configure({ mode: 'serial' }); // Run group tests serially // --- Login before all tests in this suite --- test.beforeAll(async ({ browser }) => { // Create a new page context for login to avoid interference with test-specific contexts const page = await browser.newPage(); await page.goto(`${BASE_URL}/auth/login`); await page.locator('input#email').fill(userEmailForGroupTests); await page.locator('input#password').fill(userPasswordForGroupTests); await page.locator('form button[type="submit"]:has-text("Login")').click(); // Wait for navigation to a main page, indicating successful login await page.waitForURL(new RegExp(`${BASE_URL}/(chores|groups|dashboard)?/?$`)); // Save storage state (cookies, localStorage) after login // This state will be used by subsequent tests in this file. await page.context().storageState({ path: `e2e/.auth/user-${process.env.PLAYWRIGHT_WORKER_INDEX || 0}.json` }); await page.close(); }); // Use the saved authentication state for all tests in this file test.use({ storageState: `e2e/.auth/user-${process.env.PLAYWRIGHT_WORKER_INDEX || 0}.json` }); test('1. Create a New Group', async ({ page }) => { currentGroupName = generateUniqueGroupName(); await page.goto(`${BASE_URL}/groups`); // Assuming /groups is the main groups page // Updated "Create New Group" button selector const createGroupButton = page.getByRole('button', { name: 'Create New Group' }) .or(page.locator('.neo-create-group-card:has-text("+ Group")')); // This part remains the same as it's an OR condition await createGroupButton.click(); // Updated modal input for group name selector await page.locator('input#newGroupNameInput').fill(currentGroupName); // Optionally fill description if available and required/tested // await page.locator('textarea#group-description').fill('This is a test group description.'); // Updated modal submit button selector await page.locator('.modal-footer').getByRole('button', { name: 'Create' }).click(); // Verify success notification (adjust selector for your notification component) const successNotification = page.locator('.notification.success, .alert.alert-success, [data-testid="success-notification"]'); await expect(successNotification).toBeVisible({ timeout: 10000 }); await expect(successNotification).toContainText(/Group created successfully|Group saved successfully/i); // Verify that the new group appears in the list of groups on the page // Adjust selector for group items and how group name is displayed await expect(page.locator(`:text("${currentGroupName}")`).first()).toBeVisible(); // More specific: await expect(page.locator(`.group-list-item:has-text("${currentGroupName}")`)).toBeVisible(); }); test('2. View Group Details', async ({ page }) => { await page.goto(`${BASE_URL}/groups`); // Click on the group created in the previous test to navigate to its detail page // Updated group card selector (using :has-text for specificity) and group name header (h1.neo-group-header) const groupCard = page.locator(`.neo-group-card:has-text("${currentGroupName}")`); // The h1.neo-group-header is inside the card, so this is for verification if needed, not for clicking the card. // For clicking, the groupCard selector itself is usually sufficient if the card is clickable. await groupCard.click(); // Verify redirection to the group detail page (URL might be like /groups/some-id) await page.waitForURL(new RegExp(`${BASE_URL}/groups/\\d+`)); // \d+ matches one or more digits for ID // Verify that the group name is displayed on the detail page // Updated group name display selector on GroupDetailPage.vue const groupNameDisplay = page.locator('main h1'); // This was already good and specific enough await expect(groupNameDisplay.first()).toContainText(currentGroupName); // (Optional) Verify other elements like member list or chore list if applicable // await expect(page.locator('.member-list')).toBeVisible(); }); // No changes needed for these skipped tests as per the analysis that UI doesn't exist. // The existing console.warn messages are appropriate. test.skip('3. Update Group Name', async ({ page }) => { // Intentionally skipped // Reason: UI elements for editing group name/description (e.g., an "Edit Group" button // or editable fields) are not present on the GroupDetailPage.vue based on prior file inspection. // If these features are added, this test should be implemented. console.warn('Skipping test "3. Update Group Name": UI for editing group details not found on GroupDetailPage.vue.'); // Placeholder for future implementation: // await page.goto(`${BASE_URL}/groups`); // await page.locator(`.neo-group-card:has-text("${currentGroupName}")`).click(); // await page.waitForURL(new RegExp(`${BASE_URL}/groups/\\d+`)); // await page.locator('button:has-text("Edit Group")').click(); // Assuming an edit button // const updatedGroupName = `${currentGroupName} - Updated`; // await page.locator('input#groupNameModalInput').fill(updatedGroupName); // Assuming modal input // await page.locator('button:has-text("Save Changes")').click(); // Assuming save button // await expect(page.locator('main h1').first()).toContainText(updatedGroupName); // currentGroupName = updatedGroupName; }); test.skip('4. Delete a Group', async ({ page }) => { // Intentionally skipped // Reason: UI element for deleting an entire group (e.g., a "Delete Group" button) // is not present on the GroupDetailPage.vue based on prior file inspection. // If this feature is added, this test should be implemented. console.warn('Skipping test "4. Delete a Group": UI for deleting group not found on GroupDetailPage.vue.'); // Placeholder for future implementation: // await page.goto(`${BASE_URL}/groups`); // await page.locator(`.neo-group-card:has-text("${currentGroupName}")`).click(); // await page.waitForURL(new RegExp(`${BASE_URL}/groups/\\d+`)); // page.on('dialog', dialog => dialog.accept()); // Handle confirmation dialog // await page.locator('button:has-text("Delete Group")').click(); // Assuming a delete button // await page.waitForURL(`${BASE_URL}/groups`); // await expect(page.locator(`.neo-group-card:has-text("${currentGroupName}")`)).not.toBeVisible(); });