How to reuse a Dusk test browser instance?
Asked Answered
V

1

18

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?
Vuillard answered 20/6, 2017 at 15:59 Comment(0)
S
1

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.

Sturdivant answered 27/1, 2021 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.