简体   繁体   中英

How to use Puppeteer with Stripe Elements

Been slamming my head against this for a while now and no idea why this is happening.

I'm using react-stripe-elements and trying to write a test using Puppeteer. I simply cannot get Puppeteer to fill in the Card Elements.

I've tried a few approaches

Approach 1

I try to select the input by its name and then any input on the page by its class

await page.$eval('input[name="cardnumber"]')
await page.$eval(".InputElement");

I'm told that there's Approach 2

I then tried to access the actual frame, my reasoning being that its technically a page with a different origin. Again, nothing happens. Now, strangely, when I try and print out the contents of the frame, nothing happens again.

  const cardExpiryFrameHandle = await page.$('iframe[name="__privateStripeFrame5"]')
  const cardExpiryFrame = await cardExpiryFrameHandle.contentFrame()
  const test = await cardExpiryFrame.content()
  console.log(test);

When I console log out cardExpiryFrame , it exists. This should fit the API defined here https://pptr.dev/#?product=Puppeteer&version=v3.3.0&show=api-class-frame , but it absolutely refuses to.

I also added arguments to disable some security features because I tracked down an issue that said that this might be a problem. I do so like this

module.exports = {
  server: {
    command: `npm run-script start:test:server`,
    port: 3000,
    launchTimeout: 100000,
    debug: true,
    args: ['--disable-web-security', '--disable-features=IsolateOrigins,site-per-process'],
  },
  launch: {
    headless: false,
  },
}

Approach 3

I then tried to mimic what a human would do and clicked the div and then tried to type out the test card number.

  await page.click(getClass(paymentFlowCardInput))
  await page.keyboard.type('4242424242424242', { delay: '50' })

Again no luck. No errors.

Now I'm out of ideas - what do I do?

You're likely running into this issue because your test isn't waiting for the CardElement to mount (and finish its animations) or, the animations are slower than your delay. Here's an example of a puppeteer test which takes those transitions into account for your reference: https://github.com/stripe/react-stripe-elements/issues/137#issuecomment-352092164

A good solution for this is using tab to switch to the next input. In my test I have an input for the cardholder name and I then tab to the CardElement component.

describe('Test Input', () => {
  test('Filling out card payment form', async () => {
    let browser = await puppeteer.launch({
      headless: false,
      slowMo: 100
    });
    let page = await browser.newPage();

    page.emulate({
      viewport: {
        width: 1280,
        height: 1080
      },
      userAgent: ''
    });

    await page.goto('http://localhost:3000/asd/payment-requests/50-eur-by-2021-01-15t1200');

    await page.waitForSelector('#input-name');
    await page.click('input[name=card_name]')
    await page.type('input[name=card_name]', 'Joe Bloggs')
    await page.keyboard.press("Tab");
    await page.keyboard.type(card.number, { delay: 500 })
    await page.keyboard.type(card.month, { delay: 50 })
    await page.keyboard.type(card.year, { delay: 50 })
    await page.keyboard.type(card.cvc, { delay: 50 })
    await page.keyboard.type(card.zip, { delay: 50 })

    browser.close();
  }, 90000);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM