elbformat/sulu-behat-bundle
Adds Behat contexts and helpers for easily setting up tests in Sulu applications, built on symfony-behat-bundle. Configure website or admin context per profile, tag features into suites, and use ready-made contexts for pages, snippets, media, dates, and more.
v2.0.0 is a hard fork in behaviour: the package now targets Sulu 3 only and rebuilds the Page, Article and Snippet contexts around Sulu's own content structure. If you are still on Sulu 2, stay on the 1.x line — do not attempt a partial upgrade.
composer require --dev elbformat/sulu-behat-context:^2.0
This pulls in elbformat/symfony-behat-bundle:^1.6, which is what now resolves step arguments from tables, YAML or JSON.behat.yml (Page, Article, Snippet). Only enable the ones your suite uses — the Article/Snippet contexts assume Sulu content structures that may not exist in every project.vendor/bin/behat --definitions (or --dry-run) first. This is the fastest way to see the reworked step signatures and confirm which of your existing steps no longer resolve._webspaceKey and locale, then a child page using _parentSlug. That single scenario exercises the three headline features (webspace, locale, parent resolution) and will surface most configuration problems immediately.Where to look first: the reworked Page Context for parent/webspace handling, and the symfony-behat-bundle changelog for the argument-loading syntax, since that is now the extension point for anything non-trivial.
Parent resolution via _parentSlug / _parentId. The old "as child of :parentId" step is gone. Express the relationship as a field on the page table instead:
Given there is a "default-page" page
| _webspaceKey | default |
| locale | en |
| url | /default-page |
And there is a "default-page" page
| _parentSlug | /default-page |
| url | /default-page/child |
Prefer _parentSlug in feature files — it reads as intent and survives fixture renumbering. Reserve _parentId for cases where you are deliberately asserting against a known seeded ID.
Always pin webspace and locale. With multi-webspace support, implicit defaults become a source of flaky, order-dependent tests. Set _webspaceKey and locale on the root page of each scenario and let children inherit visually via the parent link. Treat them as required fields in your team's convention, not optional extras.
Move large fixtures out of Gherkin tables. The new argument layer accepts YAML and JSON, which is the right home for anything beyond ~5 columns or reused across scenarios. Keep short, readable tables inline; externalise page trees, article taxonomies and snippet blocks. This also makes fixtures diffable and reviewable.
Compose scenarios from context responsibilities. Page Context for structure and hierarchy, Article Context for editorial content, Snippet Context for reusable blocks. Build a page skeleton first, then attach articles/snippets — this mirrors how Sulu actually stores content and keeps failures attributable to one context.
Integration tip: because arguments are now fetched through the shared bundle, any custom step you write should use the same argument-resolution mechanism rather than hand-rolling table parsing. That keeps custom steps consistent with the shipped ones and future-proof against further changes in the argument layer.
^1.x explicitly in composer.json if you cannot upgrade Sulu yet, otherwise a composer update will happily resolve you into a broken suite.as child of before upgrading and convert every occurrence — the new form requires both _parentSlug/_parentId and a full url, which is easy to get subtly wrong (a mismatched url produces a page in the wrong place rather than an error)._webspaceKey/locale on the parent rather than to the step itself.symfony-behat-bundle:^1.6 is the supported seam for doing so.How can I help you explore Laravel packages today?