Key Takeaways
- Dusk + Browserless is a powerful combo: Laravel Dusk reliably handles UI testing, but when you need PDF rendering, dynamic scraping, or full-page browser automation, the Laravel Browserless SDK takes over without adding local Chrome overhead.
- You can run real headless browser workflows remotely, from PHP: With the Browserless SDK, you can generate PDFs, capture screenshots, solve CAPTCHAs, scrape content, and execute JavaScript all without leaving Laravel or managing Chrome installs.
- BrowserQL (BQL) enables full automation pipelines: You can declaratively write scraping or interaction flows using a GraphQL-style syntax, handle CAPTCHAs, bypass bot detection, and extract structured content at scale, all from your Laravel codebase.
Introduction
Laravel Dusk handles UI testing well; it’s solid for asserting user flows, filling forms, and ensuring your frontend doesn’t break. But once your app starts growing, it’s easy to hit limits when you push Dusk into rendering PDFs, scraping external sites, or working with pages that rely heavily on JavaScript. That’s where our Laravel Browserless SDK can help, as it gives you a clean PHP API to control headless Chrome remotely using Browserless, without dealing with browser crashes, flaky CI setups, or any local Chrome config. In this article, you’ll see how to offload complex browser operations like screenshotting, content capture, or CAPTCHA-solving to Browserless while keeping your Dusk test suite fast and focused on what it does best.
What the Browserless SDK Does (and Where Dusk Stops)
Laravel Dusk is great when focused on browser-based UI testing: clicking buttons, filling out forms, and checking assertions. But once you start pushing into areas like rendering PDFs, pulling content from external sites, or managing resource-heavy JS pages, Dusk begins to hit its limit. It’s not built for scraping or output generation.
The Laravel Browserless SDK gives you an API wrapper around Browserless.io, a hosted Chrome-as-a-Service platform. You’re still writing in PHP, but now you have a fully remote, scriptable browser behind it. That means no flaky local headless crashes, no Chrome memory spikes in CI, and no dev machine overhead.
Here’s what the SDK supports out of the box:
- PDF & Screenshot Generation: Render high-quality PDFs and capture full-page or targeted screenshots from any URL or HTML content.
- Dynamic Content Capture: Extract fully-rendered HTML from JavaScript-heavy or SPA-style pages.
- Custom JavaScript Execution: Run browser-level JavaScript functions for tasks like DOM inspection, metrics, or automated interactions.
- Scraping & File Downloads: Programmatically pull structured data from pages and download assets or documents.
- Bot Evasion & CAPTCHA Handling: Bypass bot detection systems like Cloudflare and solve CAPTCHAs using built-in stealth and verification tools.
- Session & Performance Tools: Manage browser sessions, control concurrency, and run Lighthouse audits for performance insights.
Let’s say you're generating invoices and want a PDF saved to disk. You can call your app’s /invoice/123
route and turn the rendered page into a styled, print-ready document, without ever running Chrome locally:
This request happens remotely on Browserless; you don’t need to install anything beyond the Laravel SDK. There is no Chrome, Xvfb, or dependency debugging; it is just a clean API response with your PDF bytes.
You can wire this into jobs, test helpers, and feature endpoints wherever browser output is part of your feature set. The SDK keeps things in PHP, while Browserless does the heavy lifting on the browser side. For teams doing both UI testing with Dusk and content output or scraping, this setup helps you keep test logic and browser work in the same app without crossing languages or building glue scripts.
Augmenting Dusk with Remote Chrome Tasks
If you’ve worked with Laravel Dusk long enough, you’ve probably tried to stretch it beyond its original purpose. Maybe you wanted to validate a PDF, snapshot a fully rendered Vue or React page, or verify that server-side rendered content loads as expected before your test assertions run. Dusk gives you great coverage for UI interactions, but it doesn’t scale well when you need heavier browser logic or anything that steps outside your app’s frontend.
The Laravel Browserless SDK fills that gap without forcing you to leave the Laravel ecosystem. Through a clean, fluent PHP API, it gives you full browser access to headless Chrome running in the cloud.
Instead of spinning up Chrome locally or wrestling with Docker, you can run screenshots, content capture, PDF generation, and full-page evaluation remotely, straight from a Dusk hook, helper, or test case. You’re not replacing Dusk; you’re complementing it where Dusk doesn’t go far enough.
Use cases like these are where the SDK helps:
- Screenshots in CI: Grab visual output from any step in your test without running Chrome locally or relying on headless quirks.
- Preloading dynamic content: Hit a route before Dusk does to ensure hydration, animations, or API payloads are done loading.
- PDF/image validation: Trigger a backend PDF export or image render and compare the output with a baseline without rendering it locally.
- External scraping during tests: Hit third-party URLs in real Chrome, inside your test suite, without risking rate limits or timeouts locally.
Here’s a quick example where you want to confirm that an onboarding screen finished rendering before asserting its content in Dusk. Instead of relying on waitForText
, you use Browserless to wait on a real selector, capture the full HTML, and inspect it or log it:
If you tried to do it locally, this task would slow down a Dusk test, especially in CI, where resource constraints and Chrome reliability are constant headaches. With Browserless, you're running those browser steps outside your environment, keeping test jobs lean and removing dependencies on system Chrome or display buffers. All the browser logic stays in the cloud. Your Dusk tests stay Laravel-native, and your test environment doesn’t fall over every time Chrome does something unexpected.
Advanced Browser Tasks with Just PHP: No JS or Browser Setup Required
Sometimes you just need browser logic to run exactly how it would in a real browser, whether checking a title, grabbing a window property, or watching for a DOM event, and you don’t want to leave PHP to do it. That’s what executeFunction()
gives you with the Laravel Browserless SDK. It lets you write JavaScript that runs inside a remote, headless Chrome session and returns the result to PHP, so no extra setup or browser dependencies are required.
This is helpful when dealing with dynamic content, page state that doesn’t settle until a specific event, or even client-side rendering that only completes after a component mounts. You can wait for things like hydration or page transitions without needing to guess timings or simulate user behavior. Tell Chrome what to expect; it does the rest on the server.
Here’s how you can load a page and get the final URL and document title, all from a simple executeFunction()
call:
You can use this pattern for performance metrics, DOM state checks, or any headless behavior you’d normally need Node or Puppeteer. If you’re working on test flows requiring pixel-level validation or scraping third-party content that changes based on JS rendering, you can plug this into your app or test pipeline.
Because Browserless handles proxy configuration, cookies, sessions, and headers out of the box, you can combine executeFunction()
with things like stealth mode, authenticated sessions, or rotating IPs without leaving PHP. The JavaScript you pass is just a string, but it’s running in a real, sandboxed browser instance you don’t have to manage.
BQL for Full Automation Workflows: Laravel Meets GraphQL for Browsers
Working with Laravel and needing to run browser flows, such as CAPTCHAs, content extraction, and multiple page visits, BrowserQL (BQL) gives you a clean, declarative way to write those steps without spinning up or managing Chrome. It's written in GraphQL-style syntax and handled entirely through the Laravel Browserless SDK, so you can keep everything in PHP and still run full browser workflows remotely.
You can script full sessions: load a page, detect or solve CAPTCHAs, interact with forms, wait for network events, and extract content all within one mutation. BQL queries run against Browserless’ infrastructure, which means no local browser context to maintain, no containers to orchestrate, and no Chrome-related crashes to debug.
Here’s how you’d remotely detect and handle a Cloudflare “verify you’re human” gate. This mutation loads the page and runs the Cloudflare challenge solver in one pass:
For simpler scraping tasks where you don’t need custom logic or CAPTCHA detection, the SDK also gives you a dedicated scrape()
method. That wraps BQL for you and lets you extract structured data without writing full mutations:
Combining BQL and the Laravel SDK lets you define scraping or automation flows like real browser tests without spinning up anything locally. It fits well into queued jobs, background sync tasks, and test support flows where you need full browser behavior at scale and don’t want to patch together a headless setup from scratch.
Conclusion
Using Dusk, you know how useful it is for simulating user behavior across your app. But it's worth pulling in Browserless when you need to verify rendered PDFs, extract content from dynamic pages, or run scraping jobs that would normally crash a local browser in CI. Our Laravel SDK makes this feel like native Laravel code; you get structured responses, queue-friendly methods, and full control over headless Chrome without any local setup. The two tools work well: Dusk for UI testing and Browserless for browser automation that scales. If that sounds like what your test or data pipeline needs, spin up a free Browserless project and integrate our SDK; you’ll be up and running in minutes.
FAQs
How can I generate PDFs in Laravel without using local Chrome?
You can use the Laravel Browserless SDK to generate PDFs from a URL or HTML content by sending the job to a remote Chrome instance via Browserless. This removes the need to run or manage Chrome on your local machine or CI server. The SDK handles the rendering remotely and returns a PDF you can save or stream within your Laravel app.
What’s the best way to scrape dynamic content in Laravel apps?
For pages that rely on JavaScript or client-side rendering, scraping with Browserless is a reliable approach. Using the Laravel SDK, you can trigger headless Chrome in the cloud to load the page fully, wait for specific DOM elements, and return structured HTML or selected content. This avoids brittle logic and gives you access to real browser behavior without running Chrome locally.
Can I run browser automation with Laravel Dusk and avoid CI crashes?
Yes. While Dusk is great for UI testing, pushing it beyond that, especially for things like PDF generation or scraping, can lead to flaky tests or timeouts in CI. Instead, use the Browserless SDK to remotely run heavier tasks like screenshots, DOM extraction, or page rendering. This lets Dusk focus on UI logic while Browserless handles browser automation without adding load to your test runners.
What is BrowserQL, and how does it integrate with Laravel?
BrowserQL (BQL) is a GraphQL-style query language for defining browser workflows, like clicking buttons, solving CAPTCHAs, or scraping data. The Laravel Browserless SDK supports BQL, so you can write full browser sessions declaratively using PHP. You can run those flows as part of your app or in background jobs without managing browser infrastructure or writing JavaScript.