Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mink Debug Extension Laravel Package

friends-of-behat/mink-debug-extension

Behat extension that logs Mink-related data after every failed step and can save screenshots with a supporting driver. Configure a log directory, optional screenshots, and clean starts; especially useful for debugging CI runs like Travis.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Behat extension, not a Laravel package — there is no service provider, facade, or config file under config/. It only does anything inside a Behat + Mink test suite. In a Laravel codebase that usually means a behat.yml at the project root with Behat\MinkExtension (Goutte/Chrome/Selenium) driving a locally booted app. If you're on PHPUnit/Pest or Dusk, this package adds nothing.

Minimal steps

  1. Install as a dev dependency (never in require):
    composer require --dev friends-of-behat/mink-debug-extension:^2.1
    
  2. Register it in the Behat profile and point it at a writable directory:
    default:
      extensions:
        FriendsOfBehat\MinkDebugExtension:
          directory: '%paths.base%/storage/logs/behat'
          screenshot: true
    
    If your Behat version doesn't resolve the short key, use the FQCN FriendsOfBehat\MinkDebugExtension\Extension.
  3. Make sure the directory exists/writable and is gitignored (storage/logs/behat/).
  4. Run a suite with a deliberately failing step and open the generated .html file in a browser.

Where to look first

  • The generated HTML file in directory — it embeds the current URL, driver name, page source (and a base64 screenshot when enabled).
  • behat.yml only. There is no other config surface: directory (required to enable the extension), screenshot (default false), clean_start (default true).
  • The README/UPGRADE.md if you're coming from Lakion\Behat\MinkDebugExtension — the namespace was renamed in v2.0 and logs moved from .log to .html.

First use case

You have a failing Behat scenario (Then I should see "Order confirmed") in CI. Without the extension you get a one-line assertion error. With it you get an artifact you can open locally: the exact HTML the driver saw, the URL it was on, and (with a screenshot-capable driver) a picture of the page. That's the whole value proposition — post-mortem evidence for Mink failures.

Implementation Patterns

Local vs CI profiles. Keep two profiles rather than toggling a single one, because there is no env-var interpolation for the screenshot/clean_start booleans:

default:
  extensions:
    FriendsOfBehat\MinkDebugExtension:
      directory: '%paths.base%/storage/logs/behat'
      screenshot: false
      clean_start: false   # keep history across runs while you're debugging

ci:
  extensions:
    FriendsOfBehat\MinkDebugExtension:
      directory: '%paths.base%/storage/logs/behat'
      screenshot: true
      clean_start: true    # fresh artifacts per pipeline

Run with vendor/bin/behat --profile=ci. In GitHub Actions/GitLab, upload storage/logs/behat/**/*.html (and screenshots if split out) with if: failure(), retention ~7 days.

Screenshot only where the driver supports it. screenshot: true is a no-op with Goutte/Zombie-style HTTP drivers — you still get the HTML log. Pair it with Selenium2/Chrome/docker-standalone when you actually need pixels, and set it false locally if you don't want the per-failure disk churn.

Combine with Laravel app bootstrapping. The most common Laravel setup boots the framework in-process and drives it with Goutte. To make the captured HTML useful, run Behat with APP_DEBUG=true and a dedicated .env.behat / APP_ENV=behat, so a 500 in your controller produces a Laravel exception page in the log instead of a bare "500 Internal Server Error". Cross-reference with storage/logs/laravel.log — the extension captures the browser-visible surface, not the server-side trace.

Workflow for triaging a failure.

  1. Run the single scenario: vendor/bin/behat features/checkout.feature:42 --profile=ci.
  2. Open the newest .html in storage/logs/behat/.
  3. Diff the captured page source against what your step expected — missing element, wrong redirect, CSRF token page, session/login screen.
  4. Reproduce the same step interactively with vendor/bin/behat --stop-on-failure -vvv if the DOM doesn't explain it.
  5. Delete the artifacts before committing; clean_start: false means they accumulate.

Filling the gaps with your own hooks. The extension has no pluggable "log extra data" API — for Laravel-specific context (route, auth user ID, DB transaction state, Log::getMessages()), add a @AfterStep/@AfterScenario hook in a context that writes a sibling text file into the same directory:

/** @AfterStep */
public function dumpAppState(AfterStepScope $scope): void
{
    if ($scope->getTestResult()->isPassed()) {
        return;
    }
    file_put_contents(
        sprintf('%s/step-%s.txt', $this->debugDir, uniqid()),
        sprintf("route: %s\nuser: %s\n", request()->path(), auth()->id() ?? 'guest')
    );
}

Keep it in the same directory so CI artifact globbing catches everything.

Complement, don't replace, assertions. Treat the log directory as disposable diagnostics. Don't add tests that parse these files, and don't gate a pipeline on their presence.

Gotchas and Tips

  • clean_start: true is destructive on the whole directory. Never point directory at storage/logs itself, public/, or anything holding real logs — on each Behat run the extension wipes it. Use a dedicated subdirectory.
  • directory must be writable and %paths.base% resolves to the location of behat.yml, not the CWD. Running behat -c tests/behat/behat.yml shifts the base; relative paths then silently point elsewhere.
  • Only failed steps produce files. Skipped steps, failures inside BeforeScenario/AfterScenario hooks, and bootstrap/fatal errors usually generate nothing — that's a frequent "the extension is broken" false alarm. Reproduce with -vvv instead.
  • The captured HTML is the page at failure time, not a network trace. Redirects are already followed; you see the final document. Combine with -vvv and app logs when the failure is a wrong-URL problem.
  • Old tutorials use the wrong namespace. Anything referencing Lakion\Behat\MinkDebugExtension, .log files, or the removed upload-textfiles / upload-screenshots / wait-for-port binaries is v1-era and will not work on v2.
  • Version/PHP compatibility. v2.1 targets PHP ≥ 7.4 and was released in 2022; on PHP 8.3+ verify it installs and behat --strict still registers the extension before committing to it. Budget for a fork if it stalls — the package is thinly maintained.
  • Extension not loaded? Behat fails silently-ish if the config key is misspelled (the profile just doesn't get the extension). Confirm registration with vendor/bin/behat --config-reference or -vvv output listing loaded extensions.
  • Large page sources make large files. The extension deliberately stopped dumping request data because Symfony driver dumps exploded file size (v1.0.3). If you're capturing huge pages, expect multi-MB artifacts and set CI retention accordingly.
  • Don't commit the directory. Add storage/logs/behat/ to .gitignore and to any Docker build context exclusions — stale artifacts otherwise leak into images and diffs.
  • Extension points are limited by design. There's no event dispatcher or custom formatter interface; anything beyond HTML + screenshot means writing your own Behat hooks or a separate small extension listening to AfterStepTested. Plan for that rather than hunting for a config flag that doesn't exist.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels