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.
This commit is contained in:
2026-07-04 16:56:07 +02:00
parent 1710ad8612
commit 421c21345e
8 changed files with 226 additions and 90 deletions
+39 -15
View File
@@ -4,6 +4,7 @@
set -euo pipefail
FORM="user/pages/02.post/post-form.md"
SITE="user/config/site.yaml"
PASS=0
FAIL=0
ERRORS=()
@@ -12,8 +13,13 @@ ok() { echo " ✓ $1"; PASS=$((PASS+1)); }
fail() { echo "$1"; FAIL=$((FAIL+1)); ERRORS+=("$1"); }
check_grep() {
local desc="$1"; local pattern="$2"
if grep -q "$pattern" "$FORM"; then ok "$desc"; else fail "$desc"; fi
local desc="$1"; local pattern="$2"; local file="${3:-$FORM}"
if grep -q "$pattern" "$file"; then ok "$desc"; else fail "$desc"; fi
}
check_absent() {
local desc="$1"; local pattern="$2"; local file="${3:-$FORM}"
if grep -q "$pattern" "$file"; then fail "$desc"; else ok "$desc"; fi
}
echo ""
@@ -24,25 +30,43 @@ echo "────────────────────────
grep -q "add_page:\|addpage:" "$FORM" && ok "Process action is 'add_page' (plugin trigger)" \
|| fail "Process action must be 'add_page: true' — 'add-page-by-form' is not handled by the plugin"
# Config must be in frontmatter, not in the process block
check_grep "pageconfig block exists in frontmatter" "^pageconfig:"
check_grep "parent set to /trips/japan-korea-2026/dailies" "parent: '/trips/japan-korea-2026/dailies'"
check_grep "slug_field set (determines entry folder name)" "slug_field:"
check_grep "pagefrontmatter block exists in frontmatter" "^pagefrontmatter:"
check_grep "template: entry (creates entry.md filename)" "template: entry"
# Parent is now injected server-side from site.active_trip by the cache-on-save
# plugin (U1). The form must NOT hardcode pageconfig.parent — that coupling was
# the silent-misfile bug this whole change removes.
check_absent "pageconfig.parent is NOT hardcoded (injected server-side from active_trip)" "^\s*parent:"
check_grep "pageconfig block exists in frontmatter" "^pageconfig:"
check_grep "slug_field set (determines entry folder name)" "slug_field:"
check_grep "pagefrontmatter block exists in frontmatter" "^pagefrontmatter:"
check_grep "template: entry (creates entry.md filename)" "template: entry"
# The active trip — the server-side injection source — must be set in site.yaml.
check_grep "active_trip set in site.yaml (injection source)" "^active_trip:\s*\S" "$SITE"
# Form name must stay 'new-entry' — cache-on-save plugin checks this exact string
check_grep "form name is 'new-entry' (required by cache-on-save plugin)" "name: new-entry"
# Required form fields
check_grep "title field present" "name: title"
check_grep "date field present" "name: date"
check_grep "content field present" "name: content"
check_grep "lat field present" "name: lat"
check_grep "lng field present" "name: lng"
check_grep "location_city field present" "name: location_city"
# Core form fields
check_grep "title field present" "name: title"
check_grep "date field present" "name: date"
check_grep "content field present" "name: content"
check_grep "photos field present" "name: photos"
check_grep "lat field present" "name: lat"
check_grep "lng field present" "name: lng"
check_grep "location_city field present" "name: location_city"
check_grep "location_country field present" "name: location_country"
# Fields exposed by U2 (weather picker + transport + advanced trio)
check_grep "weather_desc field present" "name: weather_desc"
check_grep "weather_temp_c field present" "name: weather_temp_c"
check_grep "transport_mode field present" "name: transport_mode"
check_grep "hero_image field present" "name: hero_image"
check_grep "force_connect field present" "name: force_connect"
check_grep "featured field present" "name: featured"
# Photos must use the custom controlled picker (U4), not filepond/file — that is
# what lets post-form.js convert HEIC before upload.
check_grep "photos field uses the custom 'photos' type (HEIC pipeline)" "type: photos"
echo "────────────────────────────────────────"
echo " $PASS passed, $FAIL failed"
+5 -1
View File
@@ -7,7 +7,11 @@ set -euo pipefail
BASE_URL="${GRAV_BASE_URL:-http://localhost:8081}"
USER="${GRAV_TEST_USER:-}"
PASS="${GRAV_TEST_PASS:-}"
TRACKER="user/pages/01.trips/japan-korea-2026/01.dailies"
# Parent is injected server-side from site.active_trip (U1), so resolve the
# dailies dir from site.yaml rather than hardcoding a trip slug.
ACTIVE_TRIP=$(grep -E '^active_trip:' user/config/site.yaml | head -1 | sed -E "s/^active_trip:[[:space:]]*['\"]?//; s/['\"]?[[:space:]]*\$//")
TRIP_SLUG=$(basename "${ACTIVE_TRIP%/}")
TRACKER="user/pages/01.trips/${TRIP_SLUG:-italy-2026-demo}/01.dailies"
COOKIE_JAR="$(mktemp /tmp/grav-test-cookies.XXXXXX)"
PASS_COUNT=0
FAIL_COUNT=0