Skip to content

Commit d55df75

Browse files
committed
test: add live web platform smoke
1 parent 87a6ac7 commit d55df75

7 files changed

Lines changed: 554 additions & 44 deletions

File tree

.github/workflows/ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,44 @@ jobs:
177177

178178
- name: Check Provider-backed integration architecture progress
179179
run: pnpm test:integration:progress:check
180+
181+
web-smoke:
182+
name: Web Platform Smoke
183+
runs-on: ubuntu-latest
184+
timeout-minutes: 30
185+
env:
186+
AGENT_DEVICE_WEB_E2E: "1"
187+
steps:
188+
- name: Checkout
189+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
190+
191+
- name: Setup toolchain
192+
uses: ./.github/actions/setup-node-pnpm
193+
with:
194+
node-version: "24"
195+
196+
- name: Install agent-browser runtime
197+
run: |
198+
export PNPM_HOME="$RUNNER_TEMP/pnpm-global"
199+
mkdir -p "$PNPM_HOME"
200+
export PATH="$PNPM_HOME:$PATH"
201+
echo "PNPM_HOME=$PNPM_HOME" >> "$GITHUB_ENV"
202+
echo "$PNPM_HOME" >> "$GITHUB_PATH"
203+
pnpm config set global-bin-dir "$PNPM_HOME"
204+
pnpm add --global agent-browser@0.27.1
205+
agent-browser install --with-deps
206+
agent-browser doctor --offline --quick
207+
208+
- name: Run live web smoke
209+
run: |
210+
pnpm clean:daemon
211+
pnpm test:smoke:web
212+
213+
- name: Upload web smoke artifacts
214+
if: always()
215+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
216+
with:
217+
name: web-smoke-artifacts
218+
if-no-files-found: ignore
219+
path: |
220+
test/artifacts/web/**

docs/agents/domain.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ Before architecture, diagnosis, TDD, triage, PRD, or roadmap work, read:
77
- `CONTEXT.md` for domain vocabulary, test strategy terms, and architecture language.
88
- Relevant ADRs in `docs/adr/` for accepted architecture decisions.
99
- This `docs/agents/` directory for issue-tracker and triage-label conventions.
10+
- `docs/agents/testing.md` for maintainer-only test lane notes such as the live web smoke.
1011

1112
Use the vocabulary from `CONTEXT.md` in issue titles, refactor proposals, test names, and architecture notes. If a proposed change contradicts an ADR, call that out explicitly and explain why the decision should be reopened.

docs/agents/testing.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Testing Notes
2+
3+
## Live web smoke
4+
5+
The live web platform smoke runs the public built CLI against a local fixture page through the `agent-browser` adapter:
6+
7+
```bash
8+
agent-browser install --with-deps
9+
agent-browser doctor --offline --quick
10+
AGENT_DEVICE_WEB_E2E=1 pnpm test:smoke:web
11+
```
12+
13+
The test is skipped unless `AGENT_DEVICE_WEB_E2E=1` is set. CI installs `agent-browser@0.27.1` in the dedicated web smoke job and runs the lane on Node 24 because that adapter version requires Node >= 24. Failure artifacts, daemon state, and browser config are written under `test/artifacts/web/`.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
"test:integration:provider": "vitest run --project provider-integration",
135135
"test:integration:progress": "node --experimental-strip-types scripts/integration-progress.ts",
136136
"test:integration:progress:check": "node --experimental-strip-types scripts/integration-progress.ts --check",
137+
"test:smoke:web": "pnpm build && node --test test/integration/smoke-web-platform.test.ts",
137138
"test:skillgym": "node test/skillgym/runner-environment.ts && pnpm build && skillgym run ./test/skillgym/suites/agent-device-smoke-suite.ts --config ./test/skillgym/skillgym.config.ts",
138139
"test:skillgym:case": "node test/skillgym/runner-environment.ts && pnpm build && skillgym run ./test/skillgym/suites/agent-device-smoke-suite.ts --config ./test/skillgym/skillgym.config.ts --case",
139140
"test:smoke": "node --test test/integration/smoke-*.test.ts",

test/integration/cli-json.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { runCmd, runCmdSync, type ExecResult } from '../../src/utils/exec.ts';
2+
3+
const CLI_TIMEOUT_MS = 120_000;
4+
5+
export type CliJsonResult = {
6+
status: number;
7+
json?: any;
8+
stdout: string;
9+
stderr: string;
10+
};
11+
12+
export function runSourceCliJsonSync(
13+
args: string[],
14+
options?: { env?: NodeJS.ProcessEnv },
15+
): CliJsonResult {
16+
const result = runCmdSync(
17+
process.execPath,
18+
['--experimental-strip-types', 'src/bin.ts', ...args],
19+
{
20+
allowFailure: true,
21+
env: options?.env,
22+
timeoutMs: CLI_TIMEOUT_MS,
23+
},
24+
);
25+
return cliJsonResult(result);
26+
}
27+
28+
export async function runBuiltCliJson(
29+
args: string[],
30+
env: NodeJS.ProcessEnv,
31+
): Promise<CliJsonResult> {
32+
const result = await runCmd(process.execPath, ['bin/agent-device.mjs', ...args], {
33+
allowFailure: true,
34+
env,
35+
timeoutMs: CLI_TIMEOUT_MS,
36+
});
37+
return cliJsonResult(result);
38+
}
39+
40+
export function formatResultDebug(step: string, args: string[], result: CliJsonResult): string {
41+
const jsonText =
42+
result.json === undefined ? '(unparseable)' : JSON.stringify(result.json, null, 2);
43+
return [
44+
`step: ${step}`,
45+
`command: agent-device ${args.join(' ')}`,
46+
`status: ${result.status}`,
47+
`stderr:`,
48+
result.stderr || '(empty)',
49+
`stdout:`,
50+
result.stdout || '(empty)',
51+
`json:`,
52+
jsonText,
53+
].join('\n');
54+
}
55+
56+
function cliJsonResult(result: ExecResult): CliJsonResult {
57+
let json: any;
58+
try {
59+
json = JSON.parse(result.stdout ?? '');
60+
} catch {
61+
json = undefined;
62+
}
63+
return {
64+
status: result.exitCode,
65+
json,
66+
stdout: json ? '<JSON output>' : (result.stdout ?? ''),
67+
stderr: result.stderr ?? '',
68+
};
69+
}

0 commit comments

Comments
 (0)