import { test, expect } from '@playwright/test'; test.describe('Mood and Habits Integration', () => { test('mood + habits update tile glow and glyphs', async ({ page }) => { // Navigate to the app await page.goto('/'); // Wait for the app to load await expect(page.getByRole('heading', { level: 1 })).toHaveText(/GlowTrack/i); // Look for today's tile or a specific day tile // Assuming there's a grid with clickable day tiles const todayTile = page.locator('[data-testid="day-tile"]').first(); await expect(todayTile).toBeVisible(); // Click on the tile to open the day editor await todayTile.click(); // Set the mood - assuming there's a mood selector with hue and intensity const moodHueSlider = page.locator('[data-testid="mood-hue-slider"]'); const moodIntensitySlider = page.locator('[data-testid="mood-intensity-slider"]'); if (await moodHueSlider.isVisible()) { // Set hue to around 120 (green) await moodHueSlider.fill('120'); // Set intensity to 0.7 await moodIntensitySlider.fill('0.7'); } else { // Alternative: look for mood buttons or other mood input methods const moodSelector = page.locator('[data-testid="mood-selector"]'); if (await moodSelector.isVisible()) { await moodSelector.selectOption('happy'); // or similar } } // Add positive habits const addPositiveHabitButton = page.locator('[data-testid="add-positive-habit"]'); if (await addPositiveHabitButton.isVisible()) { await addPositiveHabitButton.click(); // Select or enter a positive habit const habitInput = page.locator('[data-testid="habit-input"]'); if (await habitInput.isVisible()) { await habitInput.fill('Exercise'); await page.keyboard.press('Enter'); } // Add another positive habit await addPositiveHabitButton.click(); await habitInput.fill('Meditation'); await page.keyboard.press('Enter'); } else { // Alternative: look for pre-defined habit checkboxes or buttons const exerciseHabit = page.locator('[data-testid="habit-exercise"]'); const meditationHabit = page.locator('[data-testid="habit-meditation"]'); if (await exerciseHabit.isVisible()) { await exerciseHabit.click(); } if (await meditationHabit.isVisible()) { await meditationHabit.click(); } } // Add negative habits const addNegativeHabitButton = page.locator('[data-testid="add-negative-habit"]'); if (await addNegativeHabitButton.isVisible()) { await addNegativeHabitButton.click(); const habitInput = page.locator('[data-testid="habit-input"]'); if (await habitInput.isVisible()) { await habitInput.fill('Procrastination'); await page.keyboard.press('Enter'); } } else { // Alternative: look for pre-defined negative habit checkboxes const procrastinationHabit = page.locator('[data-testid="habit-procrastination"]'); if (await procrastinationHabit.isVisible()) { await procrastinationHabit.click(); } } // Save or close the day editor const saveButton = page.locator('[data-testid="save-day"]'); const closeButton = page.locator('[data-testid="close-editor"]'); if (await saveButton.isVisible()) { await saveButton.click(); } else if (await closeButton.isVisible()) { await closeButton.click(); } else { // Click outside the editor to close it await page.click('body'); } // Verify the tile updates // Check that the tile has the expected visual changes // 1. Check that the tile has a glow/luminance based on net score // Since we added 2 positive and 1 negative habit, net score should be +1 // This should result in a positive glow const updatedTile = page.locator('[data-testid="day-tile"]').first(); // Check for CSS properties or data attributes that indicate glow await expect(updatedTile).toHaveAttribute('data-net-score', '1'); // Or check for specific CSS classes or computed styles const tileElement = await updatedTile.elementHandle(); if (tileElement) { const styles = await page.evaluate((el) => { const computed = window.getComputedStyle(el); return { backgroundColor: computed.backgroundColor, boxShadow: computed.boxShadow, filter: computed.filter }; }, tileElement); // Verify that the tile has some glow effect (box-shadow, filter, or background) expect( styles.boxShadow !== 'none' || styles.filter !== 'none' || styles.backgroundColor !== 'rgba(0, 0, 0, 0)' ).toBeTruthy(); } // 2. Check that glyphs are displayed correctly // According to the spec: ticks for positive count, dots for negative count const positiveGlyphs = page.locator('[data-testid="positive-glyphs"]').first(); const negativeGlyphs = page.locator('[data-testid="negative-glyphs"]').first(); // Should have 2 positive glyphs (ticks) if (await positiveGlyphs.isVisible()) { const positiveCount = await positiveGlyphs.locator('[data-testid="tick"]').count(); expect(positiveCount).toBe(2); } // Should have 1 negative glyph (dot) if (await negativeGlyphs.isVisible()) { const negativeCount = await negativeGlyphs.locator('[data-testid="dot"]').count(); expect(negativeCount).toBe(1); } // 3. Check that the mood hue is reflected in the tile color // The base hue should be around 120 (green) as we set earlier if (tileElement) { const hueValue = await page.evaluate((el) => { return el.getAttribute('data-mood-hue'); }, tileElement); expect(parseInt(hueValue || '0')).toBeCloseTo(120, 10); } // 4. Verify accessibility - tile should be keyboard navigable and have proper ARIA labels await updatedTile.focus(); const ariaLabel = await updatedTile.getAttribute('aria-label'); expect(ariaLabel).toContain('mood'); expect(ariaLabel).toContain('habit'); // Verify that the tile can be navigated with keyboard await page.keyboard.press('Tab'); // Should move to next tile or next interactive element // Test completed - the tile should now have: // - Updated glow/luminance based on net score (+1) // - 2 tick glyphs for positive habits // - 1 dot glyph for negative habit // - Green-ish hue from mood setting // - Proper accessibility attributes }); test('multiple habit entries affect net score correctly', async ({ page }) => { await page.goto('/'); // Navigate to a day tile const dayTile = page.locator('[data-testid="day-tile"]').first(); await dayTile.click(); // Add multiple positive habits with different weights const addPositiveButton = page.locator('[data-testid="add-positive-habit"]'); // Add first positive habit (default weight 1) if (await addPositiveButton.isVisible()) { await addPositiveButton.click(); await page.locator('[data-testid="habit-input"]').fill('Exercise'); await page.keyboard.press('Enter'); // Add second positive habit await addPositiveButton.click(); await page.locator('[data-testid="habit-input"]').fill('Reading'); await page.keyboard.press('Enter'); // Add third positive habit await addPositiveButton.click(); await page.locator('[data-testid="habit-input"]').fill('Healthy Eating'); await page.keyboard.press('Enter'); } // Add negative habits const addNegativeButton = page.locator('[data-testid="add-negative-habit"]'); if (await addNegativeButton.isVisible()) { await addNegativeButton.click(); await page.locator('[data-testid="habit-input"]').fill('Social Media'); await page.keyboard.press('Enter'); await addNegativeButton.click(); await page.locator('[data-testid="habit-input"]').fill('Junk Food'); await page.keyboard.press('Enter'); } // Save changes const saveButton = page.locator('[data-testid="save-day"]'); if (await saveButton.isVisible()) { await saveButton.click(); } // Verify net score: 3 positive - 2 negative = +1 await expect(dayTile).toHaveAttribute('data-net-score', '1'); // Verify glyph counts const positiveGlyphs = page.locator('[data-testid="positive-glyphs"]').first(); const negativeGlyphs = page.locator('[data-testid="negative-glyphs"]').first(); if (await positiveGlyphs.isVisible()) { const positiveCount = await positiveGlyphs.locator('[data-testid="tick"]').count(); expect(positiveCount).toBe(3); } if (await negativeGlyphs.isVisible()) { const negativeCount = await negativeGlyphs.locator('[data-testid="dot"]').count(); expect(negativeCount).toBe(2); } }); test('removing habits updates tile correctly', async ({ page }) => { await page.goto('/'); const dayTile = page.locator('[data-testid="day-tile"]').first(); await dayTile.click(); // Add some habits first const addPositiveButton = page.locator('[data-testid="add-positive-habit"]'); if (await addPositiveButton.isVisible()) { await addPositiveButton.click(); await page.locator('[data-testid="habit-input"]').fill('Exercise'); await page.keyboard.press('Enter'); } const addNegativeButton = page.locator('[data-testid="add-negative-habit"]'); if (await addNegativeButton.isVisible()) { await addNegativeButton.click(); await page.locator('[data-testid="habit-input"]').fill('Procrastination'); await page.keyboard.press('Enter'); } // Remove the negative habit const removeButton = page.locator('[data-testid="remove-habit"]').first(); if (await removeButton.isVisible()) { await removeButton.click(); } // Save changes const saveButton = page.locator('[data-testid="save-day"]'); if (await saveButton.isVisible()) { await saveButton.click(); } // Verify net score is now just +1 (only positive habit remains) await expect(dayTile).toHaveAttribute('data-net-score', '1'); // Verify only positive glyphs remain const positiveGlyphs = page.locator('[data-testid="positive-glyphs"]').first(); const negativeGlyphs = page.locator('[data-testid="negative-glyphs"]').first(); if (await positiveGlyphs.isVisible()) { const positiveCount = await positiveGlyphs.locator('[data-testid="tick"]').count(); expect(positiveCount).toBe(1); } if (await negativeGlyphs.isVisible()) { const negativeCount = await negativeGlyphs.locator('[data-testid="dot"]').count(); expect(negativeCount).toBe(0); } }); });