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.
This commit is contained in:
1 parent
708da6b9f7
commit
3f6dff5f24
94 files changed
+7213
-643
No files matched your search
@@ -0,0 +1,79 @@
|
||||
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()
|
||||
})
|
||||
Reference in new issue
Block a user