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() })