cypress icon indicating copy to clipboard operation
cypress copied to clipboard

Issue with artisan route

Open enigmatic-user opened this issue 2 years ago • 3 comments

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!

enigmatic-user avatar Jul 03 '22 08:07 enigmatic-user

@enigmatic-user do you have the web server running?

For example I have this command in my package.json

"test:e2e": "php artisan serve -q --env=cypress & cypress open --e2e --browser chrome",

and this in my cypress config cypress.config.ts

import { defineConfig } from "cypress";

export default defineConfig({
    e2e: {
        baseUrl: "http://127.0.0.1:8000",
    },
});

i-bajrai avatar Jul 05 '22 23:07 i-bajrai

@i-bajrai Thank you for your reply!

Yes, XAMPP (Apache) is always running on my system; when I remove the artisan calls, the tests work, but of course I can't use anything that uses artisan.

I have defined a local domain and added an entry in the hosts file so I can call the site using https://www.efa2021.test/. The baseUrl is defined in the cypress.config.js (laracasts/cypress add this entry when executing php artisan cypress:boilerplate).

I haven't tried using php artisan serve and the localhost URL yet - I rely on XAMPP. Hopefully I'll find some time to test it this evening.

enigmatic-user avatar Jul 06 '22 03:07 enigmatic-user

@enigmatic-user I was receiving the same error when trying to use the cy.refreshDatabase() command (which uses cy.artisan() under the hood).

I did however manage a workaround, by adding a route and controller action specifically for the command I wanted. Currently this is editing the package files in the vendor directory, but it probably wouldn't be too hard to extract it to its own controller until it gets fixed. I've been able to run tests without issue (thus far) on my set up (Laravel Homestead on Windows).

  • Edit or add a command in the tests\cypress\support\laravel-commands.js to call a new route
  • Add a new route (here it's in vendor\laracasts\cypress\src\routes\cypress.php, but perhaps a check with app()->environment() in the main routes file to only register if the environment matches the cypress test environment)
  • Add a new action in a controller to directly call the Artisan command (again, here it's shown in vendor\laracasts\cypress\src\Controllers\CypressController.php but it could be a new Controller which you control)

Sidenote: I have no idea why this works, since it does basically the same thing except skips parsing the command portion.

tests\cypress\support\laravel-commands.js

Cypress.Commands.add("refreshDatabase", (parameters = {}, options = {}) => {
-    return cy.artisan("migrate:fresh", options);
+    return cy.csrfToken().then((token) => {
+       return cy.request({
+            method: "POST",
+            url: "/__cypress__/refresh-database",
+            body: { parameters: parameters, _token: token },
+           log: false,
+        });
+    });
});

vendor\laracasts\cypress\src\routes\cypress.php

Route::post('/__cypress__/refresh-database', [CypressController::class, 'refreshDatabase'])
    ->name('cypress.refresh-database');

vendor\laracasts\cypress\src\Controllers\CypressController.php

public function refreshDatabase(Request $request)
{
    Artisan::call('migrate:fresh', $request->input('parameters', []));
}

ignium559 avatar Jul 18 '22 01:07 ignium559