element: Error thrown when switching to iframe

Describe the bug When attempting to switch context to an iframe that contains some form fields i’m recieving the folllowing error

+66s info: ===> Step 'Test: User enters credit card information'
+66s info: ---> wait()
+66s info: ---> wait()
step error -> failed
+66s error:


Error: Could not match frame by name or id: 'easyXDM_default4069_provider'


Detail:
Documentation needed! Please report this at https://github.com/flood-io/element/issues so that we can improve Element!

+66s error: xxxx Step 'Test: User enters credit card information' failed
+66s info: ---> Step 'Test: User enters credit card information' finished
failed, bailing out of steps
+66s info: Iteration completed in 64858ms (walltime)
+66s info: Test completed after 1 iterations

To Reproduce Steps to reproduce the behavior:

  1. Go to ‘https://www.blinds.com’ and simply search for a product add to cart and get all the way to credit card checkout screen where you enter in your information

Expected behavior I’m expected to be able to enter credit card details into the iframe presented in the page

Desktop (please complete the following information):

  • OS: macOS
  • Node.js version: 14.4
  • Version: 1.2.3

code

		await browser.wait(Until.urlContains('Ordering/Checkout/Billing'))
		let iframe = await browser.findElement(By.tagName('iframe'))
		await browser.switchTo().frame(iframe)

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

@HieuLeKMS I am using Element v2.0.0-beta.12 trying to fill out a form in an iframe and am also having no luck. Here is my test script:

@HieuLeKMS not sure if this is related, but I figure the more clues, the better.

In the case mentioned above, since I know the iframe containing the credit card field is the only other frame available, I tried just referencing it by the frame index and here’s what happened:

export default () => {
  step('STEP 3 - FILL OUT SUBSCRIPTION FORM', async browser => {
    const stripeIFrame = await browser.findElement(By.css('iframe[title="Secure card payment input frame"]'))
    await browser.wait(Until.elementIsVisible(stripeIFrame))

    await browser.switchTo().frame(2)

    const cardNumberInput = By.nameAttr('cardnumber')
    await browser.type(cardNumberInput, '4242424242424242')
  })
})

output:

      page.evaluate: Evaluation failed: Permission denied to access property "name" on cross-origin object
@__playwright_evaluation_script__93:5:21
callFunction@__playwright_evaluation_script__59:305:28
@__playwright_evaluation_script__94:1:44

  step -> failed

Thanks for the hep @HieuLeKMS

Hey @HieuLeKMS Were you able to find out anything on this?

Yeah, this seems to be a bug from Puppeteer v2.1.1. As Puppeteer’s docs mentioned, frame.name() should return the frame’s id if its name is empty. But actually it return an empty string even if the frame’s id exists.

So the frame cannot be found when Element trying to find it by id, like: frames.find(frame => frame.name() === id)

I’m fixing this, but it currently work if you pass in the frame’s id instead of the frame itself:

await browser.wait(Until.urlContains('Ordering/Checkout/Billing'))
let iframe = await browser.findElement(By.tagName('iframe'))
await browser.switchTo().frame(await iframe.getId())

Hey @HieuLeKMS ,

I will give this a shot and confirm the results back with you. Thanks for the hard work.

Hi @TraGicCode,

I’m trying to reproduce this issue but got “Access Denied” when visiting https://www.blinds.com/

image

That is going to be the WAF that is blocking you! Maybe you could try this again simply look at the iframe or mimic it locally to see if you can reproduce the issue. If your trying to run from the homepage all the way to checkout the WAF will most likely pick you up as a bot and block you.