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:
accuracy
- how accurate should the image comparison becontain
- check if subject contains an expected stringendWith
- check if subject ends with an expected stringequal
- check is subject is equal to expected valueexist
- check if subject existshasExited
- check if application has exitedinRegion
- defines the area on screen to compare to the subjectinterval
- set interval between chain executionsisPaused
- check if the state of video is pausedisPlaying
- check if the state of video is playingisStopped
- check if the state of video is stoppedlanguage
- defining language for ocr featurematch
- compare state of element to defined valuesmatchJS
- check if subject matches JS expressionmatchRepo
- compare state of element with element repository statenot
- universal negationrepeat
- repeat execution of a chainrequestMatches
- check if network request matches dataresponseMatches
- check if network response matches datastartWith
- check if subject starts with an expected stringtimeout
- timeout to wait until chain becomes resolveduntil
- execute chain until condition is satisfiedvisible
- check if an element is visiblewasMade
- network requests in entire request logwillBeMade
- network requests excluding previously matched requests
accuracy
¶
Define 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
¶
Checks if subject (as a string) contains an expected string.
Alias .contains()
.
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function contain(expectedValue) {}
await suitest
.cookie('cookieName')
.contains('someValue');
endWith
¶
Checks if subject (as a string) ends with an expected string.
Alias .endsWith()
.
/**
* @param {string} expectedValue
* @throws {SuitestError} if subject is unavailable
* @returns {ChainablePromise.<void|boolean>}
*/
async function endsWith(expectedValue) {}
await suitest
.cookie('cookieName')
.endsWith('someValue');
equal
¶
Checks if a subject is equal to an expected value.
Alias .equals()
.
/**
* @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
¶
Checks if a subject exists. Can be used with not
to change to "does
not exist".
Alias .exists()
.
/**
* @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();
hasExited
¶
Checks if the application has exited. hasExited
can only be used on
application
.
/**
* @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
¶
Set interval (in ms) between chain executions, used in conjunction with
press
,
click
,
sendText
and
repeat
.
/**
* @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
¶
Used in conjunction with video
,
checks video status.
const isVideoPaused = await suitest.video().isPaused();
await suitest.assert.video().isPaused();
isPlaying
¶
Used in conjunction with video
,
checks video status.
const isVideoPlaying = await suitest.video().isPlaying();
await suitest.assert.video().isPlaying();
isStopped
¶
Used in conjunction with video
,
checks video status.
const isVideoStopped = await suitest.video().isStopped();
await suitest.assert.video().isStopped();
language
¶
language
is used to define 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.LANG
constants for values.
match
¶
match
is used in conjunction with element
and video
,
it 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.
Alias .matches()
.
/**
* @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',
}
]);
.match
method can accept objects withname
property, conflicts may occur in.match
arguments due to the dictionary being able to containname
key as well.
matchJS
¶
Checks if subject matches a JS expression. Can be used on the following
subjects: element
,
video
,
location
and
cookie
.
Alias .matchesJS()
.
/**
* @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
¶
matchRepo
is used in conjunction with element
and video
,
it 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.
Alias .matchesRepo()
.
/**
* @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. Can be used with
equal
, contain
, starWith
,
endWith
, exist
, matchJs
,
jsExpression
wasMade
and willBeMade
.
Aliases .doesNot()
and .isNot()
.
/**
* @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 an image to be compared with a reference one. 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
¶
Use in conjunction with element
and
video
,
to check if element is visible.
async function visible() {}
await assert.element('logo').visible();
wasMade
¶
Used in conjunction with networkRequest
,
check for network requests in entire request log.
/**
* To be used with networkRequest chain - include previously made Ajax requests
*/
async function wasMade() {}
await suitest.networkRequest()
.contains('http://suite.st')
.wasMade();
willBeMade
¶
Used in conjunction with networkRequest
,
checks for network requests 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();