Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dusk env file not working with artisan serve #162

Closed
renedekat opened this issue Mar 1, 2017 · 14 comments
Closed

Dusk env file not working with artisan serve #162

renedekat opened this issue Mar 1, 2017 · 14 comments

Comments

@renedekat
Copy link
Contributor

When running php artisan serve and then in another terminal php artisan dusk, the env file isn't loaded properly.

I think Dusk should launch php artisan serve after copying the Dusk specific .env file, and then kill the process afterwards.

@SebastianS90
Copy link
Contributor

Make sure that you do not cache the configuration, i.e. run php artisan config:clear before starting dusk. Otherwise you will have cached configuration based on your normal .env file and .env.dusk will be ignored.

@deleugpn
Copy link
Contributor

deleugpn commented Mar 2, 2017

I like the thought of having dusk serving the application automatically instead of having to do this manually. Perhaps something to be done at DuskTestCase?

@SebastianS90
Copy link
Contributor

@deleugpn you mean that you do not wan't to run php artisan serve manually?
Dusk expects you to have a running webserver at APP_URL, this can be:

  • a php artisan serve development server
  • Laravel Valet serving your app on app.dev
  • Your staging environment using nginx with a configuration similar to your production environment. This allows for browser tests to run against your real-world environment and you might find bugs that are not present on your development machine. Pretty cool!

The only situation where it might actually be useful to have a webserver booted up by Dusk itself is if that will make mocks usable in Dusk test cases. But that is not possible so far. See also the discussion in #152.

@deleugpn
Copy link
Contributor

deleugpn commented Mar 3, 2017

Yes, that's exactly what I mean. I work on centos. Since Google Chromw doesn't support Red Hat, I installed a Ubuntu server headless just to run the tests. My activities in this machine is:

  • turn on;
  • run tests;
  • realize you forgot to run serve;
  • run serve;
  • run tests;

Since my centos runs on another VM, I thought to be over complicated to have Ubuntu connecting there for the sake of dusk. Serve would be enough. Given this idea, today I'm going to try and have DuskTestCase turn on the server for me.

@SebastianS90
Copy link
Contributor

SebastianS90 commented Mar 3, 2017

@deleugpn instead of having DuskTestCase start the webserver for every single test you could also let DuskCommand do the job once for your whole test suite:

Create a class in app/Console/Commands:

<?php

namespace App\Console\Commands;

use Laravel\Dusk\Console\DuskCommand as BaseCommand;
use Symfony\Component\Process\ProcessBuilder;

class DuskCommand extends BaseCommand
{
    public function handle()
    {
        $webserver = (new ProcessBuilder())
            ->setTimeout(null)
            ->add('exec')
            ->add(PHP_BINARY)
            ->add('artisan')
            ->add('serve')
            ->getProcess();
        $webserver->start();

        return tap(parent::handle(), function () use ($webserver) {
            $webserver->stop();
        });
    }
}

And then, in AppServiceProvider, you put:

        if ($this->app->environment('local', 'testing')) {
            $this->app->register(DuskServiceProvider::class);
            $this->commands(\App\Console\Commands\DuskCommand::class);
        }

@inxilpro
Copy link
Contributor

Here's another option. I've added a RunsWebServer trait to my test suite (which is nearly identical to the SupportsChrome trait):

<?php

namespace Tests;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessBuilder;

trait RunsWebServer
{
	/**
	 * @var Process
	 */
	protected static $webServerProcess;
	
	/**
	 * Start the web server process
	 */
	public static function startWebServer()
	{
		static::$webServerProcess = static::buildServerProcess();
		static::$webServerProcess->start();
		static::afterClass(function() {
			static::stopWebServer();
		});
	}
	
	/**
	 * Stop the web server process
	 */
	public static function stopWebServer()
	{
		if (static::$webServerProcess) {
			static::$webServerProcess->stop();
		}
	}
	
	/**
	 * Build the process to run the web server
	 *
	 * @return \Symfony\Component\Process\Process
	 * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
	 * @throws \Symfony\Component\Process\Exception\LogicException
	 */
	protected static function buildServerProcess()
	{
		$host = env('TEST_SERVER_HOST', '127.0.0.1');
		$port = env('TEST_SERVER_PORT', 8080);
		
		return (new ProcessBuilder())
			->setTimeout(null)
			->setWorkingDirectory(realpath(__DIR__.'/../'))
			->add('exec')
			->add(PHP_BINARY)
			->add('-S')
			->add("$host:$port")
			->add('server.php')
			->getProcess();
	}
}

That trait can be added to any test that needs a web server running, or to the base DuskTestCase class…

@deleugpn
Copy link
Contributor

@inxilpro Did you check if the environments match with that approach? The reason I ask is because when I tried running php artisan serve with a similar approach, it would run before Dusk and Dusk swaps the .env file AND php artisan serve is not sensitive to .env changes. You need to kill the service and spawn it again for it to pick up the changes. In other words, you need to run the server after Dusk has swapped, but before the Browser has been needed.

I wrote about it here: https://medium.com/@deleugpn/running-serve-automatically-prior-to-laravel-dusk-9eedf295bbd6

@inxilpro
Copy link
Contributor

I just have an .env.testing file, and I run my Dusk tests with phpunit --testsuite Browser — because the server is spun up via phpunit, it automatically picks up the correct environment.

@markdwhite
Copy link

markdwhite commented Mar 15, 2018

@inxilpro

Fantastic! That's helped hugely with me getting Jenkins to start the server before running Dusk tests :-)

However, I did need to add the following to make the docroot serve from /public correctly:

->add('-S')
->add("$host:$port")
->add('-t')
->add('public')
->add('server.php')
->getProcess();

@alchermd
Copy link

Maybe related, I fixed an issue similar to #531 with these steps:

  1. Create a sqlite file for testing ex: database/dusk.sqlite
  2. Create a .env.dusk.local file and customize as needed, obviously using the db from step 1.
    2.1 Might be a good idea to use the absolute path when setting DB_DATABASE
    2.2 Or just straight up create a dusk connection config on config/database.php and set DB_CONNECTION as dusk (this is what I use)
  3. Specify the environment when running the web server with php artisan serve --env=dusk.local
    3.1 I even use a dedicated port with --port=8001 just to be extra sure (update APP_URL on your .env.dusk.local if you'll do this).
  4. Same concept as step 3 when running dusk php artisan dusk --env=dusk.local

Sample snippets:

// config/database.php

// ...
        'dusk' => [
            'driver' => 'sqlite',
            'database' => database_path('dusk.sqlite'),
            'prefix' => '',
        ],
// ...
# .env.dusk.local
APP_ENV=local
APP_URL=http://127.0.0.1:8001/
DB_CONNECTION=dusk

@driesvints
Copy link
Member

Heya everyone. Try to see if @alchermd's solution can help you.

@jasonmccreary
Copy link

jasonmccreary commented Jul 14, 2019

Quick update as this was the top Google result when I was getting started with Dusk + local webserver...

The comment by @alchermd is correct, but as a bit of streamlining, the --env while explicit is unnecessary (tested on Laravel 5.8).

Dusk automatically looks for a .env.dusk.{environment} file based on the current APP_ENV environment. Meaning if your current .env sets APP_ENV=local, Dusk will look for a .env.dusk.local file. (Reference)

So, first starting the web server with php artisan serve and then running php artisan dusk works.

@TiagoSilvaPereira
Copy link

@alchermd Thanks, it worked well for me

@jasonmccreary I needed to use --env, Dusk was not founding the correct .env for me

@UzairSeikhai
Copy link

UzairSeikhai commented Nov 27, 2020

I am using Laravel 6 Dusk in ubuntu valet server, but dusk is using default laravel .env instead of .env.dusk.local. Fed up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants