Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse a Dusk test browser instance?

My project on the Laravel 5.4 framework and I am using Dusk for browser tests. I have a page that has several sections I'd like to test independently, however I'm running into the problem where I have to start a new browser instance, login, and navigate to that page, for each individual test.

public function testExample()
{
  $this->browse(function (Browser $browser) {
    $browser->loginAs(1)
            ->visit('/admin/dashboard')
            ->assertABC()
            ->assertXYZ();
  });
}

So when I have 4-5 of these in class allTheThingsTest extends DuskTestCase, I'm spawning 4-5 browser instances per test class. Obviously this gets out of hand quickly, especially when I'm running all of my tests pre-deployment.

One browser instance per test class is acceptable as far as I'm concerned, but I can't figure out how to make that happen. So here is what I'm asking:

  • Is it possible to remember/reuse a browser instance between test functions within a single test class?
  • If so, how?
like image 681
amflare Avatar asked Jun 20 '17 15:06

amflare


1 Answers

I feel like typically you would want a fresh browser instance for each test in your test class so that each test is starting out in a "fresh" state. Basically serving the same purpose as Laravel's DatabaseTransactions/RefreshDatabase testing traits.

However, if you do not want to login every time/every test method, you could try something similar to the following:

class ExampleTest extends DuskTestCase
{
    /**
     * An single instance of our browser.
     *
     * @var Browser|null
     */
    protected static ?Browser $browser = null;

    /**
     * Get our test class ready.
     *
     * @return void
     */
    protected function setUp(): void
    {
        parent::setUp();

        if (is_null(static::$browser)) {
            $this->browse(function (Browser $browser) {
                $browser->loginAs(1);
                static::$browser = $browser;
            });
        }
    }

    /** @test */
    public function first_logged_in_use_case()
    {
        static::$browser->visit('/admin/dashboard')->assertABC();
    }

    /** @test */
    public function second_logged_in_use_case()
    {
        static::$browser->visit('/admin/dashboard')->assertXYZ();
    }
}

I haven't tested this but essentially you're creating a static class property and assigning a logged in browser instance to it. Then you can use that same instance across all your test methods in your class.

like image 152
Denis Priebe Avatar answered Nov 05 '22 03:11

Denis Priebe