mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
Replace the fake resized-desktop mobile specs with real Playwright device projects (Pixel 7, iPhone 14, iPad gen 7, Galaxy Tab S9) that exercise real touch, mobile UA, DPR, and WebKit engine. Device projects in playwright.config.ts: - mobile-chromium (Pixel 7, 412x839, Chromium) - mobile-webkit (iPhone 14, 390x664, WebKit) - tablet-webkit (iPad gen 7, 810x1080, WebKit) - tablet-chromium (Galaxy Tab S9, 640x1024, Chromium) Device specs (16 mobile, 10 tablet): - Core flow: navigate to tool, upload, process, download - Responsive chrome: bottom-nav, sidebar hidden, search, overflow - Touch interactions: before-after slider, crop canvas - Editor gate: phone asserts "Desktop Recommended" message - Editor tablet: iPad (810px) renders canvas, Galaxy Tab (640px) shows gate - SSE visibility-recovery regression guard - RTL Arabic locale responsive check Key finding: Galaxy Tab S9 viewport (640px) is below the 768px mobile breakpoint, so useMobile() returns true and the editor shows the mobile gate. Only iPad gen 7 (810px) is classified as non-mobile. Component tests (17 tests, Vitest/jsdom): - use-mobile hook: breakpoint behavior across all 4 device widths - mobile-bottom-nav: render, navigation links, settings callback, icons CI wiring: - ci.yml: mobile-chromium smoke job (PR gate) - nightly.yml: full device matrix with webkit - update-visual-baselines.yml: webkit + device projects for goldens Parity: 13218 passed, 0 dropped (PARITY OK)
356 lines
13 KiB
YAML
356 lines
13 KiB
YAML
name: Nightly
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
schedule:
|
|
- cron: "0 3 * * *"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
SYSTEM_DEPS: libheif-examples libheif-plugin-x265 libheif-plugin-libde265 libimage-exiftool-perl imagemagick ghostscript libjxl-tools libopenjp2-tools ffmpeg qpdf
|
|
|
|
jobs:
|
|
e2e-full:
|
|
name: E2E Full (${{ matrix.shard }}/4)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
services:
|
|
postgres:
|
|
image: postgres:17-alpine
|
|
env:
|
|
POSTGRES_USER: snapotter
|
|
POSTGRES_PASSWORD: snapotter
|
|
POSTGRES_DB: snapotter
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U snapotter"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
shard: [1, 2, 3, 4]
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- uses: ./.github/actions/setup
|
|
- name: Get Playwright version
|
|
id: pw-version
|
|
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT"
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ runner.os }}-${{ steps.pw-version.outputs.version }}
|
|
- name: Install Playwright Chromium
|
|
run: pnpm playwright install --with-deps chromium
|
|
- name: Run full e2e suite (shard)
|
|
run: pnpm playwright test --project=chromium --shard=${{ matrix.shard }}/4
|
|
env:
|
|
PW_WORKERS: "2"
|
|
- name: Upload report on failure
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: failure()
|
|
with:
|
|
name: e2e-full-report-shard-${{ matrix.shard }}
|
|
path: playwright-report/
|
|
retention-days: 7
|
|
|
|
e2e-serial:
|
|
name: E2E Serial Bucket
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
services:
|
|
postgres:
|
|
image: postgres:17-alpine
|
|
env:
|
|
POSTGRES_USER: snapotter
|
|
POSTGRES_PASSWORD: snapotter
|
|
POSTGRES_DB: snapotter
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U snapotter"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- uses: ./.github/actions/setup
|
|
- name: Get Playwright version
|
|
id: pw-version
|
|
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT"
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ runner.os }}-${{ steps.pw-version.outputs.version }}
|
|
- name: Install Playwright Chromium
|
|
run: pnpm playwright install --with-deps chromium
|
|
- name: Run serial bucket (global-state specs)
|
|
run: pnpm playwright test --project=chromium-serial --workers=1
|
|
- name: Upload report on failure
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: failure()
|
|
with:
|
|
name: e2e-serial-report
|
|
path: playwright-report/
|
|
retention-days: 7
|
|
|
|
e2e-cross-browser:
|
|
name: E2E Cross-Browser (Firefox + WebKit)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
services:
|
|
postgres:
|
|
image: postgres:17-alpine
|
|
env:
|
|
POSTGRES_USER: snapotter
|
|
POSTGRES_PASSWORD: snapotter
|
|
POSTGRES_DB: snapotter
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U snapotter"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- uses: ./.github/actions/setup
|
|
- name: Get Playwright version
|
|
id: pw-version
|
|
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT"
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-all-${{ runner.os }}-${{ steps.pw-version.outputs.version }}
|
|
- name: Install Playwright browsers
|
|
run: pnpm playwright install --with-deps chromium firefox webkit
|
|
- name: Run cross-browser spec
|
|
run: pnpm playwright test --project=firefox --project=webkit
|
|
env:
|
|
PW_WORKERS: "1"
|
|
- name: Upload report on failure
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: failure()
|
|
with:
|
|
name: e2e-cross-browser-report
|
|
path: playwright-report/
|
|
retention-days: 7
|
|
|
|
e2e-device-matrix:
|
|
name: E2E Device Matrix (mobile + tablet)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
services:
|
|
postgres:
|
|
image: postgres:17-alpine
|
|
env:
|
|
POSTGRES_USER: snapotter
|
|
POSTGRES_PASSWORD: snapotter
|
|
POSTGRES_DB: snapotter
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U snapotter"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- uses: ./.github/actions/setup
|
|
- name: Get Playwright version
|
|
id: pw-version
|
|
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT"
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-all-${{ runner.os }}-${{ steps.pw-version.outputs.version }}
|
|
- name: Install Playwright browsers (chromium + webkit)
|
|
run: pnpm playwright install --with-deps chromium webkit
|
|
- name: Run all device projects
|
|
run: pnpm playwright test --project=mobile-chromium --project=mobile-webkit --project=tablet-webkit --project=tablet-chromium
|
|
env:
|
|
PW_WORKERS: "2"
|
|
- name: Upload report on failure
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: failure()
|
|
with:
|
|
name: e2e-device-matrix-report
|
|
path: playwright-report/
|
|
retention-days: 7
|
|
|
|
docker-e2e:
|
|
name: Docker Container E2E
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Run container test suite
|
|
run: docker compose -f docker/docker-compose.test.yml up --build --exit-code-from test-e2e
|
|
|
|
extended-matrix:
|
|
name: Extended Matrix + Fuzz
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- name: Allow ImageMagick to read EPS/PS via Ghostscript delegate
|
|
run: |
|
|
POLICY_FILE=$(find /etc/ImageMagick* -name policy.xml 2>/dev/null | head -1)
|
|
if [ -n "$POLICY_FILE" ]; then
|
|
sudo sed -i 's/<policy domain="coder" rights="none" pattern="EPS"/<policy domain="coder" rights="read" pattern="EPS"/' "$POLICY_FILE"
|
|
sudo sed -i 's/<policy domain="coder" rights="none" pattern="PS"/<policy domain="coder" rights="read" pattern="PS"/' "$POLICY_FILE"
|
|
fi
|
|
- uses: ./.github/actions/setup
|
|
- name: Run integration suite with full matrix and fuzz enabled
|
|
run: pnpm vitest run tests/integration/ --reporter=verbose
|
|
env:
|
|
FULL_MATRIX: "1"
|
|
FUZZ: "1"
|
|
FUZZ_RUNS: "50"
|
|
|
|
api-fuzz:
|
|
name: Schemathesis API Fuzz
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
services:
|
|
postgres:
|
|
image: postgres:17-alpine
|
|
env:
|
|
POSTGRES_USER: snapotter
|
|
POSTGRES_PASSWORD: snapotter
|
|
POSTGRES_DB: snapotter
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U snapotter"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
redis:
|
|
image: redis:8-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 10
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- uses: ./.github/actions/setup
|
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
with:
|
|
python-version: "3.12"
|
|
- name: Install Schemathesis
|
|
run: pip install schemathesis
|
|
- name: Start API server
|
|
run: |
|
|
mkdir -p /tmp/st-data
|
|
AUTH_ENABLED=false ANALYTICS_ENABLED=false \
|
|
DATABASE_URL=postgres://snapotter:snapotter@localhost:5432/snapotter \
|
|
REDIS_URL=redis://localhost:6379 \
|
|
WORKSPACE_PATH=/tmp/st-data/workspace DATA_DIR=/tmp/st-data \
|
|
pnpm --filter @snapotter/api dev &
|
|
for i in $(seq 1 60); do
|
|
if curl -fsS http://localhost:13490/api/v1/health > /dev/null 2>&1; then
|
|
echo "API up after ${i}s"; exit 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo "API failed to start"; exit 1
|
|
- name: Fuzz tool endpoints from the OpenAPI spec
|
|
run: |
|
|
schemathesis run http://localhost:13490/api/v1/openapi.yaml \
|
|
--url http://localhost:13490 \
|
|
--checks not_a_server_error \
|
|
--include-path-regex "^/api/v1/(tools|health|info)" \
|
|
--max-examples 25 \
|
|
--report junit \
|
|
--report-dir st-report
|
|
- name: Upload fuzz report
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: always()
|
|
with:
|
|
name: schemathesis-report
|
|
path: st-report/
|
|
retention-days: 14
|
|
|
|
coverage-report:
|
|
name: Coverage Report
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
- name: Install system dependencies
|
|
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends $SYSTEM_DEPS
|
|
- name: Allow ImageMagick to read EPS/PS via Ghostscript delegate
|
|
run: |
|
|
POLICY_FILE=$(find /etc/ImageMagick* -name policy.xml 2>/dev/null | head -1)
|
|
if [ -n "$POLICY_FILE" ]; then
|
|
sudo sed -i 's/<policy domain="coder" rights="none" pattern="EPS"/<policy domain="coder" rights="read" pattern="EPS"/' "$POLICY_FILE"
|
|
sudo sed -i 's/<policy domain="coder" rights="none" pattern="PS"/<policy domain="coder" rights="read" pattern="PS"/' "$POLICY_FILE"
|
|
fi
|
|
- uses: ./.github/actions/setup
|
|
- name: Run tests with coverage
|
|
run: pnpm vitest run --coverage tests/unit/ tests/integration/
|
|
- name: Upload coverage artifact
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: coverage-report
|
|
path: coverage/
|
|
retention-days: 14
|