I have a web app which has both Stripe and PayPal integrated. I have integrated tests set up for both of these via Laravel Dusk. The PayPal test fails about 50% of the time on GitHub Actions, even with conditional logic, because for some absolutely unhinged reason PayPal have decided that their sandbox needs to display a cookie banner, and even then only often enough so as to be completely unpredictable.
Short of PayPal fixing their sandbox, what can be done to fix this? Why does the if condition I'm using to test if the cookie banner exists only work some of the time?
Here is a simplified version of my Dusk test:
public function test_paypal_payments_are_working()
{
$this->browse(function (Browser $browser) {
$browser->visit("/product1")
->waitForLocation('/payment')
->resize(1920, 2000) # Hack to make sure PayPal button is always clickable
->withinFrame('#paypal-button-container iframe', function($browser) {
$browser
->waitFor(".paypal-button")
->click(".paypal-button");
});
$mainWindow = $browser->driver->getWindowHandle();
$paypalWindow = collect($browser->driver->getWindowHandles())->last(); // Get the PayPal popup window
$browser->driver->switchTo()->window($paypalWindow); // Switch to it
$browser
->disableFitOnFailure() # Force screenshots to show screen as interacted with
->click("#btnLogin")
->storeSource("debug"); # Verify the ID of the PayPal cookie banner button
# Check the cookie banner button exists and if so, accept it
if ($browser->element('#acceptAllButton')) {
$browser
->click("#acceptAllButton");
}
$browser
->waitFor("#payment-submit-btn")
->click("#payment-submit-btn");
$browser->driver->switchTo()->window($mainWindow); // Switch back to original window
$browser->waitFor("@payment-success", 15)
->assertSeeIn("@payment-success");
});
}
$browser->element()is not the best method to use in this case. I believe with the method$browser->assertPresent($selector)wil fix your problem