- Remove `playwright.config.js` to clean up configuration. - Add new E2E test suites (`admin-pos-orders`, `admin-module-goals`, `admin-module-pos-mobile-order-flow`) to structure Admin module tests. - Introduce reusable authentication and data seeding utilities in `fixtures` for streamlined test flows and maintainability.
148 lines
5.1 KiB
TypeScript
148 lines
5.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import {
|
|
user2FACredentials,
|
|
subuser2FACredentials,
|
|
invalidCredentials,
|
|
loginAsUserWith2FA,
|
|
loginAsSubuserWith2FA,
|
|
verify2FACode,
|
|
cancel2FA,
|
|
goToUserLogin,
|
|
goToSubuserLogin,
|
|
} from './fixtures';
|
|
|
|
/** Two-Factor Authentication (2FA) Tests */
|
|
|
|
// User 2FA Tests
|
|
test.describe('[AUTH][2FA][User]', () => {
|
|
test('should display 2FA verification screen after login for 2FA-enabled user', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
// Verify 2FA screen elements
|
|
await expect(page.locator('.fa-shield-alt')).toBeVisible();
|
|
await expect(page.locator('input[name="2fa_code"]')).toBeVisible();
|
|
await expect(page.locator('button[id="2fa-verify-button"]')).toBeVisible();
|
|
});
|
|
|
|
test('should have disabled verify button when code is not 6 digits', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
// Empty code - button should be disabled
|
|
await expect(page.locator('button[id="2fa-verify-button"]')).toBeDisabled();
|
|
|
|
// Partial code - button should still be disabled
|
|
await page.fill('input[name="2fa_code"]', '123');
|
|
await expect(page.locator('button[id="2fa-verify-button"]')).toBeDisabled();
|
|
});
|
|
|
|
test('should enable verify button when code is 6 digits', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
await page.fill('input[name="2fa_code"]', '123456');
|
|
await expect(page.locator('button[id="2fa-verify-button"]')).not.toBeDisabled();
|
|
});
|
|
|
|
test('should show error for invalid 2FA code', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
await verify2FACode(page, invalidCredentials.invalid2FACode);
|
|
|
|
// Should display error message
|
|
await expect(page.locator('#2fa_auth_alert_error')).toBeVisible();
|
|
});
|
|
|
|
test('should return to login form when cancelling 2FA', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
await cancel2FA(page);
|
|
|
|
// Should be back at login form
|
|
await expect(page.locator('input[name="customer_number"]')).toBeVisible();
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
|
});
|
|
|
|
test('should clear password when cancelling 2FA', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
await cancel2FA(page);
|
|
|
|
// Password field should be empty
|
|
const passwordValue = await page.locator('input[name="password"]').inputValue();
|
|
expect(passwordValue).toBe('');
|
|
});
|
|
|
|
test('should login successfully with valid 2FA code', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
await verify2FACode(page, user2FACredentials.validCode);
|
|
|
|
// Should show success message and redirect to user dashboard
|
|
await expect(page.locator('#2fa_auth_alert_success')).toBeVisible();
|
|
await expect(page).toHaveURL('/user', { timeout: 5000 });
|
|
});
|
|
|
|
test('should only accept numeric input in 2FA code field', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
const codeInput = page.locator('input[name="2fa_code"]');
|
|
await codeInput.type('abc123');
|
|
|
|
// Should only contain numbers
|
|
const inputValue = await codeInput.inputValue();
|
|
// The input has pattern="[0-9]*" and inputmode="numeric"
|
|
expect(inputValue.length).toBeLessThanOrEqual(6);
|
|
});
|
|
|
|
test('should limit 2FA code to 6 characters', async ({ page }) => {
|
|
await loginAsUserWith2FA(page);
|
|
|
|
const codeInput = page.locator('input[name="2fa_code"]');
|
|
await codeInput.type('1234567890');
|
|
|
|
// Should be limited to 6 characters
|
|
const inputValue = await codeInput.inputValue();
|
|
expect(inputValue.length).toBe(6);
|
|
});
|
|
});
|
|
|
|
// Subuser 2FA Tests
|
|
test.describe('[AUTH][2FA][Subuser]', () => {
|
|
test('should display 2FA verification screen after login for 2FA-enabled subuser', async ({ page }) => {
|
|
await loginAsSubuserWith2FA(page);
|
|
|
|
// Verify 2FA screen elements
|
|
await expect(page.locator('.fa-shield-alt')).toBeVisible();
|
|
await expect(page.locator('input[name="2fa_code"]')).toBeVisible();
|
|
await expect(page.locator('button[id="2fa-verify-button"]')).toBeVisible();
|
|
});
|
|
|
|
test('should show error for invalid 2FA code', async ({ page }) => {
|
|
await loginAsSubuserWith2FA(page);
|
|
|
|
await verify2FACode(page, invalidCredentials.invalid2FACode);
|
|
|
|
// Should display error message
|
|
await expect(page.locator('#2fa_auth_alert_error')).toBeVisible();
|
|
});
|
|
|
|
test('should return to login form when cancelling 2FA', async ({ page }) => {
|
|
await loginAsSubuserWith2FA(page);
|
|
|
|
await cancel2FA(page);
|
|
|
|
// Should be back at subuser login form
|
|
await expect(page.locator('input[name="phone"]')).toBeVisible();
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
|
});
|
|
|
|
test('should login successfully with valid 2FA code', async ({ page }) => {
|
|
await loginAsSubuserWith2FA(page);
|
|
|
|
await verify2FACode(page, subuser2FACredentials.validCode);
|
|
|
|
// Should show success message and redirect to user dashboard
|
|
await expect(page.locator('#2fa_auth_alert_success')).toBeVisible();
|
|
await expect(page).toHaveURL('/user', { timeout: 5000 });
|
|
});
|
|
});
|