Skip to content

Add Behat support#194

Open
hhamon wants to merge 1 commit into
zenstruck:1.xfrom
hhamon:feat/add-behat-support
Open

Add Behat support#194
hhamon wants to merge 1 commit into
zenstruck:1.xfrom
hhamon:feat/add-behat-support

Conversation

@hhamon

@hhamon hhamon commented Jun 4, 2026

Copy link
Copy Markdown

Framework-agnostic core (src/Browser/)

  • BrowserOptions (readonly value object) — env-var-driven configuration
  • BrowserRegistry — replaces the static state previously held by LegacyExtension
  • KernelBooter interface + Test/PhpUnitKernelBooter (closure-fed, captures the trait's privileged scope)
  • BrowserFactory — builds KernelBrowser / PantherBrowser from a booter
  • Artifact/{ArtifactSink, ArtifactCollector, EchoArtifactSink, FailureType} — the lifecycle/artifact-capture logic extracted out of LegacyExtension

PHPUnit Decoupling

  • HasBrowser trait: now ~95 lines, delegates to BrowserFactory with closures granting protected-static access
  • LegacyExtension / BootstrappedExtension: thin adapters forwarding events to ArtifactCollector
  • BrowserExtension: unchanged externally — same phpunit.xml.dist snippet works

Behat Bridge

  • BrowserExtension — Behat ServiceContainer Extension wiring everything
  • Context/{BrowserAware, BrowserAwareTrait} — drop-in analog of HasBrowser
  • Initializer/BrowserContextInitializer — injects services via Behat's standard DI
  • EventListener/ArtifactListener — Suite + Scenario events drive ArtifactCollector
  • Output/BehatOutputArtifactSink — STDOUT-direct summary writer
  • Kernel/{KernelBooter implementations}StandaloneKernelBooter (env-var) and SymfonyExtensionKernelBooter (FoB), selected at compile time via class_exists; PantherClientFactory adapter to bypass Panther's protected statics

Composer Update

  • composer.json: behat/behat ^3.13|^4.0@dev added to require-dev; both behat and FoB extension listed in suggest
  • tests/Behat/{behat.dist.php, behat.yml.dist, Context/BrowserContext.php, features/browser.feature} — exercises the bridge end-to-end against the existing fixture kernel
  • README.md: new "Using with Behat" section with context + config examples

Known caveat documented in the plan: friends-of-behat/symfony-extension doesn't yet support Symfony 8, so I could only end-to-end verify the StandaloneKernelBooter path. The SymfonyExtensionKernelBooter is code-complete and PHPStan-clean, but will need either a downgraded composer profile or a FoB release that supports Symfony 8 to verify in CI. The class is wired conditionally so it doesn't break consumers without FoB installed.

Co-Authored with Claude Code

@hhamon hhamon force-pushed the feat/add-behat-support branch 17 times, most recently from 627010f to 1d91ba1 Compare June 5, 2026 13:28
- `BrowserOptions` (readonly value object) — env-var-driven configuration
- `BrowserRegistry` — replaces the static state previously held by `LegacyExtension`
- `KernelBooter` interface + `Test/PhpUnitKernelBooter` (closure-fed, captures the trait's privileged scope)
- `BrowserFactory` — builds `KernelBrowser` / `PantherBrowser` from a booter
- `Artifact/{ArtifactSink, ArtifactCollector, EchoArtifactSink, FailureType}` — the lifecycle/artifact-capture logic extracted out of `LegacyExtension`

- `HasBrowser` trait: now ~95 lines, delegates to `BrowserFactory` with closures granting protected-static access
- `LegacyExtension` / `BootstrappedExtension`: thin adapters forwarding events to `ArtifactCollector`
- `BrowserExtension`: unchanged externally — same `phpunit.xml.dist` snippet works

- `BrowserExtension` — Behat `ServiceContainer` Extension wiring everything
- `Context/{BrowserAware, BrowserAwareTrait}` — drop-in analog of `HasBrowser`
- `Initializer/BrowserContextInitializer` — injects services via Behat's standard DI
- `EventListener/ArtifactListener` — Suite + Scenario events drive `ArtifactCollector`
- `Output/BehatOutputArtifactSink` — STDOUT-direct summary writer
- `Kernel/{KernelBooter implementations}` — `StandaloneKernelBooter` (env-var) and `SymfonyExtensionKernelBooter` (FoB), selected at compile time via class_exists; PantherClientFactory adapter to bypass Panther's protected statics

- `composer.json`: `behat/behat ^3.13|^4.0@dev` added to `require-dev`; both behat and FoB extension listed in suggest
- `tests/Behat/{behat.dist.php, behat.yml.dist, Context/BrowserContext.php, features/browser.feature}` — exercises the bridge end-to-end against the existing fixture kernel
- `README.md`: new "Using with Behat" section with context + config examples

Known caveat documented in the plan: `friends-of-behat/symfony-extension` doesn't yet support Symfony 8, so I could only end-to-end verify the `StandaloneKernelBooter` path. The `SymfonyExtensionKernelBooter` is code-complete and PHPStan-clean, but will need either a downgraded composer profile or a FoB release that supports Symfony 8 to verify in CI. The class is wired conditionally so it doesn't break consumers without FoB installed.
@hhamon hhamon force-pushed the feat/add-behat-support branch from 1d91ba1 to a5617e9 Compare June 5, 2026 13:32
@hhamon hhamon changed the title WIP: (PoC) Add Behat support Add Behat support Jun 5, 2026
@hhamon

hhamon commented Jun 5, 2026

Copy link
Copy Markdown
Author

@kbond I've tested this branch on a personal private project and it works :)

Edit: I'ven't tested with Panther yet.

@kbond

kbond commented Jun 8, 2026

Copy link
Copy Markdown
Member

Awesome @hhamon, thanks for working on this. I've had a quick discussion with @nikophil about it. He uses Behat in his day-to-day so he'll have a look at this when he has some time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants