Files
pleno-vue/tests/e2e/twoFactorAuth.spec.ts
T
Jeppe Bundgaard 60742bf947 Refactor and migrate Playwright E2E tests:
- 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.
2026-03-19 12:46:47 +01:00

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 });
});
});