I have to fill out a form that is inside an iframe, here the sample page. I cannot access by simply using page.focus()
and page.type()
. I tried to get the form iframe by using const formFrame = page.mainFrame().childFrames()[0]
, which works but I cannot really interact with the form iframe.

- 1,006
- 1
- 15
- 41

- 3,147
- 2
- 31
- 35
-
What the page look's like, please consider that the other can't help you if we can't see the problem. – Adi Prasetyo Oct 16 '17 at 00:23
-
http://www.goodmanmfg.com/product-registration Here's the website. I want to autofill this website and register many serial numbers automatically. – Raza Oct 16 '17 at 04:11
-
the page is too heavy, around 6.6 MB. what puppeteer version you use? – Adi Prasetyo Oct 16 '17 at 17:49
-
I'm using the version that is available right now. 0.13.0 – Raza Oct 17 '17 at 01:37
-
i was unable to continue because, i don't have a valid serial number. – Adi Prasetyo Oct 19 '17 at 13:26
-
maybe you can give me sample serial number, so i can properly fill that 3 field. – Adi Prasetyo Oct 20 '17 at 12:47
-
1708020345. There's another page after that asking about the customer information but please don't next after that page. – Raza Oct 20 '17 at 17:17
-
Your serial [doesn't have model number](https://github.com/brutalcrozt/travis-reproducer/blob/master/img/heavy.png) , your question is not ready!! – Adi Prasetyo Oct 21 '17 at 07:18
-
That's strange, it works for me just fine. [link](https://imgur.com/a/Xmu6U) – Raza Oct 21 '17 at 22:08
-
See also [puppeteer #618: Clicking on an element in an iframe fails](https://github.com/puppeteer/puppeteer/issues/618) and [puppeteer #684: Clicking element inside iFrame does not give any response](https://github.com/puppeteer/puppeteer/issues/684) – ggorlen Jan 24 '21 at 02:52
4 Answers
I figured it out myself. Here's the code.
console.log('waiting for iframe with form to be ready.');
await page.waitForSelector('iframe');
console.log('iframe is ready. Loading iframe content');
const elementHandle = await page.$(
'iframe[src="https://example.com"]',
);
const frame = await elementHandle.contentFrame();
console.log('filling form in iframe');
await frame.type('#Name', 'Bob', { delay: 100 });

- 3,147
- 2
- 31
- 35
-
it seems 'delay' is important here. otherwise it types random stuff. not sure if its a bug or what.. – Neeraj Jun 01 '20 at 21:05
-
9`$` is redundant. `waitForSelector` already returns element handle. – Oleg V. Volkov Jul 23 '20 at 10:27
Instead of figuring out how to get inside the iFrame and type, I would simplify the problem by navigating to the IFrame URL directly
https://warranty.goodmanmfg.com/registration/NewRegistration/NewRegistration.aspx?Sender=Goodman
Make your script directly go to the above URL and try automating, it should work
Edit-1: Using frames
Since the simple approach didn't work for you, we do it with the frames itself
Below is a simple script which should help you get started
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('http://www.goodmanmfg.com/product-registration', { timeout: 80000 });
var frames = await page.frames();
var myframe = frames.find(
f =>
f.url().indexOf("NewRegistration") > -1);
const serialNumber = await myframe.$("#MainContent_SerNumText");
await serialNumber.type("12345");
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
The output is

- 2,985
- 21
- 25

- 142,312
- 9
- 204
- 265
-
I tried that too. But in the next page, you interact with the iframe and the main frame. – Raza Oct 21 '17 at 22:03
If you can't select/find iFrame read this:
I had an issue with finding stripe elements. The reason for that is the following:
You can't access an with different origin using JavaScript, it would be a huge security flaw if you could do it. For the same-origin policy browsers block scripts trying to access a frame with a different origin. See more detailed answer here
Therefore when I tried to use puppeteer's methods:Page.frames()
and Page.mainFrame().
ElementHandle.contentFrame()
I did not return any iframe to me. The problem is that it was happening silently and I couldn't figure out why it couldn't find anything.
Adding these arguments to launch options solved the issue:
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process'

- 577
- 6
- 13
Though you have figured out but I think I have better solution. Hope it helps.
async doFillForm() {
return await this.page.evaluate(() => {
let iframe = document.getElementById('frame_id_where_form_is _present');
let doc = iframe.contentDocument;
doc.querySelector('#username').value='Bob';
doc.querySelector('#password').value='pass123';
});
}

- 301
- 7
- 13