2
votes

I've a small problem testing an invisible ReCaptcha on a form using Laravel Dusk. The package involved in this situation is Invisible Recaptcha by Albertcht

I've this method inside CreatesApplication.php file in /tests

protected function withoutRecaptcha() : void
{
    InvisibleReCaptcha::shouldReceive("verifyRequest")
        ->andReturnTrue();

    InvisibleReCaptcha::shouldReceive("verifyResponse")
        ->once()
        ->andReturnTrue();
}

This works quiet well for Features test, because I only need to hit APIs and I can ignore the g-recaptcha-response input from the post request.

But if I want to test the form itself, using a browser test system like Laravel Dusk, of course this is not enough.

My current Dusk method is the following.

 public function a_guest_can_fill_the_registration_form()
 {
     $this->withoutRecaptcha();

     $this->browse(function (Browser $browser) {
         $browser->maximize()
            ->visit(new Register())
            ->assertPresent("input[name=g-recaptcha-response]")
            ->fillFormWithRandomData()
            ->submitForm()
            ->waitForReload()
            ->assertVisible(".alert.alert-success");
    });
 }

Straightforward stuff here, I call the register form, fill the data, submit it and check if an alert is in sight. Currently this doesn't work and I get this error:

There was 1 failure:

1) Tests\Browser\RegisterTest::a_guest_can_fill_the_registration_form
Element [body input[name=g-recaptcha-response]] is not present.
Failed asserting that false is true.

/app/vendor/laravel/dusk/src/Concerns/MakesAssertions.php:806
/app/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:67

So the problem is clear: During the test the ReCaptcha input is not rendered thus it's impossible to hit it or even fake it

Is there a way to render of fake the ReCaptcha in order to make it works with Laravel Dusk?

Thank you

1

1 Answers

1
votes

reCaptcha usually within iframe. Dusk cannot recognize element inside iframe. However you can use method ->withinFrame('selector', function ($browser) {}); and assert the value inside withinFrame closure.