Files
homepage/tests/e2e/04-achievements.spec.js
ducoterra 3898dc3c5e Add Playwright E2E suite against the built dist/
Pin @playwright/test 1.62.0 (matches the cached chromium
revision) and serve dist/ via python3 http.server, so the
deployed artifact is what gets tested. Covers page load,
terminal commands, vim mode, achievements, and the nav menu.
Ignore node_modules, test-results, playwright-report, and the
phased-execution runtime scratch (.agents/phase-sessions,
pipeline.log).
2026-09-18 17:23:30 -04:00

92 lines
4.2 KiB
JavaScript

// @ts-check
const { test, expect } = require('@playwright/test');
const { openTerminal, typeCommand } = require('./helpers');
const STORAGE_KEY = 'reese-terminal-achievements';
test.describe('Achievements system', () => {
test('starts hidden until the first unlock', async ({ page }) => {
await page.goto('/');
await expect(page.locator('#achievements')).toBeHidden();
await expect(page.locator('#nav-achievements')).toHaveCount(0);
});
test('uptime unlock shows a toast, persists to localStorage, reveals the section', async ({ page }) => {
await page.goto('/');
await openTerminal(page);
await typeCommand(page, 'uptime');
// toast with the achievement name
const toast = page.locator('.toast').filter({ hasText: 'Time Flies' });
await expect(toast).toBeVisible();
await expect(toast).toContainText('Achievement Unlocked');
await expect(page.locator('#toast-container .toast')).toHaveCount(1);
// persisted
const stored = await page.evaluate(k => JSON.parse(localStorage.getItem(k) || '[]'), STORAGE_KEY);
expect(stored).toContain('time_flies');
// section revealed + counter + nav link
await expect(page.locator('#achievements')).toBeVisible();
await expect(page.locator('#achievements-count')).toHaveText(/1 \/ \d+ achievements unlocked/);
await expect(page.locator('#nav-achievements a')).toHaveAttribute('href', '#achievements');
// the unlocked card shows its name; locked ones stay mysterious
const cards = page.locator('#achievements-grid .achievement-card');
const unlocked = page.locator('#achievements-grid .achievement-card.unlocked');
await expect(unlocked).toHaveCount(1);
await expect(unlocked).toContainText('Time Flies');
expect(await cards.count()).toBeGreaterThan(1);
await expect(page.locator('#achievements-grid .achievement-card.locked')).not.toHaveCount(0);
});
test('unlocks survive a page reload (localStorage restore)', async ({ page }) => {
await page.goto('/');
await openTerminal(page);
await typeCommand(page, 'uptime');
await expect(page.locator('#achievements')).toBeVisible();
await page.reload();
await expect(page.locator('#achievements')).toBeVisible();
await expect(page.locator('#achievements-count')).toHaveText(/1 \/ \d+ achievements unlocked/);
await expect(page.locator('#nav-achievements a')).toHaveAttribute('href', '#achievements');
});
test('special achievements: sudo, nice-try rm, vim splash', async ({ page }) => {
await page.goto('/');
await openTerminal(page);
await typeCommand(page, 'sudo su -');
await expect(page.locator('.toast').filter({ hasText: 'Power User' })).toBeVisible();
await typeCommand(page, 'rm -rf /');
// root variant: the destruction easter egg wipes the page (and its
// toasts) ~500ms later — verify the unlock via localStorage instead
await page.reload();
await openTerminal(page);
await typeCommand(page, 'rm -rf /');
await expect(page.locator('.toast').filter({ hasText: 'Nice Try' })).toBeVisible();
await typeCommand(page, 'vim');
await expect(page.locator('.toast').filter({ hasText: 'Vi sIgnificantly worse M' })).toBeVisible();
await page.keyboard.press('q');
const stored = await page.evaluate(k => JSON.parse(localStorage.getItem(k) || '[]'), STORAGE_KEY);
expect(stored).toEqual(
expect.arrayContaining(['power_user', 'restore_backup', 'nice_try', 'vim_splash']));
});
test('multiple unlocks stack toasts and increment the counter', async ({ page }) => {
await page.goto('/');
await openTerminal(page);
await typeCommand(page, 'uptime');
await typeCommand(page, 'whoami');
await typeCommand(page, 'clear');
const stored = await page.evaluate(k => JSON.parse(localStorage.getItem(k) || '[]'), STORAGE_KEY);
expect(stored).toEqual(
expect.arrayContaining(['time_flies', 'self_aware', 'clean_slate']));
await expect(page.locator('#achievements-count')).toHaveText(/3 \/ \d+ achievements unlocked/);
});
});