Files
intotheeast-com/tests/ui/post/validation.spec.js
T
m038 421c21345e test(post-form): retarget suite to redesigned /post + add UX coverage (U7)
- test-form-config.sh: assert parent is NOT hardcoded (injected server-side),
  active_trip set in site.yaml, and the new fields incl. custom 'photos' type.
- helpers.js: resolve active trip from site.active_trip (parent coupling gone);
  fillEditor() drives EasyMDE via window.postFormEditor; waitForPhotoUpload()
  waits on the new picker.
- post.spec / validation.spec: content via the editor, filepond selectors ->
  the photo picker, P8 checks editor value, V3/V4 exercise the picker cap +
  fail-closed non-image.
- post-form-ux.spec.js (new): AE3 disclosure, AE1 HEIC->JPEG, AE4 corrupt-HEIC
  fail-closed, R18 weather gating, R20 draft restore.
- fixtures: real + corrupt .heic.
- test-post.sh: resolve dailies dir from active_trip.

Refs AE1-AE4, R18, R20, U7.
2026-07-04 16:56:07 +02:00

65 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @ts-check
// Tests: V1V4 — form validation and input constraints
const { test, expect } = require('@playwright/test');
const path = require('path');
const { fillEditor, waitForPhotoUpload } = require('../helpers');
const TEST_PHOTO = path.join(__dirname, '../../fixtures/test-photo.jpg');
const TEST_NONIMAGE = path.join(__dirname, '../../fixtures/test-nonimage.txt');
// ── V1: Missing title ─────────────────────────────────────────────────────────
test('V1: submit without title shows a validation error or stays on /post', async ({ page }) => {
await page.goto('/post');
// Leave title empty, fill only content
await fillEditor(page, 'Content without a title.');
await page.locator('.btn-post').evaluate(el => el.click());
// Grav either shows an error message OR re-renders the form (stays on /post).
// Either outcome is acceptable — what should NOT happen is a success message.
await page.waitForTimeout(2_000);
const bodyText = await page.locator('body').textContent();
expect(bodyText).not.toContain('Entry posted successfully');
});
// ── V2: Missing content ───────────────────────────────────────────────────────
test('V2: submit without content shows a validation error or stays on /post', async ({ page }) => {
await page.goto('/post');
await page.fill('input[name="data[title]"]', 'V2 title no content');
// Leave content (editor) empty
await page.locator('.btn-post').evaluate(el => el.click());
await page.waitForTimeout(2_000);
const bodyText = await page.locator('body').textContent();
expect(bodyText).not.toContain('Entry posted successfully');
});
// ── V3: Photo limit (max 4) ───────────────────────────────────────────────────
test('V3: photo picker caps attachments at 4', async ({ page }) => {
await page.goto('/post');
const input = page.locator('input.photo-picker__input');
// Attach 4 photos (same fixture — we only need four items).
await input.setInputFiles([TEST_PHOTO, TEST_PHOTO, TEST_PHOTO, TEST_PHOTO]);
await waitForPhotoUpload(page, 4);
// A 5th is rejected once the limit is reached — no new card, and a hint shows.
await input.setInputFiles([TEST_PHOTO]);
await page.waitForTimeout(500);
await expect(page.locator('.photo-card')).toHaveCount(4);
await expect(page.locator('.photo-picker__hint')).toContainText(/up to 4/i);
});
// ── V4: Non-image file rejected (fail-closed) ─────────────────────────────────
test('V4: a non-image upload fails closed and is not attached', async ({ page }) => {
await page.goto('/post');
// The picker accepts anything the OS dialog allows; the server's uploadFiles
// accept-check (image/*) rejects a .txt, so the card ends in the error state
// and never reaches "done" — the original is never posted.
await page.locator('input.photo-picker__input').setInputFiles(TEST_NONIMAGE);
await expect(page.locator('.photo-card.is-error')).toBeVisible({ timeout: 15_000 });
await expect(page.locator('.photo-card.is-done')).toHaveCount(0);
});