# Is it possible to interact with inputs or other elements in an iframe?

> Loadster's Browser Bots support special CSS-style selectors for interacting with an input or other element within an iframe.

Source: https://loadster.com/faqs/interacting-with-elements-in-an-iframe/

Loadster's [browser scripts](https://loadster.com/manual/browser-scripts/) reference elements using a selector. Whenever you want the bot to click on a
button, type text into a form input, or choose an option from a list, you'll need to use a selector to point to the element you're
interacting with.

But ordinary selectors only work in the scope of a single HTML document. That's why Loadster supports special
`iframe` selectors for resolving an element nested within an iframe.

```
iframe[id="the-iframe"] .the-element-in-the-iframe
```

These `iframe` selectors are necessary when you're scripting against a site that has important interactive elements in iframes, like
a Stripe payment form or a nested video player. Because a document inside an iframe has its own DOM tree, a normal selector wouldn't
find the nested element without a little help.

To resolve a selector within an iframe, your selector will need to specify the iframe itself as a parent element, and then reference
the element inside it with an ordinary sub-selector.

For example, let's say you have a video player nested inside an iframe, and you want the bot to click the play button
of this video player. You'll need to resolve the play button by first specifying the parent iframe, and then the play
button itself.

```
iframe[name="video-player"] #play
```

## Example of filling out a Stripe form

One common scripting challenge related to iframes is filling out a Stripe Elements form. These look like standard forms
in the browser, but with the added complication that each form field is typically buried within its own iframe.

Because each form field is in a separate iframe, the fields aren't part of the parent page's DOM and can't be
referenced by their usual selectors. Worse, the Stripe iframes themselves tend to have randomly generated IDs like
`id="__privateStripeFrame5347"` so you can't count on them being the same every time your script is played.

Instead, you can reference them by the iframe title, which is consistent.

```
iframe[title="Secure card number input frame"] input[name="cardnumber"]
```

This selector first locates the iframe titled "Secure card payment input frame" and then finds the actual input
field within that iframe.

Following is an example of filling out a Stripe frame with four elements using a Loadster
[Code Block](https://loadster.com/manual/code-blocks/).

```javascript
browser.type('iframe[title="Secure card number input frame"] input[name="cardnumber"]', '4242424242424242', { delay: 100 });
browser.type('iframe[title="Secure expiration date input frame"] input[name="exp-date"]', '1234', { delay: 100 });
browser.type('iframe[title="Secure CVC input frame"] input[name="cvc"]', '123', { delay: 100 });
browser.type('iframe[title="Secure postal code input frame"] input[name="postal"]', '90210', { delay: 100 });
```


We've found that the `{ delay: 100 }` parameter is sometimes necessary for Stripe forms, particularly for the
expiration date field, because Stripe has some client-side JavaScript that handles the keystrokes individually, and if
the bot types too fast (as bots often do) it jumbles the expiration date or other fields. For this reason it helps to
add a short 100ms delay between keystrokes when filling out Stripe forms.

Keep in mind that the bot will only be able to resolve elements inside iframes if you specify the iframe as an element
first, like in the above examples. Also keep in mind that a normal browser won't understand these `iframe` selectors –
they are a special custom extension that only works in Loadster.

## Caveats and pitfalls with iframe selectors

Again, Loadster's `iframe` selectors are a custom implementation because ordinary CSS does not allow selectors
to span multiple frames. As such, they have some caveats that make them different from ordinary CSS selectors.

* A frame selector must explicitly reference `frame` or `iframe`. It can't be a bare ID or class selector like
  `#myFrame` or `.my-frame`.
* A frame selector must match one unique result. If it matches multiple frames on the page it will fail.
* Nested frame selectors like `iframe[id="outer"] iframe[id="inner"] button` will work in most cases, but there may be
  edge cases where they don't.

