Skip to main content

ExecuteScript

Instructs an actor who has the ability to BrowseTheWeb to inject a script into the browser and execute it in the context of the current browser tab.

Learn more

Index

Constructors

Methods

Constructors

constructor

Methods

staticfrom

  • from(sourceUrl: Answerable<string>): Interaction
  • Instantiates a version of this Interaction configured to load a script from sourceUrl.


    Parameters

    • sourceUrl: Answerable<string>

      The URL to load the script from

    Returns Interaction

staticasync

  • Instructs an actor who has the ability to BrowseTheWeb to execute an asynchronous script within the context of the current browser tab.

    The script fragment will be executed as the body of an anonymous function. If the script is provided as a function object, that function will be converted to a string for injection into the target window.

    Any arguments provided in addition to the script will be included as script arguments and may be referenced using the arguments object. Arguments may be a boolean, number, string or PageElement. Arrays and objects may also be used as script arguments as long as each item adheres to the types previously mentioned.

    Unlike executing synchronous JavaScript with ExecuteScript.sync, scripts executed with this function must explicitly signal they are finished by invoking the provided callback.

    This callback will always be injected into the executed function as the last argument, and thus may be referenced with arguments[arguments.length - 1].

    If the script invokes the callback with a return value, this will be made available via the LastScriptExecution.result.

    Please note that in order to signal an error in the script you need to throw an Error instead of passing it to the callback function.

    Executing an async script

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript } from '@serenity-js/web'

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(`
    var callback = arguments[arguments.length - 1]

    // do stuff

    callback(result)
    `)
    )

    Executing async script as function

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript } from '@serenity-js/web'

    const MyPage = {
    header: () =>
    PageElement.located(By.css('h1')).describedAs('header'),
    }

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(function getText(header, callback) {
    callback(header.innerText)
    }).withArguments(MyPage.header())
    )

    Passing arguments to an async script

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript } from '@serenity-js/web'

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(`
    var name = arguments[0];
    var age = arguments[1];
    var callback = arguments[arguments.length - 1]

    // do stuff

    callback(result)
    `).withArguments('Bob', 24)
    )

    Passing PageElement arguments to an async script

    Serenity/JS automatically converts PageElement objects passed as arguments to the script into their corresponding DOM elements.

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript, PageElement } from '@serenity-js/web'

    const MyPage = {
    header: () =>
    PageElement.located(By.css('h1')).describedAs('header'),
    }

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(`
    var header = arguments[0]
    var callback = arguments[arguments.length - 1]

    callback(header.innerText)
    `).withArguments(MyPage.header())
    )

    Using nested data structures containing PageElement objects

    Serenity/JS automatically converts any PageElement objects contained in nested data structures passed to the script into their corresponding DOM elements.

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript, PageElement } from '@serenity-js/web'

    const MyPage = {
    header: () =>
    PageElement.located(By.css('h1')).describedAs('header'),

    article: () =>
    PageElement.located(By.css('article')).describedAs('article'),
    }

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(`
    var { include, exclude } = arguments[0]
    var callback = arguments[arguments.length - 1]

    callback(include[0].innerText)
    `).withArguments({
    include: [ MyPage.article() ],
    exclude: [ MyPage.header() ],
    })
    )

    Learn more


    Parameters

    • script: string | Function

      The script to be executed

    Returns ExecuteScriptWithArguments

staticsync

  • Instructs an actor who has the ability to BrowseTheWeb to execute a synchronous script within the context of the current browser tab.

    If the script returns a value, it will be made available via LastScriptExecution.result.

    Executing a sync script as string and reading the result

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript, LastScriptExecution } from '@serenity-js/web'
    import { Ensure, includes } from '@serenity-js/assertions'

    await actorCalled('Joseph')
    .attemptsTo(
    ExecuteScript.sync('return navigator.userAgent'),
    Ensure.that(LastScriptExecution.result<string>(), includes('Chrome')),
    )

    Executing a sync script as function and retrieving the result

    import { actorCalled } from '@serenity-js/core'
    import { By, Enter, ExecuteScript, LastScriptExecution, PageElement } from '@serenity-js/web'

    const Checkout = {
    someOfferField: () =>
    PageElement.located(By.id('offer-code'))
    .describedAs('offer code')

    applyOfferCodeField = () =>
    PageElement.located(By.id('apply-offer-code'))
    .describedAs('apply offer field')
    }

    await actorCalled('Joseph')
    .attemptsTo(
    // inject JavaScript to read some property of an element
    ExecuteScript.sync(function getValue(element) {
    return element.value;
    }).withArguments(Checkout.someOfferField()),

    // use LastScriptExecution.result() to read the value
    // returned from the injected script
    // and pass it to another interaction
    Enter.theValue(LastScriptExecution.result<string>()).into(Checkout.applyOfferCodeField()),
    )

    Passing PageElement arguments to a sync script

    Serenity/JS automatically converts PageElement objects passed as arguments to the script into their corresponding DOM elements.

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript, PageElement } from '@serenity-js/web'

    const MyPage = {
    header: () =>
    PageElement.located(By.css('h1')).describedAs('header'),
    }

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.sync(function getInnerHtml(element) {
    return element.innerHTML;
    }).withArguments(MyPage.header())
    )

    Using nested data structures containing PageElement objects

    Serenity/JS automatically converts any PageElement objects contained in nested data structures passed to the script into their corresponding DOM elements.

    import { actorCalled } from '@serenity-js/core'
    import { ExecuteScript, PageElement } from '@serenity-js/web'

    const MyPage = {
    header: () =>
    PageElement.located(By.css('h1')).describedAs('header'),

    article: () =>
    PageElement.located(By.css('article')).describedAs('article'),
    }

    await actorCalled('Esti').attemptsTo(
    ExecuteScript.async(function getInnerHtml(scope) {
    return scope.include[0].innerHTML;
    `).withArguments({
    include: [ MyPage.article() ],
    exclude: [ MyPage.header() ],
    })
    )

    Learn more


    Parameters

    • script: string | Function

      The script to be executed

    Returns ExecuteScriptWithArguments