776149e7d3
Sprint 12 Phase 2: Real integration tests with seed DB - R__seed_test_data.sql (Flyway repeatable, 7 members, strains, batches, docs, board, events) - TestResetController (profile-gated per-test DB reset) - docker-compose.test.yml (self-contained, tmpfs Postgres) - Dockerfile.playwright (v1.60.0, pre-installed deps) - 13 integration spec files, 70+ test cases (@smoke + @full) - seed-constants.ts, selectors.ts, api-client.ts test helpers
121 lines
3.7 KiB
TypeScript
121 lines
3.7 KiB
TypeScript
import { expect, test } from "@playwright/test"
|
|
|
|
import { ApiClient } from "../api-client"
|
|
import { SEED } from "../seed-constants"
|
|
import { SEL } from "../selectors"
|
|
|
|
const apiClient = new ApiClient()
|
|
|
|
test.describe("Stock Page @smoke", () => {
|
|
test.beforeEach(async () => {
|
|
await apiClient.login(SEED.admin.email, SEED.admin.password)
|
|
await apiClient.resetDb()
|
|
})
|
|
|
|
test("displays seed batches", async ({ page }) => {
|
|
await page.goto("/stock")
|
|
await expect(
|
|
page.getByText(SEED.strains.northernLights.name)
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByText(SEED.strains.cbdCriticalMass.name)
|
|
).toBeVisible()
|
|
await expect(page.getByText(SEED.strains.amnesiaHaze.name)).toBeVisible()
|
|
await expect(page.getByText("500")).toBeVisible()
|
|
await expect(page.getByText("300")).toBeVisible()
|
|
await expect(page.getByText("200")).toBeVisible()
|
|
})
|
|
|
|
test("status filter works", async ({ page }) => {
|
|
await page.goto("/stock")
|
|
|
|
// Filter: All — should show all 3 batches
|
|
const allFilter = page.getByRole("button", { name: /alle|all/i })
|
|
if (await allFilter.isVisible()) {
|
|
await allFilter.click()
|
|
await expect(
|
|
page.getByText(SEED.strains.northernLights.name)
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByText(SEED.strains.amnesiaHaze.name)
|
|
).toBeVisible()
|
|
}
|
|
|
|
// Filter: Available — should hide recalled batch
|
|
const availableFilter = page.getByRole("button", {
|
|
name: /verfügbar|available/i,
|
|
})
|
|
if (await availableFilter.isVisible()) {
|
|
await availableFilter.click()
|
|
await expect(
|
|
page.getByText(SEED.strains.northernLights.name)
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByText(SEED.strains.amnesiaHaze.name)
|
|
).toBeHidden()
|
|
}
|
|
|
|
// Filter: Recalled — should only show recalled batch
|
|
const recalledFilter = page.getByRole("button", {
|
|
name: /zurückgerufen|recalled/i,
|
|
})
|
|
if (await recalledFilter.isVisible()) {
|
|
await recalledFilter.click()
|
|
await expect(
|
|
page.getByText(SEED.strains.amnesiaHaze.name)
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByText(SEED.strains.northernLights.name)
|
|
).toBeHidden()
|
|
}
|
|
})
|
|
|
|
test("new batch link navigates to /stock/new", async ({ page }) => {
|
|
await page.goto("/stock")
|
|
const addBtn = page
|
|
.locator(SEL.stock.addButton)
|
|
.or(page.getByRole("link", { name: /neue charge|new batch|hinzufügen/i }))
|
|
await expect(addBtn).toBeVisible()
|
|
await addBtn.click()
|
|
await page.waitForURL(/\/stock\/new/)
|
|
})
|
|
|
|
test("recall button opens AlertDialog confirmation", async ({ page }) => {
|
|
await page.goto("/stock")
|
|
const recallBtn = page.locator(
|
|
SEL.stock.recallButton(SEED.batches.northernLights.id)
|
|
)
|
|
|
|
if (await recallBtn.isVisible()) {
|
|
await recallBtn.click()
|
|
// AlertDialog should appear with confirm/cancel
|
|
await expect(
|
|
page
|
|
.locator(SEL.common.alertDialogConfirm)
|
|
.or(page.getByRole("alertdialog"))
|
|
).toBeVisible()
|
|
}
|
|
})
|
|
|
|
test("recalled batch shows RECALLED badge", async ({ page }) => {
|
|
await page.goto("/stock")
|
|
// The Amnesia Haze batch is RECALLED
|
|
const recalledRow = page.locator(
|
|
SEL.stock.row(SEED.batches.amnesiaHaze.id)
|
|
)
|
|
|
|
if (await recalledRow.isVisible()) {
|
|
await expect(
|
|
recalledRow.getByText(/recalled|zurückgerufen/i)
|
|
).toBeVisible()
|
|
} else {
|
|
// Fallback: look for the recalled badge near Amnesia Haze text
|
|
const amnesia = page.getByText(SEED.strains.amnesiaHaze.name)
|
|
await expect(amnesia).toBeVisible()
|
|
await expect(
|
|
page.getByText(/recalled|zurückgerufen/i).first()
|
|
).toBeVisible()
|
|
}
|
|
})
|
|
})
|