Skip to content

Commit dd56491

Browse files
pRizzclaude
andcommitted
ci: add e2e tests to CI and update-opencode-commit workflows
Add Playwright e2e test job to ci.yml (runs after build, ubuntu-only) and e2e gate to update-opencode-commit.yml with failure reporting. Add `just e2e` recipe and document in CLAUDE.md/AGENTS.md. Update submodule pointer and Dockerfile pin to include fork e2e reorganization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 973f8b7 commit dd56491

7 files changed

Lines changed: 94 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,63 @@ jobs:
304304

305305
- name: Run CLI parity tests
306306
run: bun run --cwd packages/cli-node test
307+
308+
# E2E Tests - Playwright browser tests for the opencode web UI
309+
e2e:
310+
name: E2E Tests
311+
runs-on: ubuntu-latest
312+
needs: [build]
313+
steps:
314+
- uses: actions/checkout@v6
315+
316+
- name: Initialize opencode submodule
317+
run: |
318+
git -c url."https://github.com/".insteadOf=git@github.com: submodule update --init --recursive packages/opencode
319+
git submodule status --recursive
320+
321+
- name: Setup Node.js
322+
uses: actions/setup-node@v5
323+
with:
324+
node-version: '20'
325+
326+
- name: Setup Bun
327+
uses: ./.github/actions/setup-bun
328+
329+
- name: Configure git identity
330+
run: |
331+
git config --global user.email "bot@opencode.ai"
332+
git config --global user.name "opencode"
333+
334+
- name: Cache Playwright browsers
335+
uses: actions/cache@v4
336+
with:
337+
path: .cache/ms-playwright
338+
key: ${{ runner.os }}-playwright-${{ hashFiles('packages/opencode/packages/app/package.json') }}
339+
restore-keys: ${{ runner.os }}-playwright-
340+
341+
- name: Install Playwright browsers
342+
working-directory: packages/opencode/packages/app
343+
run: bunx playwright install --with-deps
344+
env:
345+
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
346+
347+
- name: Run e2e tests
348+
working-directory: packages/opencode/packages/app
349+
run: bun test:e2e:local -- --workers=2
350+
env:
351+
CI: "true"
352+
OPENCODE_DISABLE_MODELS_FETCH: "true"
353+
OPENCODE_MODELS_PATH: ${{ github.workspace }}/packages/opencode/test/tool/fixtures/models-api.json
354+
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
355+
timeout-minutes: 30
356+
357+
- name: Upload Playwright artifacts
358+
if: failure()
359+
uses: actions/upload-artifact@v4
360+
with:
361+
name: playwright-e2e-${{ github.run_attempt }}
362+
if-no-files-found: ignore
363+
retention-days: 7
364+
path: |
365+
packages/opencode/packages/app/e2e/test-results
366+
packages/opencode/packages/app/e2e/playwright-report

.github/workflows/update-opencode-commit.yml

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,25 @@ jobs:
8686
# Run the full CI check suite
8787
just ci-checks
8888
89+
- name: Install Playwright browsers
90+
if: steps.update.outputs.needs_update == 'true'
91+
working-directory: packages/opencode/packages/app
92+
run: bunx playwright install --with-deps
93+
env:
94+
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
95+
96+
- name: Run e2e tests
97+
id: e2e_checks
98+
if: steps.update.outputs.needs_update == 'true'
99+
working-directory: packages/opencode/packages/app
100+
run: bun test:e2e:local -- --workers=2
101+
env:
102+
CI: "true"
103+
OPENCODE_DISABLE_MODELS_FETCH: "true"
104+
OPENCODE_MODELS_PATH: ${{ github.workspace }}/packages/opencode/test/tool/fixtures/models-api.json
105+
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
106+
timeout-minutes: 30
107+
89108
- name: Verify OCI description label
90109
id: verify_oci
91110
run: python3 scripts/extract-oci-description.py packages/core/src/docker/Dockerfile
@@ -119,6 +138,7 @@ jobs:
119138
env:
120139
UPDATE_OUTCOME: ${{ steps.update.outcome }}
121140
CI_CHECKS_OUTCOME: ${{ steps.ci_checks.outcome }}
141+
E2E_CHECKS_OUTCOME: ${{ steps.e2e_checks.outcome }}
122142
VERIFY_OCI_OUTCOME: ${{ steps.verify_oci.outcome }}
123143
COMMIT_PUSH_OUTCOME: ${{ steps.commit_push.outcome }}
124144
SUBMODULE_BRANCH: ${{ steps.update.outputs.submodule_branch }}
@@ -167,7 +187,7 @@ jobs:
167187
fi
168188
169189
status_line="ℹ️ No update needed"
170-
if [[ "${UPDATE_OUTCOME:-}" == "failure" || "${CI_CHECKS_OUTCOME:-}" == "failure" || "${VERIFY_OCI_OUTCOME:-}" == "failure" || "${COMMIT_PUSH_OUTCOME:-}" == "failure" || "${UPDATE_OUTCOME:-}" == "cancelled" || "${CI_CHECKS_OUTCOME:-}" == "cancelled" || "${VERIFY_OCI_OUTCOME:-}" == "cancelled" || "${COMMIT_PUSH_OUTCOME:-}" == "cancelled" ]]; then
190+
if [[ "${UPDATE_OUTCOME:-}" == "failure" || "${CI_CHECKS_OUTCOME:-}" == "failure" || "${E2E_CHECKS_OUTCOME:-}" == "failure" || "${VERIFY_OCI_OUTCOME:-}" == "failure" || "${COMMIT_PUSH_OUTCOME:-}" == "failure" || "${UPDATE_OUTCOME:-}" == "cancelled" || "${CI_CHECKS_OUTCOME:-}" == "cancelled" || "${E2E_CHECKS_OUTCOME:-}" == "cancelled" || "${VERIFY_OCI_OUTCOME:-}" == "cancelled" || "${COMMIT_PUSH_OUTCOME:-}" == "cancelled" ]]; then
171191
status_line="❌ Failed"
172192
elif [[ "${PUSHED:-}" == "true" ]]; then
173193
status_line="✅ Updated and pushed"
@@ -207,12 +227,13 @@ jobs:
207227
echo "**Step outcomes:**"
208228
echo "- update: \`${UPDATE_OUTCOME:-n/a}\`"
209229
echo "- ci_checks: \`${CI_CHECKS_OUTCOME:-n/a}\`"
230+
echo "- e2e_checks: \`${E2E_CHECKS_OUTCOME:-n/a}\`"
210231
echo "- verify_oci: \`${VERIFY_OCI_OUTCOME:-n/a}\`"
211232
echo "- commit_push: \`${COMMIT_PUSH_OUTCOME:-n/a}\`"
212233
} >> "${GITHUB_STEP_SUMMARY}"
213234
214235
- name: Create issue on CI failure
215-
if: failure() && steps.ci_checks.outcome == 'failure'
236+
if: failure() && (steps.ci_checks.outcome == 'failure' || steps.e2e_checks.outcome == 'failure')
216237
env:
217238
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
218239
LATEST_COMMIT: ${{ steps.update.outputs.latest_commit }}
@@ -225,11 +246,11 @@ jobs:
225246
commit_url="${SUBMODULE_REPO_URL:-}/commit/${LATEST_COMMIT:-unknown}"
226247
branch="${SUBMODULE_BRANCH:-dev}"
227248
228-
body="## Automated submodule update failed CI checks
249+
body="## Automated submodule update failed CI/e2e checks
229250
230251
The [update-opencode-commit workflow](${run_url}) attempted to update the
231252
opencode submodule to [\`${commit_short}\`](${commit_url}) from the
232-
\`${branch}\` branch, but \`just ci-checks\` failed after auto-formatting.
253+
\`${branch}\` branch, but checks failed after auto-formatting.
233254
234255
### What to do
235256
@@ -238,6 +259,7 @@ jobs:
238259
- **TypeScript typecheck failure** in a fork-* package — fix in the opencode fork and push to \`dev\`
239260
- **Rust clippy/build failure** in opencode-broker — fix in the fork
240261
- **Formatting issue** that \`just fmt\` couldn't resolve — manual fix needed
262+
- **E2E test failure** — UI regression in the web app, check Playwright report
241263
3. After fixing, the next scheduled run (every 2 hours) will retry automatically
242264
243265
### Context

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This is a polyglot monorepo with Rust and TypeScript:
2828
```bash
2929
just build # Build all packages
3030
just test # Run all tests
31+
just e2e # Run e2e tests (Playwright, boots server in-process)
3132
just fmt # Format all code
3233
just lint # Lint all code
3334
just pre-commit # Format, lint, build, and test

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This is a polyglot monorepo with Rust and TypeScript:
2828
```bash
2929
just build # Build all packages
3030
just test # Run all tests
31+
just e2e # Run e2e tests (Playwright, boots server in-process)
3132
just fmt # Format all code
3233
just lint # Lint all code
3334
just pre-commit # Format, lint, build, and test

justfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ build-opencode-broker: opencode-submodule-check
144144
test-opencode-broker: opencode-submodule-check
145145
cargo test --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml
146146

147+
# Run e2e tests (boots server in-process, seeds data, runs Playwright)
148+
e2e: opencode-install-if-needed
149+
bun run --cwd packages/opencode/packages/app test:e2e:local
150+
147151
# Optional app unit test gate (not part of default pre-commit)
148152
test-opencode-ui: opencode-install-if-needed
149153
bun run --cwd packages/opencode/packages/app test:unit

packages/core/src/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ COPY --chown=opencoder:opencoder packages/opencode /tmp/opencode-local
525525
# Update it by running: ./scripts/update-opencode-commit.sh
526526
RUN set -eux; \
527527
OPENCODE_COMMIT_OVERRIDE="${OPENCODE_COMMIT:-}"; \
528-
OPENCODE_COMMIT="efb28d7303ba21426cc16bc3c89ad542072dd3e5"; \
528+
OPENCODE_COMMIT="dec7013fe98e9dc46fe509aad42df5988c567ac8"; \
529529
if [ -n "${OPENCODE_COMMIT_OVERRIDE}" ]; then OPENCODE_COMMIT="${OPENCODE_COMMIT_OVERRIDE}"; fi; \
530530
rm -rf /tmp/opencode-repo; \
531531
if [ "${OPENCODE_SOURCE}" = "local" ]; then \

0 commit comments

Comments
 (0)