feat: interaction-capable browser probe — drive WordPress, not just observe it (#310)#311
Merged
Merged
Conversation
Upgrade wordpress.browser-actions from the partial navigate/click/fill/press action shape into the full ordered interaction-script contract from issue #310, turning Codebox into a portable WordPress E2E sandbox that can drive the UI and assert browser behavior, not just observe a render. - Declare the backend-agnostic step schema (kinds, validation, evaluate detection) in runtime-core; implement the executor in runtime-playground, keeping the layer boundary clean. - Step kinds: navigate, click, fill, type, press, drag, hover, select, waitFor, evaluate, expect, screenshot, capture — each a 1:1 map onto a stable locator action. Pass the script via steps-json (inline or @path); actions-json is kept as a normalized back-compat alias. - Gate the arbitrary-JS evaluate step behind a dedicated wordpress.browser-actions.evaluate policy capability, separate from the non-JS interaction steps, mirroring the wordpress.run-php posture. - Emit per-step results to files/browser/steps.jsonl (index, kind, selector, ok/fail, timing) and machine-readable expect/evaluate assertions into action-summary.json; support named screenshots; enforce per-step and total-script timeouts with a clean first-failure record. - Recipe-mountable: recipe policy auto-grants the evaluate capability when a browser-actions step opts into an evaluate step. - Document the contract in the README and CLI command catalog; add a step-schema validation unit smoke and extend the browser-actions artifact smoke to a multi-step click/expect/evaluate/screenshot script. Navigate-only behavior is unchanged. Closes #310
chubes4
added a commit
that referenced
this pull request
May 30, 2026
Reference example for the wordpress.browser-actions interaction probe (#311). Mounts a tiny vendor-neutral @wordpress/element demo plugin (no build step) and drives it under WordPress trunk / React 19: clicks a counter, asserts a threshold message, moves a slider, asserts the bound value. Proves the probe verifies a component WORKS under interaction, not just that it renders. A green run reports 6/6 assertions passed, 0 errors. The plugin-specific consumer (driving the data-machine-socials react-easy-crop modal) lives in that plugin's own repo, next to the code it guards, to keep this generic cookbook example vendor-neutral.
chubes4
added a commit
that referenced
this pull request
May 30, 2026
Reference example for the wordpress.browser-actions interaction probe (#311). Mounts a tiny vendor-neutral @wordpress/element demo plugin (no build step) and drives it under WordPress trunk / React 19: clicks a counter, asserts a threshold message, moves a slider, asserts the bound value. Proves the probe verifies a component WORKS under interaction, not just that it renders. A green run reports 6/6 assertions passed, 0 errors. The plugin-specific consumer (driving the data-machine-socials react-easy-crop modal) lives in that plugin's own repo, next to the code it guards, to keep this generic cookbook example vendor-neutral.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #310. Upgrades
wordpress.browser-actionsfrom the partial navigate/click/fill/press action shape into the full ordered interaction-script contract, so WP Codebox can drive a real WordPress UI and assert browser behavior — not just prove it renders. Every consumer (Homeboytrace, CI, agent stacks, wp-gym, mobile/desktop tools) inherits a portable E2E capability against a disposable WordPress Playground for free.Design decisions (the architectural fork)
Extend the existing sibling, don't add a third command. A
wordpress.browser-actionscommand already existed (commit93c3c12) withnavigate/click/fill/press/wait/capture, but it fell short of #310: no schema inruntime-core, noevaluate/drag/hover/select/expect/type, no machine-readable assertions, nosteps.jsonl, no per-step/total timeouts. Rather than add a third overlappingwordpress.browser-scenariocommand (premature proliferation), I upgradedbrowser-actionsin place to the full contract. This satisfies every acceptance criterion while keeping one interaction command.How steps are passed.
ExecutionSpec.argsis a flatstring[]ofkey=value, so a multi-step script can't live in flat args. It's passed as a structuredsteps-json=<inline-json | @path>payload — the same*-jsonconvention recipes already use (actions-json,env-json,workloads-json) resolved via the existing JSON-arg helpers. The legacyactions-jsonshape is still accepted and normalized to steps, so existing recipes keep working.Where the schema lives (layer purity). The backend-agnostic step contract — kinds,
validateBrowserInteractionScript(),browserInteractionScriptUsesEvaluate()— is declared inruntime-core. The Playwright executor lives inruntime-playground.runtime-coreknows nothing about Playwright.Evaluate policy gate. The arbitrary-JS
evaluatestep is gated separately behind a newwordpress.browser-actions.evaluatepolicy capability (mirroringwordpress.run-php'sassertRuntimeCommandAllowedposture). Non-JS interaction steps are allowed wheneverwordpress.browser-actionsis allowed; a consumer can permit UI driving while forbidding arbitrary page JS. Recipes auto-grant the capability when a step opts into anevaluatestep.Step kinds
navigate,click,fill,type,press,drag,hover,select,waitFor,evaluate,expect,screenshot,capture— each a 1:1 map onto a stable Playwright locator action (getByRoleviarole=selectors,dragTo,selectOption, locator state checks forexpect, etc.).Artifacts & determinism
files/browser/steps.jsonl(index, kind, selector, ok/fail,durationMs, any named screenshot).expect/evaluateassertions produce a machine-readableassertionsblock (total/passed/failed+ each result) inaction-summary.jsonand the review summary, so any consumer can gate on it.screenshotstep withname) writefiles/browser/screenshot-<name>.png.timeoutplus globalstep-timeoutand totaltimeoutbudgets; the run stops cleanly on the first failing step with aprobe-error-style record — no silent partial success.browser-stepskind), review.json, and artifact redaction all includesteps.jsonl.Example steps script
[ { "kind": "click", "selector": "role=button[name='Social']" }, { "kind": "waitFor", "selector": ".reactEasyCrop_Container" }, { "kind": "drag", "from": ".reactEasyCrop_CropArea", "to": { "x": 40, "y": 40 } }, { "kind": "fill", "selector": "#caption", "value": "smoke test" }, { "kind": "evaluate", "expression": "document.querySelector('.crop').isConnected", "assert": true }, { "kind": "expect", "selector": ".crop-confirm", "state": "visible" }, { "kind": "screenshot", "name": "after-crop" } ]Verification
npm run buildgreen across all three packages.browser-interaction-script-validation-smoke(unit-level, no browser) covers every kind, evaluate detection, and per-kind required-field validation.browser-actions-artifact-smokeruns a real multi-step script (fill → click → waitFor → expect → evaluate(assert) → named screenshot) against live Playground+Playwright and assertssteps.jsonl, theassertionsblock, manifest, and review.json. Passes.command-registry-smoke,discovery-command-smoke,recipe-dry-run-smoke,recipe-browser-smoke,browser-probe-artifact-smoke,runtime-action-adapter-smoke, andpackage-distribution-smokeall pass — navigate-only and legacyactions-jsonpaths unchanged.Notes
CHANGELOG.mdor version strings (homeboy owns those).wordpress.browser-actions.evaluateentry is a policy-only capability (recipe: false, not a runnable Playground handler); it documents the gate and is excluded from the recipe JSON schema.