Skip to content

feat(security): scope office-ui agent lists to the workspace (#95) (#… #166

feat(security): scope office-ui agent lists to the workspace (#95) (#…

feat(security): scope office-ui agent lists to the workspace (#95) (#… #166

Workflow file for this run

name: E2E Tests
on:
push:
branches: [main]
paths:
- 'apps/office-ui/**'
- 'services/**'
- 'infra/**'
- '.github/workflows/e2e.yml'
pull_request:
branches: [main]
paths:
- 'apps/office-ui/**'
- 'services/**'
- 'infra/**'
- '.github/workflows/e2e.yml'
jobs:
playwright:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
# Cache office-ui's node_modules between Playwright runs so the install
# step is sub-second on a cache hit instead of a minute-plus cold install.
# Same lockfile-deterministic theme as `npm ci` in ci.yml (#91 / #42).
cache: 'npm'
cache-dependency-path: apps/office-ui/package-lock.json
- name: Install dependencies
working-directory: apps/office-ui
run: npm ci
# Install both chromium AND webkit — the mobile project in
# playwright.config.ts emulates iPhone 14, which Playwright drives via
# webkit. Without webkit installed, every mobile test fails in 3-4ms
# with "Executable doesn't exist at .cache/ms-playwright/webkit-*". (#61)
- name: Install Playwright browsers
working-directory: apps/office-ui
run: npx playwright install --with-deps chromium webkit
# Production build avoids the per-route JIT compile that `next dev`
# pays on first hit (a cold /login compile takes ~13s under CI's
# I/O budget; the previous setup blew the 30s wait-on window and
# then the 30s test timeout on subsequent first-hit routes).
# `next build` runs ESLint with stricter defaults than the
# standalone `lint` job (incl. no-undef for browser globals);
# E2E doesn't care about that — `--no-lint` skips it. The dedicated
# lint-and-typecheck job in ci.yml still gates code quality.
- name: Build office-ui
working-directory: apps/office-ui
run: npx next build --no-lint
env:
NEXT_TELEMETRY_DISABLED: '1'
# `output: "standalone"` is required for the production Docker image, but
# `next start` is a no-op under that mode. Launch the standalone server
# directly. With experimental.outputFileTracingRoot set in next.config.mjs
# the tree is rooted at .next/standalone/apps/office-ui/. The bundle
# excludes .next/static and public/, so copy them alongside server.js.
# Use nohup + disown so the server survives this shell's exit, and tee
# logs to a file we can inspect on failure.
- name: Start production server
working-directory: apps/office-ui
run: |
cp -r .next/static .next/standalone/apps/office-ui/.next/static
if [ -d public ]; then cp -r public .next/standalone/apps/office-ui/public; fi
nohup node .next/standalone/apps/office-ui/server.js \
> /tmp/next-server.log 2>&1 &
disown
echo "server PID: $!"
env:
PORT: 3000
HOSTNAME: 0.0.0.0
# The server returns 307 on `/` (redirect to /login or /office), so a
# default wait-on HTTP probe (waits for 2xx) never resolves. A TCP probe
# is sufficient — we just need the listener up; Playwright will handle
# the actual page navigation and redirects.
- name: Wait for server
run: npx wait-on tcp:127.0.0.1:3000 --timeout 60000
working-directory: apps/office-ui
- name: Dump server log (on failure)
if: failure()
run: |
echo "--- /tmp/next-server.log ---"
cat /tmp/next-server.log || echo "(no log file)"
echo "--- listening sockets ---"
ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null || true
echo "--- node processes ---"
ps -ef | grep -E "(node|next)" | grep -v grep || true
- name: Run Playwright tests
working-directory: apps/office-ui
run: npx playwright test
env:
CI: true
BASE_URL: http://localhost:3000
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: apps/office-ui/playwright-report/
retention-days: 7
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-screenshots
path: apps/office-ui/test-results/
retention-days: 7