Someone any one?
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.
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?
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?
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.
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
Does any other artisan command work when called from that route?
Does the artisan dusk command work when called from the command line?
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.
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.
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.
Hi Mike
Is there something I should add to a file to get this to work?
What ya think @MikeHopley
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!
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.
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.
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!
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?
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
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
Any ideas @MikeHopley
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.
Update. Maybe this will help some one else. I was able to get this to work by adding the Symfony Process Component/Package
https://symfony.com/doc/current/components/process.html Works like a charm now.
Thanks @dk4210. That really helped me out. Was searching for this solution.
Hi, did this worked for you @dk4210 ? Can you please give an example? Thanks
@dk4210 @bkkrishna would you guy please share your code working? No luck here ?
Thanks!!
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();
});
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.
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.
@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?
Hello, please @someone_01 could you show us the full code.
Please or to participate in this conversation.