- Added e2e tests for auth flows (registration, login, password reset, TOTP) - Added e2e tests for onboarding and organization creation - Added e2e tests for team collaboration (org switching, invitations) - Added e2e tests for activity feed - Added e2e tests for device graphs (sensors, time ranges, interfaces) - Added e2e tests for MikroTik backup comparison - Added e2e tests for sites map (geographic view) - Added e2e tests for network trace tool - Fixed 'too many open files' error by configuring Phoenix code reloader to ignore deps/, _build/, node_modules/, e2e/, and other non-source directories - This prevents the file system watcher from monitoring unnecessary files
157 lines
5.3 KiB
TypeScript
157 lines
5.3 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Authentication Flows', () => {
|
|
test.describe('Registration', () => {
|
|
test('can access registration page', async ({ page }) => {
|
|
await page.goto('/users/register');
|
|
|
|
await expect(page).toHaveURL(/\/users\/register/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows registration form fields', async ({ page }) => {
|
|
await page.goto('/users/register');
|
|
|
|
// Look for email and password fields
|
|
const emailField = page.locator('input[type="email"]').first();
|
|
const passwordField = page.locator('input[type="password"]').first();
|
|
|
|
if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(emailField).toBeVisible();
|
|
}
|
|
|
|
if (await passwordField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(passwordField).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Login', () => {
|
|
test('can access login page', async ({ page }) => {
|
|
await page.goto('/users/log-in');
|
|
|
|
await expect(page).toHaveURL(/\/users\/log-in/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows login form', async ({ page }) => {
|
|
await page.goto('/users/log-in');
|
|
|
|
const emailField = page.locator('input[type="email"]').first();
|
|
const passwordField = page.locator('input[type="password"]').first();
|
|
const submitButton = page.locator('button[type="submit"]').first();
|
|
|
|
if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(emailField).toBeVisible();
|
|
}
|
|
|
|
if (await passwordField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(passwordField).toBeVisible();
|
|
}
|
|
|
|
if (await submitButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(submitButton).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows link to password reset', async ({ page }) => {
|
|
await page.goto('/users/log-in');
|
|
|
|
const resetLink = page.locator('a[href*="reset-password"]').first();
|
|
|
|
if (await resetLink.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(resetLink).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows link to registration', async ({ page }) => {
|
|
await page.goto('/users/log-in');
|
|
|
|
const registerLink = page.locator('a[href*="register"]').first();
|
|
|
|
if (await registerLink.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(registerLink).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Password Reset', () => {
|
|
test('can access password reset page', async ({ page }) => {
|
|
await page.goto('/users/reset-password');
|
|
|
|
await expect(page).toHaveURL(/\/users\/reset-password/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows password reset form', async ({ page }) => {
|
|
await page.goto('/users/reset-password');
|
|
|
|
const emailField = page.locator('input[type="email"]').first();
|
|
const submitButton = page.locator('button[type="submit"]').first();
|
|
|
|
if (await emailField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(emailField).toBeVisible();
|
|
}
|
|
|
|
if (await submitButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(submitButton).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('TOTP Enrollment', () => {
|
|
test('can access TOTP enrollment page when authenticated', async ({ page }) => {
|
|
await page.goto('/account/totp-enrollment');
|
|
|
|
// Will redirect to login if not authenticated
|
|
const currentUrl = page.url();
|
|
if (currentUrl.includes('log-in')) {
|
|
// Expected - not authenticated
|
|
return;
|
|
}
|
|
|
|
await expect(page).toHaveURL(/\/account\/totp-enrollment/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows QR code for TOTP setup', async ({ page }) => {
|
|
await page.goto('/account/totp-enrollment');
|
|
|
|
// Skip if redirected to login
|
|
if ((await page.url()).includes('log-in')) {
|
|
return;
|
|
}
|
|
|
|
// Look for QR code or setup instructions
|
|
const qrCode = page.locator('canvas, img[alt*="QR"], [data-qr]').first();
|
|
const setupInstructions = page.locator(':has-text("scan"), :has-text("authenticator")').first();
|
|
|
|
const qrVisible = await qrCode.isVisible({ timeout: 2000 }).catch(() => false);
|
|
const instructionsVisible = await setupInstructions.isVisible({ timeout: 2000 }).catch(() => false);
|
|
|
|
if (qrVisible || instructionsVisible) {
|
|
// At least one should be visible
|
|
expect(qrVisible || instructionsVisible).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Email Confirmation', () => {
|
|
test('can access confirmation page', async ({ page }) => {
|
|
await page.goto('/users/confirm');
|
|
|
|
await expect(page).toHaveURL(/\/users\/confirm/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows confirmation instructions', async ({ page }) => {
|
|
await page.goto('/users/confirm');
|
|
|
|
const instructions = page.locator(':has-text("email"), :has-text("confirm")').first();
|
|
|
|
if (await instructions.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(instructions).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
});
|