freshyo/tests/specs/product-lifecycle.spec.ts
2026-09-12 09:06:33 +05:30

98 lines
3.2 KiB
TypeScript

import { test, expect } from '@playwright/test'
import {
CREDENTIALS_HINT,
hasStaffCredentials,
trackDialogs,
expectDialog,
openAddProduct,
fillNewProduct,
submitProductForm,
gotoProductsAndSearch,
openProductEdit,
setProductName,
setProductPrice,
toggleSuspend,
isSuspendChecked,
openAddSlot,
fillSlotDatetimes,
addProductToSlot,
submitSlotForm,
futureSlotTimes,
waitForAppHydration,
} from '../helpers/admin-app'
test.skip(!hasStaffCredentials(), CREDENTIALS_HINT)
/**
* Long, single-instance workflow: add a product, update it, create a delivery
* slot for it, then suspend it — all in one browser page/context, mirroring how
* an admin actually works through the panel.
*
* Runs as one test with named steps so the whole chain shares page state.
*/
test('product lifecycle: create → update → slot → suspend', async ({ page }) => {
const productName = `E2E Product ${Date.now()}`
const updatedName = `${productName} Updated`
const dialogs = trackDialogs(page)
await test.step('dashboard is available (authenticated session)', async () => {
await page.goto('/dashboard')
await waitForAppHydration(page)
await expect(page.getByRole('button', { name: 'Products', exact: true })).toBeVisible()
})
await test.step('add a new product', async () => {
await openAddProduct(page)
await fillNewProduct(page, {
name: productName,
price: 250,
marketPrice: 300,
quantity: '1 kg',
})
await submitProductForm(page)
await expectDialog(dialogs, 'Product created successfully!')
})
await test.step('the product appears in the products list', async () => {
await gotoProductsAndSearch(page, productName)
await expect(page.getByText(productName).first()).toBeVisible()
})
await test.step('update the product name and price', async () => {
await openProductEdit(page, productName)
await setProductName(page, updatedName)
await setProductPrice(page, 275)
await submitProductForm(page)
await expectDialog(dialogs, 'Product updated successfully!')
})
await test.step('create a delivery slot for the product', async () => {
const { delivery, freeze } = futureSlotTimes()
await openAddSlot(page)
await fillSlotDatetimes(page, delivery, freeze)
await addProductToSlot(page, updatedName)
await submitSlotForm(page)
await expectDialog(dialogs, 'Slot created successfully!')
})
await test.step('the slot card lists the product', async () => {
// submitSlotForm navigates back to /dashboard/slots
await expect(page).toHaveURL(/\/dashboard\/slots/)
await expect(page.getByText(updatedName).first()).toBeVisible()
})
await test.step('suspend the product', async () => {
await openProductEdit(page, updatedName)
expect(await isSuspendChecked(page)).toBe(false)
await toggleSuspend(page)
// The toggle must take effect in the form before we save.
await expect.poll(() => isSuspendChecked(page), { timeout: 5_000 }).toBe(true)
await submitProductForm(page)
await expectDialog(dialogs, 'Product updated successfully!')
})
await test.step('suspension persists across reloads', async () => {
await openProductEdit(page, updatedName)
expect(await isSuspendChecked(page)).toBe(true)
})
})