Introduce completeBookingCreationFlow utility and refactor booking flow tests:

- Added `completeBookingCreationFlow` utility to streamline booking creation logic in `bookingFlow.ts`.
- Refactored `userBookings.spec.ts` to replace inline booking creation steps with the new utility for improved readability and consistency.
- Applied `data-testid` attributes across booking-related components for enhanced testability and test coverage.
- Enhanced Playwright navigation error handling with `isBenignNavigationError` and `settleAuthenticatedNavigation` utilities to improve resilience and test robustness.
This commit is contained in:
Jeppe Bundgaard
2026-04-13 13:39:48 +02:00
parent 828e2fd312
commit ade565cbca
28 changed files with 726 additions and 538 deletions
+3 -76
View File
@@ -1,81 +1,8 @@
import { test, expect } from "@playwright/test";
import { test } from "@playwright/test";
import { loginAsUser, bookingTestData } from "./fixtures";
import { completeBookingCreationFlow } from "./support/bookingFlow";
/** User "Book Wash" Tests */
// Entire flow: Login -> Book Wash -> Check if booking is created
test("[BOOKINGS][User][Creation] should create a new booking", async ({ page }) => {
const { departmentId, registrationNumber, reference, poNumber, notes } = bookingTestData;
// Login as user
await loginAsUser(page);
// Does the book wash button appear?
await expect(page.locator("#book-wash-button")).toBeVisible();
// Click the book wash button and check if it navigates to the booking page
await page.click('a[id="book-wash-button"]');
await expect(page).toHaveURL("/user/bookings/book");
// Select the department (Demo: 12)
const department_select_id = `#department-option-${departmentId}`;
await page.click(department_select_id);
// Enter the registration number (Demo: EC21233)
// Click the button to reveal the input field
await page.click("#reg1-button");
// Fill in the registration number
await page.fill("#reg1-input", registrationNumber);
// Press Enter to confirm the input
await page.press("#reg1-input", "Enter");
// Note: Vehicle type selection only shows if vehicle is registered in the system.
// EC21233 is not registered, so no suggestions appear. Proceed to next step.
// Click "Next step: Select add-ons" button to proceed
await page.click('button:has-text("Næste trin")');
// Select the product (Demo: first available product)
// Wait for products to load, then click the first product box
await page.waitForSelector(".pos-product-box");
await page.locator(".pos-product-box").first().click();
// Add-ons selection is optional
// Add-ons are displayed as clickable product rows (not buttons) after selecting a product
// Skip add-on selection for this basic test flow
// Select date and time
// The date/time picker uses a button with a calendar icon - click to open
// Default date is set automatically; skip if not required
// Set reference number (Demo: test_ref123)
await page.click('button:has-text("Tilføj reference")');
await page.fill("#reference", reference);
await page.press("#reference", "Enter");
// Set PO number (Demo: test_po123)
await page.click('button:has-text("Tilføj PO nummer")');
await page.fill("#poNumber", poNumber);
await page.press("#poNumber", "Enter");
// Set Note (Demo: test_note123)
await page.click('button:has-text("Tilføj note")');
await page.fill("#notes", notes);
await page.press("#notes", "Enter");
// Set Pickup (Demo: checked)
await page.check("#pickup");
// Go to confirmation page
await page.click("#go-to-confirmation-button");
// Verify the booking summary is displayed
await expect(page.locator("#booking-summary-title")).toBeVisible();
// Confirm the booking
// Use force: true because an icon overlay can intercept pointer events on some browsers
await page.click("#confirm-booking-button", { force: true });
// Verify booking was created successfully (redirect to user dashboard or success message)
// The exact verification depends on the application behavior after booking creation
await expect(page).toHaveURL(/\/user/);
await completeBookingCreationFlow(page, bookingTestData);
});