test: add F1–F7 Playwright tests for trip page filter bar and stats toggle

This commit is contained in:
2026-06-19 21:51:13 +02:00
parent 3c35176b90
commit 28dc6c1f6c
+83
View File
@@ -0,0 +1,83 @@
// @ts-check
// Tests: F1F7 — trip page filter bar and inline stats toggle
const { test, expect } = require('@playwright/test');
const TRIP_URL = '/trips/japan-korea-2026';
// ── F1: filter bar renders with three buttons ─────────────────────────────────
test('F1: trip page shows All/Journal/Stories filter buttons', async ({ page }) => {
await page.goto(TRIP_URL);
await expect(page.locator('.trip-filter-btn[data-filter="all"]')).toBeVisible();
await expect(page.locator('.trip-filter-btn[data-filter="journal"]')).toBeVisible();
await expect(page.locator('.trip-filter-btn[data-filter="story"]')).toBeVisible();
});
// ── F2: "All content" is active by default ────────────────────────────────────
test('F2: "All content" filter button is active on load', async ({ page }) => {
await page.goto(TRIP_URL);
const allBtn = page.locator('.trip-filter-btn[data-filter="all"]');
await expect(allBtn).toHaveClass(/is-active/);
await expect(page.locator('.trip-filter-btn[data-filter="journal"]')).not.toHaveClass(/is-active/);
await expect(page.locator('.trip-filter-btn[data-filter="story"]')).not.toHaveClass(/is-active/);
});
// ── F3: clicking Journal makes it active and deactivates All ─────────────────
test('F3: clicking Journal sets it as active filter', async ({ page }) => {
await page.goto(TRIP_URL);
await page.click('.trip-filter-btn[data-filter="journal"]');
await expect(page.locator('.trip-filter-btn[data-filter="journal"]')).toHaveClass(/is-active/);
await expect(page.locator('.trip-filter-btn[data-filter="all"]')).not.toHaveClass(/is-active/);
});
// ── F4: Journal filter hides story cards ─────────────────────────────────────
test('F4: Journal filter hides story cards', async ({ page }) => {
await page.goto(TRIP_URL);
await page.click('.trip-filter-btn[data-filter="journal"]');
const storyCards = page.locator('[data-type="story"]');
const count = await storyCards.count();
for (let i = 0; i < count; i++) {
await expect(storyCards.nth(i)).toBeHidden();
}
});
// ── F5: All content filter shows journal cards ────────────────────────────────
test('F5: All content filter makes journal cards visible', async ({ page }) => {
await page.goto(TRIP_URL);
await page.click('.trip-filter-btn[data-filter="journal"]');
await page.click('.trip-filter-btn[data-filter="all"]');
const journalCards = page.locator('[data-type="journal"]');
await expect(journalCards.first()).toBeVisible();
});
// ── F6: Stories filter shows empty state when no stories exist ────────────────
test('F6: Stories filter shows empty message when no stories exist', async ({ page }) => {
await page.goto(TRIP_URL);
const storyCount = await page.locator('[data-type="story"]').count();
if (storyCount === 0) {
await page.click('.trip-filter-btn[data-filter="story"]');
await expect(page.locator('#feed-filter-empty')).toBeVisible();
await expect(page.locator('#feed-filter-empty')).toContainText('No stories');
} else {
test.skip();
}
});
// ── F7: Stats button toggles inline stats block ───────────────────────────────
test('F7: Stats button expands and collapses inline stats block', async ({ page }) => {
await page.goto(TRIP_URL);
const statsBlock = page.locator('#trip-stats-block');
const statsBtn = page.locator('#trip-stats-toggle');
// hidden by default
await expect(statsBlock).toBeHidden();
// click to expand
await statsBtn.click();
await expect(statsBlock).toBeVisible();
await expect(statsBtn).toHaveClass(/is-active/);
// click to collapse
await statsBtn.click();
await expect(statsBlock).toBeHidden();
await expect(statsBtn).not.toHaveClass(/is-active/);
});