In the previous article we learned about Concept of Pages and Generating New Page in Dusk. Let's dig more into pages to see how we can create custom methods and visit a page.

Navigate to Page

Once you have generated the new page and defined the url inside the url() method of the page. Here is how you can visit the page

use Tests\Browser\Pages\Checkout;

$browser->visit(new Checkout);

With this dusk will navigate to the url defined in the url() method and will also run the assert() method if you have defined in the Page class.

When you are working with a feature / functionality that spans over multiple pages you will often find that you are already on the page that you want to navigate to. In that case, instead of using the visit method, you must use the on method.

Consider the example of an e-commerce application browser test.

$browser->loginAs($user)
    ->visit(new Product)
    ->addProductsToCart()
    ->checkOut()
    ->on(new Checkout)
    ->verifyProductsAdded()

We visit the products page by using new Product, and then call the custom methods on the products page by calling out addProductsToCart() method which is defined inside the products page. Next we click the checkout() button.
Now since we are already on the checkout page we can use on(new Checkout) to denote dusk that we are already on that page. We can now call custom methods defined in Checkout Page to carry out further tests.

 

Custom Page Methods

In addition to the default methods on pages which is provided by Dusk. You can also create your custom methods to interact with the elements on the page. We can then use this methods multiple times in our tests.

Let's consider you are building an online survey application which has two pages. On the first page user is required to fill the form with his personal details , and on the next page user is required to answer a few radio button questions.

Here is you can create a page for these two.

Page 1 : Personal Information

<?php

namespace Tests\Browser\Pages\professional;

use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Browser\Pages\Page as Page;

class surveyPersonalInfo extends Page
{

    use withFaker;

    public function url()
    {
        return '/survey/personalInfo';
    }

    /**
     * Assert that the browser is on the page.
     *
     * @param  Browser  $browser
     * @return void
     */
    public function assert(Browser $browser)
    {
        $browser->assertPathIs($this->url());
    }


    public function fillPersonalInfo(Browser $browser)
    {

        $browser->type('first_name', $this->faker->firstName);
        $browser->type('last_name', $this->faker->lastName);
        $browser->select('subject_sex');
        //DOB
        $browser->select('DOBmon');
        $browser->select('DOBday');
        $browser->select('DOByear');
    }
}

We have created a custom method named fillPersonalInfo on this page which will fill the form data with random data using faker library.

Page 2 : Survey Questions

<?php

namespace Tests\Browser\Pages\professional;

use Laravel\Dusk\Browser;
use Tests\Browser\Pages\Page as Page;

class surveyQuestions extends Page
{

    public function url()
    {
        return '/survey/surveyQuestions';
    }

    /**
     * Assert that the browser is on the page.
     *
     * @param  Browser  $browser
     * @return void
     */
    public function assert(Browser $browser)
    {
        $browser->assertPathIs($this->url());
    }


    public function fillSurveyQuestions(Browser $browser)
    {
        for ($i = 0; $i <= 9; $i++){
            $option = $radio_option[array_rand($radio_option, 1)];
            $browser->radio('q'.$i.'_select', $option);
        }
    }
}

SurveyTest using Dusk

We can now make use of both the pages to test the survey feature

/** @test */
public function it_asserts_that_user_can_complete_survey(){
    $this->browse(function ($browser) {
        $browser->visit(new surveyPersonalInfo)
                ->fillPersonalInfo()
                ->press('Continue')
                ->on(new surveyQuestions)
                ->fillSurveyQuestions()
                ->press('Submit')
                ->assertSee('Survey Submitted');

    });
}

Passing Data to Pages

Working with the pages in dusk I have often came across the requirement of having the previous data to be passed in my pages, for filling form data or making data assertions or any other reason.

You can make use of constructor class to pass any required data to your page.

Let's consider the example below

Let's say you want to assert that whenever a new user is created in your application. It should be visible in the userLists page in your admin section.

Here is the test that creates a new user and passes the data to userLists page.

/** @test */
public function it_asserts_that_new_user_exists_in_admin_userlist_page(){

    $user = factory('App\User')->create();

    $this->browse(function ($browser) use($user) {
        $browser->visit(new userLists($user))
                ->assertUserExists();
    });
}

This is how we can make use of constructor in the Page class to accept the data.

<?php

namespace Tests\Browser\Pages\professional;

use Laravel\Dusk\Browser;
use Tests\Browser\Pages\Page as Page;

class userLists extends Page
{

    protected $user;

    public function __construct($user){
       $this->user = $user;
    }

    public function url()
    {
        return '/admin/userLists';
    }

    /**
     * Assert that the browser is on the page.
     *
     * @param  Browser  $browser
     * @return void
     */
    public function assert(Browser $browser)
    {
        $browser->assertPathIs($this->url());
    }


    public function assertUserExists(Browser $browser)
    {
        $this->assertSee($this->user->name);
    }
}

That's all about Navigating to Pages in Dusk, Creating Custom Methods and Passing Data to the Dusk Pages.

Comments