feat: create custom assertions utility for e2e test validation

This commit is contained in:
2026-04-19 07:52:23 +03:00
parent 6851ae4ed2
commit 3d57cf8d38

View File

@@ -0,0 +1,261 @@
import { expect, Page, Locator } from '@playwright/test';
/**
* Custom Playwright assertions for E2E tests
* Provides domain-specific matchers for inventory operations
*/
/**
* Assert that an inventory item is visible with expected data
*/
export async function assertItemVisible(
page: Page,
itemName: string,
expectedData?: { quantity?: number; category?: string }
): Promise<void> {
const itemRow = page.locator(`[data-testid="item-row"][data-item-name="${itemName}"]`);
await expect(itemRow).toBeVisible();
if (expectedData?.quantity !== undefined) {
const quantityCell = itemRow.locator('[data-testid="quantity-cell"]');
await expect(quantityCell).toContainText(expectedData.quantity.toString());
}
if (expectedData?.category !== undefined) {
const categoryCell = itemRow.locator('[data-testid="category-cell"]');
await expect(categoryCell).toContainText(expectedData.category);
}
}
/**
* Assert that a barcode scan was successful
*/
export async function assertScanSuccess(
page: Page,
expectedItemName: string,
expectedQuantityChange: number
): Promise<void> {
// Check for success toast notification
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 3000 });
// Verify item quantity was updated
const itemRow = page.locator(`[data-testid="item-row"][data-item-name="${expectedItemName}"]`);
await expect(itemRow).toBeVisible();
}
/**
* Assert that login form is displayed
*/
export async function assertLoginFormVisible(page: Page): Promise<void> {
const loginForm = page.locator('[data-testid="login-form"]');
await expect(loginForm).toBeVisible();
const usernameInput = page.locator('[data-testid="username-input"]');
const passwordInput = page.locator('[data-testid="password-input"]');
const submitButton = page.locator('[data-testid="login-submit"]');
await expect(usernameInput).toBeVisible();
await expect(passwordInput).toBeVisible();
await expect(submitButton).toBeVisible();
}
/**
* Assert that user is authenticated (on inventory page)
*/
export async function assertUserAuthenticated(page: Page, baseUrl: string = 'http://localhost'): Promise<void> {
// Check URL is on an authenticated page
await expect(page).toHaveURL(/inventory|dashboard|scanner/);
// Verify logout button is visible
const logoutButton = page.locator('[data-testid="logout-button"]');
await expect(logoutButton).toBeVisible();
}
/**
* Assert that admin dashboard is visible
*/
export async function assertAdminDashboardVisible(page: Page): Promise<void> {
const adminOverlay = page.locator('[data-testid="admin-overlay"]');
await expect(adminOverlay).toBeVisible();
// Check for tabs
const identityTab = page.locator('[data-testid="admin-tab-identity"]');
const databaseTab = page.locator('[data-testid="admin-tab-database"]');
await expect(identityTab).toBeVisible();
await expect(databaseTab).toBeVisible();
}
/**
* Assert that stock adjustment form is visible
*/
export async function assertStockAdjustmentVisible(page: Page, itemName: string): Promise<void> {
const adjustmentForm = page.locator('[data-testid="stock-adjustment-form"]');
await expect(adjustmentForm).toBeVisible();
const itemNameDisplay = page.locator(`[data-testid="adjustment-item-name"]`);
await expect(itemNameDisplay).toContainText(itemName);
const quantityInput = page.locator('[data-testid="adjustment-quantity-input"]');
await expect(quantityInput).toBeVisible();
}
/**
* Assert that AI extraction is in progress
*/
export async function assertAiExtractionInProgress(page: Page): Promise<void> {
const extractionOverlay = page.locator('[data-testid="ai-extraction-overlay"]');
await expect(extractionOverlay).toBeVisible();
const loadingSpinner = page.locator('[data-testid="extraction-loading"]');
await expect(loadingSpinner).toBeVisible();
}
/**
* Assert that AI extraction results are displayed
*/
export async function assertAiExtractionResults(
page: Page,
expectedFields: { name?: string; partNumber?: string; quantity?: string }
): Promise<void> {
const resultsForm = page.locator('[data-testid="extraction-results-form"]');
await expect(resultsForm).toBeVisible();
if (expectedFields.name) {
const nameInput = resultsForm.locator('[data-testid="extracted-name"]');
await expect(nameInput).toHaveValue(expectedFields.name);
}
if (expectedFields.partNumber) {
const pnInput = resultsForm.locator('[data-testid="extracted-part-number"]');
await expect(pnInput).toHaveValue(expectedFields.partNumber);
}
if (expectedFields.quantity) {
const quantityInput = resultsForm.locator('[data-testid="extracted-quantity"]');
await expect(quantityInput).toHaveValue(expectedFields.quantity);
}
}
/**
* Assert that offline sync is pending
*/
export async function assertOfflineSyncPending(page: Page): Promise<void> {
const syncIndicator = page.locator('[data-testid="offline-sync-indicator"]');
await expect(syncIndicator).toBeVisible();
const pendingBadge = page.locator('[data-testid="sync-pending-badge"]');
await expect(pendingBadge).toBeVisible();
}
/**
* Assert that offline sync completed
*/
export async function assertOfflineSyncComplete(page: Page): Promise<void> {
const syncIndicator = page.locator('[data-testid="offline-sync-indicator"]');
await expect(syncIndicator).not.toBeVisible({ timeout: 10000 });
const successBadge = page.locator('[data-testid="sync-success-badge"]');
await expect(successBadge).toBeVisible();
}
/**
* Assert that error message is displayed
*/
export async function assertErrorMessage(page: Page, errorText?: string): Promise<void> {
const errorToast = page.locator('[data-testid="toast-error"]');
await expect(errorToast).toBeVisible();
if (errorText) {
await expect(errorToast).toContainText(errorText);
}
}
/**
* Assert that category list is visible
*/
export async function assertCategoryListVisible(page: Page): Promise<void> {
const categoryList = page.locator('[data-testid="category-list"]');
await expect(categoryList).toBeVisible();
const categoryItems = page.locator('[data-testid="category-item"]');
const count = await categoryItems.count();
expect(count).toBeGreaterThan(0);
}
/**
* Assert that scanner interface is ready
*/
export async function assertScannerReady(page: Page): Promise<void> {
const scannerContainer = page.locator('[data-testid="scanner-container"]');
await expect(scannerContainer).toBeVisible();
const cameraView = page.locator('[data-testid="camera-view"]');
await expect(cameraView).toBeVisible();
const scanInput = page.locator('[data-testid="scan-input"]');
await expect(scanInput).toBeVisible();
}
/**
* Assert that item creation form is visible
*/
export async function assertItemCreationFormVisible(page: Page): Promise<void> {
const createForm = page.locator('[data-testid="create-item-form"]');
await expect(createForm).toBeVisible();
const nameInput = page.locator('[data-testid="item-name-input"]');
const categorySelect = page.locator('[data-testid="item-category-select"]');
const submitButton = page.locator('[data-testid="item-create-submit"]');
await expect(nameInput).toBeVisible();
await expect(categorySelect).toBeVisible();
await expect(submitButton).toBeVisible();
}
/**
* Assert element count matches expected
*/
export async function assertElementCount(
page: Page,
selector: string,
expectedCount: number
): Promise<void> {
const elements = page.locator(selector);
const count = await elements.count();
expect(count).toBe(expectedCount);
}
/**
* Assert element is disabled
*/
export async function assertElementDisabled(locator: Locator): Promise<void> {
await expect(locator).toBeDisabled();
}
/**
* Assert element is enabled
*/
export async function assertElementEnabled(locator: Locator): Promise<void> {
await expect(locator).toBeEnabled();
}
/**
* Assert modal is open
*/
export async function assertModalOpen(page: Page, modalId: string): Promise<void> {
const modal = page.locator(`[data-testid="${modalId}"]`);
await expect(modal).toBeVisible();
const backdrop = page.locator('[data-testid="modal-backdrop"]');
await expect(backdrop).toBeVisible();
}
/**
* Assert modal is closed
*/
export async function assertModalClosed(page: Page, modalId: string): Promise<void> {
const modal = page.locator(`[data-testid="${modalId}"]`);
await expect(modal).not.toBeVisible();
}