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

Dusk Dashboard Laravel Package

beyondcode/dusk-dashboard

Dusk Dashboard gives Laravel Dusk browser tests a web dashboard. Review test runs and pass/fail results, inspect screenshots and console output, and monitor your end-to-end suite from one place to debug failures faster.

View on GitHub
Deep Wiki
Context7

Getting Started

Install (dev only). The package belongs in require-dev and nothing else:

composer require --dev beyondcode/dusk-dashboard:^2.0

The service provider is auto-discovered, so there is no manual registration step. Publish the config and route assets next:

php artisan vendor:publish --tag=dusk-dashboard

Confirm the actual tag and provider namespace by reading the package's own src/DuskDashboardServiceProvider.php — the docs are thin, the source is ~a few hundred lines, and this is an archived package where you should not assume any tag exists until you see it.

Look here first, in this order:

  1. config/dusk-dashboard.php (after publishing) — the route path and any enable/disable flag live here.
  2. The service provider's boot() / register() — this is where route registration happens; verify whether it is environment-gated by default or whether you must gate it.
  3. routes/ inside the package — the dashboard route and, importantly, whatever endpoint re-runs a single failed test.

Gate it before you ever start the server. This is the first thing you do, not the last. Wrap the route in a check:

// In a service provider, or by wrapping the config-driven route
if (! app()->environment(['local', 'testing'])) {
    // prevent registration / abort
}

or expose it only behind auth and a non-production middleware group. Screenshots routinely capture seeded users, tokens in query strings, and PII; the route can also trigger test runs. An unauthenticated window into that in production is an incident, not a feature.

First use case — triage one red test. Start your app (php artisan serve) and your Dusk suite in a separate terminal:

php artisan dusk --filter=CheckoutFlowTest

Open the dashboard route (default path is typically /dusk-dashboard; check the config) while the run is in progress. You should see per-test progress, the failing assertion, a screenshot at the failure point, and the browser console. That single loop — red test → dashboard → screenshot → fix — is the entire value proposition. Everything else is setup.

Implementation Patterns

Run one test, watch one test. The dashboard is a live view, so the strongest workflow is --filter on a single test or a small group, not the full suite. Watching 200 tests scroll past is noise; watching the one test you are actively fixing turn green is the loop you paid for.

Tight failure loop with re-run. The dashboard's re-run-a-single-failed-test control is the highest-leverage day-to-day feature. The pattern that works:

  1. Full suite in one terminal produces N failures.
  2. Open the dashboard, triage failures by reading the exception trace + screenshot in the dashboard, without switching to the terminal.
  3. Fix, hit re-run on that one test, watch it pass in place.
  4. Only re-run the whole suite when the individual failures are green.

This keeps you out of the terminal-to-browser-to-terminal thrash that makes Dusk debugging slow.

Add explicit screenshots at interesting intermediate steps. The package captures on failure, but if you are debugging a multi-step browser flow, add ->screenshot('after-cart') (or Dusk's equivalent) at the points that matter. Those artifacts show up in the same dashboard view and let you see when the flow broke, not just where it ended.

Keep a second terminal for the app server and a third for the Dusk run. The dashboard is an in-app route, so it needs your application running. It is not a standalone binary. A make dusk-triage target or a composer script wrapping artisan serve + artisan dusk --filter=... is worth the five minutes; it removes one class of "why is the dashboard blank" confusion.

Team onboarding pattern. For a new joiner or a QA hire, this is the cheapest way to make a Dusk failure legible: they can read the screenshot and console output without knowing Dusk's internals or how to find the right file under tests/Browser/screenshots/. Make it the default recommendation in your onboarding doc for E2E debugging — open the dashboard before opening the terminal.

Treat it as local-first, not CI-native. It is a live view of a run, not a results store. Do not try to wire it into a PR check or use it to answer "was this flaky last month." Keep CI on JUnit XML / HTML reports and artifact upload, and use this only for the developer loop.

Assert the gating in a test. Whatever you do to restrict the route, write one test that hits the production environment config and asserts a 404 (or 403). Config changes can silently promote a dev tool into production; a regression test is the cheap insurance.

Gotchas and Tips

It is archived and pinned to Laravel 7. Last release 2.0.0, dated 2020-05-29, changelog entry is literally "Laravel 7 support." On Laravel 8+ you will hit a Composer constraint conflict, not a fixable code error. Before you install anything, run composer why-not beyondcode/dusk-dashboard on the target app. If it fails there, stop — this is a stack gate, not a configuration problem.

Route exposure is the number-one risk. Two things this route does that matter: it renders captured screenshots, console logs, and browser exceptions, and it can trigger test runs. Confirm from source whether the package gates by environment by default; assume it does not until you have read it. Gate it, authenticate it, and test it.

Nothing upstream will ever fix. No security patches, no PHP minor-bump fixes, no response when Chrome bumps and screenshot capture breaks. If the pilot shows value, subscribe to Dusk's test-lifecycle events yourself and ship a thin internal view — the surface area is a route, a listener, and a view, and you own the upgrade path.

Chrome / Chromedriver drift is the silent breakage. The screenshot capture depends on the browser and driver versions Dusk is driving. When those move, screenshots can stop being written and the dashboard shows a failure with no image. If screenshots are suddenly missing across runs, check the driver version before you check the package.

Artifacts pile up on disk. Screenshots and logs land somewhere under the app (typically tests/Browser/screenshots and a console-log directory). With no retention story, a busy suite fills a disk. Add cleanup to your dusk script or a scheduled prune. Also decide whether those artifacts contain regulated data before they are ever generated.

Parallel and sharded Dusk are out. The dashboard is built around observing a single run. Do not expect it to aggregate results from multiple Dusk workers; if you are parallelising the suite, this belongs in a different workflow.

Blank dashboard, three usual causes:

  1. The app server isn't running (it's an in-app route — easy to forget when you've been staring at the Dusk CLI).
  2. The route is gated out for your current APP_ENV.
  3. The storage directory for artifacts isn't writable by the web process.

Check those three in that order before reading package internals.

Config cache bites after publishing. If you change the config and the route still behaves the old way, run php artisan config:clear. This is the same trap every vendor:publishd config has, and it catches everyone at least once.

Do not trust the changelog across major versions. The 1.x→2.0 boundary is undocumented — a one-line release note. If you inherit a 1.x pin that works, leave it alone: changing it buys nothing and risks a config republish and behavioural drift you cannot diff.

Watch the re-run endpoint if it shells out. If failed-test re-run invokes an artisan/CLI command, read how it selects the test — you want an allowlisted, passed-as-argument test identifier, not a shell string built from a request parameter. This is the one place in the package where a developer-tool convenience becomes an injection surface.

Read the source before you rely on any behaviour. At a few hundred lines it is faster than waiting for docs that do not exist. The provider, the routes file, and the view are the whole thing; once you have read them, the package holds no surprises and you will know whether to vendor it or rebuild it.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo