- Introduced `.prettierrc.json` to enforce consistent code formatting across the project. - Updated unit and e2e test files to address formatting issues, improve readability, and ensure alignment with the new Prettier configuration.
168 lines
6.0 KiB
TypeScript
168 lines
6.0 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import { passkeyTestData, goToUserLogin, goToSubuserLogin, isPasskeyButtonVisible } from "./fixtures";
|
|
|
|
/** Passkey Authentication Tests */
|
|
|
|
// User Passkey Tests
|
|
test.describe("[AUTH][Passkey][User]", () => {
|
|
test("should display passkey login button on user login page when supported", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
// Check if passkey button is visible (depends on browser WebAuthn support)
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// The button visibility depends on WebAuthn support
|
|
// In most modern browsers (Chrome, Edge, Firefox), it should be visible
|
|
const isVisible = await passkeyButton.isVisible();
|
|
|
|
if (isVisible) {
|
|
await expect(passkeyButton).toBeVisible();
|
|
await expect(passkeyButton.locator(".fa-fingerprint")).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test("should have passkey button with fingerprint icon", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// Skip test if passkeys not supported in this browser
|
|
if (!(await passkeyButton.isVisible())) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Button should contain fingerprint icon
|
|
await expect(passkeyButton.locator(".fa-fingerprint")).toBeVisible();
|
|
});
|
|
|
|
test("should display loading spinner when passkey login is clicked", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// Skip test if passkeys not supported
|
|
if (!(await passkeyButton.isVisible())) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Click passkey button - this will trigger WebAuthn prompt
|
|
// Note: The actual WebAuthn flow cannot be completed in automated tests
|
|
// without additional browser configuration or mocking
|
|
await passkeyButton.click();
|
|
|
|
// Button should show loading spinner while waiting for authenticator
|
|
// (This may be brief or the test may need adjustment based on actual behavior)
|
|
await expect(passkeyButton.locator(".fa-spinner"))
|
|
.toBeVisible({ timeout: 1000 })
|
|
.catch(() => {
|
|
// Loading state may be too fast to catch
|
|
});
|
|
});
|
|
|
|
test("should not disable other login options when passkey is available", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
// Regular login form should still be functional
|
|
const customerNumberInput = page.locator('input[name="customer_number"]');
|
|
const passwordInput = page.locator('input[name="password"]');
|
|
const loginButton = page.locator('button[id="login-button"]');
|
|
|
|
await expect(customerNumberInput).toBeVisible();
|
|
await expect(passwordInput).toBeVisible();
|
|
await expect(loginButton).toBeVisible();
|
|
await expect(loginButton).not.toBeDisabled();
|
|
});
|
|
|
|
test("should show QR code login option alongside passkey", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
// QR code login should still be available
|
|
const qrLoginLink = page.locator('a[href="/auth/loginqr"], a:has-text("QR")');
|
|
await expect(qrLoginLink).toBeVisible();
|
|
});
|
|
});
|
|
|
|
// Subuser Passkey Tests
|
|
test.describe("[AUTH][Passkey][Subuser]", () => {
|
|
test("should display passkey login button on subuser login page when supported", async ({ page }) => {
|
|
await goToSubuserLogin(page);
|
|
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// The button visibility depends on WebAuthn support
|
|
const isVisible = await passkeyButton.isVisible();
|
|
|
|
if (isVisible) {
|
|
await expect(passkeyButton).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test("should not disable phone login when passkey is available", async ({ page }) => {
|
|
await goToSubuserLogin(page);
|
|
|
|
// Regular login form should still be functional
|
|
const phoneInput = page.locator('input[name="phone"]');
|
|
const passwordInput = page.locator('input[name="password"]');
|
|
const loginButton = page.locator('button[id="subuser-login-button"]');
|
|
|
|
await expect(phoneInput).toBeVisible();
|
|
await expect(passwordInput).toBeVisible();
|
|
await expect(loginButton).toBeVisible();
|
|
await expect(loginButton).not.toBeDisabled();
|
|
});
|
|
});
|
|
|
|
// Passkey Browser Support Tests
|
|
test.describe("[AUTH][Passkey][Browser Support]", () => {
|
|
test("should gracefully handle browsers without passkey support", async ({ page, browserName }) => {
|
|
await goToUserLogin(page);
|
|
|
|
// In browsers without WebAuthn, the passkey button should not be visible
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// Get visibility state - this test documents the behavior rather than asserting specific state
|
|
const isVisible = await passkeyButton.isVisible();
|
|
|
|
// Log the state for test reporting
|
|
console.log(`Passkey button visible in ${browserName}: ${isVisible}`);
|
|
|
|
// The important thing is that the page loads correctly regardless
|
|
await expect(page.locator("form")).toBeVisible();
|
|
});
|
|
|
|
test("should always show password-based login as fallback", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
// Password login should always be available, regardless of passkey support
|
|
await expect(page.locator('input[name="customer_number"]')).toBeVisible();
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
|
await expect(page.locator('button[id="login-button"]')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
// Passkey Button State Tests
|
|
test.describe("[AUTH][Passkey][Button State]", () => {
|
|
test("should disable passkey button while loading", async ({ page }) => {
|
|
await goToUserLogin(page);
|
|
|
|
const passkeyButton = page.locator('button[id="passkey-login-button"]');
|
|
|
|
// Skip if passkeys not supported
|
|
if (!(await passkeyButton.isVisible())) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Initial state - button should be enabled
|
|
await expect(passkeyButton).not.toBeDisabled();
|
|
|
|
// After clicking, button should become disabled while loading
|
|
await passkeyButton.click();
|
|
|
|
// The button should be disabled during the authentication attempt
|
|
await expect(passkeyButton).toBeDisabled();
|
|
});
|
|
});
|