laracasts/cypress gives Laravel apps a Cypress harness and a PHP-shaped test API
Laravel Cypress Integration
At a glance
- What is it?
- This package installs the plumbing that Laravel applications need to run end to end tests in Cypress: an Artisan command that copies in the boilerplate, a Cypress configuration seeded from your app URL, and commands such as cy.login and cy.create that speak in Laravel factories rather than raw HTTP calls. The environment handling is the part that needs reading carefully, because it swaps your .env file during a test run.
- Who is it for?
- laracasts/cypress fits a Laravel team that wants browser level tests without writing raw HTTP calls for authentication and record creation, and it does not fit a project that runs tests in parallel against a shared environment, because the environment swap is a single global file change.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One Artisan command installs the whole harness
The package is described in one sentence: it provides the necessary boilerplate to quickly begin testing Laravel applications using Cypress. The design decision is that everything is delivered as file stubs that the package copies into your project, rather than as a framework you configure.
The installation has four steps, and the first is not this package at all. If Cypress is not installed, that is the first step, and it goes into your npm dev dependencies:
npm install cypress --save-devThen the package itself, pulled in through Composer as a development-only dependency:
composer require laracasts/cypress --devThen the Artisan command that copies the initial boilerplate files for your Cypress tests:
php artisan cypress:boilerplateAnd then the runner:
npx cypress openIn the Cypress window that opens you choose E2E Testing, then Start E2E Testing in Chrome, and you get a list of specs. The boilerplate includes an example.cy.js spec so there is something to run immediately, and the README's first success check is that the example spec is green.
The repository is a Composer package with a src directory, its own tests and a phpunit configuration, and it is MIT licensed. The README also points to a Laracasts video tour for people who would rather watch the setup than read it.
The baseUrl is seeded from APP_URL, and the config file name is inconsistent
The package declares some initial settings in your project's Cypress configuration file, and the README asks you to look at it and make sure everything is in order. The specific setting it calls out is baseUrl, which the package defaults to your application's APP_URL environment setting.
That default is the sensible one for a test run against a shared or staging environment, where the app is already reachable at a URL, and it is the wrong one for local development, where the app runs on a different port. The README's own environment handling section resolves this by telling you to point baseUrl at your local server.
There is a small inconsistency here worth knowing about, because it costs a confused afternoon. The configuration section refers to cypress.config.js as the file where the settings are declared, while the later environment section tells you to visit cypress.json and change the baseUrl there. Both are Cypress configuration file names, from different eras of Cypress, and the README does not say which one applies to the version you have. If the file you are editing has no effect, that mismatch is the first thing to check.
The baseUrl value the README suggests for local work is:
{
"baseUrl": "http://127.0.0.1:8000"
}which matches the port that php artisan serve uses by default.
The .env swap is the mechanism, and it is the risk
After the boilerplate command runs, your project root contains a .env.cypress file, and the README says this file is a duplicate of .env that you can update as needed to prepare the application for your Cypress tests. The stated reason is that you will probably want a special database so that acceptance tests are isolated from your development database:
DB_CONNECTION=mysql
DB_DATABASE=cypressHere is the mechanism, and it is the part to understand before you rely on it. By default, when running your Cypress tests, the package automatically backs up your primary .env file and swaps it out with the Cypress one. Once the run completes, the environment files are reset to how they originally were. All Cypress tests run according to the environment specified in .env.cypress.
So the test suite changes a global file, and the change is reverted at the end. That has an obvious failure mode: if the run is interrupted, or the reset step throws, your development environment is left pointing at the test database. The README does not discuss this, so it is worth knowing that the safety of the swap depends on the cleanup step running.
The second issue is that the automatic reset makes debugging a failing test harder. The README puts it plainly: when Cypress tests fail it is often useful to manually browse your application in the exact state that triggered the failure, and you cannot do that if the environment is automatically reverted after each run.
Two ways to keep the environment around while you debug
The README offers two options for dealing with the reset, and they are genuinely different in what they ask of you.
Option one is to disable the reset task temporarily. You visit cypress/support/index.js and comment out this portion:
after(() => {
// cy.task("activateLocalEnvFile", {}, { log: false });
});With the reset disabled, the environment stays as the test run left it, and the README says to remember to manually revert to your local .env file when you are done.
Option two is to take over the environment handling yourself. When booting a server with php artisan serve, you can pass an --env flag to specify the environment you want, and the README explains that this instructs Laravel to boot up a server and use the configuration declared in .env.cypress:
php artisan serve --env="cypress"You then point baseUrl at that local server, and the README suggests adding an npm script to package.json to avoid typing it every time:
{
"scripts": {
"test:cypress": "php artisan serve --env=cypress & cypress open"
}
}With that script, npm run test:cypress starts the local server and opens Cypress together.
Option two has one more step, and it is the important one. The README tells you to visit cypress/support/index.js and delete the activateCypressEnvFile and activateLocalEnvFile tasks, because they are no longer required if you are handling the environment yourself. That removal is the point of option two: instead of a package mutating your .env behind your back, the server is booted with the right environment from the start, and the file never changes at all.
If you take option one, treat the .env file as something you must restore by hand.
cy.login, cy.create and friends speak in Laravel, not HTTP
The package adds a set of commands to your Cypress workflow so that a test reads like Laravel code rather than a sequence of form fills. The mechanism is a set of Cypress-specific endpoints exposed in your application, and the README is explicit about one thing: these endpoints will never be accessible in production. They are development-only routes that the package registers.
cy.login finds an existing user matching the optional attributes provided and sets it as the authenticated user for the test, creating a new user and logging it in if none matches. A minimal test looks like this:
test('authenticated users can see the dashboard', () => {
cy.login({ username: 'JohnDoe' });
cy.visit('/dashboard').contains('Welcome Back, JohnDoe!');
});When you need the user to be in a particular factory state, or to have a relationship eager loaded, you pass an object with attributes, state and load keys instead of a flat object. The README gives the PHP equivalent of that call, and notes that the object form is what lets you specify a factory state before the user is returned from the server.
cy.currentUser fetches the currently authenticated user from the server and is equivalent to Laravel's auth helper, and cy.logout logs that user out, equivalent to the logout call:
test('once a user logs out they cannot see the dashboard', () => {
cy.login({ username: 'JohnDoe' });
cy.logout();
cy.visit('/dashboard').assertRedirect('/login');
});cy.create is the one that saves the most typing. It uses Laravel factories to create and persist a new Eloquent record, and the README notes it is equivalent to calling the factory directly:
test('it shows blog posts', () => {
cy.create('App\\Post', { title: 'My First Post' });
cy.visit('/posts').contains('My First Post');
});You can pass a count as a second argument to create several records at once, and the README also mentions passing an object as an alternative form.
Maintenance: the last push was on 2026-04-06
This package is not moving quickly, and the record says so plainly.
The published releases are 3.0.4 on 2026-04-06, 3.0.3 on 2025-02-27 and 3.0.2 on 2024-03-19. The last push was on 2026-04-06, the same day as the 3.0.4 release, and the repository is not archived, so the work is finished rather than abandoned. On the evidence of the release dates you should plan on maintaining this yourself if a Laravel major version or a Cypress major version moves past what the package supports.
The version numbers tell their own story about compatibility. Cypress changed its configuration file layout during this period, which is visible in the README as the mismatch between cypress.config.js and cypress.json, and the 3.0.3 release label is written as 3.03 rather than 3.0.3, which is a small sign of a package maintained in bursts rather than on a schedule.
Two other structural details are worth noting. The package is a development-only Composer dependency, so it never reaches production, and the exposed test endpoints are guarded so that they are never accessible in production, which is the reason the README bothers to state it. The repository has a StyleCI configuration and a Prettier configuration, so formatting is handled by tooling, and a CHANGELOG is present in the tree.
The licensing is MIT, so if you need to fork the stubs to match a newer Cypress or Laravel, that is a routine change rather than a negotiation.
Where this package is the wrong tool
Three situations argue against it.
The first is parallel test execution. The environment handling is a single global .env swap, and the same mechanism runs a database pointed at a test schema. If you want to shard your suite across several Cypress processes or machines, that design does not extend, and you would be back to configuring environments yourself.
The second is a test suite that deliberately does not touch the application server. The value of this package is that its commands call Laravel endpoints, so cy.login and cy.create run real application code, including factories and the session layer. If your tests are better written against a mock or a fixture layer, you are paying for a server round trip and an extra dependency to do it.
The third is a team that has already standardised on another end to end approach. The package is a convenience layer with four commands and a set of stubs, and it costs a Composer dependency, a global .env mutation and a set of routes registered in your application. If your team already has a working pattern for authentication state and record creation, the incremental gain is small.
One more operational caution. Because the .env backup and restore is performed by Cypress tasks running in the test process, an aborted run is the scenario to plan for. Keep a copy of your .env outside the working tree, or commit a sanitised version, so that a failed test session cannot leave a developer pointed at the wrong database.
Editorial conclusion
laracasts/cypress fits a Laravel team that wants browser level tests without writing raw HTTP calls for authentication and record creation, and it does not fit a project that runs tests in parallel against a shared environment, because the environment swap is a single global file change. Before you adopt it, read the environment handling section and decide which of the two options you will use, and note that the last push was on 2026-04-06 with release 3.0.4 on the same date, so plan on maintaining the package yourself if your Laravel or Cypress version moves past what it supports.
Frequently asked questions
How do I install laracasts/cypress in a Laravel project?
Install Cypress as a dev dependency with npm install cypress --save-dev, pull in the package with composer require laracasts/cypress --dev, then run php artisan cypress:boilerplate to copy the boilerplate files. You can then open the runner with npx cypress open.
What does the .env.cypress file do in laracasts/cypress?
It is a duplicate of your .env file created by the boilerplate command, and it is where you point the test environment, for example at a separate database. By default the package backs up your primary .env file, swaps in the Cypress one for the duration of the test run, and restores the original afterwards.
How do I use cy.login and cy.create in laracasts/cypress?
cy.login finds or creates a user matching the attributes you give and authenticates it for the test, and can take an object with attributes, state and load keys to control factory state and eager loading. cy.create uses Laravel factories to create and persist an Eloquent record, taking the model class, an optional count and an attributes object.
How do I debug a failing Cypress test in laracasts/cypress?
The README suggests two options. You can comment out the after block in cypress/support/index.js that calls the activateLocalEnvFile task so the environment is not reverted, and restore your .env manually afterwards, or you can boot the server with php artisan serve --env="cypress", point baseUrl at it, remove the environment tasks and manage the environment yourself.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/laracasts-cypress)Was this useful?