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

add waitForElement support #3

Closed
patrickhulce opened this issue Jun 29, 2018 · 2 comments · Fixed by #44
Closed

add waitForElement support #3

patrickhulce opened this issue Jun 29, 2018 · 2 comments · Fixed by #44
Labels

Comments

@patrickhulce
Copy link
Collaborator

patrickhulce commented Jun 29, 2018

Puppeteer has its own set of waitForSelector methods so this requires some thought. My inclination is to just better document how to do the same thing with puppeteer than match exact API

Proposals

// Use puppeteer but expose dom-testing-library globally
await state.page.waitFor(() => __dom_testing_library__.queryByTestId('foo'), {polling: 'mutation'})

// Tell people to stick with `wait`
const {queries, wait} = require('pptr-testing-library')
await wait(() => queries.getByTestId($document, 'foo'))
@marcusstenbeck
Copy link

marcusstenbeck commented Jul 18, 2019

I think it's cleaner to stick with the wait(). I needed this and implemented it like below. In my particular use-case, I needed to dive into iframes added by Stripe Elements (in order to click "confirm payment" in a 3D Secure payment verification modal).

  await wait(() => findInFrames(page, '[placeholder="Card number"]'), {
    timeout: TEST_TIMEOUT - ONE_SECOND
  });
  const cardInput = await findInFrames(page, '[placeholder="Card number"]');
  await cardInput.click();
async function recursiveFindInFrames(inputFrame, selector) {
  const frames = inputFrame.childFrames();
  const results = await Promise.all(
    frames.map(async frame => {
      const el = await frame.$(selector);
      if (el) return el;
      if (frame.childFrames().length > 0) {
        return await recursiveFindInFrames(frame, selector);
      }
      return null;
    })
  );
  return results.find(Boolean);
}

async function findInFrames(page, selector) {
  const result = await recursiveFindInFrames(page.mainFrame(), selector);
  if (!result) {
    throw new Error(
      `The selector \`${selector}\` could not be found in any child frames.`
    );
  }
  return result;
}

It could be re-jiggered to more closely match the testing library style. Thoughts?

@patrickhulce
Copy link
Collaborator Author

patrickhulce commented Jul 18, 2019

nice @marcusstenbeck, clever solution! the recursive frames part is definitely interesting and worth a separate issue. my immediate reaction is let's create a new set of the testing-library functions called deepQueries that all work recursively.

sticking to the waitForElement issue, I agree the wait(() => findByX()) style is cleaner, I think we should just highlight this caveat in the docs. there are enough differences between browser and jsdom testing that it's not like a suite will be drop-in replacement anyhow.

anyone interested in a PR for it? :)

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

Successfully merging a pull request may close this issue.

2 participants