javascript - Playwright - How to test that a network request have finished after on click event - Stack Overflow

I am making BDD test with a Cucumber-Playwright suit. A page I am making a test for has buttons that wi

I am making BDD test with a Cucumber-Playwright suit. A page I am making a test for has buttons that will trigger a PUT API request and update the page (Note: The button will not link to new address, just trigger and API request).

I want to make sure that all network events have finished before moving on to the next step as it may try to act too soon before the API request has returned and cause the test to fail.

I want to avoid hard waits so I read the documentation and found a step structure that uses Promise.all([]) to bine two or more steps. From what I understand they will check that each step in the array to be true at the same time before moving on.

So the steps looks like this:


await Promise.all([inviteUserButton.click(), page.waitForLoadState('networkidle')])
await page.goto('https://example/examplepage')

This stage of the test is flaky however, it will work about 2/3 times. From the trace files I read to debug the test I see that the the network response repsondes with net::ERR_ABORTED POST https://.....

I believe this is due to to the page.goto() step has interrupted the network request/response. Due to this, it will cause the ing assertion to fail as it was not pleted.

Is there a way to test that all the pages network events have finished from a onClick event or similar before moving onto the next step?

I am making BDD test with a Cucumber-Playwright suit. A page I am making a test for has buttons that will trigger a PUT API request and update the page (Note: The button will not link to new address, just trigger and API request).

I want to make sure that all network events have finished before moving on to the next step as it may try to act too soon before the API request has returned and cause the test to fail.

I want to avoid hard waits so I read the documentation and found a step structure that uses Promise.all([]) to bine two or more steps. From what I understand they will check that each step in the array to be true at the same time before moving on.

So the steps looks like this:


await Promise.all([inviteUserButton.click(), page.waitForLoadState('networkidle')])
await page.goto('https://example/examplepage')

This stage of the test is flaky however, it will work about 2/3 times. From the trace files I read to debug the test I see that the the network response repsondes with net::ERR_ABORTED POST https://.....

I believe this is due to to the page.goto() step has interrupted the network request/response. Due to this, it will cause the ing assertion to fail as it was not pleted.

Is there a way to test that all the pages network events have finished from a onClick event or similar before moving onto the next step?

Share Improve this question asked Oct 24, 2022 at 10:03 Mayur KumarMayur Kumar 671 gold badge1 silver badge6 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

The correct practice is to wait for response before clicking the button to avoid any race conditions so that it will work correctly every single time

as long as api(s) returning back with ok response.

In this , you may add N number of api calls with mas where response from multiple api is expected.

Note: You may need to change the response status code from 200 to 204 , depending on how the api is implemented.

const [resp]= await Promise.all([
        this.page.waitForResponse(resp => resp.url().includes('/api/odata/any unique sub string of API endpoint') && resp.status() === 200),
        //API2 ,
        //API3,
        //APIN,
        this.page.click('yourButtonLocator'),
        
       ]);

   const body= await resp.json() //Next step of your scenario

If you don't wrap it in a promise is it still flaky?

await inviteUserButton.click();
await page.waitForLoadState('networkidle');
await page.goto('https://example/examplepage');

How long do the network requests last? The default timeout is set to 30 seconds, did you try to increase it?

  waitForLoadState(state?: "load"|"domcontentloaded"|"networkidle", options?: {
    /**
     * Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be
     * changed by using the
     * [browserContext.setDefaultNavigationTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-navigation-timeout),
     * [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout),
     * [page.setDefaultNavigationTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout)
     * or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods.
     */
    timeout?: number;
  }): Promise<void>;

You can try and wait for more milliseconds

await Promise.all([inviteUserButton.click(), page.waitForLoadState('networkidle', { timeout:60_000 })])
await page.goto('https://example/examplepage')

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744616920a4584106.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信