All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m39s
- Introduced a toggle button to enable or disable chores in the scheduler. - The toggle will be available in both types of schedulers. - Added UI design proposal and considerations for mobile dimensions. - Included E2E tests to ensure toggle state persistence and correct behavior in child view.
559 lines
21 KiB
Markdown
559 lines
21 KiB
Markdown
# Chore Scheduler E2E Tests
|
||
|
||
## Application Overview
|
||
|
||
The chore scheduler allows parents to configure when chores appear for their children and set deadline times. Schedules operate in two modes: **Specific Days** (select weekdays + per-day deadlines with optional exceptions) and **Every X Days** (interval-based with anchor date). Schedules can be **paused** (enabled/disabled toggle) — a paused schedule makes the chore appear every day with no deadline, as if unscheduled. All schedule logic runs client-side; the backend only stores and returns raw schedule data.
|
||
|
||
**Key behavioral difference between parent and child mode:**
|
||
|
||
- **Parent mode** (`/parent/:id`): All assigned chores are always visible regardless of schedule. Off-day and expired chores are grayed out (`.chore-inactive`). A kebab menu provides Schedule, Edit Points, Extend Time (when expired), and Reset (when completed) options.
|
||
- **Child mode** (`/child/:id`): Chores not scheduled for today are **hidden entirely** (filtered out client-side). Expired chores show a `TOO LATE` badge and are grayed out. No kebab menu or scheduling controls exist in child mode.
|
||
|
||
**Specs covered:**
|
||
|
||
- `feat-calendar-chore.md` — base schedule feature
|
||
- `feat-calendar-schedule-refactor-01.md` — Specific Days UI refactor (day chips, default deadline, exceptions, TimePickerPopover)
|
||
- `feat-calendar-schedule-refactor-02.md` — Every X Days UI refactor (stepper, DateInputField, anchor date, next occurrence preview, Anytime toggle)
|
||
- `feat-schedule-enable-disable.md` — enable/disable (pause) toggle
|
||
|
||
---
|
||
|
||
## Implementation
|
||
|
||
Tests live in `e2e/mode_parent/chore-scheduler/`. Each spec creates its own isolated child and chore tasks via the API so files can run in parallel. All created resources are deleted in `afterAll`.
|
||
|
||
## Playwright Projects
|
||
|
||
| Project | testMatch | Notes |
|
||
| -------------------------- | -------------------------------------------- | ----------------------- |
|
||
| `chromium-chore-scheduler` | `/mode_parent/chore-scheduler/.+\.spec\.ts/` | Depends on `setup` only |
|
||
|
||
**Config:** Add project to `playwright.config.ts` with `dependencies: ['setup']`. Exclude from the catch-all project via `testIgnore`.
|
||
|
||
---
|
||
|
||
## Seed Strategy
|
||
|
||
Each spec file creates an isolated child and one or more chore tasks via `beforeAll` API calls. Schedule configuration is done via the `PUT /api/child/:childId/task/:taskId/schedule` API. Cleanup (`delete child + tasks`) runs in `afterAll`.
|
||
|
||
For tests that need to verify child-mode behavior, the test navigates to `/child/:id` (no parent auth required for child view). For parent-mode behavior, navigate to `/parent/:id`.
|
||
|
||
**Time-sensitive tests:** Tests that depend on "Due by" labels or "TOO LATE" badges must set a schedule deadline far in the future (e.g., 23:59) to avoid the chore expiring mid-test, or set a deadline in the past (e.g., 00:01) to guarantee expiry. Use `page.clock` or carefully chosen deadline times to control time-dependent state.
|
||
|
||
---
|
||
|
||
## Test Scenarios
|
||
|
||
### 1. Schedule Modal — Opening & Structure
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-modal.spec.ts`
|
||
|
||
**Seed:** Creates child `ScheduleModalChild` and chore `ScheduleModalChore` via API. Assigns chore to child. Deletes all in `afterAll`.
|
||
|
||
#### 1.1. Schedule option appears in kebab menu
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- Click the chore card, then click the kebab "Options" button
|
||
- expect: "Schedule" button is visible in the menu
|
||
|
||
#### 1.2. Schedule modal opens with correct title and subtitle
|
||
|
||
- Open kebab menu → click "Schedule"
|
||
- expect: Modal heading shows "Schedule Chore"
|
||
- expect: Modal subtitle shows the chore's name
|
||
|
||
#### 1.3. Default state for new schedule — days mode selected, no days checked
|
||
|
||
- Open the Schedule modal for a chore with no existing schedule
|
||
- expect: "Specific Days" mode button is active
|
||
- expect: No day chips are in the active state
|
||
- expect: Enable/disable toggle shows "Enabled" label and is ON
|
||
|
||
#### 1.4. Mode toggle switches between Specific Days and Every X Days
|
||
|
||
- Open the Schedule modal
|
||
- Click "Every X Days" button
|
||
- expect: Interval form is visible (stepper, "Starting on" date field, deadline row)
|
||
- Click "Specific Days" button
|
||
- expect: Day chips row is visible
|
||
|
||
#### 1.5. Cancel closes the modal without saving
|
||
|
||
- Open the Schedule modal, select Monday, click Cancel
|
||
- Reopen the modal
|
||
- expect: No days are selected (change was not persisted)
|
||
|
||
#### 1.6. Save is disabled when form is not dirty
|
||
|
||
- Open the Schedule modal (no existing schedule)
|
||
- expect: Save button is disabled
|
||
|
||
---
|
||
|
||
### 2. Schedule Modal — Specific Days Mode
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-days-mode.spec.ts`
|
||
|
||
**Seed:** Creates child `ScheduleDaysChild` and chore `ScheduleDaysChore` via API. Assigns chore. Deletes all in `afterAll`.
|
||
|
||
#### 2.1. Clicking day chips toggles them active/inactive
|
||
|
||
- Open Schedule modal
|
||
- Click "Mo" chip
|
||
- expect: "Mo" chip has active styling
|
||
- Click "Mo" chip again
|
||
- expect: "Mo" chip is no longer active
|
||
|
||
#### 2.2. Default deadline row appears when at least one day is selected
|
||
|
||
- Open Schedule modal, no days selected
|
||
- expect: No deadline row visible
|
||
- Click "Tu" chip
|
||
- expect: Deadline row with "Deadline" label and a time picker appears
|
||
|
||
#### 2.3. Default deadline "Anytime" toggle hides the time picker
|
||
|
||
- Select a day so the deadline row appears
|
||
- Click "Clear (Anytime)" link
|
||
- expect: Time picker disappears, "Anytime" label is shown
|
||
- Click "Set deadline" link
|
||
- expect: Time picker reappears
|
||
|
||
#### 2.4. Exception time — "Set different time" creates per-day override
|
||
|
||
- Select Monday and Wednesday
|
||
- In the day list, click "Set different time" on Wednesday
|
||
- expect: A separate time picker appears for Wednesday
|
||
- expect: Monday still shows the default time label
|
||
|
||
#### 2.5. Exception time — "Reset to default" removes the override
|
||
|
||
- With Wednesday exception set, click "Reset to default" on Wednesday
|
||
- expect: Wednesday row shows the default time label again
|
||
|
||
#### 2.6. Save with specific days — schedule persists on reopen
|
||
|
||
- Select Monday and Friday, set default deadline to 03:00 PM, Save
|
||
- Reopen the Schedule modal
|
||
- expect: Monday and Friday chips are active
|
||
- expect: Default deadline shows 03:00 PM
|
||
|
||
#### 2.7. Save with zero days selected deletes the schedule
|
||
|
||
- Open a schedule that has days selected, uncheck all days, Save
|
||
- Reopen the modal
|
||
- expect: No days selected (schedule was removed), form appears as new
|
||
|
||
#### 2.8. Dirty detection — changing days enables Save
|
||
|
||
- Open modal with an existing schedule
|
||
- Toggle a different day
|
||
- expect: Save becomes enabled
|
||
|
||
---
|
||
|
||
### 3. Schedule Modal — Every X Days Mode
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-interval-mode.spec.ts`
|
||
|
||
**Seed:** Creates child `ScheduleIntervalChild` and chore `ScheduleIntervalChore` via API. Assigns chore. Deletes all in `afterAll`.
|
||
|
||
#### 3.1. Interval stepper increments and decrements within 1–7
|
||
|
||
- Switch to "Every X Days" mode
|
||
- expect: Stepper shows "1" by default
|
||
- expect: Decrement (−) button is disabled at 1
|
||
- Click increment (+) 6 times
|
||
- expect: Value shows "7"
|
||
- expect: Increment (+) button is disabled at 7
|
||
|
||
#### 3.2. Anchor date field shows today's date by default
|
||
|
||
- Switch to "Every X Days" mode
|
||
- expect: "Starting on" date field contains today's ISO date
|
||
|
||
#### 3.3. Next occurrence preview label updates correctly
|
||
|
||
- Set interval to 2, set anchor date to today
|
||
- expect: "Next occurrence" label shows a date 2 days from today
|
||
|
||
#### 3.4. Interval deadline "Anytime" toggle works
|
||
|
||
- Switch to interval mode; deadline time picker is visible by default
|
||
- Click "Clear (Anytime)"
|
||
- expect: Time picker disappears, "Anytime" label shown
|
||
- Click "Set deadline"
|
||
- expect: Time picker reappears
|
||
|
||
#### 3.5. Save interval schedule — persists on reopen
|
||
|
||
- Set interval to 3, pick a specific anchor date, set deadline to 04:30 PM, Save
|
||
- Reopen Schedule modal
|
||
- expect: "Every X Days" mode is active
|
||
- expect: Interval shows 3, anchor date matches, deadline shows 04:30 PM
|
||
|
||
#### 3.6. Dirty detection — changing interval enables Save
|
||
|
||
- Open modal with an existing interval schedule
|
||
- Change interval from 3 to 5
|
||
- expect: Save becomes enabled
|
||
|
||
---
|
||
|
||
### 4. Schedule Enable/Disable Toggle
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-enable-disable.spec.ts`
|
||
|
||
**Seed:** Creates child `ScheduleToggleChild` and chore `ScheduleToggleChore` via API. Assigns chore. Creates a "Specific Days" schedule for a non-today weekday via API. Deletes all in `afterAll`.
|
||
|
||
#### 4.1. Toggle row is visible in the schedule modal
|
||
|
||
- Open Schedule modal
|
||
- expect: Toggle row with "Enabled" label and a switch is visible above the mode buttons
|
||
|
||
#### 4.2. Toggling OFF shows "Paused" label and dims the form body
|
||
|
||
- Click the toggle switch to OFF
|
||
- expect: Label changes to "Paused"
|
||
- expect: Mode toggle and form fields have reduced opacity (dimmed)
|
||
- expect: Cancel and Save buttons remain fully interactive
|
||
|
||
#### 4.3. Toggling ON shows "Enabled" label and restores the form body
|
||
|
||
- Toggle OFF, then toggle back ON
|
||
- expect: Label returns to "Enabled"
|
||
- expect: Form body opacity is restored
|
||
|
||
#### 4.4. Save paused state — persists on reopen
|
||
|
||
- Toggle OFF, Save
|
||
- Reopen Schedule modal
|
||
- expect: Toggle is OFF, label shows "Paused", form body is dimmed
|
||
|
||
#### 4.5. Dirty detection — toggling enabled state enables Save
|
||
|
||
- Open an existing schedule (enabled), toggle OFF
|
||
- expect: Save becomes enabled
|
||
- Toggle back ON
|
||
- expect: Save is disabled again (reverted to original)
|
||
|
||
#### 4.6. Paused schedule in parent mode — chore is visible (not grayed out)
|
||
|
||
- Set up a schedule for a non-today weekday, then pause it via API
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore card is visible and NOT grayed out (paused = show always like unscheduled)
|
||
|
||
#### 4.7. Paused schedule in child mode — chore is visible (not hidden)
|
||
|
||
- Same paused schedule as 4.6
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore card IS visible (paused = scheduled for every day)
|
||
|
||
#### 4.8. Paused schedule shows no "Due by" label
|
||
|
||
- Pause a schedule that has a deadline set
|
||
- Navigate to `/parent/:childId`
|
||
- expect: No "Due by" sub-text on the chore card (paused = no deadline)
|
||
|
||
---
|
||
|
||
### 5. Parent Mode — Chore Card Schedule States
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/parent-card-states.spec.ts`
|
||
|
||
**Seed:** Creates child `ParentCardChild` with multiple chores via API. Assigns chores. Creates various schedules via API. Deletes all in `afterAll`.
|
||
|
||
**Chores:**
|
||
|
||
- `AlwaysActiveChore` — no schedule (always visible, normal appearance)
|
||
- `ScheduledTodayChore` — schedule includes today's weekday, deadline at 23:59
|
||
- `NotScheduledTodayChore` — schedule for a weekday that is NOT today
|
||
- `ExpiredChore` — schedule for today's weekday, deadline at 00:01 (guaranteed past)
|
||
- `AnytimeChore` — schedule for today, deadline set to "Anytime" (no expiry)
|
||
|
||
#### 5.1. Chore with no schedule — normal appearance, no annotations
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- expect: `AlwaysActiveChore` card is visible with normal styling (no grayout, no badge)
|
||
|
||
#### 5.2. Chore scheduled for today — shows "Due by" label
|
||
|
||
- expect: `ScheduledTodayChore` card is visible
|
||
- expect: Card shows "Due by 11:59 PM" sub-text
|
||
- expect: Card is NOT grayed out
|
||
|
||
#### 5.3. Chore not scheduled for today — grayed out in parent mode
|
||
|
||
- expect: `NotScheduledTodayChore` card IS visible (parent mode shows all chores)
|
||
- expect: Card has grayed-out styling (`.chore-inactive` class — reduced opacity)
|
||
|
||
#### 5.4. Chore with expired deadline — grayed out with TOO LATE badge
|
||
|
||
- expect: `ExpiredChore` card is visible
|
||
- expect: Card has grayed-out styling
|
||
- expect: "TOO LATE" badge is visible on the card
|
||
|
||
#### 5.5. Chore with "Anytime" deadline — no "Due by" label, no TOO LATE
|
||
|
||
- expect: `AnytimeChore` card is visible with normal styling
|
||
- expect: No "Due by" sub-text
|
||
- expect: No "TOO LATE" badge
|
||
|
||
#### 5.6. Kebab menu always accessible on grayed-out chores
|
||
|
||
- Click the `NotScheduledTodayChore` card (grayed out)
|
||
- expect: Kebab "Options" button is visible
|
||
- Click "Options" → "Schedule" is available
|
||
- expect: Schedule modal opens normally
|
||
|
||
#### 5.7. Chore can still be triggered by parent regardless of schedule state
|
||
|
||
- Click the `ExpiredChore` (which has TOO LATE badge)
|
||
- Click again to activate
|
||
- expect: Confirmation dialog appears (parent can still trigger expired chores)
|
||
|
||
---
|
||
|
||
### 6. Child Mode — Chore Visibility and Schedule States
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/child-card-states.spec.ts`
|
||
|
||
**Seed:** Creates child `ChildCardChild` with multiple chores. Assigns chores. Creates schedules via API. Deletes all in `afterAll`. Uses same chore set as test 5 where applicable.
|
||
|
||
**Chores:**
|
||
|
||
- `ChildAlwaysChore` — no schedule
|
||
- `ChildTodayChore` — scheduled for today, deadline at 23:59
|
||
- `ChildNotTodayChore` — scheduled for a non-today weekday
|
||
- `ChildExpiredChore` — scheduled for today, deadline at 00:01 (past)
|
||
- `ChildAnytimeChore` — scheduled for today, deadline "Anytime"
|
||
|
||
#### 6.1. Chore with no schedule — visible normally in child mode
|
||
|
||
- Navigate to `/child/:childId`
|
||
- expect: `ChildAlwaysChore` card is visible with normal styling
|
||
|
||
#### 6.2. Chore scheduled for today — visible with "Due by" label
|
||
|
||
- expect: `ChildTodayChore` card is visible
|
||
- expect: "Due by 11:59 PM" sub-text shown on card
|
||
- expect: Card is NOT grayed out
|
||
|
||
#### 6.3. Chore not scheduled for today — HIDDEN in child mode
|
||
|
||
- expect: `ChildNotTodayChore` card is NOT visible (fully hidden, not just grayed out)
|
||
|
||
#### 6.4. Chore with expired deadline — grayed out with TOO LATE badge
|
||
|
||
- expect: `ChildExpiredChore` card IS visible (still shown, but expired)
|
||
- expect: Card has grayed-out styling
|
||
- expect: "TOO LATE" badge visible
|
||
|
||
#### 6.5. Chore with "Anytime" — visible, no badge, no "Due by"
|
||
|
||
- expect: `ChildAnytimeChore` card visible with normal styling
|
||
- expect: No "Due by" label, no "TOO LATE" badge
|
||
|
||
#### 6.6. No kebab menu or schedule controls in child mode
|
||
|
||
- Click on `ChildTodayChore` card
|
||
- expect: No "Options" button or kebab menu appears on the card
|
||
|
||
---
|
||
|
||
### 7. Parent vs Child Mode Comparison
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/parent-vs-child.spec.ts`
|
||
|
||
**Seed:** Creates child `CompareChild` and two chores: `VisibleBothChore` (scheduled for today) and `ParentOnlyChore` (scheduled for a non-today weekday). Assigns both. Deletes all in `afterAll`.
|
||
|
||
#### 7.1. Parent mode shows all chores including off-day ones
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Both `VisibleBothChore` and `ParentOnlyChore` are visible
|
||
- expect: `ParentOnlyChore` is grayed out (`chore-inactive`)
|
||
- expect: `VisibleBothChore` is NOT grayed out
|
||
|
||
#### 7.2. Child mode hides off-day chores
|
||
|
||
- Navigate to `/child/:childId`
|
||
- expect: `VisibleBothChore` IS visible
|
||
- expect: `ParentOnlyChore` is NOT visible (hidden entirely)
|
||
|
||
#### 7.3. Adding a schedule via parent mode hides chore in child mode on wrong day
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- Open Schedule for `VisibleBothChore`, set it to a non-today weekday only, Save
|
||
- Navigate to `/child/:childId`
|
||
- expect: `VisibleBothChore` is no longer visible in child mode
|
||
|
||
#### 7.4. Removing a schedule via parent mode shows chore in child mode again
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- Open Schedule for the chore, uncheck all days (removes schedule), Save
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore is visible again in child mode (no schedule = always shown)
|
||
|
||
#### 7.5. Paused schedule — chore visible in both modes
|
||
|
||
- Set a non-today schedule and pause it via API
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore visible, NOT grayed out (paused = acts unscheduled)
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore IS visible (paused = shows every day)
|
||
|
||
---
|
||
|
||
### 8. Extend Time
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/extend-time.spec.ts`
|
||
|
||
**Seed:** Creates child `ExtendTimeChild` and chore `ExtendTimeChore` with a schedule for today and a deadline at 00:01 (guaranteed expired). Assigns chore. Deletes all in `afterAll`.
|
||
|
||
#### 8.1. "Extend Time" appears in kebab menu only when chore is expired
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- expect: `ExtendTimeChore` shows "TOO LATE" badge (deadline is 00:01, already past)
|
||
- Click chore card, then "Options"
|
||
- expect: "Extend Time" menu item is visible
|
||
|
||
#### 8.2. "Extend Time" is absent when chore is not expired
|
||
|
||
- Set up a second chore with deadline at 23:59 (not yet passed)
|
||
- Click chore card, then "Options"
|
||
- expect: "Extend Time" menu item is NOT visible
|
||
|
||
#### 8.3. Clicking "Extend Time" removes the TOO LATE badge
|
||
|
||
- Click "Extend Time" on the expired chore
|
||
- expect: "TOO LATE" badge disappears from the card
|
||
- expect: Card is no longer grayed out
|
||
|
||
#### 8.4. Extended chore no longer shows "Due by" label
|
||
|
||
- After extending, the chore card
|
||
- expect: No "Due by" sub-text (extended = no deadline for remainder of day)
|
||
|
||
#### 8.5. Extending the same chore twice returns 409
|
||
|
||
- After the first extension, try opening kebab again
|
||
- expect: "Extend Time" is no longer in the menu (chore is no longer expired)
|
||
|
||
#### 8.6. Extension effect is visible in child mode
|
||
|
||
- After extending the chore in parent mode
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore is visible and NOT showing "TOO LATE" badge
|
||
|
||
---
|
||
|
||
### 9. Schedule with Interval Mode — Anchor Date & Next Occurrence
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/interval-anchor.spec.ts`
|
||
|
||
**Seed:** Creates child `IntervalAnchorChild` and chore `IntervalAnchorChore`. Assigns chore. Deletes all in `afterAll`.
|
||
|
||
#### 9.1. Interval schedule set to every 1 day from today — chore active today
|
||
|
||
- Create interval schedule: `interval_days=1`, `anchor_date=today`, deadline 23:59
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore is NOT grayed out (hits today)
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore IS visible
|
||
|
||
#### 9.2. Interval schedule set to every 2 days from yesterday — chore NOT active today
|
||
|
||
- Create interval schedule: `interval_days=2`, `anchor_date=yesterday`
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore IS grayed out (yesterday + 2 = tomorrow, not today)
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore is NOT visible
|
||
|
||
#### 9.3. Interval schedule set to every 2 days starting today — active today
|
||
|
||
- Create interval schedule: `interval_days=2`, `anchor_date=today`
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore is NOT grayed out
|
||
- Navigate to `/child/:childId`
|
||
- expect: Chore IS visible
|
||
|
||
#### 9.4. Interval "Anytime" deadline — no "Due by" label
|
||
|
||
- Create interval schedule with `interval_has_deadline=false`
|
||
- Navigate to `/parent/:childId`
|
||
- expect: No "Due by" sub-text on the chore card
|
||
|
||
---
|
||
|
||
### 10. SSE Real-Time Updates
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-sse.spec.ts`
|
||
|
||
**Seed:** Creates child `SSEScheduleChild` and chore `SSEScheduleChore`. Assigns chore. Deletes all in `afterAll`.
|
||
|
||
#### 10.1. Setting a schedule via API reflects in an already-open parent view
|
||
|
||
- Navigate to `/parent/:childId`
|
||
- expect: Chore is visible, no schedule annotations
|
||
- Via API call (`request.put`), create a schedule for a non-today weekday
|
||
- expect: Within a few seconds, the chore card becomes grayed out (SSE `chore_schedule_modified` fires, list refreshes)
|
||
|
||
#### 10.2. Deleting a schedule via API un-grays the chore in parent view
|
||
|
||
- (Continuing from 10.1) Delete the schedule via API
|
||
- expect: Within a few seconds, the chore card returns to normal styling
|
||
|
||
#### 10.3. Extending time via API reflects in an already-open parent view
|
||
|
||
- Set up a schedule with a past deadline (00:01) via API so chore is expired
|
||
- Navigate to `/parent/:childId`
|
||
- expect: "TOO LATE" badge visible
|
||
- Extend time via API call
|
||
- expect: "TOO LATE" badge disappears (SSE `chore_time_extended` fires, list refreshes)
|
||
|
||
---
|
||
|
||
### 11. Schedule Loading — Backward Compatibility
|
||
|
||
**File:** `e2e/mode_parent/chore-scheduler/schedule-load.spec.ts`
|
||
|
||
**Seed:** Creates child and chore. Uses direct API calls to create schedules with specific field combinations. Deletes all in `afterAll`.
|
||
|
||
#### 11.1. Schedule with `enabled` field missing defaults to enabled
|
||
|
||
- Create schedule via API without `enabled` field
|
||
- Open Schedule modal
|
||
- expect: Toggle shows "Enabled" (defaults to true)
|
||
|
||
#### 11.2. Schedule with `interval_has_deadline=false` shows "Anytime"
|
||
|
||
- Create interval schedule with `interval_has_deadline=false`
|
||
- Open Schedule modal
|
||
- expect: "Anytime" label is shown instead of time picker
|
||
|
||
#### 11.3. Existing days schedule with mixed times loads correctly
|
||
|
||
- Create days schedule with 3 days: Mon (08:00), Wed (08:00), Fri (10:30) — Fri is an exception
|
||
- Open Schedule modal
|
||
- expect: Mo, We, Fr chips are active
|
||
- expect: Default deadline shows 08:00 AM
|
||
- expect: Friday row shows its own time picker with 10:30 AM
|
||
|
||
#### 11.4. Interval schedule loads anchor date and interval correctly
|
||
|
||
- Create interval schedule via API with `anchor_date="2026-03-15"`, `interval_days=3`
|
||
- Open Schedule modal
|
||
- expect: "Every X Days" mode is active
|
||
- expect: Stepper shows 3
|
||
- expect: Date field shows 2026-03-15
|
||
|
||
---
|
||
|
||
## CSS Spec References
|
||
|
||
- `.chore-inactive`: `opacity: 0.45; filter: grayscale(60%)` — applied in both parent and child views
|
||
- `.chore-stamp`: absolute-positioned badge overlay for "TOO LATE", "COMPLETED", "PENDING"
|
||
- `.due-label`: "Due by X:XX PM" sub-text below point value
|
||
- `.schedule-body.disabled`: `opacity: 0.45; pointer-events: none` — dim wrapper when schedule is paused
|
||
- `.toggle-track.on`: `background: var(--btn-primary)` — toggle ON state
|