bilhej/frontend/e2e/admin-fulfillment.spec.ts
Joakim Mörling 1c9269699e
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Failing after 1m50s
CI / E2E browser tests (pull_request) Failing after 1m38s
Add admin order fulfillment tracking.
Register PostNord shipments, admin notes, and guarded status transitions
with customer emails. Expandable admin UI, V11 migration, serial E2E suite,
and AGENTS.md Docker-only E2E guidance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 12:21:17 +02:00

99 lines
3.5 KiB
TypeScript

import { test, expect } from '@playwright/test'
/**
* Admin order status and shipment flows (serial — mutates seeded orders).
* Requires docker e2e stack with dev seeds (DEF456, JKL012, ABC123).
*/
test.describe.configure({ mode: 'serial' })
const PENDING_ORDER_SHORT_ID = 'c2eebc99'
const PROCESSING_PLATE = 'JKL012'
const SENT_ORDER_SHORT_ID = 'c1eebc99'
async function loginAsAdmin(page: import('@playwright/test').Page) {
await page.goto('/logga-in')
await page.getByLabel('E-postadress').fill('admin@bilhalsning.se')
await page.getByLabel('Lösenord').fill('test1234')
await page.getByRole('button', { name: 'Logga in' }).click()
await page.waitForURL('/')
}
async function openAdmin(page: import('@playwright/test').Page) {
await page.goto('/admin')
await expect(page.locator('.admin__loading')).toBeHidden({ timeout: 30_000 })
}
function orderRowByPlate(page: import('@playwright/test').Page, plate: string) {
return page.locator('.admin__row').filter({
has: page.locator('.admin__plate', { hasText: plate }),
})
}
function orderRowByShortId(
page: import('@playwright/test').Page,
shortId: string,
) {
return page.locator('.admin__row', { hasText: shortId })
}
test.describe('Admin fulfillment flows', () => {
test.beforeEach(async ({ page }) => {
await loginAsAdmin(page)
await openAdmin(page)
})
test('can mark unpaid order as failed', async ({ page }) => {
await page.locator('#admin-order-search').fill(PENDING_ORDER_SHORT_ID)
const row = orderRowByShortId(page, PENDING_ORDER_SHORT_ID)
const select = row.locator('.admin__status-select')
await select.selectOption('failed')
await expect(select).toHaveValue('failed')
await expect(page.getByRole('alert')).not.toBeVisible()
})
test('can revert unpaid failed order to pending payment', async ({
page,
}) => {
await page.locator('#admin-order-search').fill(PENDING_ORDER_SHORT_ID)
const row = orderRowByShortId(page, PENDING_ORDER_SHORT_ID)
const select = row.locator('.admin__status-select')
await expect(select).toHaveValue('failed')
await select.selectOption('pending_payment')
await expect(select).toHaveValue('pending_payment')
})
test('can register shipment for processing order', async ({ page }) => {
const row = orderRowByPlate(page, PROCESSING_PLATE)
await row.click()
await page
.locator('.admin__tracking-input')
.fill('PN-E2E-FULFILLMENT-001')
await page.getByRole('button', { name: 'Registrera utskick' }).click()
await expect(row.locator('.admin__status-select')).toHaveValue('sent')
await expect(page.locator('.admin__tracking-link')).toBeVisible()
})
test('can mark sent order as delivered', async ({ page }) => {
await page.locator('#admin-order-search').fill(SENT_ORDER_SHORT_ID)
const row = orderRowByShortId(page, SENT_ORDER_SHORT_ID)
const select = row.locator('.admin__status-select')
if ((await select.inputValue()) !== 'delivered') {
await select.selectOption('delivered')
}
await expect(select).toHaveValue('delivered')
})
test('can mark delivered order as failed then back to sent when tracking exists', async ({
page,
}) => {
await page.locator('#admin-order-search').fill(SENT_ORDER_SHORT_ID)
const row = orderRowByShortId(page, SENT_ORDER_SHORT_ID)
const select = row.locator('.admin__status-select')
await select.selectOption('failed')
await expect(select).toHaveValue('failed')
await select.selectOption('sent')
await expect(select).toHaveValue('sent')
})
})