Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question : How can we wait using this service until all/particular network request is completed ? #149

Open
krarpitgupta opened this issue Sep 24, 2021 · 7 comments

Comments

@krarpitgupta
Copy link

Scenario:

  • User click on a button in web-app and let's say it calls 10 network requests internally
  • Now how can we wait until all these 10 requests are completed irrespective of HTTP status ?

Any help would be really appreciated, TIA .

@splurgeop
Copy link

this would be tricky.If you compare with other js tool you can achieve this very easily by waiting for the http call implicitly.
in webdriver context, you can achieve this using the below steps:

  1. set up the interceptor

  2. get all the request via browser.requests()

  3. manually wait until you get all the request and validate it in the array returned by browser.request
    something like that
    wihle(somecondition){
    var allreq = await browser.requests();
    for(var i=0;i<allreq.length;i++)
    {
    if(allreq[i].includes('/api/yourcall'){
    }
    else{
    break the loop
    }
    }
    }

  4. it is advisable to wait for the last 1 or 2 request. Assuming when the last request is finished the prior 9 would eventually had finished

PS: This is how i have achieved it.if you have any better solution ,please share

@krarpitgupta
Copy link
Author

Hi @splurgeop Thanks for getting back to me but the biggest challenge which I see at the moment when we use browser.requests(); method it itself don't capture the intended Api request sometimes for e.g. I am trying to intercept a request /v1/getCustomer/ but when we use this method browser.requests() sometimes it capture this request and sometimes not

@splurgeop
Copy link

that's what the problem is.You have to wait explicitly.since you mentioned that sometimes it captures and sometimes not so you have to wait explicitly for the browser.getrequests till you get the api that you are looking for.
Hope that answers your question

@tehhowch
Copy link
Contributor

See #111 for a previous request for this functionality.

@tehhowch
Copy link
Contributor

tehhowch commented Dec 8, 2021

@krarpitgupta @splurgeop You should be able to write a simple utility function in your test library that makes use of the functionality in #186 , which is available beginning with version 4.2.0.

async function doWhenSettled(callbackFn) {
  while(await browser.hasPendingRequests()) {
    await browser.pause(50);
  }
  // execute the callback
  return callbackFn();
}
// example
doWhenSettled(() => console.log('network activity has subsided for the moment!');

In a future release this library may provide a direct option to e.g. assertRequests that would block until the network settles. (Note that such an option could remove a lot of control from the user over how long to wait, etc. so I opted to put the primitives out in #186 and let discussion over the best library implementation occur)

@krarpitgupta
Copy link
Author

krarpitgupta commented Dec 22, 2021

Hi @tehhowch Thanks for getting back to me, to tackle this problem I tried below code but seems like browser.getRequests({includePending: true}) is not getting refresh, here is my code

do {
        networkRequests = browser.getRequests({includePending: true});
        pendingRequest = networkRequests.filter(request => request.pending == true);
        console.log('check : ' + pendingRequest.length);
    } while (pendingRequest.length > 0);

Any better way to tackle it or Am I missing something here ?

P.S. I also tried by adding following statement browser.setupInterceptor(); as a first statement inside loop but no luck

@serhiiboreiko
Copy link

serhiiboreiko commented Jun 2, 2022

Idk, maybe this will help someone:

export const waitForRequest = async (browser, match) =>
  new Promise((resolve) => {
    let timeout = 0;
    const step = 500;
    const interval = setInterval(async () => {
      if (timeout <= 20000) {
        const requests = await browser.getRequests({ includePending: true });
        const hasRequest = requests.find((r) => r.url.includes(match));
        if (hasRequest) {
          clearInterval(interval);
          resolve(true);
        } else {
          timeout += step;
        }
      } else {
        resolve(false);
        clearInterval(interval);
      }
    }, step);
  });

And usage is:

const requestFound = await waitForRequest(browser, 'api.com/user'); // true or false

This will wait for particular request or until it reaches timeout. You can modify it if you want to wait for multiple requests or maybe use regex instead of strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants