Files
chore/frontend/vue-app/e2e/mode_parent/tasks/kindness-create-edit.spec.ts
Ryan Kegel f250c42e5e
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m31s
Add end-to-end tests for parent item management
- Implement tests for creating, editing, and deleting chores, kindness acts, and penalties.
- Add tests to verify conversion of default items to user items and restoration of system defaults upon deletion.
- Ensure proper cancellation of creation and editing actions.
- Create a comprehensive plan document outlining the test scenarios and expected behaviors.
2026-03-12 12:22:37 -04:00

137 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// spec: frontend/vue-app/e2e/plans/parent-item-management.plan.md
// seed: e2e/seed.spec.ts
import { test, expect } from '@playwright/test'
test.describe('Kindness act management', () => {
test.beforeEach(async ({ page }, testInfo) => {
test.skip(testInfo.project.name === 'chromium-no-pin', 'Requires parent-authenticated mode')
})
// avoid parallel execution within this file; shared backend state and SSE events
test.describe.configure({ mode: 'serial' })
test('Create a new kindness act (parent mode)', async ({ page }) => {
// use a unique name so repeated runs don't collide
const suffix = Date.now()
const name = `Share toys ${suffix}`
// 1. navigate once and switch to kindness tab
await page.goto('/parent/tasks/chores')
await page.click('text=Kindness Acts')
await expect(page.locator('text=Kindness Acts')).toBeVisible()
// 2. open form
await page.getByRole('button', { name: 'Create Kindness Act' }).click()
await expect(page.locator('text=Name')).toBeVisible()
// 34. fill using evaluate helper
await page.evaluate((name) => {
const setVal = (sel, val) => {
const el = document.querySelector(sel)
if (el) {
el.value = val
el.dispatchEvent(new Event('input', { bubbles: true }))
el.dispatchEvent(new Event('change', { bubbles: true }))
}
}
setVal('#name', name)
setVal('#points', '5')
}, name)
await expect(page.getByRole('button', { name: 'Create' })).toBeEnabled()
// 5. submit and assert the new row is visible
await page.getByRole('button', { name: 'Create' }).click()
await expect(page.locator('.error')).toHaveCount(0)
await expect(page.locator(`text=${name}`).first()).toBeVisible()
})
test('Edit an existing kindness act', async ({ page }) => {
const suffix = Date.now()
const original = `Share toys ${suffix}`
const updated = `Help with homework ${suffix}`
// navigate and create fresh item
await page.goto('/parent/tasks/chores')
await page.click('text=Kindness Acts')
await page.getByRole('button', { name: 'Create Kindness Act' }).click()
await page.evaluate((name) => {
const setVal = (sel, val) => {
const el = document.querySelector(sel)
if (el) {
el.value = val
el.dispatchEvent(new Event('input', { bubbles: true }))
el.dispatchEvent(new Event('change', { bubbles: true }))
}
}
setVal('#name', name)
setVal('#points', '5')
}, original)
await page.getByRole('button', { name: 'Create' }).click()
await expect(page.locator(`text=${original}`).first()).toBeVisible()
// 2. open edit by clicking first matching row
await page.locator(`text=${original}`).first().click()
// wait for edit form to appear
await expect(page.locator('text=Name')).toBeVisible()
await expect(page.getByRole('button', { name: 'Save' })).toBeVisible()
// 3. update values once form is ready
await page.evaluate((name) => {
const setVal = (sel, val) => {
const el = document.querySelector(sel)
if (el) {
el.value = val
el.dispatchEvent(new Event('input', { bubbles: true }))
el.dispatchEvent(new Event('change', { bubbles: true }))
}
}
setVal('#name', name)
setVal('#points', '8')
}, updated)
// 4. save and verify (wait until button is enabled)
await expect(page.getByRole('button', { name: 'Save' })).toBeEnabled()
await page.getByRole('button', { name: 'Save' }).click()
await expect(page.locator(`text=${updated}`).first()).toBeVisible()
})
test('Delete a kindness act', async ({ page }) => {
const suffix = Date.now()
const name = `Help with homework ${suffix}`
await page.goto('/parent/tasks/chores')
await page.click('text=Kindness Acts')
// create fresh item
await page.getByRole('button', { name: 'Create Kindness Act' }).click()
await page.evaluate((name) => {
const setVal = (sel, val) => {
const el = document.querySelector(sel)
if (el) {
el.value = val
el.dispatchEvent(new Event('input', { bubbles: true }))
el.dispatchEvent(new Event('change', { bubbles: true }))
}
}
setVal('#name', name)
setVal('#points', '8')
}, name)
await page.getByRole('button', { name: 'Create' }).click()
await expect(page.locator(`text=${name}`).first()).toBeVisible()
// click the delete button on the first matching row
await page
.locator(`text=${name}`)
.first()
.locator('..')
.getByRole('button', { name: 'Delete' })
.click()
// confirmation modal should appear
await expect(
page.locator('text=Are you sure you want to delete this kindness act?'),
).toBeVisible()
// click the red danger button inside the modal
await page.locator('button.btn-danger:has-text("Delete")').click()
await expect(page.locator(`text=${name}`)).toHaveCount(0)
})
})