feat: Add Focus Tools (ADHD-friendly productivity features)
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
- Add Focus Tools dashboard with collapsible help section - Implement Quick Wins page for tasks under 15 minutes - Add Single Task Focus mode to reduce overwhelm - Create Body Doubling page for virtual co-working - Add visual timer, break reminders, and energy tracking - Implement hyperfocus protection alerts - Add ADHD settings panel with customizable options - Include full English and German translations - Fix larger touch targets CSS to not break button layouts - Add Playwright tests for Focus Tools features
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('ADHD Mode Features', () => {
|
||||
const username = 'adhd_test_' + Date.now();
|
||||
const email = username + '@example.com';
|
||||
const password = 'testpass123';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Listen for console logs and errors
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
console.log(`BROWSER ERROR: ${msg.text()}`);
|
||||
}
|
||||
});
|
||||
page.on('pageerror', exception => console.log(`PAGE ERROR: ${exception}`));
|
||||
});
|
||||
|
||||
test('ADHD Dashboard is accessible and displays features', async ({ page }) => {
|
||||
test.setTimeout(120000);
|
||||
|
||||
// Go to app
|
||||
await page.goto('http://localhost:2100');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Register if needed
|
||||
const registerBtn = page.getByRole('button', { name: 'Register' });
|
||||
if (await registerBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await registerBtn.click();
|
||||
await page.fill('input[name="username"]', username);
|
||||
await page.fill('input[name="email"]', email);
|
||||
await page.fill('input[name="password"]', password);
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
} else {
|
||||
// Try login
|
||||
await page.fill('input[name="username"]', 'admin');
|
||||
await page.fill('input[name="password"]', 'admin');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Navigate to ADHD Dashboard
|
||||
await page.goto('http://localhost:2100/adhd');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Check if ADHD Dashboard loaded (look for any ADHD-related content)
|
||||
const pageContent = await page.content();
|
||||
console.log('Page loaded, checking for ADHD content...');
|
||||
|
||||
// Should see ADHD-related content
|
||||
const hasADHDContent = pageContent.includes('ADHD') ||
|
||||
pageContent.includes('ADHS') ||
|
||||
pageContent.includes('Quick Win') ||
|
||||
pageContent.includes('Schnelle') ||
|
||||
pageContent.includes('Focus') ||
|
||||
pageContent.includes('Fokus');
|
||||
|
||||
expect(hasADHDContent).toBeTruthy();
|
||||
console.log('ADHD Dashboard test passed!');
|
||||
});
|
||||
|
||||
test('ADHD navigation item exists in sidebar', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto('http://localhost:2100');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Try to login first
|
||||
const loginInput = page.locator('input[name="username"]');
|
||||
if (await loginInput.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await page.fill('input[name="username"]', 'admin');
|
||||
await page.fill('input[name="password"]', 'admin');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Check for ADHD navigation item (Brain icon or ADHD text)
|
||||
const pageContent = await page.content();
|
||||
const hasADHDNav = pageContent.includes('/adhd') ||
|
||||
pageContent.includes('ADHD Mode') ||
|
||||
pageContent.includes('ADHS-Modus');
|
||||
|
||||
console.log('Checking for ADHD navigation...');
|
||||
expect(hasADHDNav).toBeTruthy();
|
||||
console.log('ADHD navigation test passed!');
|
||||
});
|
||||
|
||||
test('Quick Wins page loads and shows tasks', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto('http://localhost:2100');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Login
|
||||
const loginInput = page.locator('input[name="username"]');
|
||||
if (await loginInput.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await page.fill('input[name="username"]', 'admin');
|
||||
await page.fill('input[name="password"]', 'admin');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Navigate to Quick Wins page
|
||||
await page.goto('http://localhost:2100/adhd/quick-wins');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const pageContent = await page.content();
|
||||
const hasQuickWinsContent = pageContent.includes('Quick Win') ||
|
||||
pageContent.includes('Schnelle') ||
|
||||
pageContent.includes('dopamine') ||
|
||||
pageContent.includes('Dopamin');
|
||||
|
||||
console.log('Checking Quick Wins page...');
|
||||
expect(hasQuickWinsContent).toBeTruthy();
|
||||
console.log('Quick Wins page test passed!');
|
||||
});
|
||||
|
||||
test('Single Task Focus page loads', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto('http://localhost:2100');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Login
|
||||
const loginInput = page.locator('input[name="username"]');
|
||||
if (await loginInput.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await page.fill('input[name="username"]', 'admin');
|
||||
await page.fill('input[name="password"]', 'admin');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Navigate to Single Task page
|
||||
await page.goto('http://localhost:2100/adhd/single-task');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const pageContent = await page.content();
|
||||
const hasSingleTaskContent = pageContent.includes('Single Task') ||
|
||||
pageContent.includes('Einzelaufgabe') ||
|
||||
pageContent.includes('focus') ||
|
||||
pageContent.includes('Fokus') ||
|
||||
pageContent.includes('select') ||
|
||||
pageContent.includes('wählen');
|
||||
|
||||
console.log('Checking Single Task page...');
|
||||
expect(hasSingleTaskContent).toBeTruthy();
|
||||
console.log('Single Task page test passed!');
|
||||
});
|
||||
|
||||
test('Body Doubling page loads', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto('http://localhost:2100');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Login
|
||||
const loginInput = page.locator('input[name="username"]');
|
||||
if (await loginInput.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await page.fill('input[name="username"]', 'admin');
|
||||
await page.fill('input[name="password"]', 'admin');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Navigate to Body Doubling page
|
||||
await page.goto('http://localhost:2100/adhd/body-doubling');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const pageContent = await page.content();
|
||||
const hasBodyDoublingContent = pageContent.includes('Body Doubling') ||
|
||||
pageContent.includes('Virtuelles') ||
|
||||
pageContent.includes('session') ||
|
||||
pageContent.includes('Sitzung') ||
|
||||
pageContent.includes('together') ||
|
||||
pageContent.includes('gemeinsam');
|
||||
|
||||
console.log('Checking Body Doubling page...');
|
||||
expect(hasBodyDoublingContent).toBeTruthy();
|
||||
console.log('Body Doubling page test passed!');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user