Last active
July 27, 2022 14:42
-
-
Save Patabugen/da53bca6ed46cadf7e36eefed0f21ab1 to your computer and use it in GitHub Desktop.
Laravel Dusk "waitForAjax" Macro (and an old CodeCeption one)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* $browser->waitForAjax() macro for Laravel Dusk. See comment below for details. | |
**/ | |
namespace App\Providers; | |
use Illuminate\Support\ServiceProvider; | |
use Laravel\Dusk\Browser; | |
class DuskServiceProvider extends ServiceProvider | |
{ | |
public function boot() | |
{ | |
/** | |
* Adds $browser->waitForAjax() to simply wait and let the browser finish any | |
* outstanding AJAX requests. The goals it provide a simple method call which | |
* is really reliable, even if it may not always be the most efficient way. | |
* | |
* There's no straightforward API to know whether the browser is currently making | |
* any ajax requests, so we have to use site specific ways to figure it out. | |
* | |
* In my current example I only need to check for the jQuery BlockUI plugin's overlay | |
* but other techniques include adding hook to axios or checking for the presence of | |
* indicators. | |
* | |
* See AcceptanceHelper.php for a more comprehensive example from an older project. | |
* | |
* The Repeat parameter lets you simply run all the checks again, either by default or | |
* by passing in a value appropriate to your own test - this is especially useful | |
* if you've got a lot going on or repeated calls. | |
*/ | |
Browser::macro( | |
'waitForAjax', | |
function($seconds = null, $repeat = 0) { | |
/** @var Browser $this */ | |
$this->waitUntilMissing('.blockOverlay', $seconds); | |
if ($repeat-- > 0) { | |
$this->waitForAjax($seconds, $repeat); | |
} | |
return $this; | |
} | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This is an older version of the same idea I've been using in CodeCeption since around 2017 | |
* and which has been working well (albeit sometimes because of the brute force nature of | |
* the method itself!). | |
* | |
**/ | |
namespace Codeception\Module; | |
class AcceptanceHelper extends \Codeception\Module | |
{ | |
/** | |
* Wait for all the Ajax requests to be completed | |
* | |
* @param \AcceptanceTester $I The CodeCeption tester we're usig | |
* | |
* @return \AcceptanceTester | |
*/ | |
public function waitForAjax(\AcceptanceTester $I, $timeout = 60, $repeat = true) | |
{ | |
// Check that our JS Counter is 0 | |
$I->waitForJS("return (jQuery('#ajax-counter').text() * 1) == 0;", $timeout); | |
// Check that our JS Loader icon is gone | |
$I->waitForJS("return jQuery('#ajax-loader.ajax-active:visible').length == 0;", $timeout); | |
// Check that the overlay isn't visible | |
$I->waitForJS("return jQuery('#overlay:visible').length == 0;", $timeout); | |
// Then check that jQuery thinks it's done with Ajax too | |
$I->waitForJS("return $.active == 0;", $timeout); | |
$I->waitForElementNotVisible("#overlay"); | |
// Now lets be reallly sure | |
$I->wait(1); | |
// Now lets be really, really sure (handy for things which trigger Ajax which | |
// then trigger another set of Ajax and the above may clear out between the two | |
// - Confirming a SupplierBooking on ViewBooking page does this) | |
if ($repeat) { | |
$this->waitForAjax($I, $timeout, false); | |
} | |
return $I; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment