laravel/nova-dusk-suite
Laravel Nova Dusk Suite provides helpers and assertions for browser-testing Laravel Nova applications with Laravel Dusk. It simplifies writing reliable end-to-end tests for Nova resources, actions, filters, and UI interactions.
Architecture fit. laravel/nova-dusk-suite is a development-time harness, not a runtime dependency. It sits in require-dev and orchestrates a disposable Laravel application: it installs Nova and the package under test, publishes assets, migrates and seeds a database, boots a headless Chrome session, and drives browser-level assertions against the Nova UI. That makes it an integration and end-to-end layer in the test pyramid — above PHPUnit unit tests and above component-level Livewire/Dusk tests that don't need the full Nova shell. For a team that builds or maintains Nova components (custom fields, tools, cards, resource tools, filters, actions), this is the only credible way to verify that a component actually renders and behaves inside a real Nova admin panel. For a team that merely consumes Nova and writes application code, it is architecturally irrelevant — that is the single most important scoping decision a TPM makes here.
Integration feasibility. Feasible, but gated on prerequisites rather than on engineering difficulty. The hard prerequisites are (a) Nova licenses that cover every developer machine and every CI runner — Nova is commercial and the suite boots a real Nova install; (b) a CI image with PHP, Node (for asset compilation), a database, and a Chrome/ChromeDriver pair that are version-matched; and (c) acceptance that the suite owns the test bootstrap, meaning teams conform to its NovaDuskTestCase base class and directory conventions rather than bringing their own. The integration is therefore high-confidence but high-constraint: it is a "fit the team to the tool" adoption, not a "fit the tool to the team" one.
Technical risk. Three risks dominate. First, version coupling: the suite tracks Nova major releases, and a Nova upgrade can strand the harness until the maintainers publish a compatible tag — a schedule dependency on a third party for a first-party-adjacent tool. Second, browser flake: full-app Chrome tests are the most flake-prone tier in any stack, and this package deliberately runs the heaviest possible variant (asset build + migrations + Nova boot + browser). Third, thin community surface: ~100 stars and an unclear/undocumented repository pointer mean few public answers, few forks, and no ecosystem of blog posts. Support burden lands on the adopting team. Secondary risks: license-expiry failures in CI, test isolation failures from shared database state, and slow feedback loops that erode TDD habits.
Key questions. (1) Are we authoring Nova extensions, or only consuming Nova in an app? If consuming, stop — the suite adds no value. (2) Which Nova major and minor are we pinned to, and does a compatible suite tag exist today? (3) Do we hold CI-eligible Nova licenses, and who owns renewal? (4) What is our per-PR CI budget, and does a 5–15 minute E2E job fit inside it? (5) Is there an upstream roadmap signal that Laravel will fold this capability into Nova itself, which would make a bespoke harness a stranded asset? (6) What flake rate will we tolerate before we start ignoring red builds? (7) Build-vs-adopt: our opportunity signal (12.59) suggests the marginal engineering time freed by adopting exceeds the cost of maintaining a homegrown harness — worth validating with a one-sprint spike rather than a document.
Stack fit. The suite presumes a conventional Laravel + Nova stack: Composer-managed PHP, Node for Vite/Mix asset builds, a relational database, and a browser binary. It fits cleanly if the team already runs Dusk anywhere; it forces new infrastructure if the team has only ever run PHPUnit. Confirm PHP minor version alignment with both Dusk and Nova before committing — this is the most common silent blocker.
Migration path. Do not attempt a big-bang retrofit. Treat the first adoption as a capability spike: pick the single highest-risk or highest-churn Nova component, stand up the suite in a throwaway branch, and prove three things end to end — that it boots in local dev, that it boots in the target CI image, and that a deliberately broken component reliably fails the suite. Only after that spike passes should the suite be promoted to a shared harness. Existing unit and feature tests stay untouched; this layer is additive and should never replace cheaper tests.
Compatibility. Maintain a written compatibility matrix covering Nova version, PHP version, Dusk version, and Chrome/ChromeDriver pairing, and pin all four in CI. Chrome's auto-update channel is the most common source of overnight breakage; a pinned, image-baked browser plus a scheduled canary job that tests the newest Chrome is the standard mitigation.
Sequencing. (1) Scope decision and license audit. (2) Two-week spike on one component. (3) CI job authored as a reusable workflow/template, with caching for Composer and Node so the E2E job doesn't pay full install cost every run. (4) Golden-path documentation: how to add a test, how to debug a failure locally, how to bump Nova. (5) Expand coverage component by component, ranked by business criticality. (6) Introduce a merge gate only once the suite has demonstrated a stable flake rate over roughly twenty runs.
Maintenance. This is the real cost and it is recurring, not one-off. Someone must own Nova upgrades, Dusk upgrades, Chrome pinning, and database/seed drift. Budget a standing fraction of one engineer's time, plus a defined response window whenever a Nova release lands, because the harness cannot be upgraded to a Nova version the suite doesn't yet support. Pin exact versions; floating constraints on a package this small and this coupled to a commercial product invite surprise breakage.
Support. There is no vendor SLA. Internal ownership is mandatory — a named platform or QA engineer who is the escalation point when the suite fails for reasons unrelated to the code under test. Without that owner, the suite's failures become indistinguishable from product failures and trust collapses.
Scaling. Every test boots a full application plus a browser, so wall-clock time scales roughly linearly with test count. Plan for parallelization (test sharding across CI runners), a headless Chrome pool, and aggressive caching of Composer and Node artifacts. Also plan a coverage ceiling: not every component needs E2E coverage, and a suite that tries to cover everything will be slow enough that people route around it. Selectivity is the scaling strategy.
Failure modes. Expect and pre-write runbooks for: Chrome/ChromeDriver version drift; Nova license expiry or seat exhaustion in CI; asset compilation failures that surface as opaque browser timeouts rather than build errors; database state leaking between tests; and upstream incompatibility immediately after a Nova release. Each of these should be distinguishable in CI output, which usually means wrapping the suite invocation in a small script that captures artifacts — screenshots, browser console logs, Laravel logs — on failure. Without artifacts, debugging E2E failures is disproportionately expensive and the suite loses credibility fast.
Ramp-up. A Laravel-comfortable engineer with no Dusk experience should reach productive use in one to two weeks; the suite's own configuration surface is small, but the surrounding stack (asset builds, headless browser debugging, database seeding) is where the learning happens. Engineers unfamiliar with browser automation generally need a month to become self-sufficient at diagnosing failures rather than merely re-running them. Factor this into planning: the first two sprints after adoption will look unproductive on paper even if the spike succeeded.
Recommendation. Adopt, but narrowly and conditionally: only if the team authors Nova extensions, only with confirmed CI licensing and a named owner, and only after a spike proves boot + failure-detection in the real CI image. Otherwise defer, and revisit if Nova ships first-party in-product testing support.
How can I help you explore Laravel packages today?