Skip to content

Iframes, selectors and waiting for elements#

This page shows how to target the right iframe, pick one of several elements that match a selector, wait for an element, and read the result of EvalScript.

An element inside an iframe can only be found when you point to the right frame. Most page functions take frameSearch and frameSearchType as their last two parameters to choose the frame, including cross-domain iframes. You must pass both: without frameSearchType, the function ignores frameSearch and acts on the main frame. Leave both empty to act on the main frame.

frameSearchType How the frame is found
frame-path By nesting position, no URL needed: "0" is the first frame at the top level, "0>1" is the second child frame inside that frame
src-starts The URL starts with frameSearch
src-ends The URL ends with frameSearch
src-equals The URL exactly matches frameSearch
src-contains The URL contains frameSearch (also used when frameSearchType is not a valid value)
src-regex The URL matches the regex frameSearch
// Click the #submit button in the iframe whose URL contains "checkout"
await ClickBySelector("#submit", 0, 1, "checkout", "src-contains");

// Fill in the input in the 2nd child frame of the first frame
await SetById("my-input", "value", "hello", "0>1", "frame-path");

The index parameter of the Click/Set functions#

When a selector, class or tag matches several elements, functions such as ClickBySelector, ClickByClass, ClickByTag, SetByClass, SetByTag take an index parameter: a position number (0 is the first matching element), "random" to pick one at random, or "all" (only with the Set* functions) to apply to every matching element.

await ClickByClass("skip-button", "random"); // click any one .skip-button button
await SetByClass("promo-code", "value", "SALE10", "all"); // fill in every .promo-code field

The state parameter of WaitForElmt*#

WaitForElmtBySelector and WaitForElmtByXpath take a state parameter that describes the condition to wait for. state must be an object, not a string:

{ exists: true }                        // the element appears (false: it is removed from the page)
{ attr: "data-state", exists: true }    // the attribute appears (false: it is removed)
{ attr: "data-state", equals: "ready" } // the attribute has exactly this value
{ attr: "data-state", contains: "ok" }  // likewise: startsWith, endsWith
{ attr: "text", equals: "Hello!" }      // "text" compares with innerText, "html" with innerHTML

The function checks once per second, for up to timeout seconds, then returns true if the condition happens in time or false if time runs out. The macro does not stop on its own; you decide what to do based on this value.

What EvalScript returns#

EvalScript (and EvalScriptWithPromise) always wraps the result in an object:

{ result: <return value> }   // ran successfully
{ error: "TypeError: ..." }   // the JS in the page threw an error
{}                           // the expression returned undefined

Get the value through the result field. When the JS fails or returns nothing, val is undefined:

const val = (await EvalScript("document.title"))?.result;