Files
open-safetylog-ehs/e2e/incident-lifecycle.spec.ts
T
jayjennings 3f6dff5f24
CI / Lint, typecheck, test, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
feat: implement permissions and actions management
- Add permissions logic for status options in corrective actions.
- Create tests for permissions functionality.
- Implement queries for user authentication and actions management.
- Develop Actions page to display and manage corrective actions.
- Create authentication pages for login, setup, and password reset.
- Add IncidentDetail page to view incident details and associated actions.
- Implement Settings page for user management and password changes.
2026-10-06 11:20:44 -07:00

80 lines
4.4 KiB
TypeScript

import { expect, test, type Page } from '@playwright/test'
import { photo, signIn, unique, users } from './fixtures'
test.describe.configure({ mode: 'serial' })
/** The incident page section with this heading. */
const section = (page: Page, heading: string) => page.locator('section').filter({ has: page.getByRole('heading', { name: heading, exact: true }) })
async function move(page: Page, button: string) {
await page.getByRole('button', { name: button }).click()
await expect(page.getByRole('button', { name: button })).toHaveCount(0)
}
test('takes an incident from report to close across three roles', async ({ browser, isMobile }) => {
test.skip(isMobile, 'Long multi-role flow runs on desktop only')
test.setTimeout(90_000)
const title = unique('Guard missing on press 4')
// Reporter files the report with a photo
const reporter = await (await browser.newContext()).newPage()
await signIn(reporter, 'reporter')
await reporter.getByRole('link', { name: 'Report incident' }).click()
await reporter.getByLabel('Incident title').fill(title)
await reporter.getByLabel('Incident type').selectOption('hazard')
await reporter.getByLabel('Severity').selectOption('high')
await reporter.getByLabel('Building or area').selectOption({ label: 'Press Shop' })
await reporter.getByLabel('What happened?').fill('Safety guard removed and left off after maintenance.')
await reporter.locator('input[type=file]').setInputFiles(photo)
await reporter.getByRole('button', { name: 'Submit report' }).click()
await expect(reporter.getByText(/has been reported/)).toBeVisible()
await expect(reporter.getByRole('heading', { level: 1 })).toHaveText(title)
await expect(reporter.getByRole('img', { name: 'scene.png' })).toBeVisible()
const url = reporter.url()
// Supervisor triages, investigates and assigns an action back to the reporter
const supervisor = await (await browser.newContext()).newPage()
await signIn(supervisor, 'supervisor')
await supervisor.goto(url)
await move(supervisor, 'Start triage')
await move(supervisor, 'Start investigation')
await supervisor.getByRole('button', { name: 'Add root cause' }).click()
await supervisor.getByLabel('Category').selectOption('process')
await supervisor.getByLabel('Root cause').fill('No step to refit guards after maintenance')
await supervisor.getByLabel('Why 1').fill('Guard was not refitted')
await supervisor.getByRole('button', { name: 'Add root cause' }).click()
await expect(section(supervisor, 'Investigation').getByText('No step to refit guards after maintenance')).toBeVisible()
await move(supervisor, 'Move to corrective actions')
await supervisor.getByRole('button', { name: 'Add action' }).click()
await supervisor.getByLabel('Action', { exact: true }).fill('Add guard check to maintenance sign-off')
await supervisor.getByLabel('Assign to').selectOption({ label: users.reporter.name })
await supervisor.getByRole('button', { name: 'Add action' }).click()
await expect(section(supervisor, 'Corrective actions').getByText(`Assigned to ${users.reporter.name}`)).toBeVisible()
await expect(supervisor.getByRole('button', { name: 'Send for verification' })).toBeDisabled()
// Reporter completes the action from My actions
await reporter.goto('/actions')
const row = reporter.getByRole('listitem').filter({ hasText: 'Add guard check to maintenance sign-off' })
await row.getByRole('combobox').selectOption('done')
await expect(row).toHaveCount(0) // leaves the Open list
await reporter.getByRole('tab', { name: 'Done' }).click()
await expect(row.getByRole('combobox')).toHaveValue('done')
// Supervisor sends it for verification; admin verifies and closes
await supervisor.reload()
await move(supervisor, 'Send for verification')
const admin = await (await browser.newContext()).newPage()
await signIn(admin, 'admin')
await admin.goto(url)
await expect(admin.getByRole('button', { name: 'Verify and close' })).toBeDisabled()
await admin.getByRole('combobox', { name: /Status of Add guard check/ }).selectOption('verified')
await admin.getByLabel('Note').fill('Checked on the floor: guard refitted and checklist updated.')
await move(admin, 'Verify and close')
// The record shows the whole story
await expect(admin.getByText('Closed', { exact: true }).first()).toBeVisible()
const activity = section(admin, 'Activity')
await expect(activity.getByText('moved it from Verification to Closed')).toBeVisible()
await expect(activity.getByText('Checked on the floor')).toBeVisible()
})