test: add S1–S6 Playwright tests for story mode (listing, shortcodes, back nav, cross-trip)
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
// @ts-check
|
||||||
|
// Tests: S1–S6 — story mode rendering and navigation
|
||||||
|
// Requires demo data: run `make demo-load` before this suite.
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
|
||||||
|
const STORIES_URL = '/trips/italy-2025/stories';
|
||||||
|
const STORY_GALLERY = '/trips/italy-2025/stories/val-dorcia-dawn'; // gallery-led: snap-gallery × 2, chapter-break, text-only pull-quote
|
||||||
|
const STORY_SCROLLY = '/trips/italy-2025/stories/long-climb-montalcino'; // scrolly-led: scrolly-section × 2, chapter-break, pull-quote with image
|
||||||
|
const JAPAN_STORY = '/trips/japan-korea-2026/stories/the-thousand-gates';
|
||||||
|
|
||||||
|
// ── S1: Stories listing shows cards ──────────────────────────────────────────
|
||||||
|
test('S1: stories listing renders at least 3 story cards', async ({ page }) => {
|
||||||
|
await page.goto(STORIES_URL);
|
||||||
|
const cards = page.locator('.story-card');
|
||||||
|
await expect(cards.first()).toBeVisible({ timeout: 5000 });
|
||||||
|
const count = await cards.count();
|
||||||
|
expect(count, 'At least 3 story cards').toBeGreaterThanOrEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── S2: Gallery-led story — hero image + snap-gallery + chapter-break + text-only pull-quote ──
|
||||||
|
test('S2: gallery-led story renders hero, snap-gallery, chapter-break, text-only pull-quote', async ({ page }) => {
|
||||||
|
await page.goto(STORY_GALLERY);
|
||||||
|
// Hero: real image rendered, no placeholder
|
||||||
|
await expect(page.locator('.story-hero__img')).toBeVisible({ timeout: 8000 });
|
||||||
|
await expect(page.locator('.story-hero__img-placeholder')).toHaveCount(0);
|
||||||
|
// Snap-gallery (there are two in this story)
|
||||||
|
const galleries = page.locator('.pgallery');
|
||||||
|
await expect(galleries.first()).toBeVisible();
|
||||||
|
expect(await galleries.count(), 'Two snap-galleries').toBe(2);
|
||||||
|
// Chapter-break
|
||||||
|
await expect(page.locator('.chapter-break')).toBeVisible();
|
||||||
|
// Text-only pull-quote (no background image variant)
|
||||||
|
await expect(page.locator('.pull-quote__inner--no-image')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── S3: Scrolly-led story — two scrolly-sections + pull-quote with image ─────
|
||||||
|
test('S3: scrolly-led story renders two scrolly-sections and pull-quote with background image', async ({ page }) => {
|
||||||
|
await page.goto(STORY_SCROLLY);
|
||||||
|
await expect(page.locator('.story-hero__img')).toBeVisible({ timeout: 8000 });
|
||||||
|
// Two scrolly-sections
|
||||||
|
const scrollySections = page.locator('.scrolly');
|
||||||
|
await expect(scrollySections.first()).toBeVisible();
|
||||||
|
expect(await scrollySections.count(), 'Two scrolly-sections').toBe(2);
|
||||||
|
// Pull-quote with background image
|
||||||
|
await expect(page.locator('.pull-quote__bg')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── S4: Scrolly story loads without JS errors (Scrollama CDN) ────────────────
|
||||||
|
test('S4: scrolly story page loads without JS errors', async ({ page }) => {
|
||||||
|
const errors = [];
|
||||||
|
page.on('pageerror', e => errors.push(e.message));
|
||||||
|
await page.goto(STORY_SCROLLY);
|
||||||
|
await expect(page.locator('.story-hero__img')).toBeVisible({ timeout: 8000 });
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
expect(errors, 'No JS errors on story page').toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── S5: Back button returns to stories listing ────────────────────────────────
|
||||||
|
test('S5: back button navigates back to stories listing', async ({ page }) => {
|
||||||
|
// Establish history: listing → story → back
|
||||||
|
await page.goto(STORIES_URL);
|
||||||
|
await page.locator('.story-card').first().click();
|
||||||
|
await expect(page.locator('.story-hero__img')).toBeVisible({ timeout: 8000 });
|
||||||
|
await page.locator('.story-escape').click();
|
||||||
|
// After history.back(), URL should be the stories listing
|
||||||
|
await expect(page).toHaveURL(/italy-2025\/stories$/);
|
||||||
|
await expect(page.locator('.story-card').first()).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── S6: Japan story — cross-trip hero image sanity check ─────────────────────
|
||||||
|
test('S6: Japan story renders hero image without placeholder', async ({ page }) => {
|
||||||
|
await page.goto(JAPAN_STORY);
|
||||||
|
await expect(page.locator('.story-hero__img')).toBeVisible({ timeout: 8000 });
|
||||||
|
await expect(page.locator('.story-hero__img-placeholder')).toHaveCount(0);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user