Skip to content

DOM and JavaScript functions#

Functions that read and write elements on the page, wait for elements, and run JavaScript in the page. Macro code does not run inside the page, so to use the page's document or window, call EvalScript.

EvalScript#

Runs a piece of JavaScript in the page (or in a given iframe) and returns the result. The function does not wait for Promises; to wait for one, use EvalScriptWithPromise.

Syntax
await EvalScript(js, frameSearch, frameSearchType);
Parameters
Name Description
js The JavaScript to run; the value of the last expression is the result. You can pass a function instead of a string to avoid escaping quotes: the function is called right inside the page, so it cannot use the macro's variables.
frameSearch Condition for finding the iframe to run the JS in, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

Always an object: {result} when the code runs, {error} when the JS throws an error or the iframe is not found, {} when the JS returns no value. The result should only be a number, string, array or plain object: a DOM element comes back as an empty object. See What EvalScript returns.

Examples
await WaitForLoading(30);

const r1 = await EvalScript('(5 + 4) + "hits"');
// r1 = {result: "9hits"}

const r2 = await EvalScript("null[0]");
// r2 = {error: "TypeError: Cannot read properties of null ..."}
if (r2.error) Log("JS error:", r2.error);

// get the value directly, undefined on error
const title = (await EvalScript("document.title"))?.result;

// pass a function instead of a string: count the links on the page
const r3 = await EvalScript(() => document.querySelectorAll("a").length);
// r3 = {result: 42}

// run in the iframe whose URL contains "checkout"
const r4 = await EvalScript("location.href", "checkout", "src-contains");

EvalScriptWithPromise#

Like EvalScript, but if the JS returns a Promise (an async function, fetch, ...), it waits for the Promise to finish before returning the result. If the JS does not return a Promise, use EvalScript.

Syntax
await EvalScriptWithPromise(js, frameSearch, frameSearchType);
Parameters
Name Description
js JavaScript that returns a Promise, for example 'Promise.resolve("9hits")' or an async function that is called immediately. You can pass an async function directly instead of a string; the function runs in the page, so it cannot use the macro's variables.
frameSearch Condition for finding the iframe to run the JS in, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

{result} with the value the Promise resolves to, or {error} when the Promise is rejected, the JS throws an error or the iframe is not found. See What EvalScript returns.

Examples
await WaitForLoading(30);

const r1 = await EvalScriptWithPromise('(async () => { return "9hits" })()');
// r1 = {result: "9hits"}

const r2 = await EvalScriptWithPromise('Promise.resolve("9hits")');
// r2 = {result: "9hits"}

const r3 = await EvalScriptWithPromise('Promise.noSuchFunc("9hits")');
// r3 = {error: "TypeError: Promise.noSuchFunc is not a function ..."}

// fetch robots.txt of the current site, wait until it finishes, then get the content
const r4 = await EvalScriptWithPromise(async () => {
    const res = await fetch("/robots.txt");
    return res.text();
});
Log(r4.result);

GetElementPos#

Gets the coordinates of the element returned by a piece of JavaScript. Use it when a normal selector cannot reach the element (for example an element inside a shadow DOM). This is the coordinates-only version of ClickByCustomJS.

Syntax
await GetElementPos(jsCode, frameSearch="", frameSearchType="");
Parameters
Name Description
jsCode JavaScript that runs in the page and whose last value is the element to measure; it can also be a function that returns the element. The function does not scroll to the element by itself: if the element may be off screen, call scrollIntoView() inside this code.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

An object {x1, y1, x2, y2}: the top-left and bottom-right corners of the element, relative to the visible area of the page. {error} when there is no element, the element is not visible or the JS fails.

Examples
// the .submit button is inside the shadow DOM of #app
const pos = await GetElementPos("document.querySelector('#app').shadowRoot.querySelector('.submit')");
// pos = {x1: 100, y1: 200, x2: 180, y2: 230}
if (!pos.error) await ClickByCoordinates(pos.x1, pos.y1, pos.x2, pos.y2);

// scroll the element to the middle of the screen, then measure it
const pos2 = await GetElementPos(() => {
    const el = document.getElementById("submit-button");
    el.scrollIntoView({block: "center"});
    return el;
});

GetElementPosBySelector#

Gets the coordinates of the first visible element that matches a CSS selector, for use with coordinate-based functions such as ClickByCoordinates, MoveMouseToArea and CaptureArea. The function scrolls the element to the middle of the screen before measuring; if the page scrolls away, the coordinates change too.

Syntax
await GetElementPosBySelector(selector, frameSearch="", frameSearchType="", skipZeroOffset=true);
Parameters
Name Description
selector A CSS selector, for example "#banner". Hidden elements (display: none, visibility: hidden) are skipped.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
skipZeroOffset true skips elements whose width or height is 0; false includes them. Default true (ClickBySelector does not skip them, so with the same selector the two functions can pick different elements).
Returns

An object {x1, y1, x2, y2}: the top-left and bottom-right corners of the element, relative to the visible area of the page. {error} when the element is not found.

Examples
1
2
3
4
5
6
const pos = await GetElementPosBySelector("#banner");
// pos = {x1: 120, y1: 300, x2: 840, y2: 390}
if (!pos.error) await MoveMouseToArea(pos.x1, pos.y1, pos.x2, pos.y2);

// the element is inside an iframe whose URL contains "ads"
const ad = await GetElementPosBySelector("img", "ads", "src-contains");

SetAttrBySelector#

Sets an attribute on the element that matches a CSS selector: fill in an input, check a checkbox, change the displayed text or change any HTML attribute.

Syntax
await SetAttrBySelector(selector, attr, value, index, frameSearch="", frameSearchType="");
Parameters
Name Description
selector A CSS selector, for example "input[name='email']".
attr Name of the attribute to set. "value" is the input's value, "checked" is the checkbox state, "text" is the element's displayed text; any other name (for example "href", "data-id") is written as an HTML attribute. "html" is not supported: to change the HTML inside the element, use EvalScript.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
index Which element to use when several match: a position counted from 0, "random" to pick one at random, or "all" to set every matching element. Empty means 0. Hidden elements are counted too. See The index parameter.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when selector or attr is invalid.

Examples
1
2
3
4
5
6
7
8
// check the agree checkbox
await SetAttrBySelector("#agree-checkbox", "checked", true);

// fill the same value into every .text-box field
await SetAttrBySelector(".text-box", "value", "text value", "all");

// change the link of the 2nd a.download element
await SetAttrBySelector("a.download", "href", "https://9hits.com/", 1);

Warning

Setting value this way does not fire input events, so many forms do not pick it up. To fill a form reliably, click the field and then use Typing.

SetByClass#

Like SetAttrBySelector, but picks elements whose class attribute contains the string className, so "box" also matches "text-box".

Syntax
await SetByClass(className, attr, value, index, frameSearch="", frameSearchType="");
Parameters
Name Description
className String that must appear in the element's class attribute, for example "text-box".
attr Name of the attribute to set: "value", "checked", "text" or any HTML attribute name. See SetAttrBySelector.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
index Which element to use when several match: a position counted from 0, "random" to pick one at random, or "all" to set every matching element. Empty means 0.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when a parameter is invalid.

Examples
1
2
3
4
await SetByClass("text-box", "value", "text value");           // first matching field
await SetByClass("text-box", "value", "text value", 2);        // 3rd matching field
await SetByClass("text-box", "value", "text value", "random"); // a random field
await SetByClass("text-box", "value", "text value", "all");    // every matching field

SetById#

Like SetAttrBySelector, but picks exactly one element by id, so there is no index.

Syntax
await SetById(id, attr, value, frameSearch="", frameSearchType="");
Parameters
Name Description
id The element's id value, without the #, for example "email".
attr Name of the attribute to set: "value", "checked", "text" or any HTML attribute name. See SetAttrBySelector.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when a parameter is invalid.

Examples
1
2
3
4
5
// fill an email address into the field with id="email"
await SetById("email", "value", "[email protected]");

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

SetByName#

Like SetAttrBySelector, but picks elements whose name attribute equals this value exactly.

Syntax
await SetByName(name, attr, value, index, frameSearch="", frameSearchType="");
Parameters
Name Description
name Value of the element's name attribute, for example "email". Must match exactly.
attr Name of the attribute to set: "value", "checked", "text" or any HTML attribute name. See SetAttrBySelector.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
index Which element to use when several match: a position counted from 0, "random" to pick one at random, or "all" to set every matching element. Empty means 0.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when a parameter is invalid.

Examples
1
2
3
4
5
// fill the input with name="email"
await SetByName("email", "value", "[email protected]");

// select a random radio button with name="gender"
await SetByName("gender", "checked", true, "random");

SetByTag#

Like SetAttrBySelector, but picks elements by tag name.

Syntax
await SetByTag(tagName, attr, value, index, frameSearch="", frameSearchType="");
Parameters
Name Description
tagName HTML tag name, for example "input", "textarea".
attr Name of the attribute to set: "value", "checked", "text" or any HTML attribute name. See SetAttrBySelector.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
index Which element to use when several match: a position counted from 0, "random" to pick one at random, or "all" to set every matching element. Empty means 0.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when a parameter is invalid.

Examples
1
2
3
4
await SetByTag("input", "value", "text value");           // first input element
await SetByTag("input", "value", "text value", 2);        // 3rd input element
await SetByTag("input", "value", "text value", "random"); // a random input element
await SetByTag("input", "value", "text value", "all");    // every input element

SetByXpath#

Like SetAttrBySelector, but picks the first element that matches an xpath, so there is no index.

Syntax
await SetByXpath(xpath, attr, value, frameSearch="", frameSearchType="");
Parameters
Name Description
xpath An XPath expression, for example '//input[@type="email"]'. You can build one with GenerateXpath.
attr Name of the attribute to set: "value", "checked", "text" or any HTML attribute name. See SetAttrBySelector.
value The value to set, converted to a string. For "checked", pass true to check and "" to uncheck.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the value is set, false when a parameter is invalid or the element is not found.

Examples
1
2
3
4
await SetByXpath('//input[@type="email"]', "value", "[email protected]");

// combined with GenerateXpath: the input whose name starts with "user"
await SetByXpath(GenerateXpath("input", "name", "user%"), "value", "9hits");

SetFilesToElement #

Assigns files on your computer to the <input type="file"> field that matches a CSS selector, as if the user picked files to upload, without opening the file picker. The function cannot be used in 9Hits campaign macros.

Syntax
await SetFilesToElement(selector, files, frameSearch="", frameSearchType="");
Parameters
Name Description
selector A CSS selector that points to an <input type="file"> field, for example "#file-input". The function takes the first visible matching element; a field hidden with display: none or visibility: hidden is not picked.
files Array of absolute paths to the files, for example ["C:/path/to/avatar.png"]. Every file must exist.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true when the files are assigned, false when the element is not found or a file does not exist; {error: "Blocked"} in 9Hits campaign macros.

Examples
1
2
3
4
5
6
// pick an avatar image, then click the upload button
const ok = await SetFilesToElement("#file-input", ["C:/path/to/avatar.png"]);
if (ok === true) await ClickBySelector("#upload");

// assign several files to an input that has the multiple attribute
await SetFilesToElement("input[type=file][multiple]", ["C:/photos/1.jpg", "C:/photos/2.jpg"]);

WaitForElmtBySelector#

Waits until the element that matches a CSS selector meets a condition (appears, disappears, or an attribute or the displayed text has the expected value), or until timeout runs out. The function checks once per second.

Syntax
await WaitForElmtBySelector(selector, state, timeout=60, frameSearch="", frameSearchType="");
Parameters
Name Description
selector A CSS selector, for example "#result". Only the first matching element is checked.
state Object that describes the condition to wait for (not a string), with the fields below. See also The state parameter.
state.exists Without attr: true waits for the element to appear, false waits for it to disappear. With attr: true waits for the element to have that attribute, false waits for the attribute to be removed.
state.attr Name of the attribute to check, or "text" (displayed text), "html" (HTML inside the element). Use it with exists or with one of the four comparison fields below.
state.equals Waits until the value of attr is exactly this string.
state.contains Waits until the value of attr contains this string.
state.startsWith Waits until the value of attr starts with this string.
state.endsWith Waits until the value of attr ends with this string.
timeout Maximum number of seconds to wait (seconds, not milliseconds). Default 60.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true if the condition is met before timeout runs out, false if not. The macro does not stop by itself when time runs out; handle it yourself based on this value.

Examples
// wait up to 15 seconds for #result to appear
const ok = await WaitForElmtBySelector("#result", { exists: true }, 15);
if (!ok) Log("#result not found");

// wait for the .loading overlay to disappear
await WaitForElmtBySelector(".loading", { exists: false }, 30);

// wait for the text in .status to contain "Done"
await WaitForElmtBySelector(".status", { attr: "text", contains: "Done" }, 30);

// wait until the #submit button is no longer disabled
await WaitForElmtBySelector("#submit", { attr: "disabled", exists: false });

// wait for the #pay button in the iframe whose URL contains "checkout"
await WaitForElmtBySelector("#pay", { exists: true }, 20, "checkout", "src-contains");

WaitForElmtByXpath#

Like WaitForElmtBySelector, but finds the element by xpath.

Syntax
await WaitForElmtByXpath(xpath, state, timeout=60, frameSearch="", frameSearchType="");
Parameters
Name Description
xpath An XPath expression, for example "//div[@id='result']". Only the first matching element is checked.
state Condition object: {exists}, {attr, exists}, or {attr} with one of equals, contains, startsWith, endsWith. Each field means the same as in WaitForElmtBySelector; see also The state parameter.
timeout Maximum number of seconds to wait (seconds, not milliseconds). Default 60.
frameSearch Condition for finding the iframe that contains the element, used together with frameSearchType; leave empty for the main frame. See Iframes, selectors and waiting.
frameSearchType How to match frameSearch: "src-starts", "src-ends", "src-equals", "src-contains", "src-regex" or "frame-path". Required when you use frameSearch: if it is empty, the function ignores frameSearch and works on the main frame.
Returns

true if the condition is met before timeout runs out, false if not.

Examples
1
2
3
4
5
// wait for div#result to appear, up to 60 seconds (the default)
await WaitForElmtByXpath("//div[@id='result']", { exists: true });

// wait up to 20 seconds for a button with the text "Continue"
const ok = await WaitForElmtByXpath("//button[contains(., 'Continue')]", { exists: true }, 20);