287 lines
11 KiB
TypeScript
287 lines
11 KiB
TypeScript
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);
|
|
}
|
|
});
|
|
});
|