Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions tests/dashboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,28 @@ test.describe('Dashboard page', () => {
const rows = table.locator('tbody tr');
await expect(rows).not.toHaveCount(0);
});

test('should display correct row data in activity table', async ({ page }) => {
await page.goto('/dashboard');

const table = page.locator('#activity-table');
const rows = table.locator('tbody tr');

await expect(rows).toHaveCount(3);

const firstRow = rows.nth(0);
await expect(firstRow.getByRole('cell', { name: 'Alice' })).toBeVisible();
await expect(firstRow.getByRole('cell', { name: 'Created account' })).toBeVisible();
await expect(firstRow.getByRole('cell', { name: '2026-05-14' })).toBeVisible();

const secondRow = rows.nth(1);
await expect(secondRow.getByRole('cell', { name: 'Bob' })).toBeVisible();
await expect(secondRow.getByRole('cell', { name: 'Placed order' })).toBeVisible();
await expect(secondRow.getByRole('cell', { name: '2026-05-13' })).toBeVisible();

const thirdRow = rows.nth(2);
await expect(thirdRow.getByRole('cell', { name: 'Charlie' })).toBeVisible();
await expect(thirdRow.getByRole('cell', { name: 'Updated profile' })).toBeVisible();
await expect(thirdRow.getByRole('cell', { name: '2026-05-12' })).toBeVisible();
});
});
18 changes: 18 additions & 0 deletions tests/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,22 @@ test.describe('Login page', () => {
await expect(message).toBeVisible();
await expect(message).toHaveClass(/error/);
});

test('should show correct error text when submitting empty form', async ({ page }) => {
await page.goto('/login');

await page.getByRole('textbox', { name: 'Username' }).evaluate(
(el: HTMLInputElement) => el.removeAttribute('required')
);
await page.getByRole('textbox', { name: 'Password' }).evaluate(
(el: HTMLInputElement) => el.removeAttribute('required')
);

await page.getByRole('button', { name: 'Login' }).click();

const message = page.locator('#message');
await expect(message).toBeVisible();
await expect(message).toHaveClass(/error/);
await expect(message).toHaveText('Username and password required');
});
});
24 changes: 24 additions & 0 deletions tests/specs/test-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,27 @@ Sample Web App — a React application with React Router that provides routes su
Expectation: Login page loads
4. Step: Click "SampleApp" logo link
Expectation: URL changes to /

### Dashboard — Activity Table
4. **Activity table displays correct row data** — `tests/dashboard.spec.ts`
- Preconditions: Authenticated (storageState from auth.setup.ts)
- Step/Expectation Pairs:
1. Step: Navigate to /dashboard
Expectation: Dashboard page loads with Recent Activity table
2. Step: Inspect first row
Expectation: Contains "Alice", "Created account", "2026-05-14"
3. Step: Inspect second row
Expectation: Contains "Bob", "Placed order", "2026-05-13"
4. Step: Inspect third row
Expectation: Contains "Charlie", "Updated profile", "2026-05-12"

### Login — Error Messages
5. **Empty form submission shows correct error text** — `tests/login.spec.ts`
- Preconditions: TEST_USER_EMAIL and TEST_USER_PASSWORD env vars set
- Step/Expectation Pairs:
1. Step: Navigate to /login
Expectation: Login page loads
2. Step: Remove required attributes from username and password fields, click Login
Expectation: Error message appears with text "Username and password required"
3. Step: Inspect error message styling
Expectation: Message has error class styling
Loading