If you try to interact with elements on an Iframe within your Laravel Dusk you might come across ElementNotFound Exception. This is because Iframe page source different from your main page source.

Since the iFrame is out of context for your Dusk automation test we need to tell dusk to specifically look for elements inside iFrame by switching into it.

Here is how you do it

Laravel has a withinFrame method defined that makes it pretty easy to work with iFrames

public function withinFrame($selector, Closure $callback)

To switch to any Iframe you pass in the CSS selector of that Iframe followed by a callback function that you need to execute within that Iframe

Here is an example

    $browser->assertSee('Pay with Card')
        ->press('Pay with Card')
        ->waitFor('iframe[name=stripe_checkout_app]')
        ->withinFrame('iframe[name=stripe_checkout_app]', function($browser){
            $browser->pause(3000);
            $browser->keys('input[placeholder="Email"]', 'tushar@5balloons.info')
                ->keys('input[placeholder="Card number"]', '4242 4242 4242 4242')
                ->keys('input[placeholder="MM / YY"]', '0122')
                ->keys('input[placeholder="CVC"]', '123')
                ->press('button[type="submit"')
                ->waitUntilMissing('iframe[name=stripe_checkout_app]');
        });

This is an example of stripe payment, where on clicking of Pay With Card button it opens up an iFrame. We pass in the CSS selector path of the Iframe and then a closure function to fill in the payment details within the withinFrame function.

withinFrame function works like this

  • Switches the automation context to iFrame
  • Execute the closure function.
  • Switch the automation context back to Original Content.

If for some reason you are looking to do this manually without using the withinFrame function . Here is how you can do it

$browser->driver->switchTo()->frame('id of iframe');

To switch back to the original content or the parent frame do this.

$browser->driver->switchTo()->defaultContent();
Comments