Giter Site home page Giter Site logo

cypress's Introduction

Laravel + Cypress Integration

This package provides the necessary boilerplate to quickly begin testing your Laravel applications using Cypress.

Video Tour

If you'd prefer a more visual review of this package, please watch this video on Laracasts.

Table of Contents

Installation

If you haven't already installed Cypress; that's your first step.

npm install cypress --save-dev

Now you're ready to install this package through Composer. Pull it in as a development-only dependency.

composer require laracasts/cypress --dev

Finally, run the cypress:boilerplate command to copy over the initial boilerplate files for your Cypress tests.

php artisan cypress:boilerplate

That's it! You're ready to go. We've provided an example.cy.js spec for you to play around with it. Let's run it now:

npx cypress open

In the Cypress window that opens, Choose "E2E Testing," and then "Start E2E Testing in Chrome." This will bring up a list of all specs in your application. Of course, at this point, we only have the single example spec. Click example.cy.js to run it. Wew! All green.

Cypress Configuration

We've declared some initial settings in your project's cypress.config.js file. Have a quick look now to ensure that everything is in order. In particular, please ensure that the baseUrl property is set correctly (we default to your app's APP_URL environment setting).

Environment Handling

After running the php artisan cypress:boilerplate command, you'll now have a .env.cypress file in your project root. To get you started, this file is a duplicate of .env. Feel free to update it as needed to prepare your application for your Cypress tests.

Likely, you'll want to use a special database to ensure that your Cypress acceptance tests are isolated from your development database.

DB_CONNECTION=mysql
DB_DATABASE=cypress

When running your Cypress tests, this package, by default, will automatically back up your primary .env file, and swap it out with env.cypress. Once complete, of course the environment files will be reset to how they originally were.

All Cypress tests run according to the environment specified in .env.cypress.

However, when your Cypress tests fail, it can often be useful to manually browse your application in the exact state that triggered the test failure. You can't do this if your environment is automatically reverted after each test run.

To solve this, you have two choices:

Option 1:

Temporarily disable the Cypress task that resets the environment. Visit cypress/support/index.js and comment out this portion.

after(() => {
  // cy.task("activateLocalEnvFile", {}, { log: false });
});

That should do it! Just remember to manually revert to your local .env file when you're done performing your Cypress tests.

Option 2:

When booting a server with php artisan serve, you can optionally pass an --env flag to specify your desired environment for the application.

php artisan serve --env="cypress"

^ This command instructs Laravel to boot up a server and use the configuration that is declared in .env.cypress.

Now visit cypress.json and change the baseUrl to point to your local server.

{
  "baseUrl": "http://127.0.0.1:8000"
}

And you're all set! I'd recommend creating an npm script to simplify this process. Open package.json, and add:

{
  "scripts": {
    "test:cypress": "php artisan serve --env=cypress & cypress open"
  }
}

Now from the command line, you can run npm run test:cypress to start a local server and open Cypress.

If you choose this second option, visit cypress/support/index.js and delete the activateCypressEnvFile and activateLocalEnvFile tasks, as shown here. They're no longer required, as you'll be handling the environment handling yourself.

API

This package will add a variety of commands to your Cypress workflow to make for a more familiar Laravel testing environment.

We allow for this by exposing a handful of Cypress-specific endpoints in your application. Don't worry: these endpoints will never be accessible in production.

cy.login()

Find an existing user matching the optional attributes provided and set it as the authenticated user for the test. If not found, it'll create a new user and log it in.

test('authenticated users can see the dashboard', () => {
  cy.login({ username: 'JohnDoe' });

  cy.visit('/dashboard').contains('Welcome Back, JohnDoe!');
});

Should you need to also eager load relationships on the user model or specifiy a certain model factory state before it's returned from the server, instead pass an object to cy.login(), like so:

test('authenticated users can see the dashboard', () => {
    cy.login({
        attributes: { username: 'JohnDoe' },
        state: ['guest'],
        load: ['profile']
    });

    cy.visit('/dashboard').contains('Welcome Back, JohnDoe!');
});

If written in PHP, this object would effectively translate to:

$user = User::factory()->guest()->create([ 'username' => 'JohnDoe' ])->load('profile');

auth()->login($user);

cy.currentUser()

Fetch the currently authenticated user from the server, if any. Equivalent to Laravel's auth()->user().

test('assert the current user has email', () => {
    cy.login({ email: '[email protected]' });

    cy.currentUser().its('email').should('eq', '[email protected]');
    
    // or...
    
    cy.currentUser().then(user => {
        expect(user.email).to.eql('[email protected]');
    });
});

cy.logout()

Log out the currently authenticated user. Equivalent to Laravel's auth()->logout().

test('once a user logs out they cannot see the dashboard', () => {
  cy.login({ username: 'JohnDoe' });

  cy.logout();

  cy.visit('/dashboard').assertRedirect('/login');
});

cy.create()

Use Laravel factories to create and persist a new Eloquent record.

test('it shows blog posts', () => {
  cy.create('App\\Post', { title: 'My First Post' });

  cy.visit('/posts').contains('My First Post');
});

Note that the cy.create() call above is equivalent to:

App\Post::factory()->create(['title' => 'My First Post']);

You may optionally specify the number of records you require as the second argument. This will then return a collection of posts.

test('it shows blog posts', () => {
  cy.create('App\\Post', 3, { title: 'My First Post' });
});

Lastly, you can alternatively pass an object to cy.create(). This should be the preferred choice, if you need to eager load relationships or create the model record in a given model factory state.

test('it shows blog posts', () => {
    cy.create({
        model: 'App\\Post',
        attributes: { title: 'My First Post' },
        state: ['archived'],
        load: ['author'],
        count: 10
    })
});

If written in PHP, this object would effectively translate to:

$user = \App\Post::factory(10)->archived()->create([ 'title' => 'My First Post' ])->load('author');

auth()->login($user);

cy.refreshRoutes()

Before your Cypress test suite run, this package will automatically fetch a collection of all named routes for your Laravel app and store them in memory. You shouldn't need to manually call this method, however, it's available to you if your routing will change as side effect of a particular test.

test('it refreshes the list of Laravel named routes in memory', () => {
    cy.refreshRoutes();
});

cy.refreshDatabase()

Trigger a migrate:refresh on your test database. Often, you'll apply this in a beforeEach call to ensure that, before each new test, your database is freshly migrated and cleaned up.

beforeEach(() => {
  cy.refreshDatabase();
});

test('it does something', () => {
  // php artisan migrate:fresh has been
  // called at this point.
});

cy.seed()

Run all database seeders, or a single class, in the current Cypress environment.

test('it seeds the db', () => {
  cy.seed('PlansTableSeeder');
});

Assuming that APP_ENV in your .env.cypress file is set to "acceptance," the call above would be equivalent to:

php artisan db:seed --class=PlansTableSeeder --env=acceptance

cy.artisan()

Trigger any Artisan command under the current environment for the Cypress test. Remember to precede options with two dashes, as usual.

test('it can create posts through the command line', () => {
  cy.artisan('post:make', {
    '--title': 'My First Post',
  });

  cy.visit('/posts').contains('My First Post');
});

This call is equivalent to:

php artisan post:make --title="My First Post"

cy.php()

While not exactly in the spirit of acceptance testing, this command will allow you to trigger and evaluate arbitrary PHP.

test('it can evaluate PHP', () => {
    cy.php(`
        App\\Plan::first();
    `).then(plan => {
        expect(plan.name).to.equal('Monthly'); 
    });
});

Be thoughtful when you reach for this command, but it might prove useful in instances where it's vital that you verify the state of the application or database in response to a certain action. It could also be used for setting up the "world" for your test. That said, a targeted database seeder - using cy.seed() - will typically be the better approach.

Routing

Each time your test suite runs, this package will fetch all named routes for your Laravel application, and store them in memory. You'll additionally find a ./cypress/support/routes.json file that contains a dump of this JSON.

This package overrides the base cy.visit() method to allow for optionally passing a route name instead of a URL.

test('it loads the about page using a named route', () => {
    cy.visit({
        route: 'about'
    });
});

If the named route requires a wildcard, you may include it using the parameters property.

test('it loads the team dashboard page using a named route', () => {
    cy.visit({
        route: 'team.dashboard',
        parameters: { team: 1 }
    });
});

Should you need to access the full list of routes for your application, use the Cypress.Laravel.routes property.

// Get an array of all routes for your app.

Cypress.Laravel.routes; // ['home' => []]

Further, if you need to translate a named route to its associated URL, instead use the Cypress.Laravel.route() method, like so:

Cypress.Laravel.route('about'); // /about-page

Cypress.Laravel.route('team.dashboard', { team: 1 }); // /teams/1/dashboard

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

cypress's People

Contributors

bencarter78 avatar brainlet-ali avatar carlobeltrame avatar dillingham avatar jakski avatar jamesking56 avatar jeffreyway avatar jenky avatar jeroenvanrensen avatar laravel-shift avatar manogi avatar mpociot avatar sam-ngu avatar tnorthcutt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cypress's Issues

Problems with Passport command `passport:install` does not exist

I'm struggling to call the artisan command passport:install or any passport command with the following error:
Symfony\Component\Console\Exception\CommandNotFoundException: The command "passport:install" does not exist. in file /var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php on line 190

On my test I'm trying:
beforeEach(() => { cy.refreshDatabase() cy.artisan('migrate', { '--path': 'vendor/laravel/passport/database/migrations' }) cy.artisan('passport:install') cy.seed() })

Am I missing something or it's just not possible to run passport commands from the tests?
I'm using Laravel 9 and PHP 8.1

[Discussion] Gitlab Pipeline

Has anyone managed to get the Gitlab pipeline to work?

It fails when cypress try to get http://localhost:8080/__cypress__/csrf_token (not found)

script: 
    - ... other steps ...    
    - yarn cypress:run (fails here when try to get /__cypress__/csrf_token)

So, manually I have tried to get with some urls

script: 
    - curl http://localhost:8080/posts  (works)
    - curl http://localhost:8080/users (works)
    - curl http://localhost:8080/__cypress__/csrf_token (fail)

cy.create() 500 error - Laravel 8

Hello,

I'm new to cypress and trying to following the README and create a user via the cy.create() method but I continue to get 500 errors.

I wish I could provide more error details but I can't seem to get the specific error. Even setting {failOnStatusCode: false} inside the Cypress.Commands.add('create' method does not provide more information, it just skips the error and moves on.

Laravel: 8.11.2
Cypress: 5.6.0
laracasts/cypress: 1.1

Inside my login.spec.js file

describe('Login', () => {
    before(() => {
        cy.refreshDatabase().seed();

        cy.create('App\\Models\\User', {
            name: 'Mike Fake Person',
            email: '[email protected]',
            password: 'superawesomepasword',
            timezone: 'America/Los_Angeles'
        })

    })


    describe('with valid credentials', () => {
        it('works!');
    });
});

I get the following error in cypress:

Screenshot from 2020-11-13 20-58-54

Screenshot from 2020-11-13 20-58-59

I've also tried a few other models just in case but it continues to error.

I have verified the cy.refreshDatabase().seed(); is running correctly and all seed records are seeding so I assume the connection is working.

Is this possibly due to laravel 8's changes in how factories are handled?

Thanks!

Environment variables undefined in tests

Using latest version 3.0.0 with Cypress 10.3.1 and have been noticing environment variable are undefined in my tests.

For example, running console.log(Cypress.env('APP_NAME')) from a test outputs undefined to the console.

Anyone else having this issue?

Add support for Laravel 9

PHP 8.1
Laravel 9
OSX 12.1

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Root composer.json requires laracasts/cypress ^1.4 -> satisfiable by laracasts/cypress[1.4.0, 1.4.1].
- laracasts/cypress[1.4.0, ..., 1.4.1] require illuminate/support ^6.0|^7.0|^8.0 -> found illuminate/support[v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.

You can also try re-running composer require with an explicit version constraint, e.g. "composer require laracasts/cypress:*" to figure out if any version is installable, or "composer require laracasts/cypress:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

[Question] Handle factory response

Am I missing something?

Works

describe('Test', () => {
    let allUsers = []

    beforeEach(() => {
        cy.refreshDatabase()

        cy.create('App\\Models\\User', 3).then(users => { allUsers.push(...users) })
        cy.create('App\\Models\\User', 4).then(users => { allUsers.push(...users) })

   })

   it('Example' , () => {
        console.log(allUsers) // works

   });

})

Does not work

describe('Test', () => {

    beforeEach(() => {
        cy.refreshDatabase()        
   })

   it('Example' , () => {
         let allUsers = []

        cy.create('App\\Models\\User', 3).then(users => { allUsers.push(...users) })
        cy.create('App\\Models\\User', 4).then(users => { allUsers.push(...users) })


       // How to wait factories promises to be resolve before going on?

        console.log(allUsers) // empty

   });

})

Feature Request: Modify values using config

Reason

Not all projects keep their web middleware group untouched. Some projects add extra middleware to that group which hinders the functionality of the private routes. This will allow users to easily edit the middleware for their private routes.

Request

Can we add the following code to the CypressServiceProvider::boot function?

$this->publishes([
      __DIR__.'/../config/cypress.php' => config_path('cypress.php'),
]);

Then just make a config/cypress.php file that defines the following parameters:

return [
  'routing' => [
     'middleware' => env('CYPRESS_ROUTES_MIDDLEWARE', 'web')
  ]
]

Finally, in CypressServiceProvider::addRoutes, replace it with the following code:

protected function addRoutes()
{
    Route::namespace('')
        ->middleware(config('cypress.routing.middleware'))
        ->group(__DIR__.'/routes/cypress.php');
}

The 'task' event has not been registered in the plugins file.

I've followed the installation steps as per the Laracasts video series on Cypress integration with Laravel, but when running a simple test I got the follow error:

cy.task('activateLocalEnvFile') failed with the following error:

The 'task' event has not been registered in the plugins file. You must register it before using cy.task()

I created the cypress.sqlite file and referenced it in the .env.cypress file.

Receiving a 419 error when config:clear runs in the after hook

I can't seem to figure this out, I'm receiving a 419 error when running the Cypress suite. I only have one basic test so far that is passing, but I encounter this error every time I run Cypress on this project. I'm not sure what is causing this as all my configs align to other working projects and I've followed the install instructions for Cypress fairly closely.

I do also have Dusk installed on this project - I was looking into migrating my tests to Cypress. Not sure if that has anything to do with this though.

Any information / help is much appreciated.

Laravel Version: 9.2.0
MySQL Version: 8.0.28 for macos12.0 on arm64 (Homebrew)
Local Server: Laravel Valet

Full error output:

CypressError
cy.request() failed on:

https://myproject.test/cypress/artisan

The response we received from your web server was:

  > 419: Unknown Status Code

This was considered a failure because the status code was not 2xx or 3xx.

If you do not want status codes to cause failures pass the option: failOnStatusCode: false

-----------------------------------------------------------

The request we sent was:

Method: POST
URL: https://myproject.test/cypress/artisan
Headers: {
  "Connection": "keep-alive",
  "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/9.5.0 Chrome/94.0.4606.81 Electron/15.3.4 Safari/537.36",
  "accept": "/",
  "cookie": "__stripe_sid=fd6175c3-f67b-4931-a718-56650879ec7b8c6d69; mAK5jVJ4dA5Ucy0tGAAXovRxxDF4tqzmX3hwEnTD=eyJpdiI6IkZSLzJSVGhkei9rU1NvR2E5dkNVYUE9PSIsInZhbHVlIjoiQ3ZnaCtQejI4UlpUWEJSN2YveWtCSm9oZGFMUmphR0JJSjNNaU5iaWV5bXloaUFnTHFnemFza0Z6TjNBK0p3MlJpWGEvRy83MmN0NG8wNWU1bUp5enlEcEdxUzZjSEF4b3NxcVRNcU1JSWZSOC9uV1Z3RHlsVkY2MEk3Uk1ucjNpdm9neXpDWHNkdlg2UHByTHBVck42bXhzd0p1QzRDSG9BQ1g2Yk5wRzdIK0E2azVHSWwrSjdXaEhmYXFBblF2aFVBNnA2a29VZ3I0aFBtaHFYRXBuWUR0MHlub0ZzZ1BUbWpWcXhDTUliM0p2dWQ4SUVhd1ViL2hjc2gyUmw5RHNTaXF4cVdJL2xudC80MGc0QmNoZ3FLYmJFdlkwVzBEdkdHMTFxc2MvRmh2a2pnNFZQb2Z0UjNpa0NxeDFLR2o1MWQvMWlla0hwR1RrZEVPcHFtMXBvSVVWd3hmVTJ4ZkVyaC9XVTZsbjZ4YWxHWWkveVQ4ZC9sMUVmK052OVcyQUQ3Y0k1WWtIWEVYeDhKMkpWb3JURWo3blRrY0FWNEs5NEUzbENnMFNrb1BQM0F3ZjdMcEk1dWhCRjNNU2UwY1k4aVpneWtCRWNtMVJ3SzBqV2NNcUpvLzNXdzBIYmhiVzZhRUVOSUJiTGludVdEK3dHU1dnZW43OUM4Z3NiS2EiLCJtYWMiOiI2YzRiMzlkZThlZWZhODk5ZGUwOTQ5YzQ5YTg3YjQ1ZjE4MmZjOTEwMjliZDdhM2EzNmQwN2I3N2EzN2U4Y2IwIiwidGFnIjoiIn0%3D; deskninja_session=eyJpdiI6Imd3MnNlaUpvL3FFNjNEb1QvUWYxdnc9PSIsInZhbHVlIjoibUxzS0pKMTVXOHp4Z0dRME1vUEpxQlZJSjBUbjJRL1pVUk9nZ29YVHhxY0w2a3ZNVjk4MDRQTCtKaGlHOHRldlNIR3lPcmxQYVlPR3VVa3lzbXdMWmxCYXNYZk5oTERpanNiMDZ1WVNmQTZiQXhjRzRmWGZhaVp2d3lVZGF5RjciLCJtYWMiOiI4MjU5MTZjZGNhNTllMTRjNjU0ZDQ2Njk2ZTZlZDM4Y2VjMmFjMzk2ZjRlMzI4NmIzMzI5ZDBmZjdkM2M3ZmEzIiwidGFnIjoiIn0%3D; XSRF-TOKEN=eyJpdiI6IjJiU2E2aWNTM25BUXIySDNMSHRFVHc9PSIsInZhbHVlIjoiV3RBeWFKMkxYWVhMd0U5UjhZUWUwdElmQ2pUK09CemR1NjhJTm85UEF5eGZsLzFTb3BxeG55dmdJd2lQTEFTclJhRWNrdTQ2ekpJR1ZBVTB6TTRRV2dib3lESjhnTFlJeCtsMnF0eWdXUFBaZ3pxdE44U2lQdDVRV0tJc3N6T3kiLCJtYWMiOiI2NDI1ZjJkYWY2MWFiZDFmMDAzYTE2YTJkNGI0MjBlMzEyMTQ4MTI0ZmZiNjA3YWJkYjdkNTRiMzdhZDUzOGJhIiwidGFnIjoiIn0%3D; __stripe_mid=bf630cea-98d2-4030-880d-3462df9be84872b377",
  "accept-encoding": "gzip, deflate",
  "content-type": "application/json",
  "content-length": 75694
}
Body: {"command":"config:clear","parameters":{},"_token":"<!DOCTYPE html>\n<html lang="en">\n    <head>\n        <meta charset="utf-8">\n        <meta name="viewport" content="width=device-width, initial-scale=1">\n        <meta name="theme-color" content="#212121">\n\n        <title inertia>DeskNinja</title>\n\n        \n        <link rel="dns-prefetch" href="//fonts.gstatic.com">\n        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap">\n\n        \n        <link rel="stylesheet" href="https://myproject.test/css/app.css">\n\n        \n        <link rel="icon" type="image/png" sizes="32x32" href="https://myproject.test/img/favicon-32-by-32.png">\n\n        \n        <script type="text/javascript">\n    const Ziggy = {"url":"https:\/\/myproject.test","port":null,"defaults":{},"routes":{"debugbar.openhandler":{"uri":"_debugbar\/open","methods":["GET","HEAD"]},"debugbar.clockwork":{"uri":"_debugbar\/clockwork\/{id}","methods":["GET","HEAD"]},"debugbar.assets.css":{"uri":"_debugbar\/assets\/stylesheets","methods":["GET","HEAD"]},"debugbar.assets.js":{"uri":"_debugbar\/assets\/javascript","methods":["GET","HEAD"]},"debugbar.cache.delete":{"uri":"_debugbar\/cache\/{key}\/{tags?}","methods":["DELETE"]},"cypress.factory":{"uri":"cypress\/factory","methods":["POST"]},"cypress.login":{"uri":"cypress\/login","methods":["POST"]},"cypress.logout":{"uri":"cypress\/logout","methods":["POST"]},"cypress.artisan":{"uri":"cypress\/artisan","methods":["POST"]},"cypress.run-php":{"uri":"cypress\/run-php","methods":["POST"]},"cypress.csrf-token":{"uri":"cypress\/csrf_token","methods":["GET","HEAD"]},"cypress.routes":{"uri":"cypress\/routes","methods":["POST"]},"cypress.current-user":{"uri":"_cypress...

-----------------------------------------------------------

The response we got was:

Status: 419 - Unknown Status Code
Headers: {
  "server": "nginx/1.21.6",
  "content-type": "text/html; charset=UTF-8",
  "transfer-encoding": "chunked",
  "connection": "keep-alive",
  "x-powered-by": "PHP/8.1.2",
  "cache-control": "no-cache, private",
  "date": "Thu, 24 Feb 2022 20:51:44 GMT",
  "set-cookie": [
    "deskninja_session=eyJpdiI6ImpPVnljeHk2ZllBcUY0REU4c3pwNEE9PSIsInZhbHVlIjoiSWpwNzlZOVpKUXhoL2txL0w0MGsydllrbGloUDRLNkZDejR0eEhuQzZaOWxOcEFRbzRzZXNOaGtLWW05Q3BFdEVKZlFDUTlIai8wbzJvaDQ2emMwN081MjlJSlhBQkhNR2xJYit6KzVTZFZDa3NtRjQxN294U2I2djZONlFmOEMiLCJtYWMiOiIxNWVmNjg3ZDA2ZDRlMzU1OWRlNzljOWJjNTk4YmQxNDAzODA5Yjc0ZTE2ODI2NWY4ZTE0ZmE2YmZiMTIzZmQ1IiwidGFnIjoiIn0%3D; expires=Sat, 26-Mar-2022 20:51:44 GMT; Max-Age=2591999; path=/; httponly; samesite=lax",
    "mAK5jVJ4dA5Ucy0tGAAXovRxxDF4tqzmX3hwEnTD=eyJpdiI6IkM0RGM1RTJsdy9SWGM3bDZNQXYyaHc9PSIsInZhbHVlIjoiVEJ2QnJrMU5weDhtamgwYXpsRllzRjJGZHNwTjlMRlFnT3JuU1RUZlYxMjBOZEpKcHJTUm8rYkxxdXlaS2JhZWJIcXlZOWUzclFpVmNVRTNvM2RZRjJyZ0IzR0ZUNFpWeXoxRUp6TUx3SVI0eTJwTTcxamxRcVB3emYyaGFmZ2JEOW9LdGl2VnhQRzVMbFFiZ2dERmljY29JMkJ4c1ZNZ29PbW9BZHNQOTVxMldGL2xTbVVibVVkVElrK1prMzc0d1NieHRJY1VrbHJjQU40NmhRSy8rSGN4elFyWU9NSTNzd0lKelViZFduRDFJSWlPaWNFQjNKSkRJK051QmhoeXJqWHRramVxK2hQMFAzQUN3WStqWGZuczI5NmtqbzFoMzNrZEJGMFdYMDVDdTFvRnV2TFlKN2g4aXplUkgwclZPNFh6VDM1SlkwdFY0L0NZSG9LS3NVbGFVaGNwbURWVmRkcitKbjNZUktYdlQySS9vUFhYU3RCdmVhUjIrcVQ5YU9xMk8rRUlhTzlTdWZGd2NlUHhtbWsxNTd5S0E3WnE2YWl0QlltVTFJOU9uVWdyZ05kUEJpM0N2dkoySkkvcUl4a0JvYzEzQkZ1dmwzazJadCtiakxiQVJQdTJCUEJ3TjNzN3p2bUhwVzRJODRralJkeTB3SmtmSDIvN25PN3QiLCJtYWMiOiJiNGNmYjIyYjI1MmQ0NjJkOTI5ZGExODgwZDEzM2VlZDY2MGE5MTgyYmFiNGNhZTM2ZmJlOTc4YWM2OGJkZmI0IiwidGFnIjoiIn0%3D; expires=Sat, 26-Mar-2022 20:51:44 GMT; Max-Age=2591999; path=/; httponly; samesite=lax"
  ]
}
Body: <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Page Expired</title>

        <!-- Fonts -->
        <link rel="dns-prefetch" href="//fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

        <style>
  /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css /html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5},:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-medium{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5...


Because this error occurred during a after all hook we are skipping all of the remaining tests.[Learn more](https://on.cypress.io/request)
[tests/cypress/support/laravel-commands.js:261:19](https://myproject.test/__/#)

Laravel route "login" does not exist.

I'm using Cypress 10, which may be relevant, and version 2.2.1 of this package.

I have a simple test to check the login form works

describe('Login', function () {
    it('redirects to the home page once logged in', function () {
        cy.visit({route: 'login'})
            .get('#email').type('[email protected]')
            .get('#password').type('password')
            .get('[type="submit"]').click()
            .url().should('eq', Cypress.config().baseUrl + '/');
    });
});

The test passes, but I get the message Laravel route "login" does not exist.

Screenshot 2022-06-04 at 15 31 05

It clearly exists so I'm not sure what is that about. Besides, the message in an assertion and it's green, which indicates it's not an error (which is correct).

Could it be that maybe the package is trying to assert the route exist rather than it doesn't?

Caching problems with `config:clear` in cypress/support/index.js

cy.artisan('config:clear', {}, { log: false });

I was having problems with Laravel using fallback DB credentials randomly instead of my .env. This results in 500 Errors when trying to get the csrf token, for example. Once I changed these lines from

cy.artisan('config:clear', {}, { log: false });

to

cy.artisan('config:cache', {}, { log: false });

everything seemed to be working. Is there anything I'm missing?

Strange issue with .env configurations

Hello!

Thank you very much for this amazing contribution!

I've been coming across a really strange issue which I'm not being able to debug..
For some reason, when booting Cypress and doing the before() JS callback, when it clears out the config it's placing information which isn't anywhere to be seen.

It's auto-injecting forge for database username and database name, as well as hard-setting my environment to production, which is causing some issues with my tests.

Has anyone had this issue?

Thank you!

Problem using .env.cypress

I can see that activateCypressEnvFile runs, but when running tests, values are always picked from the original .env file.

I have a an APP_ENV check in my routes file and I can confirm it'll only print out the .env value in artisan dump-server, never .env.cypress.

Anyone had a similar issue? Any ideas?

Thanks.

index.js is importing non existing ./commands Module

In the boilerplate code in support/index.js, the file is importing a non existing Module: ./commands

I removed this in my app and webpack errors for that went away.

Is there any reason why this is being imported? If not, I would be happy to submit a pr fix.

In cypress/support/index.js:

Current:

import './commands'; // Import of non existing Module:
import './laravel-commands';
import './laravel-routes';
import './assertions';

before(() => {
    cy.task('activateCypressEnvFile', {}, { log: false });
    cy.artisan('config:clear', {}, { log: false });

    cy.refreshRoutes();
});

after(() => {
    cy.task('activateLocalEnvFile', {}, { log: false });
    cy.artisan('config:clear', {}, { log: false });
});

Webpack Errors generated:

Error: Webpack Compilation Error
./cypress/support/index.js
Module not found: Error: Can't resolve './commands' in 'C:\laragon\www\quickinventory\cypress\support'
Looked for and couldn't find the file at the following paths:
[C:\laragon\www\quickinventory\cypress\support\commands]
[C:\laragon\www\quickinventory\cypress\support\commands.js]
[C:\laragon\www\quickinventory\cypress\support\commands.json]
[C:\laragon\www\quickinventory\cypress\support\commands.jsx]
[C:\laragon\www\quickinventory\cypress\support\commands.mjs]
[C:\laragon\www\quickinventory\cypress\support\commands.coffee]

using the php command

I am having mixed results with the cy.php command bundled with this library. I'll often get this error:

CypressError: Timed out retrying after 4000ms: cy.its()errored because the property:result does not exist on your subject.

Which I had deduced was happening due to the php I am executing not returning a value, but that assumption has been challenged a bunch of times to the point where I really have no idea what that error represents.

Is there a particular interface I should be adhering to when using the cy.php command and when returning data from the php I am executing therein?

Unable to Locate Factory

I'm getting this error
InvalidArgumentException: Unable to locate factory for [App\User]. in file

From login_spec.js file containing

    before(() => {
        cy.refreshDatabase().seed();

        cy.create("App\\User", {
            first_name: "First",
            last_name: "Last",
            email: "[email protected]",
            password: "password",
        });
    });

I'm able to get past the error if I comment out the following in CypressController.php

    protected function factoryBuilder($model)
    {
        // Should we use legacy factories?
        // if (class_exists('Illuminate\Database\Eloquent\Factory')) {
        //     return factory($model);
        // }

        return (new $model())->factory();
    }
}

Has anyone else come across this?

My project has the following dependencies

  • php: ^7.4
  • laravel/legacy-factories: ^1.1
  • cypress: ^7.2.0
  • laracasts/cypress: ^1.3
  • laravel/framework: ^8.0

Error occurs with or without laravel/legacy-factories: ^1.1

Global installation of Cypress

Hello,

Anyway to handle Cypress installed globally?
I have a prebuilt devcontainer shared across the team where cypress is installed globally, so it is available for any type projects, and I can use that same container in the pipeline.
But here it assumes Cypress is installed locally.

Thanks,

Use the models that were just created

Hello everyone,

I'm new to Cypress and I want a test that a user can see its projects after signing in.

I tried to save the user, but this does not work:

it('can see its projects', () => {
    let user = cy.login()
    let project = cy.create('App\\Models\\Project', { user_id: user.id })
    cy.visit('/home').contains(project.name)
})

However, this does work:

it('can see its projects', () => {
    cy.login().then(user => {
        cy.create('App\\Models\\Project', { user_id: user.id }).then(project => {
            cy.visit('/home').contains(project.name)
        })
    })
})

Is the last one the only way to do this, or are there other ways to save the just created models?

Receiving error: http://localhost:8000/cypress/artisan - 419: Unknown Status Code

I'm running into this error when trying to run Cypress.

cy.request() failed on:

http://localhost:8000/cypress/artisan

The response we received from your web server was:

> 419: Unknown Status Code

This was considered a failure because the status code was not 2xx or 3xx.

If you do not want status codes to cause failures pass the option: failOnStatusCode: false

Has anyone encountered this? Any thoughts on how to get around it?

[Feature][Documentation] Execute more complex php

I had a need to add more complex helpers during the setup phase to assist in generating additional users, admins, etc prior to the test running.

For example, I have the need to test that one admin cannot edit another admin user. For this, I need to seed two users into the database and check that one does not have access to edit the other. Was considering copying the service provider structure used by this package like so:

class CypressHelperServiceProvider extends ServiceProvider
{
    public function boot()
    {
        if ($this->app->environment('production')) {
            return;
        }
        $this->addRoutes();
    }


    protected function addRoutes()
    {
        Route::namespace('')
            ->middleware('web')
            ->group(base_path('Tests/Cypress/routes/cypress_helpers.php'));
    }
}

Then in the route area

return [
    // Create new admin user and assign all permissions
Route::post('/__cypress__/createAdmin', [CypressHelperController::class, 'createAdmin'])->name('cypress.create.admin'),
    // Login via a given email address
    Route::post('/__cypress__/loginByEmail', [CypressHelperController::class, 'loginByEmail'])->name('cypress.login.email'),
    // Login via a given ID
    Route::post('/__cypress__/loginById', [CypressHelperController::class, 'loginById'])->name('cypress.login.id'),
];

Then in AppServiceProvider.php

 public function register()
    {
        if (config('app.env') !== 'production') {
            // Other service providers
            $this->app->register(CypressHelperServiceProvider::class);
        }
    }

Directory like so:

image

Example Controller

use Laracasts\Cypress\Controllers\CypressController;
use Spatie\Permission\Models\Permission;

class CypressHelperController extends CypressController
{
    public function createAdmin(Request $request)
    {
        $user = factory($this->userClassName())
            ->create($request->input('attributes', []));
        $user->setRole('admin');
        auth()->login($user);
        return $user;
    }

    public function loginByEmail(Request $request)
    {
        $user = User::find(['email' => $request->get('email')]);
        auth()->login($user);
        return $user;
    }

    public function loginById(Request $request)
    {
        $user = User::find($request->get('id'));
        auth()->login($user);
        return $user;
    }
}

Does this appear to be the correct approach for handling this requirement? If so, I can contribute some documentation to help others or update the package to publish some of these assets so users can just drop in their more complex requirements.

Timeout when running `cy.refreshDatabase()`

I am adding Cypress to a very large repository that has 700+ migrations. As a result, the migrate command takes a while to run. If I set up a basic test like this:

describe('Example Test', () => {
    before(() => {
        cy.refreshDatabase();
    });
});
When I run this test, it hangs for ~30 seconds and returns me:

cy.request() timed out waiting 30000ms for a response from your server.

The request we sent was:

Method: POST
URL: http://evaluagent.test/cypress/artisan

No response was received within the timeout.

In my cypress.config.js file, I have tried to use longer timeouts but these are ignored:

const threeMinutesInMiliseconds = 180000;

module.exports = defineConfig({
    chromeWebSecurity: false,
    retries: 2,
    defaultCommandTimeout: threeMinutesInMiliseconds,
    responsetimeout: threeMinutesInMiliseconds,
    requestTimeout: threeMinutesInMiliseconds,

Have I set something up wrongly? I followed the instructions in the readme of this page.

Feature request: factory state

Would be handy to have factory states like:

 cy.create('App\\Models\\Proposal', {}, 'with-comments')

Maybe a param list like:

Cypress.Commands.add('create', (model, times = 1, attributes = {}, state) => {

}

Calling Login() a second time does not work

Whenever I call Login() a second time on a different user, it does not login as expected. Calling login() a second time on the same user works just as expected. Why is this small test case not logging in as expected?

describe('empty spec', () => {

  beforeEach(function () {

    cy.create({model: 'App\\Models\\User', state: {'representative':[],}}).as('regularUser1')
    cy.create({model: 'App\\Models\\User', state: {'representative':[],}}).as('regularUser2')

  });

  it('Example Test Case', function () {
    cy.visit('/')
    cy.login({id:this.regularUser1.id})
    cy.visit('/')
    cy.url().should('contain', '/dashboard') // this works
    cy.logout()
    cy.visit('/')
    cy.login({id:this.regularUser2.id})
    cy.visit('/')
    cy.url().should('contain', '/dashboard') // this fails, will be redirected to the login page instead
  })
})

Migrating packages

I attempted to make a user factory but spark specific columns were not found
I moved the spark migration files to the project database/migrations and it works

Class "App\User" not found

Hi,

First time using this package, I'm on Laravel 9.

I have the pre-built User model in App\User, so I did this to try and create a user in my test:

describe('workouts index', () => {
  it('allows us to see a list of workouts', () => {
    cy.create('App\\User', { attributes: { email: '[email protected]' }});
  });
});

But I get an error in Cypress:

Error: Class "App\User" not found in file /home/jamesking56/PhpstormProjects/<project>/vendor/laracasts/cypress/src/Controllers/CypressController.php on line 124

Any ideas what I'm doing wrong here?

Typescript support

Hi!

Wondering if there's a way to get typescript support for the custom commands?

I'm savvy enough to get it working with Cypress but not enough to register the information, if some one can point me in the right direction I'll try and add something to the docs or the repo about getting it working.

Thanks!

Screen Shot 2022-06-23 at 3 10 51 pm

PUT requests do not work

Hi,

I have a route which accepts PUT only which I'd like to call in my Cypress test but it doesn't seem to work when I use cy.visit():

cy.visit({ route: 'my-route', params: { comment: 1 } });
```

I get this error:

```
CypressError: `cy.visit()` was called with an invalid method: `PUT`. Method can only be `GET` or `POST`.
```

Issue with artisan route

I just wanted to give Cypress a try; I need to add some integration tests to an existing Laravel 9 project (which uses Livewire, if that makes a difference).

I'm developing on a Windows 10 (21H2) system with XAMPP 8.0.5.

I installed Cypress 10.3.0 and laracasts/cypress 3.0.0 as described (copy & paste). When I try to run the example spec (or any other basic spec), an error occurs:

CypressError: cy.request() timed out waiting 30000ms for a response from your server.

The request we sent was:

Method: POST
URL: https://www.efa2021.test/__cypress__/artisan

No response was received within the timeout.

Because this error occurred during a after all hook we are skipping all of the remaining tests.

Although you have test retries enabled, we do not retry tests when before all or after all hooks fail
at https://www.efa2021.test/__cypress/runner/cypress_runner.js:158491:78
From previous event:
at Context.request (https://www.efa2021.test/__cypress/runner/cypress_runner.js:158490:15)
From Your Spec Code:
at Context.eval (https://www.efa2021.test/__cypress/tests?p=tests\cypress\support\index.js:455:15)

The artisan route seems to have a problem; when I remove

cy.artisan('config:clear', {}, { log: false });

from the tests/cypress/support/index.js (both lines), the test passes.

cy.exec('php artisan config:clear');

works, so calling artisan is no general problem.

I'm not sure if it is connected, but on the console where I started Cypress, the line

[37252:0703/093736.462:ERROR:gpu_init.cc(446)] Passthrough is not supported, GL is disabled, ANGLE is

can be found between the access log lines, and yes, the text is cropped at the end.

I tried testing with Chrome and Electron.

Could this be a Windows- or XAMPP-specific issue? I couldn't find anything about this problem.

Any help would be greatly appreciated!

Alternative factory syntax proposal

proposed parameter syntax using object keys:

cy.create({
    model: 'App\\Models\\Post',
    fill: {title: 'I override factory default'},
    with: ['author'],
    state: ['published'],
    count: 50
}).then(post => {

})

The current parameter list

cy.create('App\\Models\\Post', { title: 'I override factory default' }, ['author']);
  • Allows stacked parameters for more readable parameter list
  • Allows more obvious parameters via object keys, with returns the relation
  • Avoids 4th parameter for a much needed factory state or count parameter

Additionally would love if cy.visit automatically detects an object and uses id

{ route: 'posts.show', post } becomes {route: 'posts.show', parameters: { post: post.id } }

cy.create({
    model: 'App\\Models\\Post',
}),then(post => {
    cy.visit({ route: 'posts.show , post})
});

Improve safety of environment check

Currently, our service provider checks the environment and disables everything if it is production.

if ($this->app->environment('production')) {
return;
}

This is probably fine for most situations, but one of my projects uses "prod" instead of "production". I think we should reverse this logic to only permit cypress testing in given environments, rather than prohibiting it. This would be more flexible, and would be a safer default that protects against values other than "production".

If approved, I'll put together a PR that changes the following.

- if ($this->app->environment('production')) {
+ if (in_array($this->app->environment(), explode(',', env('CYPRESS_ENVIRONMENTS')))) {
     return;
  }

This will give us more control with our environment files

CYPRESS_ENVIRONMENTS=local,testing

Unfortunately though, this is a breaking change. But given the gotcha I encountered of 'prod' != 'production' and how serious the security implications would have been, I think it is worth it. One option however to avoid the breaking change is to only apply this logic if a CYPRESS_ENVIRONMENTS value exists, and otherwise fall back to assume "production". Either way, the documentation should still be updated to improve awareness of environment names.

Laravel Nova login Issue and possible fix

Hey @JeffreyWay

Today were having a bad time trying to log in on Nova using Cypress. We were having constantly a 419 Page expired error.

After several hours of research and trial and error we fixed it adding this code to the before hook in support/index.js

Cypress.Cookies.defaults({
        preserve: ["XSRF-TOKEN", "laravel_session", "remember_token"]
});

Cypress clears all cookies before each test (https://docs.cypress.io/api/commands/clearcookies.html#).

Do you think it worths creating a PR for that or is it just a specific case that should be added to the docs?

Thanks!

CypressError: cy.its() only accepts a single argument.

I've just setup using this package, and am receiving the above error message when I try to invoke one of the Laravel integration commands. The source of the error is in the laravel-commands.js, when the CSRF Token is retrieved. It currently reads:

Cypress.Commands.add('csrfToken', () => {
    return cy
        .request({
            method: 'GET',
            url: '/__cypress__/csrf_token',
            log: false,
        })
        .its('body', { log: false });
});

If I remove the { log: false } argument to its the command works successfully.

Of course I can get it to work this way, as I can simply remove this option specification in my published copy of the commands (I am assuming I will have this issue across the board where this pattern is used).

I am posting this as information for others, but also to see if anyone else has seen this and if there's a better solution to the problem?

I am using the official docker containers for cypress for actually invoking my tests (rather than a local install of cypress), but I don't believe that should be having an impact.

Bit new to cypress though, so very aware that I could be missing a subtlety in the setup.

500 and 404 HTTP Errors after setup

I'm running this package inside a Laravel 8 application with Sail.

The tests very sporadically tend to pass then after re-running them they fail with the following error messages.

cy.request() failed on:

http://digiam.test/cypress/artisan

The response we received from your web server was:

  > 500: Internal Server Error

Screenshot 2021-09-09 at 17 25 50

I also occasionally get 404 errors.

I've noticed that the routes are registered as :
__cypress__/artisan and __cypress__/csrf_token but cypress seem to try to access /cypress/artisan and cypress/csrf_token

My only test file under integration/patients is

describe('Creating a new patient', () => {
    beforeEach(() => {
        cy.login({ email: '[email protected]' })
    })

    it('works', () => {
        cy.visit({ route: 'patients.create' }).contains('Create a new patient')
    })
})

The wildcard for routes RegExp fails on optional parameters

Right now the RegExp for wildcard parameters requires the wildcard to be exact

Using your example:

 cy.visit({
        route: 'team.dashboard',
        parameters: { team: 1 }
});

This will replace following
/teams/{team}/dashboard to /teams/1/dashboard

What if you have a route that have optional parameters

 cy.visit({
        route: 'team.dashboard.style',
        parameters: { team: 1, style: 3 }
});

/teams/{team}/dashboard/{style?} to /teams/1/dashboard/%7Bstyle%7D

laravel 9 - problem with CSRF TOKEN

Hi.
I've got problem on start.
When I run example test, I've got:
Screenshot_2

The request we sent was:

Method: GET
URL: http://127.0.0.1:8000/cypress/csrf_token
Headers: {
"Connection": "keep-alive",
"user-agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
"accept": "/",
"accept-encoding": "gzip, deflate"
}

What should I do ?

Testing with Sail

Hey @JeffreyWay,

Another great package, thanks.

I just wanted to share my journey into getting to work this with Laravel Sail. We can add this to the Readme.md, adding configurations during the scaffold might be a bit of an overkill.

Follow the Installation and Environment Handling sections in Readme.md

Edit: cypress/support/index.js to stop the swapping of the .env files

before(() => {
    // cy.task('activateCypressEnvFile', {}, { log: false });
    // cy.artisan('config:clear', {}, { log: false });

    cy.refreshRoutes();
});

after(() => {
    // cy.task('activateLocalEnvFile', {}, { log: false });
    // cy.artisan('config:clear', {}, { log: false });
});

Run sail using .env.cypress

sail --env-file .env.cypress up


If you want to run tests on a separate database follow the rest of this guide.


Create a separate database

Sail does not provide sqlite, there might be a way to install it and configure it but I didn't find anything.

Credit to: https://michaelheap.com/laravel-sail-test-database/

Edit .env.cypress

DB_CONNECTION=mysql
DB_HOST=mysql_test
DB_DATABASE=
DB_USERNAME=root

Edit docker-compose.yml to create a new database

services:
   mysql_test:
        image: "mysql:8.0"
        environment:
            MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
            MYSQL_DATABASE: "${DB_DATABASE}"
            MYSQL_USER: "${DB_USERNAME}"
            MYSQL_PASSWORD: "${DB_PASSWORD}"
            MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        networks:
            - sail

[Question/Issue] Working with Livewire component

Hi,

when I try to type some text into a Livewire component, I somehow get immediately disconnected.
I can see in the console that the route for the component gets hit, and a 419 Unknown response is returned, which disconnects the user.

Please see the screenshot for details.

Screenshot 2020-10-14 at 18 49 41

Did I forget something in the configuration?

thanks

There are no commands defined in the "cypress" namespace.

I'm getting a There are no commands defined in the "cypress" namespace. error after installing and trying to run the cypress:boilerplate command.

Already tried this:

php artisan config:clear
php artisan cache:clear
composer dump-autoload

Assertion proxy for phpunit & http assertions

Firstly, awesome package! Really enjoying the quick familiarity it brings my laravelian brain.

I was curious about the possibility of magic methods that just send to php

cy.php(`assertOk()`).then(outcome => {
    expect(outcome).to.equal(true); 
});

Like behind the scenes it makes phpunit calls & asserts outcomes behind a helper method

Maybe pestphp would help since it's syntax is similar, not super familiar with it.

Would be a cool way to avoid duplicating all the stuff.

osx big sur upgrade broken support/routes.json file

Since I upgraded OSX today the routes.json file is being populated with the home page html and not the json object containing the routes.

Site is running on vagrant and cypress on osx.

Any suggestions gratefully received.

AWS mock or stub functions

Hi guys, i'm trying to test a peace of system that submit a form there is some files to upload directly to our S3 bucket. But i need to mock or stub the function that putobject on this bucket. Anyone knows how can i do this?

I'm using laravel nova.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.