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.
Set File
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setFile(selector: string, fileName: string);
The selector
parameter specifies input field element selector, e.g.
input[type="file"]
, input#file-upload
.
The fileName
parameter specifies chosen file name. Choose desired file from
the table below.
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)
.takeScreenshot("file_set.png");
}
setFile(By selector, String fileName);
The selector
parameter specifies input field element selector, e.g.
input[type="file"]
, input#file-upload
.
The fileName
parameter specifies chosen file name. Choose desired file from
the table below.
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 element
parameter specifies the input element where file name has to be
set.
The file_name
parameter specifies chosen file name. 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")
Set User Agent
This command changes User-Agent
header for outgoing requests and navigator.userAgent
.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setUserAgent(userAgent: string);
To reset User-Agent
to its default value, pass null
as the new value.
setUserAgent(String userAgent);
To reset User-Agent
to its default value, pass null
as the new value.
def set_user_agent(driver: TestUIDriver, value: str or None = None) -> None
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.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
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)
.takeScreenshot("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)
.takeScreenshot("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)
.takeScreenshot("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)
.takeScreenshot("reverted_user_agent.png");
}
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 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 original value in browser built-in pages and WebRTC dump.
Update Network
This command updates network conditions for participant while the test is running.
Predefined network condition usage
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.updateNetwork(networkMode: string);
The networkMode
parameter specifies what network conditions should be used.
Available network configurations and networkMode
parameter values can be found
here or they can be accessed using
constants. Constants pertaining to this command can be accessed via
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
client
.url('https://www.bing.com')
.waitForElementVisible('[type=search]', 10000)
.updateNetwork(loaderoConstants.network.mobile_3g);
}
updateNetwork(String networkMode);
The networkMode
parameter specifies what network conditions should be used.
Available network configurations and networkMode
values can be found
here or they can be accessed using
constants. Constants pertaining to this command can be accessed via
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 constants
open("https://www.bing.com");
E(byCssSelector(".dimmer"))
.waitFor(10).untilIsVisible();
// Update network condition to mobile 4G value
updateNetwork(loaderoConstants.getNetwork().getMobile4G());
}
def update_network(
driver: TestUIDriver,
network_mode: str
) -> None
The network_mode
parameter specifies what network conditions should be used.
Available network configurations and network_mode
values can be found
here or they can be accessed using
constants. 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):
driver.navigate_to("https://www.bing.com")
e(driver, "css", ".dimmer").wait_until_visible(seconds=10)
update_network(driver, LOADERO_CONSTANTS.network.mobile_3g)
Custom network condition usage
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.updateNetwork(networkMode: string, config: object);
The config
parameter that specifies exact network conditioner field values.
Custom network configuration is taken into effect only if provided networkMode
is "custom".
There is also an option to create custom network conditioner configuration and
pass that instead into updateNetwork()
command.
updateNetwork(Conditioner config);
There are several ways to create custom configuration. One way of doing it is to
create Conditioner
variable and use setters to set specific fields.
Conditioner config = new Conditioner();
config.setLatencyUp(10);
def update_network(
driver: TestUIDriver,
network_mode: str,
network_config: dict or None = None
) -> None
The network_config
parameter specifies exact network conditioner field values.
Custom network configuration is taken into effect only if provided
network_mode
is "custom".
Currently available custom network configuration metrics are:
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 available ConditionerBuilder
methods:
.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 waits until file download is completed or timeout is exceeded. This function is useful if download has to be completed before the end of the test. Download completion check is done every 500 ms, so 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 file name to wait for in downloads directory.
This parameter can not be empty, otherwise an Error will be thrown.
The timeout
parameter specifies time in ms, how long to wait for file download
to be completed. If no timeout parameter is provided, default value 1000
ms is
used. When 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)
.takeScreenshot('after_download.png')
}
waitForDownloadFinished(String fileName, long timeout)
The fileName
parameter specifies file name to wait for in downloads directory.
This parameter can not be null or empty, otherwise an Error will be thrown.
The timeout
parameter specifies time in ms, how long to wait for file download
to be completed. If no timeout parameter is provided, default value 1000
ms is
used. When 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 file_name
parameter specifies file name to wait for in downloads directory.
This parameter can not be None
or empty, otherwise an Error will be thrown.
The timeout
parameter specifies time in ms, how long to wait for file download
to be completed. If no timeout parameter is provided, default value 1000
ms is
used. When timeout is exceeded the function will raise an Py-TestUI error 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 browser sends out.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.setRequestHeader(headerName: string, headerValue: string);
The parameter headerName
is the name of the request header to be changed. The
parameter headerValue
is used to set a new value for the specified header.
To reset 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)
.takeScreenshot('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
).takeScreenshot('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
).takeScreenshot('reset_headers.png')
}
setRequestHeader(String headerName, String headerValue);
The parameter headerName
is the name of the request header to be changed. The
parameter headerValue
is used to set a new value for the specified header.
To reset 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 parameter header
is the name of the request header to be changed. The
parameter value
is used to set a new value for the specified header.
To reset request header to its default value, pass None
as the new header
value.
Setting value
to empty string will actually update request header value as 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")
Ignore Alert
Command will close alert opened by alert()
, prompt()
or confirm()
JavaScript functions. Calling command on a non-existent alert will log an error
but not fail the test.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client => {
client
// Example of closing alert before taking a screenshot
.url("https://www.bing.com")
.waitForElementVisible("[type=search]", 10000)
.execute(function () {
prompt("prompt!");
})
.ignoreAlert()
.takeScreenshot("screenshot.png");
}
public void testUIWithLoadero() {
// Example of ignore alert
open("http://www.bing.com");
E(byCssSelector("[type=search]")).waitFor(10).untilIsVisible();
executeJs("prompt('prompt!')");
ignoreAlert();
E(byCssSelector("[type=search]")).saveScreenshot("screenshot.png");
}
def test(driver):
# Example of ignore alert function
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 execution time of some 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. 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);
name
- identifying name for the timedCommand
function. If name
is an empty
string, then timedCommand.name
attribute value will be used if it is
available, otherwise name
will default to "anonymous"
. If name
is provided
then the maximum length for this argument is 150 characters and can only contain
alphanumeric characters, underscores and hyphens.
timedCommand
- function whose execution will be timed. timedCommand
will be
executed as part of the NightWatch
command queue.
timedCommand
can have up to two parameters:
- 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 oftimedCommand
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
- specifies the time in milliseconds, how long to wait for the
timedCommand
to execute. Timeout value must be positive. If the execution time
exceeds the timeout
value, then an error will be thrown. If timeout
parameter is omitted then no limit is placed on the execution time of
timedCommand
.
Use of the timeExecution
custom command will produce a log that contains
timing information of the timedCommand
. 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 totimeExecution
name
parameter.${DURATION}
is the execution time in milliseconds of thetimedCommand
function${START}
,${END}
are unix timestamp values in milliseconds.
client => {
const reallyLongPause = 5 * 60 * 1000; // 5 minutes
client
// Example of timing execution without specifying a timeout.
.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)
.pause(reallyLongPause);
})
.takeScreenshot("screenshot.png");
}
client => {
client
// Example of timing execution with a timeout.
.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
)
.takeScreenshot("screenshot.png");
}
timeExecution(String name, Command command, int timeout)
timeExecution(String name, Command command)
name
- unique identifying name for the command
function. If name
is an
empty string, then name
will default to "anonymous"
. If name
is provided
then the maximum length for this argument is 150 characters and can only contain
alphanumeric characters, underscores and hyphens.
command
- function whose execution will be timed. command
must be a lambda
expression. command
is a functional interface Command
.
@FunctionalInterface
public interface Command {
void execute();
}
timeout
- specifies the time in seconds, how long to wait for the command
to
execute. Timeout value cannot be negative. If the execution time exceeds the
timeout
value, then an error will be thrown. If timeout
parameter is omitted
or 0, then no limit on the execution time of command
is placed.
Use of the timeExecution
custom command will produce a log that contains
timing information of the timedCommand
. 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 totimeExecution
name
parameter.${DURATION}
is the execution time in milliseconds of thecommand
function.${START}
,${END}
are Unix timestamp values in milliseconds.
public void testUIWithLoadero() {
int reallyLongPause = 5 * 60 * 1000; // 5 minutes
open("https://duckduckgo.com/");
// Example of timing execution without specifying a timeout.
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();
sleep(reallyLongPause);
}
);
}
public void testUIWithLoadero() {
open("https://duckduckgo.com/");
// Example of timing execution with a timeout.
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
);
}
def time_execution(name: str, command: Callable, timeout: int or None = None) -> None
name
- identifying name for the command
callable. If name
is an empty
string, then command.__name__
attribute value will be used if it is available,
otherwise name
will default to "anonymous"
. If name
is provided
then the maximum length for this argument is 150 characters and can only contain
alphanumeric characters, underscores and hyphens.
command
- a Callable
object whose execution will be timed. command
can be a lambda expression.
timeout
- specifies the time in seconds, how long to wait for the command
to
execute. Timeout value must be positive. If the execution time exceeds the
timeout
value, then an error will be thrown. timeout
parameter can be
omitted and if done so, then no limit on the execution time of command
is
placed.
Use of the time_execution
custom command will produce a log that contains
timing information of the time_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 totime_execution
name
parameter.${DURATION}
is the execution time in milliseconds of thecommand
function.${START}
,${END}
are Unix timestamp values in milliseconds.
def test_on_loadero(driver: TestUIDriver):
really_long_pause = 300
driver.navigate_to("https://duckduckgo.com/")
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()
time.sleep(really_long_pause)
# Example of timing execution without specifying a timeout.
time_execution("locate_search_bar", locate_search_bar)
def test_on_loadero(driver: TestUIDriver):
driver.navigate_to("https://duckduckgo.com/")
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()
# Example of timing execution with a timeout.
time_execution("locate_search_bar", locate_search_bar, 10)
Generate Email Address
This custom command creates an email address based on a prefix string, which
will be added to the beginning of the email address. The prefix is used to
identify a specific participant within the test, such as their name or ID. The
generated email address will have the format of {prefix}-{runID}@{domain}
.
The "runID" and "domain" parts of the email address will be automatically filled
in.
Manually formatting email address in this 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 custom command will pass the generated email address to the callback function provided as its first argument. The email address will be accessible within the callback function as a string, allowing you to use it for further processing.
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 on email variable
client.genEmail("test", addr => {
email = addr;
});
// Use the email address here
client.perform(() => {
console.log(`Generated email address: ${email}`);
});
}
Keep in mind, that taking into consideration the asynchronous nature of the
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)
public void test() {
String addr = genEmail("test");
System.out.println("Generated email address: " + addr);
}
def gen_email(prefix: str) -> str
def test(driver: TestUIDriver):
addr = gen_email("test")
print("Generated email address:", addr)
Receive Email
This custom command will return an array of email messages that were sent to the specified email address during test execution. To generate the email address, you should use the Generate Email Address custom command.
- JavaScript + Nightwatch.js
- Java + TestUI
- Python + Py-TestUI
client.receiveEmail(address: string, callback: Function);
The command itself will not wait for any messages to arrive, so it's recommended to use it within a loop that will wait for the email to be visible within the the array.
The emails will be available within the provided callback function as an array. The email message object 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"]}`)
}
});
})
}
EmailMessage[] receiveEmail(String address)
The command itself will not wait for any messages to arrive, so it's recommended
to use it within a loop that will wait for the email to be visible within the
EmailMessage
array.
The email message object 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.
Emails are stored within EmailMessage objects, which have the following methods to get the email 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[] emails = receiveEmail(genEmail("test"));
System.out.println("Amount of received emails: " + emails.length);
for (EmailMessage email : emails) {
System.out.println("From: " + email.getFrom());
System.out.println("Subject: " + email.getSubject());
System.out.println("Plain text content: " + email.getTextPlain());
}
}
def receive_email(driver: TestUIDriver, address: str) -> []
The command itself will not wait for any messages to arrive, so it's recommended to use it within a loop that will wait for the email to be visible within the the array.
The email message object 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):
emails = receive_email(driver, gen_email("test"))
print("Amount of received emails:", len(emails))
for email in emails:
print("From:", email["from"])
print("Subject:", email["subject"])
print("Plain text content:", email["text/plain"])