From orocommerce-skills
Use when debugging or troubleshooting Behat tests in Oro Commerce 6.1 — failing scenarios, intermittent/flaky runs (passes 4 of 5, fails 3 of 20), missing elements, AJAX races, waitForAjax limits with fetch/XHR, step definition discovery and grepping `-dl`/`-di` output, snippet generation, verbosity flags `-v`/`-vv`/`-vvv` and quieting passing-step noise, screenshots, ScreenshotTrait, breadth-first multi-gate dumps, scenario isolation, --stop-on-failure, step ordering or missing Background, fixture-vs-render-timing differentiation, consumer/queue state mid-scenario, leftover `And I wait for action` blocking CI and pre-commit detection, tmpfs PostgreSQL tuning, PgsqlIsolator, var/log forensics for hidden 500s, and Xdebug across split CLI + PHP-FPM (two listeners, XDEBUG_SESSION cookie, path mapping). Relevant whenever a Behat scenario fails, hangs, flakes, or needs investigation — even when phrased casually without "behat" but mentioning step definitions, feature files, Mink, Gherkin, or ScreenshotTrait.
How this skill is triggered — by the user, by Claude, or both
Slash command
/orocommerce-skills:oro-behat-debuggingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Start with the cheapest signal and escalate. Most failures resolve at steps 1-3.
Start with the cheapest signal and escalate. Most failures resolve at steps 1-3.
var/log/<env>.log — Behat surfaces "element not found" for what is often a 500 in the app. The real cause lives in the server log, not the Behat stack trace.-v / -vv / -vvv — verbose shows the matched step definition, very verbose adds hook execution, debug adds the full step matcher trace. Escalate one level at a time.And I take screenshot at the suspected failure point. Oro's ScreenshotTrait::takeScreenshot captures cursor position too, except when a browser alert is showing. Drop dump($variable) into Context classes to inspect runtime state.
@Then I dump X for :arg step in the Context that queries EVERY plausible culprit in one shot and throws the combined state as a RuntimeException. One 2–4 minute behat cycle then returns all the evidence at once. Serialised hypothesis-at-a-time runs compound cost and context-switching. Wrap each sub-query in try/catch so a missing table or wrong service name doesn't suppress the rest. Revert the diagnostic step before committing — it's scaffolding, not permanent test coverage. See the Comprehensive Visibility/State Dump pattern in references/breadth-first-diagnostics.md.--stop-on-failure — tight feedback loop when chasing a single failing scenario.references/ajax-flake.md. Adding And I wait is not a fix.This is the part the Oro docs gloss over and it is the highest-leverage technique in the skill.
The Behat runner and the application under test are two separate PHP processes, usually in two containers:
bin/behat itself. Runs Context classes, step definitions, element classes, fixtures. Breakpoints in PHP test code fire here.Xdebug on only one of them misses everything on the other. Debugging both requires two targets listening on two ports.
Minimal CLI attach:
XDEBUG_MODE=debug XDEBUG_SESSION=1 php bin/behat path/to/feature.feature
Debugging FPM requires setting the XDEBUG_SESSION cookie inside the Mink browser session so FPM activates its debugger — Mink's Selenium2 driver supports this directly:
$this->getSession()->setCookie('XDEBUG_SESSION', 'IDEKEY');
Put that in a @BeforeScenario hook or a dedicated debug step. Full setup (two listeners, path mapping, container networking, common silent failures) in references/xdebug-split.md.
Don't guess step wording. List what's actually available:
php bin/behat -dl -s OroUserBundle # names only
php bin/behat -di -s OroUserBundle # names + descriptions + examples
php bin/behat -dl -s OroUserBundle | grep "grid" # filter
Generate skeletons for undefined steps instead of writing them by hand:
php bin/behat path/to/your.feature --dry-run --append-snippets --snippets-type=regex
Tag filtering for focused runs:
php bin/behat --tags=@smoke
php bin/behat --tags="@smoke&&@checkout" # AND
php bin/behat --tags="@smoke,@checkout" # OR
php bin/behat --tags="~@wip" # NOT
Full reference: references/step-discovery.md.
And I wait for action
Prints "Press [RETURN] to continue..." and blocks until you hit return. Local only — in CI this hangs the job until it times out. Add a pre-commit check (grep for the phrase) if this bites repeatedly.
waitForAjax on non-jQuery requests. The helper only tracks jQuery-registered XHR. Native fetch() and raw XMLHttpRequest never enter its queue, so it returns immediately while the request is still in flight. Wait for an observable DOM state, not the AJAX queue.And I wait for action. CI blocks forever on the stdin read. Budget a pre-commit hook for it.var/log/<env>.log after a failure. A server-side exception in a controller surfaces as a frontend "element not found" — Behat can't see the 500, only the missing element that would have rendered on success.references/xdebug-split.md — Full two-process Xdebug setup, cookie propagation, path mapping, silent-failure checklistreferences/step-discovery.md — -dl/-di, snippet generation, tag filtering, verbosity progressionreferences/ajax-flake.md — Race conditions, detached element references, backend-vs-HTTP completion, spin predicate patternreferences/performance-tmpfs.md — PostgreSQL in tmpfs for faster test runs (advanced, not in official docs)references/v6.1.md — 6.1-stable debugging specificsreferences/v7.0.md — 7.x notes (placeholder)npx claudepluginhub netresearch/claude-code-marketplace --plugin orocommerceCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.