Search code examples
laraveltestinglaravel-dusklaravel-testing

How can I make Laravel Dusk run seeders consistently?


I have been working on an issue with Laravel Dusk for a few hours and I cannot seem to find a solution.

To start, I have a few tests written for the home page of my application. These tests all succeed individually (commenting out all but one) but when I run them in sequence they all fail. I suspect there is something wrong with how Laravel Dusk is handling seeders when using the DatabaseTruncation class. Here's an example of one of my test files:

<?php

namespace Tests\Browser;

use App\Classes\Settings;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class ProductTest extends DuskTestCase
{
    use DatabaseTruncation;

    public bool $seed = true;

    /**
     * A Dusk test example.
     */
    public function testCanSeeProducts(): void
    {
        $this->browse(function (Browser $browser) {
            $browser->loginAs(User::first())
                ->visit('/')
                ->waitFor('@product-card')
                ->assertVisible('@product-card');
        });
    }

    public function testAddToCartVisibility(): void
    {
        nova_set_setting_value('add_to_cart', true);
        $this->browse(function (Browser $browser) {
            $browser->loginAs(User::first())
                ->visit('/')
                ->waitForText('Add to Cart')
                ->assertVisible('@add-to-cart')
                ->logout();
        });
    }

    /*public function testAddToCartInvisible(): void
    {
        nova_set_setting_value('add_to_cart', false);
        $this->browse(function (Browser $browser) {
            $browser->loginAs(User::first())
                ->visit('/')
                ->assertMissing('@add-to-cart')
                ->logout();
        });
    }*/

    /*public function testShowInventory(): void
    {
        nova_set_setting_value('show_inventory', true);
        $this->browse(function (Browser $browser) {
            $browser->loginAs(User::first())
                ->visit('/')
                ->assertVisible('@show-inventory');
        });
    }*/

    /*public function testHideInventory(): void
    {
        nova_set_setting_value('show_inventory', false);
        $this->browse(function (Browser $browser) {
            $browser->loginAs(User::first())
                ->visit('/')
                ->assertMissing('@show-inventory');
        });
    }*/
}

I realize as well that I have loginAs() in every test but that is because I've been running them individually to see if they pass. I also could not get the loginAs() to persist between tests even though the documentation claims it should work that way, but this is probably because the users table gets truncated between tests.

I have tried using the setUp() class function

public function setUp(): void 
{
   parent::setUp();
   $this->seed();
}

and that will give me the same outcome: working for one test but not for multiple. I expect the database structure to stay in tact between tests and for seeders to be ran before each test and then truncated after they finish. I've also tried setting

public bool $seed = true;

and that gives the same exact result. I am at a bit of a loss since the documentation for Dusk does not go over how seeders should work. Any insight/suggestions would be greatly appreciated.

Thanks!

Edit: If I run the first two tests, both fail, the first one shows:

1) Tests\Browser\ProductTest::testCanSeeProducts Facebook\WebDriver\Exception\TimeoutException: Waited 5 seconds for selector [@product-card]. 

and the second one shows:

2) Tests\Browser\ProductTest::testAddToCartVisibility ErrorException: Attempt to read property "id" on null 

Basically, the seeders don't run at all when settings $seed = true; When I set the setUp() up to run seeders, the first test passes but then it does not seed again for the second test:

There was 1 error:

1) Tests\Browser\ProductTest::testAddToCartVisibility
ErrorException: Attempt to read property "id" on null

/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:266
/Users/ananelson/PhpstormProjects/storefront/app/Models/Vendor.php:22
/Users/ananelson/PhpstormProjects/storefront/app/Observers/ProductObserver.php:21
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:441
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:249
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php:189
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1316
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1138
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:986
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Support/helpers.php:306
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:987
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:23
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2330
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2342
/Users/ananelson/PhpstormProjects/storefront/database/seeders/ProductSeeder.php:24
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Util.php:41
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:37
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Container.php:661
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:184
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:193
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:61
/Users/ananelson/PhpstormProjects/storefront/database/seeders/DatabaseSeeder.php:17
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Util.php:41
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:37
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Container.php:661
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:184
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:193
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeedCommand.php:81
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php:155
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeedCommand.php:82
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Util.php:41
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:37
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Container/Container.php:661
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
/Users/ananelson/PhpstormProjects/storefront/vendor/symfony/console/Command/Command.php:312
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Console/Command.php:153
/Users/ananelson/PhpstormProjects/storefront/vendor/symfony/console/Application.php:1022
/Users/ananelson/PhpstormProjects/storefront/vendor/symfony/console/Application.php:314
/Users/ananelson/PhpstormProjects/storefront/vendor/symfony/console/Application.php:168
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Console/Application.php:102
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Console/Application.php:194
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:336
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Testing/PendingCommand.php:296
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Testing/PendingCommand.php:481
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:80
/Users/ananelson/PhpstormProjects/storefront/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php:286
/Users/ananelson/PhpstormProjects/storefront/tests/Browser/ProductTest.php:18


Solution

  • this might be an solution

    public function tearDown(): void
    {
      session()->fush();
      parent::tearDown();
    }
    

    this will flush the session between after tests this function must be implemented in the duskBaseTestCase.php if it doesn't work say what the error was and another quistion if you run all the tests after each other are the rest of the errors Attempt to read property "id" on null or something else