When writing Laravel Dusk tests, sometimes you need to change your application configs on the fly to test different scenarios.
For a bare bones example, imagine you were building an e-learning platform and had an app config called openEnrollment
. When this config is true
, your homepage should display a link for new students to enroll. When false
, your homepage should display a message saying enrollments are closed:
@if (config('app.openEnrollment'))
<p dusk='enrollment-open'><a href='/enroll'>Click here to enroll</a></p>
@else
<p dusk='enrollment-closed'>Enrollments are closed</p>
@endif
Now imagine you wanted to test the correct output was being displayed in both scenarios. In pseudo code, your tests would look like this:
If openEnrollment == true, assert that enrollment link is visible.
If openEnrollment == false, assert that “enrollments are closed” message is visible.
Accomplishing this requires you to be able to change the config allowNewStudents
before reach test.
Instinctually, you might try and use Laravel’s config
helper in your test to make this config change. E.g.:
public function testEnrollmentOpen(): void
{
$this->browse(function (Browser $browser) {
# This won’t work as expected...
config('app.openEnrollment', true);
$browser->visit('/')
->assertPresent('@enrollment-open');
});
}
The problem with this is the config will change for your Dusk instance, but not the instance of your app that is being tested.
To address this we can use a package called AlexandreBellas/duskapiconf. This package adds a route in your application that lets you set configs. When you invoke the duskapiconf setConfig
method during testing, it will visit that route, changing the config for the test.
Set up
To set up the duskapiconf
package, first install it via Composer:
> composer require alebatistella/duskapiconf --dev
Then add the UsesDuskApiConfig
trait to your DuskTestCase.php
file:
<?php
use Laravel\Dusk\TestCase as BaseTestCase;
use AleBatistella\DuskApiConf\Traits\UsesDuskApiConfig;
abstract class DuskTestCase extends BaseTestCase {
use UsesDuskApiConfig;
// ...
}
You will now have access to the methods getConfig
, setConfig
, and resetConfig
in your Desk tests. Examples:
$appName = $this->getConfig('app.name');
$this->setConfig('app.name', 'Demo');
$this->resetConfig();
Applying these methods, here’s what our tests would look like for our hypothetical e-learning application described above:
class ExampleTest extends DuskTestCase
{
public function testEnrollmentOpen(): void
{
$this->browse(function (Browser $browser) {
# ⭐ Use duskapiconf to setConfig ⭐
$this->setConfig('app.openEnrollment', true);
$browser->visit('/')
->assertPresent('@enrollment-open');
});
}
public function testEnrollmentClosed(): void
{
$this->browse(function (Browser $browser) {
# ⭐ Use duskapiconf to setConfig ⭐
$this->setConfig('app.openEnrollment', false);
$browser->visit('/')
->assertPresent('@enrollment-closed');
});
}
}
Tear down
I suggest adding a tearDown method to DeskTestCase.php
that invokes the resetConfig method, ensuring that any config changes made during testing are not persisted:
/**
*
*/
protected function tearDown(): void
{
parent::tearDown();
$this->resetConfig();
}