Puppeteer - why doesn't element reflect DOM changes?

Viewed 185

I have a function that waits for a selector under the scope of an element. The ElementHandle I'm passing in doesn't seem to be getting updated as the DOM updates- I log the outerHTML of this element each time my waitForFunction call fails, and changes aren't there.

async function waitForSubElSelector(page, el, subElSelector) {
  // offset/rects checks for visible check (from https://stackoverflow.com/a/33456469)
  await page.waitForFunction((selector, scopeEl) => {
      const subEl = scopeEl.querySelector(selector)
      let found = !!(subEl && (subEl.offsetWidth || subEl.offsetHeight || subEl.getClientRects().length));
      if (!found) {
        console.log(`waitForSubElSelector failed EL: ${scopeEl.outerHTML}  SELECTOR: "${selector}", ${!subEl ? 'not found' : subEl.offsetWidth + ', ' + subEl.offsetHeight + ', ' + subEl.getClientRects().length}`)
      }
      return found;
    }, {}, subElSelector, el
  ).catch(e => {
    console.log(`waitForSubElSelector failed w/ selector '${subElSelector}'`)
    throw e;
  })
  return await el.$(subElSelector);
}

I also verified this in the browser Console - I'm able to find the element and then the selector from there.

One use case is waiting for a Next button to be available, e.g.:

await waitForSubElSelector(this.browserPage, pageEl, '#nextButton:not([disabled])')

How can I get this working?

One idea I had— maybe my web framework replaces part of the DOM so the ElementHandle I have isn't the current one; is there some 'in-DOM' check in Puppeteer?

0 Answers
Related