Handling AJAX requests on Laravel Dusk

Handling AJAX requests on Laravel Dusk

I recently started to write browser tests using Laravel Dusk and while I'm applying the basic principles of it, I needed much more advanced techniques to make my application work with the browser automation.

My application uses scheduled tasks to complete payments, queues to transfer payments to the seller, again scheduled tasks for the expired order handling and Laravel Livewire for the forms on the user interface. The prior I could handle with directly calling the job handler methods but the last one had asynchronous javascript included, so I needed to catch where the AJAX request ended to skip to the next automation step.

I tried using pause(milliseconds) to give a brak while the server request finishes, but that had a major disadvantage such as waiting much more when the request finishes in less time than the assumption, and when you are checking something in a loop, it may take much more than it really takes. So I needed a different approach.

Then I found this github issue answered by Jonas Staudenmeir and used the script from the answer to suit my needs.

If you've extended the browser instance, you can add the extension like this:

<?php 

use Laravel\Dusk\Browser;

class MyBrowser extends Browser {
    public function waitUntilAjaxFinishes($seconds = 5)
    {
        return $this->waitUntil(
            "!$.active", 
            $seconds, 
            "AJAX request didn't finish in $seconds seconds."
        );
    }
}

or you can create a wrapper:

// test_helpers.php or inside your test class

public function waitUntilAjaxFinishes($browser, $seconds = 5)
{
    return $browser->waitUntil(
        "!$.active", 
        $seconds, 
        "AJAX request didn't finish in $seconds seconds."
    );
}