mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-05-07 20:32:26 +00:00
234 lines
10 KiB
TypeScript
234 lines
10 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { PLAYWRIGHT_BASE_URL } from '../playwright/config';
|
|
import { getPasswordResetUrl } from './utils/mailpit';
|
|
|
|
async function registerNewUser(page, email, password) {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/register');
|
|
await page.getByLabel('Name').fill('John Doe');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password', { exact: true }).fill(password);
|
|
await page.getByLabel('Confirm Password').fill(password);
|
|
await page.getByLabel('I agree to the Terms of').click();
|
|
await page.getByRole('button', { name: 'Register' }).click();
|
|
await expect(page.getByTestId('dashboard_view')).toBeVisible();
|
|
}
|
|
|
|
test('can register, logout and log back in', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL);
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const password = 'suchagreatpassword123';
|
|
await registerNewUser(page, email, password);
|
|
await expect(page.getByTestId('dashboard_view')).toBeVisible();
|
|
await page.getByTestId('current_user_button').click();
|
|
await page.getByText('Log Out').click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/login');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password').fill(password);
|
|
await page.getByRole('button', { name: 'Log in' }).click();
|
|
await expect(page.getByTestId('dashboard_view')).toBeVisible();
|
|
});
|
|
|
|
test('can register and delete account', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL);
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const password = 'suchagreatpassword123';
|
|
await registerNewUser(page, email, password);
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/user/profile');
|
|
await page.getByRole('button', { name: 'Delete Account' }).click();
|
|
await expect(page.getByRole('dialog')).toBeVisible();
|
|
await page.getByPlaceholder('Password').fill(password);
|
|
await page.getByRole('dialog').getByRole('button', { name: 'Delete Account' }).click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/login');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password').fill(password);
|
|
await page.getByRole('button', { name: 'Log in' }).click();
|
|
await expect(page.getByRole('alert')).toContainText(
|
|
'These credentials do not match our records.'
|
|
);
|
|
});
|
|
|
|
test('shows error for invalid email on forgot password', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
|
|
// Request password reset with non-existent email
|
|
await page.getByLabel('Email').fill('nonexistent@example.com');
|
|
await page.getByRole('button', { name: 'Email Password Reset Link' }).click();
|
|
|
|
// Should show error message
|
|
await expect(page.getByText("We can't find a user with that email address.")).toBeVisible();
|
|
});
|
|
|
|
test('shows browser validation for invalid email format on forgot password', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
|
|
// Request password reset with invalid email format
|
|
const emailInput = page.getByLabel('Email');
|
|
await emailInput.fill('notanemail');
|
|
|
|
// Check for browser validation - the input should be invalid
|
|
const isInvalid = await emailInput.evaluate((el: HTMLInputElement) => !el.validity.valid);
|
|
expect(isInvalid).toBe(true);
|
|
});
|
|
|
|
test('shows browser validation for empty email on forgot password', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
|
|
// The email input is required, so it should be invalid when empty
|
|
const emailInput = page.getByLabel('Email');
|
|
|
|
// Check for browser validation - the input should be invalid because it's required and empty
|
|
const isInvalid = await emailInput.evaluate((el: HTMLInputElement) => el.validity.valueMissing);
|
|
expect(isInvalid).toBe(true);
|
|
});
|
|
|
|
test('can reset password via email link', async ({ page, request }) => {
|
|
// First register a new user
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const originalPassword = 'suchagreatpassword123';
|
|
const newPassword = 'mynewsecurepassword456';
|
|
await registerNewUser(page, email, originalPassword);
|
|
|
|
// Log out
|
|
await page.getByTestId('current_user_button').click();
|
|
await page.getByText('Log Out').click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
|
|
// Request password reset
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByRole('button', { name: 'Email Password Reset Link' }).click();
|
|
await expect(page.getByText('We have emailed your password reset link.')).toBeVisible();
|
|
|
|
// Get password reset URL from email
|
|
const resetUrl = await getPasswordResetUrl(request, email);
|
|
|
|
// Navigate to reset page
|
|
await page.goto(resetUrl);
|
|
|
|
// Fill in new password
|
|
await page.getByLabel('Password', { exact: true }).fill(newPassword);
|
|
await page.getByLabel('Confirm Password').fill(newPassword);
|
|
await page.getByRole('button', { name: 'Reset Password' }).click();
|
|
|
|
// Should redirect to login page after successful reset
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
|
|
// Try logging in with new password
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password').fill(newPassword);
|
|
await page.getByRole('button', { name: 'Log in' }).click();
|
|
await expect(page.getByTestId('dashboard_view')).toBeVisible();
|
|
});
|
|
|
|
test('shows validation error for password mismatch on reset', async ({ page, request }) => {
|
|
// First register a new user
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const originalPassword = 'suchagreatpassword123';
|
|
await registerNewUser(page, email, originalPassword);
|
|
|
|
// Log out
|
|
await page.getByTestId('current_user_button').click();
|
|
await page.getByText('Log Out').click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
|
|
// Request password reset
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByRole('button', { name: 'Email Password Reset Link' }).click();
|
|
await expect(page.getByText('We have emailed your password reset link.')).toBeVisible();
|
|
|
|
// Get password reset URL from email
|
|
const resetUrl = await getPasswordResetUrl(request, email);
|
|
|
|
// Navigate to reset page
|
|
await page.goto(resetUrl);
|
|
|
|
// Fill in mismatched passwords
|
|
await page.getByLabel('Password', { exact: true }).fill('newpassword123');
|
|
await page.getByLabel('Confirm Password').fill('differentpassword456');
|
|
await page.getByRole('button', { name: 'Reset Password' }).click();
|
|
|
|
// Should show validation error
|
|
await expect(page.getByText('The password field confirmation does not match.')).toBeVisible();
|
|
});
|
|
|
|
test('shows validation error for short password on reset', async ({ page, request }) => {
|
|
// First register a new user
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const originalPassword = 'suchagreatpassword123';
|
|
await registerNewUser(page, email, originalPassword);
|
|
|
|
// Log out
|
|
await page.getByTestId('current_user_button').click();
|
|
await page.getByText('Log Out').click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
|
|
// Request password reset
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/forgot-password');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByRole('button', { name: 'Email Password Reset Link' }).click();
|
|
await expect(page.getByText('We have emailed your password reset link.')).toBeVisible();
|
|
|
|
// Get password reset URL from email
|
|
const resetUrl = await getPasswordResetUrl(request, email);
|
|
|
|
// Navigate to reset page
|
|
await page.goto(resetUrl);
|
|
|
|
// Fill in short password
|
|
await page.getByLabel('Password', { exact: true }).fill('short');
|
|
await page.getByLabel('Confirm Password').fill('short');
|
|
await page.getByRole('button', { name: 'Reset Password' }).click();
|
|
|
|
// Should show validation error about minimum length
|
|
await expect(page.getByText('must be at least')).toBeVisible();
|
|
});
|
|
|
|
test('shows error for invalid login credentials', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/login');
|
|
await page.getByLabel('Email').fill('nonexistent@example.com');
|
|
await page.getByLabel('Password').fill('wrongpassword123');
|
|
await page.getByRole('button', { name: 'Log in' }).click();
|
|
|
|
await expect(page.getByText('These credentials do not match our records.')).toBeVisible();
|
|
});
|
|
|
|
test('shows error when registering with existing email', async ({ page }) => {
|
|
const email = `john+${Math.round(Math.random() * 10000)}@doe.com`;
|
|
const password = 'suchagreatpassword123';
|
|
|
|
// Register first user
|
|
await registerNewUser(page, email, password);
|
|
|
|
// Log out
|
|
await page.getByTestId('current_user_button').click();
|
|
await page.getByText('Log Out').click();
|
|
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
|
|
|
// Try to register with the same email
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/register');
|
|
await page.getByLabel('Name').fill('Another User');
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password', { exact: true }).fill(password);
|
|
await page.getByLabel('Confirm Password').fill(password);
|
|
await page.getByLabel('I agree to the Terms of').click();
|
|
await page.getByRole('button', { name: 'Register' }).click();
|
|
|
|
// Should show error about email already taken
|
|
await expect(page.getByText('The resource already exists.')).toBeVisible();
|
|
});
|
|
|
|
test('shows validation error for weak password on registration', async ({ page }) => {
|
|
await page.goto(PLAYWRIGHT_BASE_URL + '/register');
|
|
await page.getByLabel('Name').fill('Weak Password User');
|
|
await page.getByLabel('Email').fill(`weak+${Math.round(Math.random() * 10000)}@test.com`);
|
|
await page.getByLabel('Password', { exact: true }).fill('short');
|
|
await page.getByLabel('Confirm Password').fill('short');
|
|
await page.getByLabel('I agree to the Terms of').click();
|
|
await page.getByRole('button', { name: 'Register' }).click();
|
|
|
|
await expect(page.getByText('must be at least')).toBeVisible();
|
|
});
|