Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dk4210's avatar

Invoking the Artisan Dusk command outside the CLI

Hello Guys,

I can't seem to figure out how to run the Artisan Dusk Command via route.

I have the following but doesn't work

Route::get('/logintest', function() 
{
     Artisan::queue('command:dusk);
});

Please advise.

0 likes
29 replies
MikeHopley's avatar

Hmm, not sure that idea is going to work.

Dusk runs a Chromedriver process from the command line. I would not expect this to execute if invoked from a browser -- if nothing else, the browser should not have privileges to run arbitrary software!

What are you trying to achieve, more generally?

dk4210's avatar

Hi @MikeHopley

What I'm trying to achieve is I'm building an app that requires users to login and after login they will be directed to an Automated testing area. I was hoping to have a link when clicked on it calls the dusk test, therefore open a browser and starts the test. I'm gong to have the options for headless tests also, but wanted this to work. Any suggestions?

MikeHopley's avatar

Oh, right -- interesting!

You said it doesn't work, but what error message do you get (if any)?

I would start by removing the queue, as it's an unnecessary complication at this stage. It also looks like you're calling a command that doesn't exist. Try this:

Route::get('/logintest', function() 
{
     Artisan::call('dusk');
});

The other problem is that, even if this does somehow work, I don't think the user will see it -- because the process will run on your server, not on their local machine.

dk4210's avatar

Hi @MikeHopley

I'm still having the issue. When I add it to the web.php file and verify that the route is correct, this is what i get.


(1/1) CommandNotFoundException
Command "dusk" is not defined.
in Application.php (line 579)
at Application->find('dusk')
in Application.php (line 204)
at Application->doRun(object(ArrayInput), object(BufferedOutput))
in Application.php (line 130)
at Application->run(object(ArrayInput), object(BufferedOutput))
in Application.php (line 141)
at Application->call('dusk', array(), null)
in Kernel.php (line 220)
at Kernel->call('dusk')
in Facade.php (line 221)
at Facade::__callStatic('call', array('dusk'))
in web.php (line 17)
at Artisan::call('dusk')
in web.php (line 17)
at Router->{closure}()
in Route.php (line 190)

Any ideas.

Thanks, Dan

MikeHopley's avatar

Does any other artisan command work when called from that route?

Does the artisan dusk command work when called from the command line?

dk4210's avatar

Actually it does. I tested that with the make:controller and it worked fine. I also noticed that dusk is listed in the artisan list but wont work from a controller or route. Seems like there is another setting somewhere that has to be updated to make this work. Surely, some one else has fired a test script from the UI.

dk4210's avatar

Here is a sample that works

Route::get('runtests', function() 
{
    echo '<br>init Dusk...';
    Artisan::call('make:controller', [ 'name' => 'myController' ]);
    echo 'done dusk';
});

This successfully creates a controller.

MikeHopley's avatar

Okay, I just tried it myself -- running Artisan::call('dusk') from a web route.

I did not get the same error. Instead, I got a timeout after 30 seconds:

(1/1) FatalErrorException
Maximum execution time of 30 seconds exceeded
in OutputStyle.php (line 83)

Surely, some one else has fired a test script from the UI.

Yes, I do that for several tests.

dk4210's avatar

Hi Mike

Is there something I should add to a file to get this to work?

MikeHopley's avatar

Afraid I don't know, sorry.

Even though I'm getting a more sensible error, it's still not working for me.

And as I mentioned earlier, I don't think it's going to work, no matter what. :( Good luck though!

dk4210's avatar

Well how else can you build a test ui interface instead of going to the command line everytime. Can't accept that there isn't a way to accomplish this.

MikeHopley's avatar

Well how else can you build a test ui interface instead of going to the command line everytime. Can't accept that there isn't a way to accomplish this.

I'm not saying it's an impossible task, but it might be impossible with the systems you are using. But maybe I haven't understood it properly.

I think this is what you are trying to do:

  • The user is on your website, in their browser
  • They visit a web page (a route)
  • The route invokes Dusk

The problem is that Dusk will not be running on the user's computer, it will be running on your server. This means the user will never see the Dusk tests running in the browser.

Do you want them to see the tests running in the browser, or is it sufficient to just see the result of the tests (e.g. "5 tests passed")?

If the latter, then it might work. You would need to find a way to pass the console output of Dusk back to the browser.

It might be worth looking into how this works with continuous integration and headless browsers.

dk4210's avatar

Hi Mike,

If I can get it to preform the test and pass the results back and forth that would work fine, I know that selenium will work for loading the browser because I've seen it done before. I was just hoping I could get dusk to work the same way.

I just need it somehow kick off the tests via the route or controller.

Thanks!

MikeHopley's avatar

Okay, that sounds achievable then. :)

The first puzzle is why you are getting such a strange error (the error I get seems more expected).

Have you tried doing this with a fresh install of Laravel?

dk4210's avatar

So I found that I needed to remove this if statement from DuskServiceProvider.php

"if ($this->app->runningInConsole()) {"

Now when I just run this

 $_SERVER['argv'] = []; 
    echo '<br>init Dusk...';
    Artisan::call('dusk');
    echo 'done dusk';

Nothing happens. Seems as the test never runs. I'm now trying to figure out how to make it call a certain test like this

 $_SERVER['argv'] = []; 
    echo '<br>init Dusk...';
    Artisan::call('dusk:',['tests/Browser/MyTestHeadless.php']);
    echo 'done dusk';

When I run this I get this error

(1/1) CommandNotFoundException
Command "dusk:" is ambiguous.
Did you mean one of these?
dusk:install Install Dusk into the application
dusk:make Create a new Dusk test class
dusk:page Create a new Dusk page class

Every inch i get closer

dk4210's avatar

Update - if I add the dd like this

$_SERVER['argv'] = []; 
    echo '<br>init Dusk...';
    Artisan::call('dusk');
    dd(Artisan::output());
    echo 'done dusk';

I get this


Warning: TTY mode is not supported on Windows platform.\r\n
Could not open input file: vendor/phpunit/phpunit/phpunit\n

MikeHopley's avatar

The "TTY mode not supported" message is the first thing that Dusk outputs to the console on Windows. It seems this is not a real issue. This suggests you have succeeded in running Dusk.

No idea about the second line (phpunit), which looks like a genuine error. Obviously it's having problems finding phpunit, but why? That appears to be the correct location.

louposk's avatar

Hi, did this worked for you @dk4210 ? Can you please give an example? Thanks

bkkrishna's avatar

Here's my implementation @KEEFOX_CHECKED_FLAG_FALSE :

use Symfony\Component\Process\Process;
use Illuminate\Support\Facades\Artisan;
use Symfony\Component\Process\Exception\ProcessFailedException;

Route::get('/', function () {
    $process = new Process('cd .. && php artisan dusk --group=bkkrishna');
    $process->setPTY(true);
    $process->run();

    if (!$process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }

    echo '<pre>'.$process->getOutput();
});
SomeOne_01's avatar

You were almost there. I have a Custom DuskCommand, like this:

class CustomDuskCommand extends DuskCommand {
    protected function binary() {
        return [PHP_BINARY, base_path().'/vendor/phpunit/phpunit/phpunit'];
    }
}

That will fix the problem where it cannot find the phpunit binary. To load that command, I use the AppServiceProvider, but you can make your own if preferred. with this specific command:

if(!$this->app->runningInConsole()) {
    $_SERVER['argv'] = [];
    $this->commands([
        StplusDuskCommand::class
    ]);
}

The DuskCommand is added to Artisan. Then you can simply use Artisan::call to call dusk.

ivanmiranda's avatar

I've been following this discussion cause I was interested in doing something similar. I've tried this and also seems to work:

        $pathToArtisan = 'C:\xampp\htdocs\k24';
        
        echo exec("cd $pathToArtisan && php artisan dusk");

In case it helps.

mmelo's avatar

@ivanmiranda where do you put that code? can you pleashe show me how you do it? and @bkkrishna i tried your code but i have the following error:

'php' is not recognized as an internal or external command

can you know why?

Please or to participate in this conversation.