Search code examples
laravellaravel-5laravel-dusklaravel-5.5

Testing HTML5 Validation with Laravel Dusk


I am creating a simple test inside Laravel Dusk that a user cannot register when leaving the email field blank. The test code is below:

    /** @test */
    public function a_user_cannot_register_without_filling_in_email_field()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/register')
                ->type('password', $this->user->password)
                ->type('password_confirmation', $this->user->password)
                ->press('Register')
                ->assertSee('The email field is required.');
        });
    }

When the required attribute is removed from the form input this test passes, but when it is added the test fails.

Is there another way to test this?


Solution

  • The way that I have managed to get this test to pass is to do the following:

    Create a helpers.php inside the app directory. Make sure that this file is included in your autoloaders in your composer.json

    "autoload": {
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
            "app/helpers.php"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    

    Inside helpers.php you can create the following custom function:

    <?php
    
    /**
     * Helper to put novalidate on a form when testing
     */
    
    function disableValidationIfTesting() {
        $env = env('APP_ENV');
        if ($env == 'local') {
            echo 'novalidate';
        } else {
            return;
        }
    }
    

    Change this to reflect your local environment name. Sometimes it can be testing but in my instance its just local.

    Then, in your forms you're checking with tests add the following code to your form

    {{ disableValidationIfTesting() }} - this is how you render the function in your blade file.

    In my instance I have included it like this:

    <form class="form-horizontal" method="POST" action="{{ route('register') }}" {{ disableValidationIfTesting() }}>
    

    This means that when I'm developing and testing locally (as you shouldn't use dusk on a production server) the form gets a novalidate attribute added to it that allows the browser to skip the HTML5 Validation and just continue with the standard Laravel validation.

    After doing this, all of my tests pass no problems :D