openvidu/openvidu-dashboard/dashboard-ce/e2e/tests/auth.spec.ts

114 lines
4.7 KiB
TypeScript
Raw Normal View History

import { expect, test } from '../fixtures/api.js';
test.describe('signed out', () => {
test.use({ apiOptions: { signedIn: false } });
test('a protected route sends to the login with the URL to return to', async ({ page, api }) => {
await page.goto('/settings?tab=about');
await expect(page).toHaveURL('/login?redirect=%2Fsettings%3Ftab%3Dabout');
await expect(page.getByText('CE', { exact: true })).toBeVisible();
await expect(page.getByText('3.10.0', { exact: true })).toBeVisible();
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password', { exact: true }).fill('secret');
await page.getByLabel('Password', { exact: true }).press('Enter');
await expect(page).toHaveURL('/settings?tab=about');
expect(api.calls()).toContain('POST auth/login');
});
test('an unknown path while signed out returns to it after the login', async ({ page }) => {
await page.goto('/nowhere');
await expect(page).toHaveURL('/login?redirect=%2Fnowhere');
});
test.describe('with wrong credentials', () => {
test.use({ apiOptions: { signedIn: false, login: 'invalid' } });
test('shows the error, clears the password and focuses the username', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password', { exact: true }).fill('wrong');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('alert')).toHaveText('Invalid username or password');
await expect(page.getByLabel('Password', { exact: true })).toHaveValue('');
await expect(page.getByLabel('Username')).toBeFocused();
});
});
test.describe('when rate limited', () => {
test.use({ apiOptions: { signedIn: false, login: 'rate-limited', retryAfter: 2 } });
test('counts down and enables the form again', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password', { exact: true }).fill('secret');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('alert')).toHaveText('Too many attempts, try again in 2 s');
await expect(page.getByRole('button', { name: 'Sign in' })).toBeDisabled();
await expect(page.getByRole('alert')).toHaveText('Too many attempts, try again in 1 s');
await expect(page.getByRole('button', { name: 'Sign in' })).toBeEnabled({ timeout: 5_000 });
});
});
test.describe('when the server is unreachable', () => {
test.use({ apiOptions: { signedIn: false, login: 'unreachable' } });
test('shows a banner with retry', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password', { exact: true }).fill('secret');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByText('The server is unreachable.')).toBeVisible();
await expect(page.getByRole('button', { name: 'Retry' })).toBeVisible();
});
});
});
test('a reload restores the session silently', async ({ page, api }) => {
await page.goto('/settings');
await expect(page.getByRole('heading', { level: 1, name: 'Settings' })).toBeVisible();
await page.reload();
await expect(page).toHaveURL('/settings');
await expect(page.getByRole('heading', { level: 1, name: 'Settings' })).toBeVisible();
expect(api.calls().filter((call) => call === 'POST auth/refresh')).toHaveLength(2);
expect(api.calls()).not.toContain('POST auth/login');
});
test('an expired token is refreshed once and the requests are replayed', async ({ page, api }) => {
await page.goto('/overview');
await expect(page.getByRole('heading', { level: 1, name: 'Overview' })).toBeVisible();
const refreshes = api.calls().filter((call) => call === 'POST auth/refresh').length;
api.expireToken();
await page.getByRole('combobox', { name: 'Search' }).fill('dem');
await expect.poll(() => api.calls().filter((call) => call === 'GET rooms').length).toBe(2);
expect(api.calls().filter((call) => call === 'POST auth/refresh')).toHaveLength(refreshes + 1);
expect(api.calls().filter((call) => call === 'GET participants')).toHaveLength(2);
await expect(page).toHaveURL('/overview?tz=Europe%2FMadrid');
});
test('sign out ends the session and shows the login without redirect', async ({ page, api }) => {
await page.goto('/rooms');
await page.getByRole('button', { name: 'User menu' }).click();
await page.getByRole('menuitem', { name: 'Sign out' }).click();
await expect(page).toHaveURL('/login');
expect(api.calls()).toContain('POST auth/logout');
});
test('an authenticated user opening the login goes to the redirect target', async ({ page }) => {
await page.goto('/login?redirect=%2Fsettings');
await expect(page).toHaveURL('/settings');
});