Files
hyperframes/Dockerfile.test
T
Vance IngallsandClaude Sonnet 4.6 a0ee97210b fix(sdk,core): css tokenizer, override-set replay, setattribute safety, persist errors (#1350)
* fix(sdk,core): css tokenizer, override-set replay, setattribute safety, persist errors

* test(sdk,ci): smoke test + explicit sdk-tests CI gate

Smoke test covers the full public surface:
  openComposition → setStyle/setText/dispatch(moveElement) → serialize
  applyPatches + ORIGIN_APPLY_PATCHES tagging
  batch() coalescing + transactional rollback on throw
  undo/redo round-trip
  persist adapter write + persist:error surfacing
  T3 embedded mode: override-set apply on open + getOverrides round-trip

Adds sdk-tests CI job so SDK coverage is explicitly named and required —
prevents a repeat of the demo-next vitest-never-ran incident.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sdk): export adapter types, awaitable flush(), never-coalesce mode

- Export PersistAdapter, PreviewAdapter, PersistVersionEntry from package
  root — callers can now write typed fakes without reaching into internals
- Add flush(): Promise<void> to Composition interface + CompositionImpl —
  app-close handlers can await a clean drain of the persist queue
- coalesceMs <= 0 disables coalescing entirely in createHistory — enables
  deterministic test scenarios without per-entry timestamp manipulation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(sdk): p2 edge cases — setText no-text-node, override-remove non-existent, flush in smoke

- setText on element with no prior text node (firstTextIdx=-1 path)
- applyOverrideSet null removal on non-existent prop is a no-op (no throw)
- smoke persist test uses comp.flush() instead of setTimeout
- can() JSDoc clarifies Phase 3b false-return is intentional feature-detection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: trigger regression suite

* fix(ci): add packages/sdk/package.json to Dockerfile.test workspace copy

bun install --frozen-lockfile fails in the regression Docker build because
the lockfile references the sdk workspace member but its package.json was
not copied into the image before the install step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 14:07:49 -07:00

100 lines
3.7 KiB
Docker

# HyperFrames Producer - Regression Test Image
#
# Matches the production rendering environment (same Chromium, fonts, FFmpeg)
# but includes the full source + devDependencies for running the test harness.
#
# This ensures golden baselines match what production actually renders.
#
# Usage:
# docker build -f Dockerfile.test -t hyperframes-producer:test .
# docker run --rm -v ./packages/producer/tests:/app/packages/producer/tests hyperframes-producer:test
# docker run --rm -v ./packages/producer/tests:/app/packages/producer/tests hyperframes-producer:test --update
FROM node:22-bookworm-slim
# ── System dependencies (identical to production) ────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
unzip \
ffmpeg \
chromium \
libgbm1 \
libnss3 \
libatk-bridge2.0-0 \
libdrm2 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
libcups2 \
libasound2 \
libpangocairo-1.0-0 \
libxshmfence1 \
libgtk-3-0 \
# Font support — matches production
fonts-liberation \
fonts-noto-color-emoji \
fonts-noto-cjk \
fonts-noto-core \
fonts-noto-extra \
fonts-noto-ui-core \
fonts-freefont-ttf \
fonts-dejavu-core \
fontconfig \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean \
&& fc-cache -fv
# Use system Chromium (same as production)
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
ENV CONTAINER=true
# Install chrome-headless-shell for deterministic BeginFrame rendering.
# This lightweight Chrome binary supports HeadlessExperimental.beginFrame.
# Install to ~/.cache/puppeteer/ where resolveHeadlessShellPath() looks.
#
# Pinned to a specific build (NOT @stable) so the regression-test golden
# baselines in packages/producer/tests/*/output/output.mp4 stay reproducible.
# Each Chrome stable bump shifts pixel output enough to fail PSNR. Bump this
# version together with regenerating baselines via `docker:test:update`.
RUN npx --yes @puppeteer/browsers install chrome-headless-shell@148.0.7778.167 \
--path /root/.cache/puppeteer \
&& find /root/.cache/puppeteer/chrome-headless-shell -name "chrome-headless-shell" -type f \
&& echo "chrome-headless-shell installed"
WORKDIR /app
# Install bun
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:$PATH"
# Install dependencies (full, including devDependencies for tsx + test harness)
COPY package.json bun.lock ./
COPY packages/core/package.json packages/core/package.json
COPY packages/engine/package.json packages/engine/package.json
COPY packages/player/package.json packages/player/package.json
COPY packages/producer/package.json packages/producer/package.json
COPY packages/cli/package.json packages/cli/package.json
COPY packages/studio/package.json packages/studio/package.json
COPY packages/shader-transitions/package.json packages/shader-transitions/package.json
COPY packages/aws-lambda/package.json packages/aws-lambda/package.json
COPY packages/gcp-cloud-run/package.json packages/gcp-cloud-run/package.json
COPY packages/sdk/package.json packages/sdk/package.json
RUN bun install --frozen-lockfile
# Copy source
COPY packages/core/ packages/core/
COPY packages/engine/ packages/engine/
COPY packages/producer/ packages/producer/
# Build core runtime artifacts (needed by renderer)
RUN bun run --filter @hyperframes/core build:hyperframes-runtime:modular
# Generate embedded font data (deterministicFonts.ts imports this at runtime)
RUN cd packages/producer && bunx tsx scripts/generate-font-data.ts
WORKDIR /app/packages/producer
ENTRYPOINT ["bunx", "tsx", "src/regression-harness.ts", "--", "--sequential"]