Custom commands
Loadero provides several predefined custom commands you can use in your test scripts which extend the built-in commands of the frameworks themselves. These commands provide additional functionality for various scenarios.
There are also packages available to support local script development by providing equivalent commands to the ones described on this page. However, not all of these commands will work the exact same way as they would on Loadero (e.g., the "Update Network" command is implemented as a no-op locally, so that using the command does not fail the test, if the script is copied over from Loadero). Make sure to check the documentation of the package. A link to the local development package for each language is provided below:
Set File
This custom command allows uploading a file to a file upload element.
Loadero sets up every participant's browser so that there are five files already prepared for use. These are intended for cases where the file content itself is not of importance and the actual objective is to simply check whether uploading a file of that size works at all or to evaluate how long it takes.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setFile(selector: string, fileName: string);
The selector
parameter specifies the selector of the input element, e.g.
input[type="file"]
, input#file-upload
.
The fileName
parameter specifies the name of the file you would like to
upload. To use files names more safely in code it's recommended to use the
predefined constants.
Sample file | Constant | String value |
---|---|---|
100 KB (PNG) | png100KB | "loaderoSample100KB.png" |
1 MB (PNG) | png1MB | "loaderoSample1MB.png" |
5 MB (PNG) | png5MB | "loaderoSample5MB.png" |
30 MB (PNG) | png30MB | "loaderoSample30MB.png" |
100 MB (TXT) | txt100MB | "loaderoSample100MB.txt" |
In case there is a need for other file format or size, feel free to contact us.
client => {
// Example of uploading sample file into file input field using constants
client
// Open DemoQA upload/download page
.url("https://demoqa.com/upload-download")
// Wait for up to 10s for "Choose file" button to be visible
.waitForElementVisible("#uploadFile", 10 * 1000)
// Upload Loadero sample image
.setFile("#uploadFile", loaderoConstants.sampleFiles.png100KB)
.saveScreenshot("file_set.png");
}
Nightwatch.js has its own file upload method - uploadFile()
, which relies on
access to the file system. Participants do not have access to the file system of
the server on which they are executing the test - they only have access to their
specific browser's context. The prepared files mentioned above and any files
downloaded during the test will be accessible within the browser's context, but
these files will only be accessible via the custom setFile()
command.
setFile(By selector, String fileName);
The selector
parameter specifies the selector of the input element, e.g.
input[type="file"]
, input#file-upload
.
The fileName
parameter specifies the name of the file you would like to
upload. To use files names more safely in code it's recommended to use the
getters.
Sample file | Getter | String value |
---|---|---|
100 KB (PNG) | getPNG100KB() | "loaderoSample100KB.png" |
1 MB (PNG) | getPNG1MB() | "loaderoSample1MB.png" |
5 MB (PNG) | getPNG5MB() | "loaderoSample5MB.png" |
30 MB (PNG) | getPNG30MB() | "loaderoSample30MB.png" |
100 MB (TXT) | getTXT100MB() | "loaderoSample100MB.txt" |
In case there is a need for other file format or size, feel free to contact us.
public void testUIWithLoadero() {
// Example of setting sample file into file input field using constants
// Open DemoQA upload/download page
open("https://demoqa.com/upload-download");
E(byCssSelector("#app")).waitFor(10).untilIsVisible();
E(byCssSelector("#uploadFile")).waitFor(10).untilIsVisible();
E(byCssSelector("#app")).saveScreenshot("before_upload.png");
// Upload Loadero sample image
setFile(
byCssSelector("#uploadFile"),
loaderoConstants.getSampleFiles().getPNG100KB()
);
sleep(10*1000);
E(byCssSelector("#app")).saveScreenshot("search_by_image_results.png");
}
def set_file(driver: TestUIDriver, element: Elements, file_name: str) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The element
parameter specifies the input element. Note that this must be an
element, not its selector. E.g., input#file-upload
will not work, but
E(driver, "css", "input#file-upload")
will.
The file_name
parameter specifies the name of the file you would like to
upload. To use files names more safely in code it's recommended to use the
predefined constants.
Sample file | Constant | String value |
---|---|---|
100 KB (PNG) | png_100KB | "loaderoSample100KB.png" |
1 MB (PNG) | png_1MB | "loaderoSample1MB.png" |
5 MB (PNG) | png_5MB | "loaderoSample5MB.png" |
30 MB (PNG) | png_30MB | "loaderoSample30MB.png" |
100 MB (TXT) | txt_100MB | "loaderoSample100MB.txt" |
In case there is a need for other file format or size, feel free to contact us.
def test(driver: TestUIDriver):
# Example of setting sample file into file input field using constants
# Open DemoQA upload/download page
driver.navigate_to("https://demoqa.com/upload-download")
e(driver, "css", "#app").wait_until_visible()
e(
driver, "css", "#uploadFile"
).wait_until_visible()
file_input_element = e(
driver, "css", "#uploadFile"
)
driver.save_screenshot("before_file_is_set.png")
# Upload Loadero sample image
set_file(
driver, file_input_element, LOADERO_CONSTANTS.sample_files.png_100KB
)
time.sleep(5)
driver.save_screenshot("search_by_image_results.png")
You can also host your own custom file somewhere that is accessible on the web,
navigate to that URL in the test and download the file from there. You will then
have that file accessible in the browser's downloads and be able to upload it
elsewhere (e.g., a mock ID photo), as long as you predict what that file's name
will be and reference it with the /home/seluser/Downloads/
path prefix.
Set User Agent
This command changes the
User-Agent
header
for outgoing requests and
navigator.userAgent
.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setUserAgent(userAgent: string);
The only parameter of this function is a string value that you want to have your user agent changed to.
To reset User-Agent
to its default value, pass null
as the new value.
Setting User-Agent
to an empty string will actually update the User-Agent
to
empty string.
client => {
// Example of setting custom user-agent
client
// Open page and create screenshot with default User-Agent
.url("https://www.bing.com/")
.waitForElementVisible("[type=search]", 10 * 1000)
.saveScreenshot("default_user_agent.png")
// Set custom User-Agent value
.setUserAgent("Custom User Agent")
// Refresh the page
.refresh()
// Wait for the page to load and create screenshot with changed User-Agent
.waitForElementVisible("[type=search]", 10 * 1000)
.saveScreenshot("custom_user_agent.png")
// Set User-Agent to empty string value
.setUserAgent("")
// Refresh the page
.refresh()
// Wait for the page to load and create screenshot with empty User-Agent
.waitForElementVisible("[type=search]", 10 * 1000)
.saveScreenshot("empty_user_agent.png")
// Reset User-Agent to original value
.setUserAgent(null)
// Refresh the page
.refresh()
// Wait for the page to load and create screenshot with reset User-Agent
.waitForElementVisible("[type=search]", 10 * 1000)
.saveScreenshot("reverted_user_agent.png");
}
setUserAgent(String userAgent);
The only parameter of this function is a string value that you want to have your user agent changed to.
To reset User-Agent
to its default value, pass null
as the new value.
Setting User-Agent
to an empty string will actually update the User-Agent
to
empty string.
public void testUIWithLoadero() {
// Example of setting custom user-agent
// Open page and create screenshot with default User-Agent
open("https://www.bing.com");
E(byCssSelector(".dimmer")).waitFor(10).untilIsVisible()
.saveScreenshot("default_user_agent.png");
// Set custom User-Agent value
setUserAgent("Custom User Agent");
// Refresh the page
getSelenideDriver().navigate().refresh();
// Wait for the page to load and create screenshot with changed User-Agent
E(byCssSelector(".dimmer")).waitFor(10).untilIsVisible()
.saveScreenshot("custom_user_agent.png");
// Set User-Agent to empty string value
setUserAgent("");
// Refresh the page
getSelenideDriver().navigate().refresh();
// Wait for the page to load and create screenshot with empty User-Agent
E(byCssSelector(".dimmer")).waitFor(10).untilIsVisible()
.saveScreenshot("empty_user_agent.png");
// Reset User-Agent to original value
setUserAgent(null);
// Refresh the page
getSelenideDriver().navigate().refresh();
// Wait for the page to load and create screenshot with reset User-Agent
E(byCssSelector(".dimmer")).waitFor(10).untilIsVisible()
.saveScreenshot("reset_user_agent.png");
}
def set_user_agent(driver: TestUIDriver, value: str or None = None) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The value
parameter is a string value that you want to have your user agent
changed to.
To reset User-Agent
to its default value, pass None
as the new value.
Setting User-Agent
to an empty string will actually update the User-Agent
to
empty string.
def test(driver: TestUIDriver):
# Example of setting custom user-agent
# Open page and create screenshot with default User-Agent
driver.navigate_to("https://www.bing.com")
e(driver, "css", ".dimmer").wait_until_visible()
driver.save_screenshot("default_user_agent.png")
# Set custom User-Agent value and reload browser
set_user_agent(driver, "Custom User Agent")
driver.get_driver().refresh()
e(driver, "css", ".dimmer").wait_until_visible()
# Take screenshot with custom User Agent
driver.save_screenshot("custom_user_agent.png")
# Set empty user agent header
set_user_agent(driver, "")
# Wait for page to load and create screenshot
driver.get_driver().refresh()
e(driver, "css", ".dimmer").wait_until_visible()
driver.save_screenshot("empty_user_agent.png")
# Reset user agent header
set_user_agent(driver, None)
# Wait for page to load and create screenshot
driver.get_driver().refresh()
e(driver, "css", ".dimmer").wait_until_visible()
driver.save_screenshot("reset_user_agent.png")
User-Agent will revert to its original value in browser built-in pages and the WebRTC dump.
Update Network
This command allows updating network conditions dynamically during the test.
Predefined network condition usage
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.updateNetwork(networkMode: string);
The networkMode
parameter specifies the network conditions that you would like
to switch to. Available network configurations and their associated
networkMode
parameter values can be found
here. These network configurations can be
provided as a string value or as a constant. Constants pertaining to this
command can be accessed under loaderoConstants.network
. Refer to the table below
for a full reference of the available constants.
Network mode | Constant | String value |
---|---|---|
Default | default | "default" |
4G | mobile_4g | "4g" |
3.5G/HSPDA | mobile_hsdpa | "hsdpa" |
3G | mobile_3g | "3g" |
GPRS | mobile_gprs | "gprs" |
Edge | mobile_edge | "edge" |
High jitter | jitter | "jitter" |
High latency | latency | "latency" |
Asymmetric | asymmetric | "asymmetric" |
Satellite phone | satellite | "satellite" |
5% packetloss | packetloss5 | "5packet" |
10% packetloss | packetloss10 | "10packet" |
20% packetloss | packetloss20 | "20packet" |
50% packetloss | packetloss50 | "50packet" |
100% packetloss | packetloss100 | "100packet" |
Custom | custom | "custom" |
client => {
// Example of updating network conditions via constant
client
.url('https://www.bing.com')
.waitForElementVisible('[type=search]', 10000)
.updateNetwork(loaderoConstants.network.mobile_3g);
}
client => {
// Example of updating network conditions via string value
client
.url('https://www.bing.com')
.waitForElementVisible('[type=search]', 10000)
.updateNetwork("3g");
}
updateNetwork(String networkMode);
The networkMode
parameter specifies the network conditions that you would like
to switch to. Available network configurations and their associated
networkMode
values can be found here or
they can be accessed using getters. Getters pertaining to this command can be
accessed under loaderoConstants.getNetwork()
. Refer to the table below for a
full reference of the available constants.
Network mode | Getter | String value |
---|---|---|
Default | getDefault() | "default" |
4G | getMobile4G() | "4g" |
3.5G/HSPDA | getMobileHSDPA() | "hsdpa" |
3G | getMobile3G() | "3g" |
GPRS | getMobileGPRS() | "gprs" |
Edge | getMobileEdge() | "edge" |
High jitter | getJitter() | "jitter" |
High latency | getLatency() | "latency" |
Asymmetric | getAsymmetric() | "asymmetric" |
Satellite phone | getSatellite() | "satellite" |
5% packetloss | getPacketLoss5() | "5packet" |
10% packetloss | getPacketLoss10() | "10packet" |
20% packetloss | getPacketLoss20() | "20packet" |
50% packetloss | getPacketLoss50() | "50packet" |
100% packetloss | getPacketLoss100() | "100packet" |
Custom | getCustom() | "custom" |
public void testUIWithLoadero() {
// Example of updating network conditions using a getter
open("https://www.bing.com");
E(byCssSelector(".dimmer"))
.waitFor(10).untilIsVisible();
// Update network conditions to mobile 4G settings
updateNetwork(loaderoConstants.getNetwork().getMobile4G());
}
public void testUIWithLoadero() {
// Example of updating network conditions via string value
open("https://www.bing.com");
E(byCssSelector(".dimmer"))
.waitFor(10).untilIsVisible();
// Update network conditions to mobile 4G settings
updateNetwork("4g");
}
def update_network(
driver: TestUIDriver,
network_mode: str
) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The network_mode
parameter specifies what network conditions you would like to
switch to. Available network configurations and their associated network_mode
values can be found here. These network
configurations can be provided as a string value or as a constant. Constants
pertaining to this command can be accessed via LOADERO_CONSTANTS.network
.
Refer to the table below for a full reference of the available constants.
Network mode | Constant | String value |
---|---|---|
Default | default | "default" |
4G | mobile_4g | "4g" |
3.5G/HSPDA | mobile_hsdpa | "hsdpa" |
3G | mobile_3g | "3g" |
GPRS | mobile_gprs | "gprs" |
Edge | mobile_edge | "edge" |
High jitter | jitter | "jitter" |
High latency | latency | "latency" |
Asymmetric | asymmetric | "asymmetric" |
Satellite phone | satellite | "satellite" |
5% packetloss | packetloss5 | "5packet" |
10% packetloss | packetloss10 | "10packet" |
20% packetloss | packetloss20 | "20packet" |
50% packetloss | packetloss50 | "50packet" |
100% packetloss | packetloss100 | "100packet" |
Custom | custom | "custom" |
def test(driver: TestUIDriver):
# Example of updating network conditions via constant
driver.navigate_to("https://www.bing.com")
e(driver, "css", ".dimmer").wait_until_visible(seconds=10)
update_network(driver, LOADERO_CONSTANTS.network.mobile_3g)
def test(driver: TestUIDriver):
# Example of updating network conditions via string value
driver.navigate_to("https://www.bing.com")
e(driver, "css", ".dimmer").wait_until_visible(seconds=10)
update_network(driver, "3g")
Custom network condition usage
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
It is possible to also supply the command with a configuration object that
explicitly defines various aspects of network quality. This object is considered
only if the provided networkMode
value is "custom", otherwise it will be
ignored.
client.updateNetwork(networkMode: string, config: object);
The config
object is effectively a map between configuration fields and the
values you want to set for them. The table below lists the fields you can
configure, where the JSON key
column refers to the name of the field.
It is possible to also supply the command with a configuration object that explicitly defines various aspects of network quality, instead of using one of the presets.
updateNetwork(Conditioner config);
The custom configuration can be defined by creating a Conditioner
variable and
then using its setters to set specific fields.
Conditioner config = new Conditioner();
config.setLatencyUp(10);
The table below lists all available fields that can be configured via the
conditioner. You can infer setter names through the JSON key
, e.g., the setter
for rate_up
is setRateUp()
.
It is possible to also supply the command with a configuration object that
explicitly defines various aspects of network quality. This object is considered
only if the provided network_mode
value is "custom", otherwise it will be
ignored.
def update_network(
driver: TestUIDriver,
network_mode: str,
network_config: dict or None = None
) -> None
The network_config
parameter is a dictionary consisting of explicitly defined
network conditioner field values. The available fields to configure are listed
in the table below, where the JSON key
column refers to the names of these
fields.
Network parameter | Traffic direction | JSON key | Unit of measure | Min value | Max value |
---|---|---|---|---|---|
Bandwidth | Outgoing | rate_up | mbit | 0 | |
Incoming | rate_down | mbit | 0 | ||
Latency | Outgoing | latency_up | ms | 0 | |
Incoming | latency_down | ms | 0 | ||
Jitter | Outgoing | jitter_up | ms | 0 | |
Incoming | jitter_down | ms | 0 | ||
Packet loss | Outgoing | loss_up | % | 0 | 100 |
Incoming | loss_down | % | 0 | 100 |
For custom network configuration jitter parameters must be defined together with latency. If jitter parameters are set without also defining latency parameters, then jitter configuration will not be applied.
The network parameters not defined in custom network configuration will be reset to their default values.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client => {
// Example of updating network conditions using custom values
let customNetworkConfig = {
latency_up: 100,
latency_down: 50,
jitter_up: 20,
jitter_down: 10,
rate_up: 50,
rate_down: 80,
loss_up: 5,
loss_down: 75,
};
client
.url('https://www.bing.com')
.waitForElementVisible('[type=search]', 10000)
.updateNetwork(loaderoConstants.network.custom, customNetworkConfig);
}
These are the available ConditionerBuilder
methods to set up the Conditioner
object, which should then be finalized with a .buildConditioner()
call:
.latency(up, down)
.latencyUp(up)
.latencyDown(down)
.jitter(up, down)
.jitterUp(up)
.jitterDown(down)
.rate(up, down)
.rateUp(up)
.rateDown(down)
.loss(up, down)
.lossUp(up)
.lossDown(down)
public void testUIWithLoadero() {
// Example of updating network conditions using custom network configuration
open("https://www.bing.com");
Conditioner config = new ConditionerBuilder()
.latency(10, 10)
.buildConditioner();
updateNetwork(config);
config.setRateUp(20);
updateNetwork(config);
}
def test(driver: TestUIDriver):
customNetworkConfig = {
"latency_up": 100,
"latency_down": 50,
"jitter_up": 20,
"jitter_down": 10,
"rate_up": 50,
"rate_down": 80,
"loss_up": 5,
"loss_down": 75
}
driver.navigate_to("https://www.bing.com")
e(driver, "css", ".dimmer").wait_until_visible(seconds=10)
update_network(
driver,
LOADERO_CONSTANTS.network.custom,
customNetworkConfig
)
Wait for Download Finished
This command checks if a file exists in the browser's Downloads directory, and if it does not exist, then the command will wait for the given amount of time. During this time period the command will check every 0.5s whether the file has appeared, and if it has, then the command will complete. If the file does not appear within the allotted time, then the command and test will both fail.
Since the download completion check is done every 0.5s, it can be used for crude download time measurement as well.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.waitForDownloadFinished(fileName: string, timeout = 1000: int);
The fileName
parameter specifies the name of the file that should appear in
the browser's Downloads directory. This parameter cannot be null or empty,
otherwise an Error will be thrown.
The timeout
parameter specifies time in milliseconds, how long to wait for
the file to appear. If no timeout parameter is provided, then a default value of
1000 ms is used. When the timeout is exceeded an Error is thrown.
client => {
// Example of waiting for file to be downloaded
client
// Open DemoQA upload/donwload page
.url('https://demoqa.com/upload-download')
.waitForElementVisible('#app', 1000)
// Start download
.waitForElementVisible('#downloadButton', 10 * 1000)
.click('#downloadButton')
// Wait for download to finish
.waitForDownloadFinished('sampleFile.jpeg', 5 * 60 * 1000)
.saveScreenshot('after_download.png');
}
waitForDownloadFinished(String fileName, long timeout);
The fileName
parameter specifies the name of the file that should appear in
the browser's Downloads directory. This parameter cannot be null or empty,
otherwise an Error will be thrown.
The timeout
parameter specifies time in milliseconds, how long to wait for
the file to appear. If no timeout parameter is provided, then a default value of
1000 ms is used. When the timeout is exceeded an Error is thrown.
public void testUIWithLoadero() {
// Example of waiting for file to be downloaded
// Open DemoQA upload / donwload page
open("https://demoqa.com/upload-download");
E(byCssSelector("#app")).waitFor(10).untilIsVisible();
E(byCssSelector("#app")).saveScreenshot("before_download.png");
// Start download
E(byCssSelector("#downloadButton")).waitFor(10).untilIsVisible().click();
// Wait for download to finish
waitForDownloadFinished("sampleFile.jpeg", 30 * 1000);
E(byCssSelector("#app")).saveScreenshot("after_download.png");
}
def wait_for_download_finished(
driver: TestUIDriver,
file_name: str,
timeout: int = 1000
) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The file_name
parameter specifies the name of the file that should appear in
the browser's Downloads directory. This parameter cannot be None
or empty,
otherwise an Error will be thrown.
The timeout
parameter specifies time in milliseconds, how long to wait for the
file to appear. If no timeout parameter is provided, then a default value 1000
ms is used. When the timeout is exceeded, a Py-TestUI error will be raised but
test execution will continue.
def test(driver: TestUIDriver):
# Example of waiting for file to be downloaded
# Open DemoQA upload/download page
driver.navigate_to("https://demoqa.com/upload-download")
e(driver, "css", "#app").wait_until_visible()
download_element = e(driver, "css", "#downloadButton")
driver.save_screenshot("before_download.png")
# Start download
download_element.click()
wait_for_download_finished(driver, "sampleFile.jpeg", 30 * 1000)
driver.save_screenshot("after_download.png")
Set Request Header
This function allows updating the header values for any requests that the browser sends out.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setRequestHeader(headerName: string, headerValue: string);
The headerName
parameter is the name of the request header to be changed. The
headerValue
parameter is used to set a new value for the specified header.
To reset a request header to its default value, pass null
as the new header
value.
Setting headerValue
to an empty string will actually update the request header
value to an empty string.
client => {
// Example of setting custom request header value
client
// Open page and create screenshot with default request header
.url('https://myhttpheader.com/')
.waitForElementVisible('#ua_table', 10 * 1000)
.saveScreenshot('default_headers.png')
// Set custom request header, reload the page and create screenshot
.setRequestHeader('Accept-Language', 'lv-LV')
.pause(1000)
.refresh()
.useXpath()
.waitForElementVisible(
'//div[contains(text(), "Accept-Language:")]/following-sibling::div[contains(text(), "lv-LV")]',
10 * 1000
).saveScreenshot('custom_headers.png')
// Reset request header, reload the page and create screenshot
.setRequestHeader('Accept-Language', null)
.pause(1000)
.refresh()
.waitForElementNotPresent(
'//div[contains(text(), "Accept-Language:")]/following-sibling::div[contains(text(), "lv-LV")]',
10 * 1000
).saveScreenshot('reset_headers.png')
}
setRequestHeader(String headerName, String headerValue);
The headerName
parameter is the name of the request header to be changed.
The headerValue
parameter is used to set a new value for the specified header.
To reset a request header to its default value, pass null
as the new header
value.
Setting headerValue
to an empty string will actually update the request header
value to an empty string.
public void testUIWithLoadero() {
// Example of setting custom request header value
// Open page and create screenshot with default request header
open("https://myhttpheader.com/");
E(byCssSelector("#ua_table")).waitFor(10).untilIsVisible();
E(byCssSelector("#ua_table")).saveScreenshot("default_headers.png");
// Set custom request header, reload the page and create screenshot
setRequestHeader("Accept-Language", "lv-LV");
sleep(1000);
getSelenideDriver().navigate().refresh();
E(byXpath(
"//div[contains(text(), 'Accept-Language:')]/following-sibling::div[contains(text(), 'lv-LV')]"
)).waitFor(10).untilIsVisible();
E(byCssSelector("#ua_table")).saveScreenshot("custom_headers.png");
// Reset request header, reload the page and create screenshot
setRequestHeader("Accept-Language", null);
sleep(1000);
getSelenideDriver().navigate().refresh();
E(byXpath(
"//div[contains(text(), 'Accept-Language:')]/following-sibling::div[contains(text(), 'lv-LV')]"
)).waitFor(10).untilNotVisible();
E(byCssSelector("#ua_table")).saveScreenshot("reset_headers.png");
}
def set_request_header(
driver: TestUIDriver,
header: str,
value: str or None = None
) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The header
parameter is the name of the request header to be changed.
The value
parameter is used to set a new value for the specified header.
To reset a request header to its default value, pass None
as the new header
value.
Setting value
to an empty string will actually update the request header
value to an empty string.
def test(driver: TestUIDriver):
# Example of setting custom request header value
# Open page and create screenshot with default request header
driver.navigate_to("https://myhttpheader.com/")
e(driver, "css", "#ua_table").wait_until_visible()
driver.save_screenshot("default_headers.png")
# Set custom request header, reload the page and create screenshot
set_request_header(driver, "Accept-Language", "lv-LV")
time.sleep(1)
driver.get_driver().refresh()
e(
driver,
"xpath",
"//div[contains(text(), 'Accept-Language:')]/following-sibling::div[contains(text(), 'lv-LV')]"
).wait_until_visible()
driver.save_screenshot("custom_headers.png")
# Reset request header, reload the page and create screenshot
set_request_header(driver, "Accept-Language", None)
time.sleep(1)
driver.get_driver().refresh()
e(
driver,
"xpath",
"//div[contains(text(), 'Accept-Language:')]/following-sibling::div[contains(text(), 'lv-LV')]"
).no().wait_until_visible()
driver.save_screenshot("reset_headers.png")
The "Set User Agent" custom command is equivalent to using the "Set Request Header" command to set the value of the "User-Agent" header. Either approach may be used.
Ignore Alert
This command will dismiss an alert opened by alert()
, prompt()
, or
confirm()
JavaScript functions. Calling this command when an alert is not
present will log an error but it will not fail the test.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.ignoreAlert();
This function does not require any parameters.
client => {
client
// Example of closing an alert before taking a screenshot
.url("https://www.bing.com")
.waitForElementVisible("[type=search]", 10000)
.execute(function () {
prompt("prompt!");
})
.ignoreAlert()
.saveScreenshot("screenshot.png");
}
ignoreAlert();
This function does not require any parameters.
public void testUIWithLoadero() {
// Example of closing an alert before taking a screenshot
open("http://www.bing.com");
E(byCssSelector("[type=search]")).waitFor(10).untilIsVisible();
executeJs("prompt('prompt!')");
ignoreAlert();
E(byCssSelector("[type=search]")).saveScreenshot("screenshot.png");
}
def ignore_alert(driver: TestUIDriver) -> None
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
def test(driver):
# Example of closing an alert before taking a screenshot
driver.navigate_to("https://www.bing.com/")
e(driver, "css", '[type=search]').wait_until_visible()
driver.execute_script("prompt('prompt!');", None)
ignore_alert(driver)
driver.save_screenshot("screenshot.png")
A typical use case, as shown in the example, is to close an alert if there is one before taking a screenshot.
Time Execution
This custom command measures and reports the execution time of the provided function. It allows timing the execution of some flow in a website, e.g., logging in, checking out in an e-commerce site, joining a WebRTC call, etc. Results from this command can be used in post-run analysis.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.timeExecution(name: string, timedCommand: Function, timeout?: number);
The name
parameter defines the name that you would like to provide to the
associated execution time metric that will be generated as a result of this
function. E.g., providing the value openURL
will cause the execution time
metric to be labeled as openURL
in the run report. The name may only contain
alphanumeric characters, underscores and hyphens, otherwise the command and test
will fail. The name must not exceed 150 characters in length.
The timedCommand
parameter is the function that will have its execution timed.
This can both be provided as the name of a declared function within the script
or as an anonymous function that is defined within the parameter itself.
Examples of both approaches are provided below. The provided function will be
executed as part of the
NightWatch command queue.
If name
is left blank, then:
- if the name of a declared function is provided as the value of
timedCommand
, the associated execution time metric will be labeled by using the name of the function; - if the value of
timedCommand
is an anonymous function, then the metric will be labeled asanonymous
.
timedCommand
can have up to two parameters of its own which follow the exact
same pattern and logic as the
built-in .perform()
command:
- no parameters - function runs and execution timing completes immediately at the end of the execution of the function;
- one parameter - allows for asynchronous execution within the function.
The parameter must be a
done
callback function that will indicate the completion of thetimedCommand
function. Ifdone
callback is not invoked, function execution will last indefinitely. - two parameters - allows for asynchronous execution with the Nightwatch
API
object passed in as the first argument, followed by thedone
callback.
timeout
is an optional parameter which specifies the time in milliseconds,
how long to wait for the provided timedCommand
to execute. The timeout value
must be positive. If the execution time exceeds the timeout
value, then an
error will be thrown. If the timeout
parameter is not provided, then no time
limit is placed on the execution time of timedCommand
.
Usage of this custom command will generate an execution time metric in the run report. That metric will also be output to the Selenium log at the end of the command's execution. This log entry's structure is shown below.
[LOADERO] Execution time for '${NAME}': ${DURATION}ms (start: ${START}; end: ${END}).
${NAME}
has the value that was supplied to thename
parameter.${DURATION}
is the execution time in milliseconds of the function provided to thetimedCommand
parameter${START}
,${END}
are Unix timestamp values in milliseconds.
client => {
client
.url("https://duckduckgo.com/")
.timeExecution("locate_search_bar", () => {
client
.waitForElementVisible("#searchbox_input", 10 * 1000)
.sendKeys("#searchbox_input", "QA Processes")
.click("[aria-label='Search']")
.waitForElementVisible("#r1-0 > div > h2", 10 * 1000)
})
.saveScreenshot("screenshot.png");
}
client => {
client
.url("https://duckduckgo.com/")
.timeExecution(
"locate_search_bar",
() => {
client
.waitForElementVisible(
"#searchbox_input",
10 * 1000
)
.sendKeys("#searchbox_input", "QA Processes")
.click("[aria-label='Search']")
.waitForElementVisible("#r1-0 > div > h2", 10 * 1000);
},
10 * 1000
)
.saveScreenshot("screenshot.png");
}
client => {
const locateSearchBar = () => {
client
.waitForElementVisible(
"#searchbox_input",
10 * 1000
)
.sendKeys("#searchbox_input", "QA Processes")
.click("[aria-label='Search']")
.waitForElementVisible("#r1-0 > div > h2", 10 * 1000);
};
client
.url("https://duckduckgo.com/")
.timeExecution(
"locate_search_bar",
locateSearchBar,
10 * 1000
)
.saveScreenshot("screenshot.png");
}
timeExecution(String name, Command command, int timeout);
timeExecution(String name, Command command);
The name
parameter defines the name that you would like to provide to the
associated execution time metric that will be generated as a result of this
function. E.g., providing the value openURL
will cause the execution time
metric to be labeled as openURL
in the run report. The name may only contain
alphanumeric characters, underscores and hyphens, otherwise the command and test
will fail. The name must not exceed 150 characters in length.
If name
is left blank, then the associated time execution metric will be
labeled as anonymous
.
The command
parameter is the function that will have its execution timed. It
must be provided in one of two ways:
- Anonymously as a lambda expression which is an implementation of the
functional interface
Command
, shown below. - By declaring a separate function and then passing a reference to that function as the parameter.
@FunctionalInterface
public interface Command {
void execute();
}
Examples are given further below for both approaches.
timeout
is an optional parameter which specifies the time in seconds, how long
to wait for the provided command
to execute. The timeout value must not be
negative. If the execution time exceeds the timeout
value, then an error will
be thrown. If the timeout
parameter is not provided or set to be 0, then no
time limit is placed on the execution time of command
.
Usage of this custom command will generate an execution time metric in the run report. That metric will also be output to the Selenium log at the end of the command's execution. This log entry's structure is shown below.
[LOADERO] Execution time for '${NAME}': ${DURATION}ms (start: ${START}; end: ${END}).
${NAME}
has the value that was supplied to thename
parameter.${DURATION}
is the execution time in milliseconds of the function provided to thecommand
parameter.${START}
,${END}
are Unix timestamp values in milliseconds.
public void testUIWithLoadero() {
open("https://duckduckgo.com/");
timeExecution(
"locate_search_bar",
() -> {
E(byCssSelector("#searchbox_input"))
.waitFor(10)
.untilIsVisible()
.sendKeys("QA Processes");
E(byCssSelector("[aria-label='Search']"))
.waitFor(10)
.untilIsVisible()
.click();
E(byCssSelector("#r1-0 > div > h2"))
.waitFor(10)
.untilIsVisible();
}
);
}
public void testUIWithLoadero() {
open("https://duckduckgo.com/");
timeExecution(
"locate_search_bar",
() -> {
E(byCssSelector("#searchbox_input"))
.waitFor(10)
.untilIsVisible()
.sendKeys("QA Processes");
E(byCssSelector("[aria-label='Search']"))
.waitFor(10)
.untilIsVisible()
.click();
E(byCssSelector("#r1-0 > div > h2"))
.waitFor(10)
.untilIsVisible();
},
10
);
}
public void testUIWithLoadero() {
open("https://duckduckgo.com/");
timeExecution("locate_search_bar", this::locateSearchBar, 10);
}
public void locateSearchBar() {
E(byCssSelector("#searchbox_input"))
.waitFor(10)
.untilIsVisible()
.sendKeys("QA Processes");
E(byCssSelector("[aria-label='Search']"))
.waitFor(10)
.untilIsVisible()
.click();
E(byCssSelector("#r1-0 > div > h2"))
.waitFor(10)
.untilIsVisible();
}
def time_execution(name: str, command: Callable, timeout: int or None = None) -> None
The name
parameter defines the name that you would like to provide to the
associated execution time metric that will be generated as a result of this
function. E.g., providing the value openURL
will cause the execution time
metric to be labeled as openURL
in the run report. The name may only contain
alphanumeric characters, underscores and hyphens, otherwise the command and test
will fail. The name must not exceed 150 characters in length.
The command
parameter is a
Callable
whose execution
will be timed. This can both be provided as the name of a declared function
within the script or as an anonymous lambda function. Examples of both
approaches are provided below.
If name
is left blank, then:
- if a callable with a
__name__
attribute is provided as the value ofcommand
(e.g., a declared function), the associated execution time metric will be labeled by using this attribute's value; - if the value of
command
is an anonymous callable, then the metric will be labeled asanonymous
.
timeout
is an optional parameter which specifies the time in seconds, how long
to wait for the provided command
to execute. The timeout value must be
positive. If the execution time exceeds this value, then an error will be
thrown. If the timeout
parameter is not provided, then no time limit is placed
on the execution time of command
.
Usage of this custom command will generate an execution time metric in the run report. That metric will also be output to the Selenium log at the end of the command's execution. The log message structure is shown below.
[LOADERO] Execution time for '${NAME}': ${DURATION}ms (start: ${START}; end: ${END}).
${NAME}
has the value that was supplied to thename
parameter.${DURATION}
is the execution time in milliseconds of the callable provided to thecommand
parameter.${START}
,${END}
are Unix timestamp values in milliseconds.
def test_on_loadero(driver: TestUIDriver):
def locate_search_bar():
e(
driver, "css", "#searchbox_input"
).wait_until_visible().send_keys("QA Processes")
e(driver, "css", "[aria-label='Search']").wait_until_visible().click()
e(driver, "css", "#r1-0 > div > h2").wait_until_visible()
driver.navigate_to("https://duckduckgo.com/")
time_execution(
"locate_search_bar",
locate_search_bar
)
def test_on_loadero(driver: TestUIDriver):
def locate_search_bar():
e(
driver, "css", "#searchbox_input"
).wait_until_visible().send_keys("QA Processes")
e(driver, "css", "[aria-label='Search']").wait_until_visible().click()
e(driver, "css", "#r1-0 > div > h2").wait_until_visible()
driver.navigate_to("https://duckduckgo.com/")
time_execution(
"locate_search_bar",
locate_search_bar,
10
)
def test_on_loadero(driver: TestUIDriver):
def locate_search_bar():
e(
driver, "css", "#searchbox_input"
).wait_until_visible().send_keys("QA Processes")
e(driver, "css", "[aria-label='Search']").wait_until_visible().click()
e(driver, "css", "#r1-0 > div > h2").wait_until_visible()
# Lambda functions lend themselves well for timing a single line of code
time_execution(
"open_url",
lambda: driver.navigate_to("https://duckduckgo.com/"),
10
)
# Locating the element afterwards still requires multiple lines of code
# For timing the whole sequence, you will need to define a function for them
time_execution(
"locate_search_bar",
locate_search_bar,
10
)
As you can see, if you want to make measurements in a Py-TestUI script, you will want to declare the sequence of steps you are measuring as a function most of the time. Providing a function anonymously is only viable for when that sequence is just one line of code long.
Generate Email Address
This custom command creates an email address which can then be used to receive emails, such as verifications emails in sign-up processes.
The generated email is generated based on a prefix string provided
as a parameter to the command, which will be added to the beginning of the
generated email address. The generated email address will have the format of
{prefix}-{runID}@{domain}
, where "runID" and "domain" will be automatically
filled in by Loadero.
If you want to generate an email address for multiple participants in the test, then it is best to supply something that uniquely identifies the participant as the prefix, such as their global ID.
Manually formatting an email address from scratch to meet the
{prefix}-{runID}@{domain}
format is not recommended, as it may lead to errors
in the test. Use this custom command instead.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.genEmail(prefix: string, callback: Function);
The prefix
parameter specifies the value that you want to provide at the
beginning of the email, which the command will then append with the remaining
-{runID}@{domain}
component.
The callback
parameter contains a callback function (either by
passing a name of an existing function or defining it inline). The callback can
be supplied with an argument, whose value will be the generated email address.
Refer to the example below
client => {
client.genEmail("test", addr => {
console.log(`Generated email address: ${addr}`);
});
}
To save the generated email address for later use, you can use the following code snippet:
client => {
let email;
// Generate the email address and save it as a variable
client.genEmail("test", addr => {
email = addr;
});
// Alternatively, generate a unique email address for each participant
client.genEmail(`test${client.globals.participant.globalID}`, addr => {
email = addr;
});
// Use the email address here
client.perform(() => {
console.log(`Generated email address: ${email}`);
});
}
Keep in mind, that because of the asynchronous nature of Nightwatch, the email
address will not be available immediately after calling the genEmail()
function, so it's recommended to use the saved value within a perform()
command. Otherwise you may encounter an error that the email
variable is
undefined.
String genEmail(String prefix);
The prefix
parameter specifies the value that you want to provide at the
beginning of the email, which the command will then append with the remaining
-{runID}@{domain}
component.
public void test() {
// Generate the email address and save it as a variable
String addr = genEmail("test");
// Alternatively, generate a unique email address for each participant
String uniquePrefix = String.format(
"test%s",
globalConfig.getParticipant().getGlobalId();
);
addr = genEmail(uniquePrefix);
// Use the email address here
System.out.println("Generated email address: " + addr);
}
def gen_email(prefix: str) -> str
The prefix
parameter specifies the value that you want to provide at the
beginning of the email, which the command will then append with the remaining
-{runID}@{domain}
component.
def test(driver: TestUIDriver):
# Generate the email address and save it as a variable
addr = gen_email("test")
# Alternatively, generate a unique email address for each participant
addr = gen_email(f"test{GLOBALS.participant.global_id}")
# Use the email address here
print("Generated email address:", addr)
Receive Email
This custom command will return a collection of email messages that have been received by the specified email address. To designate the email address that will receive these messages, you should use the Generate Email Address custom command. You can not use this command on your own personal email address, for example. It must be a testing email generated by Loadero itself.
The command itself will not wait for any email messages to arrive at the specified email adrress - if an email message has not yet arrived by the time this command is called, then the returned collection will not contain this email message. The returned data functions as a snapshot of all received email messages at that point in time in which the command was executed. As such, it is recommended to use the command within a loop that will wait for the email message to be visible within the collection.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.receiveEmail(address: string, callback: Function);
The address
parameter specifies the email address whose received messages
you would like to inspect. The value provided to this parameter should be
generated by the "Generate Email Address" custom
command and should not be written out manually.
The callback
parameter accepts a callback function (either by
passing a name of an existing function or defining it inline). The callback can
be supplied with an argument, whose value will be the array of email messages
that had been returned by the command, so that they can be further processed
within the callback.
The email messages within the array will have the following properties:
- from - The email address of the sender.
- subject - The subject of the email.
- headers - The headers of the email.
- text/plain - The plain text content of the email.
- text/html - The HTML content of the email.
The email message object is a JavaScript object, so it is possible to access
the properties using the dot notation, for example: email.from
, but since
the property names contain special characters, it is not recommended. Instead,
it is recommended to access the properties using the array notation,
for example: email["from"]
, by doing this you will avoid any potential
issues with the special characters.
client => {
client.genEmail("test", addr => {
client.receiveEmail(addr, emails => {
console.log(`Amount of received emails: ${emails.length}`)
for (let email of emails) {
console.log(`From: ${email["from"]}`)
console.log(`Subject: ${email["subject"]}`)
console.log(`Plain text content: ${email["text/plain"]}`)
}
});
})
}
client => {
let email;
// Create the address to use first
client.genEmail("test", addr => {
email = addr;
});
/*
Some UI interactions that cause an email message to be sent
*/
// Loops work funny in Nightwatch.js due to the command queue
// A recursive approach instead helps things go a little more... synchronously
const retry = (retries, emailReceived) => {
// If the email has been received already, continue
// If retrying has already occurred 10 times, give up
// If a retry was called, wait 5 seconds before checking again
if (emailReceived) return
else if (retries >= 10) throw Error("Email did not arrive.")
else if (retries != 0) client.pause(5*1000);
client.perform(()=> {
console.log("Iteration No. ", retries);
client
.receiveEmail(email, messages => {
console.log(`Amount of received emails: ${messages.length}`);
for (let email of messages) {
console.log(`From: ${email["from"]}`);
console.log(`Subject: ${email["subject"]}`);
console.log(`Plain text content: ${email["text/plain"]}`);
//If the email has arrived, we can stop retrying
if (email["from"]=="expected@email.com") emailReceived = true;
}
})
retries++;
}).perform(()=> {
// Since this is encased in a .perform(),
// the function call will be inserted into the queue with updated parameter values
retry(retries, emailReceived);
});
}
// Wrapping the first call of the recursive function inside another function
// Calling a recursive function directly from the main body is uncommon
const waitForEmail = () => {
retry(0, false);
};
waitForEmail();
/*
Further actions after successfully retrieving the email
Such as navigating to a URL sent in the email, etc.
*/
}
EmailMessage[] receiveEmail(String address);
The address
parameter specifies the email address whose received messages
you would like to inspect. The value provided to this parameter should be
generated by the "Generate Email Address" custom
command and should not be written out manually.
The email messages within the array returned by this command will have the following properties:
- from - The email address of the sender.
- subject - The subject of the email.
- headers - The headers of the email.
- text/plain - The plain text content of the email.
- text/html - The HTML content of the email.
Email messages are stored within EmailMessage
objects, which have the
following methods to get the object's properties:
String getFrom()
- Returns the email address of the sender.String getSubject()
- Returns the subject of the email.Map<String, String> getHeaders()
- Returns the headers of the email.String getTextPlain()
- Returns the plain text content of the email.String getTextHtml()
- Returns the HTML content of the email.
public void test() {
EmailMessage[] messages = receiveEmail(genEmail("test"));
System.out.println("Amount of received emails: " + messages.length);
for (EmailMessage email : messages) {
System.out.println("From: " + email.getFrom());
System.out.println("Subject: " + email.getSubject());
System.out.println("Plain text content: " + email.getTextPlain());
}
}
public void test() throws Exception {
String addr = genEmail("test");
Boolean emailReceived = false;
int retries;
/*
Some UI interactions that cause an email message to be sent
*/
for (retries = 0; retries < 10 && !emailReceived; retries++) {
// If the email has been received already, continue
// If retrying has already occurred 10 times, give up
// If a retry was called, wait 5 seconds before checking again
if (retries != 0) sleep(5*1000);
System.out.println("Iteration No. " + retries);
EmailMessage[] messages = receiveEmail(addr);
System.out.println("Amount of received emails: " + messages.length);
for (EmailMessage email : messages) {
System.out.println("From: " + email.getFrom());
System.out.println("Subject: " + email.getSubject());
System.out.println("Plain text content: " + email.getTextPlain());
//If the email has arrived, we can stop retrying
if (email.getFrom().equals("expected@email.com")) {
emailReceived = true;
}
}
}
if (retries >= 10) {
throw new Exception("Email did not arrive.");
}
/*
Further actions after successfully retrieving the email
Such as navigating to a URL sent in the email, etc.
*/
}
def receive_email(driver: TestUIDriver, address: str) -> []
The driver
parameter corresponds to the TestUIDriver
object being used
in the test script. You don't need to set this object up yourself as it will
already be set up by Loadero - you simply need to pass it to the function via
driver
.
The address
parameter specifies the email address whose received messages
you would like to inspect. The value provided to this parameter should be
generated by the "Generate Email Address" custom
command and should not be written out manually.
The email messages within the list returned by this command will have the following properties:
- from - The email address of the sender.
- subject - The subject of the email.
- headers - The headers of the email.
- text/plain - The plain text content of the email.
- text/html - The HTML content of the email.
def test(driver: TestUIDriver):
messages = receive_email(driver, gen_email("test"))
print("Amount of received emails:", len(messages))
for email in messages:
print("From:", email["from"])
print("Subject:", email["subject"])
print("Plain text content:", email["text/plain"])
def test_on_loadero(driver: TestUIDriver):
addr = gen_email("test")
emailReceived = False
retries = 0
'''
Some UI interactions that cause an email message to be sent
'''
for retries in range(10):
# If the email has been received already, continue
# If retrying hsa already occurred 10 times, give up
# If a retry was called, wait 5 seconds before checking again
if emailReceived:
break
if retries != 0:
time.sleep(5)
print(f"Iteration No. {retries}")
messages = receive_email(driver, addr)
print(f"Amount of received emails: {len(messages)}")
for email in messages:
print(f"From: {email['from']}")
print(f"Subject: {email['subject']}")
print(f"Plain text content: {email['text/plain']}")
# If the email has arrived, we can stop retrying
if email["from"] == 'expected@email.com':
emailReceived = True
if retries>=10:
raise Exception("Email did not arrive.")
'''
Further actions after successfully retrieving the email
Such as navigating to a URL sent in the email, etc.
'''
Perform Timed
This custom command is exclusive to Nightwatch.js, and there is no equivalent for the TestUI and Py-TestUI frameworks.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
The built-in .perform()
command in Nightwatch.js uses an asyncHookTimeout
value for the done
invocation timeout.
By default the asyncHookTimeout
value is set to 10 seconds, but there may be
cases where this value should be customized in order to control the maximum
execution time of the callback. So to allow defining this value for each case
separately and avoid having to redefine asyncHookTimeout
, the
.performTimed()
command was created.
client.performTimed(callback: function, timeout: int);
The callback
parameter defines the function that will be executed as part of
the command queue. This callback is defined the same way as in the built-in
.perform()
command.
The callback signature can also have up to two parameters whose logic is also
the exact same as for the original .perform()
command:
- no parameters - callback runs and perform completes immediately at the end of the execution of the callback.
- one parameter - allows for asynchronous execution within the callback.
The parameter must be a
done
callback function that will indicate the completion ofperformTimed
callback function. - two parameters - allows for asynchronous execution with the Nightwatch
API
object passed in as the first argument, followed by thedone
callback.
The timeout
parameter defines the done
invocation timeout and is specified
in milliseconds.
The performTimed()
command will be useful in cases where the done
callback is
used within a custom callback function in order to notify the
Nightwatch command queue
about the end of the command's execution. Without the done
callback invocation
performTimed()
command behaves the same as the built-in perform()
command
and completes immediately after the callback is executed.
client => {
let version = "";
client
.url("https://www.bing.com")
.performTimed((done) => {
// Get latest ChromeDriver version
getChromeDriverVersion(done);
}, 20000)
// Insert Bing search query for ChromeDriver version
.perform(() => {
client.setValue("[type=search]", [`chromedriver ${version}`, client.Keys.ENTER])
})
// Wait up to 10 seconds until search results are visible
.waitForElementVisible("[aria-label='Search Results']", 10 * 1000);
function sleepFor(sleepDuration) {
const now = new Date().getTime();
while (new Date().getTime() < now + sleepDuration) { }
}
function getChromeDriverVersion(done) {
retry = 60;
request(
{
url: `https://chromedriver.storage.googleapis.com/LATEST_RELEASE`,
},
function (error, response, body) {
if (error) {
throw new Error(error);
}
if (response.statusCode != 200) {
sleepFor(1000);
retry--;
if (retry > 0) {
getChromeDriverVersion(done, retry);
} else {
done();
}
} else {
version = body;
done();
}
}
);
}
}
This custom command is only available for Nightwatch.js.
This custom command is only available for Nightwatch.js.
Screenshot (deprecated)
Deprecation notice (October 31st, 2024): users are recommended to use the
built-in functionality of the frameworks for taking a screenshot
(saveScreenshot()
for Nightwatch.js and TestUI; save_screenshot()
for
Py-TestUI).
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.takeScreenshot(filename: string, exitOnFail: boolean = false);
The filename
parameter specifies the name that will be given to the saved file
containing the captured screenshot.
The exitOnFail
parameter determines whether the participant should terminate
test execution if there was a problem taking the screenshot. This parameter can
be omitted and will default to false
.
client => {
// Example of taking a browser screenshot
client
.url('https://www.bing.com')
.waitForElementVisible('[type=search]', 10000)
.takeScreenshot('screenshot.png');
}
Screenshot creation is impossible in some cases, for example, when an alert is open. If there are concerns that an alert might get in the way, then the Ignore Alert command can be used - this command will close an alert if it is open, and if there is no alert to close, it won't impact test execution.
This custom command is exclusive to Nightwatch.js. In TestUI you should use
the already built-in saveScreenshot()
command instead.
This custom command is exclusive to Nightwatch.js. In Py-TestUI you should use
the already built-in save_screenshot()
command instead.