Chain modifiers¶
Chain modifier are added to manipulate and check for specific aspects of test subjects or change the behavior of test operations.
Subjects can be found in test subjects.
List of chain modifiers:
| Modifier + aliases | To be used with | Explanation |
|---|---|---|
accuracy |
image |
Defines how accurate should the image comparison be. |
contain, contains |
any string | Evaluates if subject contains an expected string. |
endWith, endsWith |
any string | Evaluates if subject ends with an expected string. |
equal, equals |
any string | Evaluates if subject is equal to expected value. |
exist, exists |
cookie, element, video |
Evaluates if subject exists. |
getAttributes |
element |
Returns a list of attributes with values. |
getCssProperties |
element |
Returns a list of CSS properties with values. |
hasExited |
application |
Evaluates if application has exited. |
inRegion |
image |
Defines the area on screen to compare to the subject. |
interval |
click, press, repeat, send text |
Sets an interval between chain executions. |
isPaused |
video |
Evaluates if the state of video is paused |
isPlaying |
video |
Evaluates if the state of video is playing |
isStopped |
video |
Evaluates if the state of video is stopped |
language |
ocr |
Defines language for ocr feature. |
match, matches |
element, video |
Compares state of an element to defined values. |
matchJS, matchesJS |
cookie, element, location, video |
Evaluates if subject matches JS expression. |
matchRepo, matchesRepo |
element, video |
Compares state of element with element repository state. |
not, doesNot, isNot |
contain, endWith, equal, exist, jsExpression, matchJs, starWith, wasMade and willBeMade. |
Negates the state. |
repeat |
click, interval, press, send text |
Repeats the execution of a chain. |
requestMatches |
network request |
Evaluates if network request matches data. |
responseMatches |
network request |
Evaluates if network response matches data. |
startWith, startsWith |
any string | Evaluates if subject starts with an expected string. |
timeout |
any assertion | Sets timeout to wait until chain becomes resolved. |
until |
click, tap |
Executes chain until condition is satisfied. |
visible |
element, image, video |
Evaluates if an element is visible. |
wasMade |
network request |
Evaluates if network request was made in entire request log. |
willBeMade |
network request |
Evaluates if network request will be made (excludes previously matched requests). |
accuracy¶
Defines how accurately should Suitest compare the images. Different levels are useful depending on the image capture device (lower for mobile phones, higher for HDMI capture).
Default value is low. For other options we recommend using corresponding suitest.ACCURACY constants.
// examples
await suitest.assert.image('myImageID').accuracy(suitest.ACCURACY.MEDIUM).visible();
await suitest.assert.image({url: 'https://my.server.com/myImage'}).accuracy(suitest.ACCURACY.HIGH).isNot().visible();
contain¶
Evaluates if subject (as a string) contains an expected string.
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function contain(expectedValue) {}
await suitest
.cookie('cookieName')
.contains('someValue');
endWith¶
Evaluates if subject (as a string) ends with an expected string.
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function endsWith(expectedValue) {}
await suitest
.cookie('cookieName')
.endsWith('someValue');
equal¶
Evaluates if a subject is equal to an expected value.
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function equal(expectedValue) {}
await suitest
.cookie('cookieName')
.equals('Some Value');
exist¶
Evaluates if a subject exists. Can be used with not to change to "does
not exist".
/**
* @returns {ChainablePromise.<void|boolean>}
*/
async function exists() {}
// Check if element exists
await suitest
.element('Element name')
.exists();
// Check if cookie does not exist
await suitest
.cookie('cookieName')
.doesNot()
.exist();
getAttributes¶
Returns a list of attributes with values.
/**
* Returns specific list of element attributes / all attributes
* @param {string[]} [attributes] - listing what attributes should be returned
* @returns {Promise.<Object>} - returns attributes with their values
*/
async function getAttributes(attributes) {}
// Get all attributes of my logo element
const myElementAttributes = await suitest.element({attributes: 'data-testid="logo"'}).getAttributes();
console.log(myElementAttributes['class']); // printing the class values of given element
getCssProperties¶
Returns a list of CSS properties with values.
/**
* Returns specific list of element css properties / all css properties
* @param {string[]} [properties] - listing what CSS properties should be returned
* @returns {Promise.<Object>} - CSS properties with their values
*/
async function getCssProperties(properties) {}
// Get size of a logo element
const myElementSize = await suitest.element({attributes: 'data-testid="logo"'}).getCssProperties(['width', 'height']);
console.log("element width: ", myElementSize['width']);
console.log("element height: ", myElementSize['height']);
hasExited¶
Evaluates if the application has exited.
/**
* @throws {SuitestError} in case subject is different from application
* @returns {Promise.<void|boolean>}
*/
async function hasExited() {}
// Wait until application has exited but at most 2s
await suitest
.application()
.hasExited();
interval¶
Sets interval (in ms) between chain executions.
/**
* @param {number} ms
* @returns {ChainablePromise.<void|boolean>}
*/
async function interval(ms) {}
// Press OK 10x every 10s
await suitest.press(suitest.VRC.OK)
.repeat(10)
.interval(10000);
isPaused¶
Evaluates the video status.
const isVideoPaused = await suitest.video().isPaused();
await suitest.assert.video().isPaused();
isPlaying¶
Evaluates the video status.
const isVideoPlaying = await suitest.video().isPlaying();
await suitest.assert.video().isPlaying();
isStopped¶
Evaluates the video status.
const isVideoStopped = await suitest.video().isStopped();
await suitest.assert.video().isStopped();
language¶
Defines in which language ocr is supposed to read a text displayed on a screen.
const readText = await suitest.ocr(ocrObjects).language(suitest.LANG.ENGLISH);
await suitest.assert.ocr(ocrObjects).language(suitest.LANG.ENGLISH);
We recommend using corresponding
suitest.LANGconstants for values.
match¶
Compares the state of the element with the defined properties set.
For the properties available refer to constant element properties.
For properties with enumerable values (VIDEO_STATE, VISIBILITY_STATE, CONTENT_MODE, ELEMENT_STATE, TEXT_ALIGNMENT, BORDER_STYLE) value must be provided as Suitest constant.
/**
* @param {Symbol} name - properties to match against
* @param {string|number|Symbol} [val] - properties to match against. Defaults to VALUE.REPO
* @param {string} [type] - how to compare property, defaults to COMP.EQUAL
* @param {string} [deviation] - how accurate type should be, only if value is of type number and type is COMP.APPROX
* @returns {ChainablePromise.<void|boolean>}
*/
async function match(name, val, type, deviation) {}
async function match({name, val, type, deviation}) {}
async function match([{name, val, type, deviation}/*, ...*/]) {}
// Check if element's width and height match snapshot from element repo, top position as in repo +- 20px and custom background color
const element = suitest.element('repo-id');
await element.matches(suitest.PROP.WIDTH);
await element.matches(suitest.PROP.HEIGHT);
await element.matches(suitest.PROP.TOP, suitest.VALUE.REPO, suitest.COMP.APPROX, 20);
await element.matches(suitest.PROP.BG_COLOR, '#F00');
// Same with object syntax
await suitest.element('repo-id').matches({
name: suitest.PROP.WIDTH,
});
await suitest.element('repo-id').matches({
name: suitest.PROP.HEIGHT,
});
await suitest.element('repo-id').matches({
name: suitest.PROP.TOP,
val: suitest.VALUE.REPO,
type: suitest.COMP.APPROX,
deviation: 20,
});
await suitest.element('repo-id').matches({
name: suitest.PROP.BG_COLOR,
val: '#F00',
});
await suitest.element({css: '#repo-id'}).matches({
[PROP.BG_COLOR]: 'red',
[PROP.HREF]: 'http://somelink',
borderWidth: 233,
});
// Preferred syntax as only one command and one server communication request is executed.
await suitest.element('repo-id').matches([
PROP.WIDTH,
PROP.HEIGHT,
{
name: PROP.TOP,
val: VALUE.REPO, // could be omitted
type: COMP.APPROX,
deviation: 20,
},
{
name: PROP.BG_COLOR,
val: '#F00',
},
{
[PROP.CLASS]: 'friendlyClass',
[PROP.TEXT_CONTENT]: 'Lorem ipsum',
}
]);
.matchmethod can accept objects withnameproperty, conflicts may occur in.matcharguments due to the dictionary being able to containnamekey as well.
matchJS¶
Evaluates if subject matches a JS expression.
/**
* @param {string|Function} matcher
* @throws {SuitestError} if subject is unavailable
* @throws {TypeError} if matcher produced error
* @returns {ChainablePromise.<void|boolean>}
*/
async function matchesJS(matcher) {}
// Pass function as parameter
await suitest
.cookie('cookieName')
.matchesJS(function(cookieValue) { return /foo|bar/i.test(cookieValue); });
// Pass string as parameter
await suitest
.cookie('cookieName')
.matchesJS('function (cookieValue) { return /foo|bar/i.test(cookieValue) }');
matchRepo¶
Compares the state of the element with the state in the Element repository with the current state within the app.
For the properties available refer to constant element properties.
/**
* @param {Symbol} name - properties to match against
* @param {string} [type] - how to compare property, defaults to COMP.EQUAL
* @param {string} [deviation] - how accurate type should be, only if value is of type number and type is COMP.APPROX
* @returns {ChainablePromise.<void|boolean>}
*/
async function matchRepo(name, type, deviation) {}
async function matchRepo({name, type, deviation}) {}
async function matchRepo([{name, type, deviation}/*, ...*/]) {}
// Alias for repo-only elements - same syntax as matches, except "value" argument is always omitted
await suitest
.element('repo-id')
.matchesRepo([
{
name: suitest.PROP.BG_COLOR,
val: '#F00', // invalid, value is always taken from repo. Use matches for this
},
{
name: suitest.PROP.LEFT,
type: suitest.COMP.EQUAL,
},
]);
not¶
Universal negation of other chain commands.
/**
* @returns {ChainablePromise.<void|boolean>}
*/
async function not() {}
// Wait until cookie does not equal '1', but at most 3s
await suitest
.cookie('cookieName')
.doesNot()
.equal('1')
.timeout(3000);
repeat¶
Repeat sets how many times a chain is executed, used in conjunction with
press,
click,
sendText and
interval.
/**
* @param {number} times
* @returns {ChainablePromise.<void|boolean>}
*/
async function repeat(times) {}
// Press OK 10x every 10s
await suitest.press(suitest.VRC.OK)
.repeat(10)
.interval(10000);
requestMatches¶
requestMatches is used in conjunction with networkRequest.
/**
* @param {string|Symbol} name - properties to match against (some of names can be found in NETWORK_PROP)
* @param {string|number} value - properties to match against.
* @param {string} [type] - how to compare property, defaults to COMP.EQUAL
* @returns {ChainablePromise.<void|boolean>}
*/
async function requestMatches(name, value, type);
async function requestMatches({name, value, type});
async function requestMatches([{name, val, type}/*, ...*/]);
/**
* @param {Object.<name, value>} keyValueHash
* @param {string|Symbol} name - properties to match against (some of names can be found in NETWORK_PROP)
* @param {string|number} value - properties to match against.
* @returns {ChainablePromise.<void|boolean>}
*/
async function requestMatches(keyValueHash);
await networkRequest().requestMatches('propName', 'propVal');
await networkRequest().requestMatches('propName', 'propVal', COMP.NOT_CONTAIN);
await networkRequest().requestMatches(NETWORK_PROP.METHOD, NETWORK_METHOD.GET);
await networkRequest().requestMatches({
name: NETWORK_PROP.BODY,
val: 'body'
});
await networkRequest().requestMatches({
name: NETWORK_PROP.BODY,
val: 'body',
type: COMP.START
});
await networkRequest().requestMatches({
[NETWORK_PROP.BODY]: 'some body',
[NETWORK_PROP.METHOD]: NETWORK_METHOD.GET,
'Any-Header': 'header-value'
});
await networkRequest().requestMatches([
{
name: NETWORK_PROP.METHOD,
val: NETWORK_METHOD.GET,
},
{
[NETWORK_PROP.BODY]: '{}',
'Any-Header': 'header-value'
}
]);
inRegion¶
inRegion is used with image assertion subject to specify the area on a screen where Suitest should look for a match with a reference image. If this modifier is not used, Suitest searches on the whole screen.
// Compare reference image stored on my server with the top-left quarter of the screen
await suitest.assert.image({url: 'https://myserver.com/myimage.png'}).inRegion(
[0, 0, 50, 50] // left, top, width, height values in % of the screen
);
responseMatches¶
responseMatches is used in conjunction with networkRequest.
/**
* @param {Object.<name, value>} keyValueHash
* @param {string|Symbol} name - properties to match against (some of names can be found in NETWORK_PROP)
* @param {string|number} value - properties to match against.
* @returns {ChainablePromise.<void|boolean>}
*/
async function responseMatches(keyValueHash);
/**
* @param {string|Symbol} name - properties to match against (some of names can be found in NETWORK_PROP)
* @param {string|number} [value] - properties to match against.
* @param {string} [type] - how to compare property, defaults to COMP.EQUAL
* @returns {ChainablePromise.<void|boolean>}
*/
async function responseMatches(name, value, type);
async function responseMatches({name, value, type});
async function responseMatches([{name, val, type}/**, ...*/]);
await networkRequest().responseMatches('propName', 'propVal');
await networkRequest().responseMatches(NETWORK_PROP.STATUS, 200);
await networkRequest().responseMatches({
name: NETWORK_PROP.BODY,
val: 'body',
});
await networkRequest().responseMatches({
name: NETWORK_PROP.BODY,
val: 'body',
type: COMP.START
});
await networkRequest().responseMatches({
[NETWORK_PROP.BODY]: 'some body',
[NETWORK_PROP.STATUS]: 200,
'Any-Header': 'header-value'
});
await networkRequest().responseMatches([
{
name: NETWORK_PROP.STATUS,
val: 200
},
{
[NETWORK_PROP.BODY]: '{}',
'Any-Header': 'header-value'
}
]);
startWith¶
Checks if subject (as a string) starts with an expected string.
Alias .startsWith().
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function startWith(expectedValue) {}
// Cookie value starts with a certain string
await suitest
.cookie('cookieName')
.startsWith('value');
timeout¶
Set a timeout (in ms) or wait time for the chain to become resolved if it's not resolved an assertion error will be thrown.
Similar to assertion with timeout in Suitest Test editor.
By default the timeout is set to 2000 ms, therefore if you do not include
.timeout(ms), the chain will implicitly have .timeout(2000).
/**
* @param {number} ms - time in milliseconds
* @throws {SuitestError} - something unexpected happened while polling chain
* @returns {ChainablePromise.<void|boolean>}
*/
async function timeout(ms) {}
// Element exists
await suitest
.element('Some Element')
.exists()
.timeout(0);
// Wait until element exists but at most 10s
await suitest
.element('Some Element')
.exists()
.timeout(10000);
until¶
Executes the chain with given interval, max count number of
repeats until evaluation
chain is satisfied. Accepts another chain as only parameter.
Please note that the condition is being evaluated before each run (including the first one). Therefore the application has to be already running before the first evaluation.
/**
* @param {ChainablePromise} conditionChain - condition chain
* @returns {ChainablePromise.<void|boolean>}
*/
async function until(conditionChain) {}
// Check if element 'menu' appeared on a page after clicking on 'openMenuButton' element, but at most 5 times with 1 second interval
await suitest.element('openMenuButton').click().until(
suitest.element('menu').exists()
).interval(1000).repeat(5);
// Check if application has exited after pressing 'power' button several times
await suitest.assert.press(suitest.VRC.POWER).until(
suitest.application().hasExited()
).repeat(5).interval(2000);
visible¶
Evaluates if element is visible.
async function visible() {}
await assert.element('logo').visible();
wasMade¶
Evaluates if the network request has been made / will be soon made.
/**
* To be used with networkRequest chain - include previously made Ajax requests
*/
async function wasMade() {}
await suitest.networkRequest()
.contains('http://suite.st')
.wasMade();
willBeMade¶
Evaluates if a network requests will be made (excluding previously matched requests).
/**
* To be used with networkRequest chain - exclude previously made Ajax requests
*/
async function willBeMade() {}
await suitest.networkRequest()
.contains('http://suite.st')
.willBeMade();