skip to Main Content

I’m trying to wait until text appears on certain element. My page is fully loaded but on one screen there is something like a "buffering", informations on the element appears later, I don’t want to use page.waitForTimeout because it is "luck" depending, what if my timeout is too small etc. I want to wait for text to appear

My current state is

await expect(page.locator('my-locator')).toContainText('a')

It is working pretty well because letter "a" is in basically every single world and I want to find a solution to just wait for text to appears, nothing else, I just want my page to wait until that one element which is "buffering" shows fully, but I know there is a solution for it which I don’t know about, looking for help!

2

Answers


  1. I think you want page.waitForFunction() (docs). It’s great for nuanced criteria like this one.

    await page.waitForFunction(() => {
      return document.querySelector('my-locator')?.innerText.includes('a');
    }, {timeout: 1000 * 60 /* max millis before aborting */ });
    
    Login or Signup to reply.
  2. If I understand correctly, you need to wait for the downloading/buffering panel to complete before you action you next click, so we can do this a few ways.

    1. We can simply check when the buffering panel is done. This can be done in several ways but an easy one is something like:
    const bufferingElement = page.locator('<your locator for buffering panel>');
    await expect(bufferingElement).toHaveCount(0);

    This will find the buffering element, whatever that is for your site, and then wait until it disappears, i.e. loading complete. You can easily extend that to look for specific text such as ‘loading’ or whatever you need. As I don’t know your HTML, I am keeping it generic here, but the logic is the same.

    If you wanted to conditionally check for it, its very similar. Something like:

    const bufferingElement = page.locator('<your locator for buffering panel>');
    
    //If there is a buffering job, wait for it to complete
    if(await bufferingElement.count() > 0){
      //Do whatever you need to do while job is buffering
      await expect(bufferingElement).toHaveCount(0);
    }
    1. If we know what the endpoint is that controls this buffering, we can wait until it is done, before moving on. Something like this could work for that:
    const responsePromise = page.waitForResponse(response =>
      response.url() === '<endpoint url>' && response.status() === 200
    );
    await page.getByRole('<role>', { name: '<name>' }).click();
    const response = await responsePromise;

    This code block creates a promise (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), then you should replace the ‘getByRole’ line with the action that performs the load, which is presumably just opening the page under test. Then, we resolve the promise, at which point the response is returned and buffering complete, then you can move on.

    1. If you want to use a more precise locator than getting text that contains ‘a’ I would recommend using the getByRole locator. This is the best way to go as it uses a user-centric way to gather your locators. Essentially you would find your elements role, and its name value, and use that. It is much nicer than using a text contains type of approach. This link explains a nice easy way to find those things – https://www.smashingmagazine.com/2020/08/accessibility-chrome-devtools/
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search