sylius-labs/suite-tags-extension
sylius-labs/suite-tags-extension is a Sylius plugin that adds tagging capabilities to your e-commerce stack. Use it to attach reusable tags to resources and streamline organization, filtering, and management within Sylius Suite-based applications.
Despite the "reusable tagging for Sylius resources" description floating around, this package is a Behat test-suite filter extension — there is no Laravel service provider, no Eloquent model, no migration. It plugs into behat.yml and lets you split one feature tree into independently-runnable suites (api, ui, admin) by tag. Start there.
Install as a dev dependency:
composer require --dev sylius-labs/suite-tags-extension
Wire it into behat.yml:
default:
suites:
api:
contexts: [App\Tests\Behat\ApiContext]
ui:
contexts: [App\Tests\Behat\UiContext]
extensions:
SyliusLabs\SuiteTagsExtension\Behat\SuiteTagsExtension:
suite_tags:
api: ['@api']
ui: ['@ui', '@javascript']
Tag features/scenarios, then run bin/behat --suite=api — untagged scenarios are filtered out.
Read the source first. Two stars, zero dependents, no real docs. Order:
src/Behat/SuiteTagsExtension.php — configure()/load() reveal the actual config keys. The YAML above is representative; confirm before debugging.Configuration.php in DependencyInjection/ — the canonical accepted keys.spec/ / tests/ — intended usage and tag-inheritance edge cases.First use case: a growing features/ tree where you want fast API-only acceptance tests on every PR and the browser suite nightly, without duplicating .feature files or maintaining two Behat configs.
Tag at the feature level, override at the scenario level. Behat inherits feature tags onto every scenario — tagging a whole .feature file @api is the cheapest routing. Only add scenario-level tags when one scenario legitimately belongs to two suites.
One CI job per suite — the pattern the extension exists for:
# .github/workflows/behat.yml
matrix:
suite: [api, ui]
steps:
- run: bin/behat --suite=${{ matrix.suite }} --format=progress
Keep the tag map small and semantic. api and ui cover most projects. Don't invent @slow, @flaky, @deprecated as suite tags — those are selection concerns for --tags, not suite routing. Mixing them makes the filter tree hard to reason about.
Be deliberate about @javascript. In Sylius-style setups @javascript drives Mink/Panther. Mapping it into ui: pulls any inheriting scenario into the UI job even from an API-oriented feature file — usually what you want, but be explicit in config or you'll chase phantom CI failures.
Register before other filter-contributing extensions. The extension contributes a Behat filter at bootstrap; later registrations stack on top. If filters misbehave, disable the other extension to isolate.
Local fast loop. Configure a small default suite (e.g. smoke: ['@smoke']) so bare bin/behat runs a representative slice; invoke --suite=api explicitly otherwise.
Fork when you outgrow it. It's a thin filter over Behat's tag system. If you need per-suite hook contexts or custom behaviour, copy SuiteTagsExtension.php into tests/Behat/, register it locally, and drop the unmaintained dev dependency — roughly a half-hour job.
Config key names are the main trap. With effectively no docs, open configure() and confirm whether the key is suite_tags, tags, or a nested suites: map. A wrong key under extensions: fails silently in Behat — there is no "config not published" warning like Laravel gives you.
--tags and suite filters AND together. A CLI --tags=@foo combined with the suite filter means a scenario needs both — the classic cause of "zero scenarios matched" in CI where the same command works locally. Drop one or verify both.
Tag inheritance is one-way. Feature tags propagate to scenarios; a scenario cannot un-tag itself. If one scenario in an @api feature truly needs the browser, move it to its own feature file.
Behat major-version compatibility. Written for Behat 3.x and dormant since. Pin the version and re-verify after any Behat upgrade — the Extension hook was stable in 3.x, but Suite/Filter internals have shifted. Treat an unverified Behat 4 upgrade as a blocker.
Debug with --dry-run. Run bin/behat --suit... with --dry-run to print the scenario set the filter actually selected before executing anything — the fastest way to confirm your tag map without waiting on Mink boot.
Don't adopt it for application-level tagging. If you read the package description and expected taggable Eloquent models, stop — this is a test-runner extension. For real tagging in a Laravel app, use a maintained polymorphic tag/taggable implementation and treat this only as a reference for suite filtering.
How can I help you explore Laravel packages today?