// spec: e2e/plans/chore-scheduler.plan.md — Section 1: Schedule Modal Opening & Structure import { test, expect } from '@playwright/test' import { createChild, createChoreTask, assignChore, deleteSchedule, choreCard, openChoreOptions, openScheduleModal, } from './helpers' const CHILD_NAME = 'ScheduleModalChild' const CHORE_NAME = 'ScheduleModalChore' test.describe('Schedule Modal — Opening & Structure', () => { test.describe.configure({ mode: 'serial' }) let childId = '' let choreId = '' test.beforeAll(async ({ request }) => { childId = await createChild(request, CHILD_NAME) choreId = await createChoreTask(request, CHORE_NAME) await assignChore(request, childId, [choreId]) }) test.afterAll(async ({ request }) => { if (childId) await request.delete(`/api/child/${childId}`) if (choreId) await request.delete(`/api/task/${choreId}`) }) test.beforeEach(async ({ request }) => { await deleteSchedule(request, childId, choreId) }) test('1.1 Schedule option appears in kebab menu', async ({ page }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openChoreOptions(page, card) await expect(page.getByRole('button', { name: 'Schedule' })).toBeVisible() }) test('1.2 Schedule modal opens with correct title and subtitle', async ({ page }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openScheduleModal(page, card) await expect(page.locator('.modal-title')).toHaveText('Schedule Chore') await expect(page.locator('.modal-subtitle')).toHaveText(CHORE_NAME) }) test('1.3 Default state: Specific Days mode, no chips selected, toggle Enabled', async ({ page, }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openScheduleModal(page, card) // Specific Days mode button is active await expect(page.getByRole('button', { name: 'Specific Days' })).toHaveClass(/active/) await expect(page.getByRole('button', { name: 'Every X Days' })).not.toHaveClass(/active/) // No day chips are active const chips = page.locator('.day-chips').getByRole('button') for (const chip of await chips.all()) { await expect(chip).not.toHaveClass(/active/) } // Toggle is ON and shows "Enabled" await expect(page.getByRole('switch')).toHaveAttribute('aria-checked', 'true') await expect(page.locator('.toggle-label')).toHaveText('Enabled') }) test('1.4 Mode toggle switches between Specific Days and Every X Days', async ({ page }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openScheduleModal(page, card) // Switch to Every X Days await page.getByRole('button', { name: 'Every X Days' }).click() await expect(page.locator('.interval-form')).toBeVisible() await expect(page.locator('.days-form')).not.toBeVisible() // Switch back to Specific Days await page.getByRole('button', { name: 'Specific Days' }).click() await expect(page.locator('.days-form')).toBeVisible() await expect(page.locator('.interval-form')).not.toBeVisible() }) test('1.5 Cancel closes the modal without saving', async ({ page }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openScheduleModal(page, card) // Select Monday chip await page.locator('.day-chips').getByRole('button', { name: 'Mo' }).click() await expect(page.locator('.day-chips').getByRole('button', { name: 'Mo' })).toHaveClass( /active/, ) // Cancel — modal closes await page.getByRole('button', { name: 'Cancel' }).click() await expect(page.locator('.modal-title')).not.toBeVisible() // Navigate fresh to reset card ready-state, then reopen modal await page.goto(`/parent/${childId}`) await card.waitFor() await openScheduleModal(page, card) await expect(page.locator('.day-chips').getByRole('button', { name: 'Mo' })).not.toHaveClass( /active/, ) }) test('1.6 Save is disabled when form is not dirty', async ({ page }) => { await page.goto(`/parent/${childId}`) const card = choreCard(page, CHORE_NAME) await card.waitFor() await openScheduleModal(page, card) // Save button is disabled — no changes made await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled() }) })