How to use Puppeteer with Stripe Elements

Viewed 936

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?

2 Answers

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);
});
Related