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");
});
}
2
Answers
Unfortunately after testing
$browser->assertPresent($selector)
for a few runs this didn't work either. Although I haven't yet been able to find a single Laravel Dusk/Selenium method that can successfully check for the existence of PayPal's cookie banner and accept it, I think I may have stumbled on a workaround for this issue, or at least an answer to what causes it.For whatever reason, the PayPal sandbox seems to trigger the cookie banner prompt when it determines you're pushing "too often" - in my experience this was about 4 times within the space of an hour. After seeing a failed push, waiting about 20 mins before pushing again seems to be enough for PayPal to stop showing the cookie banner and allow my GitHub Action run to pass as expected.
The issue is both a failure of Laravel Dusk to have any documented, working methods for conditional existence of elements, and of PayPal for deciding to serve a cookie banner in a sandbox designed for testing, but since I don't currently have the time or energy to chase up either, this is the closest thing to a solution it seems there will be.
$browser->element()
is not the best method to use in this case. I believe with the method$browser->assertPresent($selector)
wil fix your problem