TestCafe overview
Applitools Eyes SDK for TestCafe.
Installation
Install Eyes-Testcafe as a local dev dependency in your tested project:
npm i -D @applitools/eyes-testcafe
Getting started
To get started with this SDK, you need to set the following:
- Applitools API key
- Eyes server URL - Required only if the Eyes server is not deployed on the Eyes public server.
Entering the Applitools API key
To authenticate via the Applitools server and run tests, you need to set the environment variable APPLITOOLS_API_KEY
to the API key provided from Applitools Eyes. For details how to retrieve your API key, see the Applitools documentation in the Eyes Knowledge Center.
To to this, set the environment variable APPLITOOLS_API_KEY
to the API key before running your tests.
Entering the API Key on Linux or a Mac
export APPLITOOLS_API_KEY=<your_key>
npx testcafe chrome:headless some-test-dir
Entering the API Key on Windows
set APPLITOOLS_API_KEY=<your_key>
npx testcafe chrome:headless some-test-dir
Entering the API Key in the config.js file
You can also specify the API key in the applitools.config.js
file. The property name is apiKey
.
Example
module.exports = {
apiKey: 'YOUR_API_KEY',
...
}
Recommended practice for using the SDK
A test in Applitools Eyes always starts with a eyes.open
call and ends with eyes.close
. The steps in the test are calls to eyes.check
between eyes.open
and eyes.close
calls.
A test is structured as following:
eyes.open
[step 1]
[step 2]
...
eyes.close
In order to get a test structure in Eyes that corresponds to the test structure in TestCafe, we recommend that you open and close tests in every test
call. You can use afterEach
for calling eyes.close()
After all tests are complete you should call eyes.waitForResults
, you can use after()
for calling eyes.waitForResults
, this is is done for the following reasons:
- To signal to TestCafe to wait until all the tests have been completed.
- To obtain test results if needed.
Example
fixture`Hello world`
.page('https://applitools.com/helloworld')
.afterEach(async () => eyes.close());
.after(async () => eyes.waitForResults())
Eyes will take screenshots and perform the visual comparisons in the background. Performance of the tests will not be affected during the test run, but there will be a small phase at the end of the test run that waits for visual tests to end.
When running tests concurrently you should create an eyes instance for each test, see Concurrency
Using the TestCafe SDK
After defining the API key, you will be able to use commands from Eyes-Testcafe in your TestCafe tests to take screenshots and use Applitools Eyes to manage them:
Example
import Eyes from '@applitools/eyes-testcafe';
const eyes = new Eyes();
fixture`Hello world`
.page('https://applitools.com/helloworld')
.afterEach(async () => eyes.close())
.after(async () => eyes.waitForResults());
test('Cookies', async t => {
await eyes.open({
appName: 'Hello World!',
testName: 'My first JavaScript test!',
browser: [{ width: 800, height: 600, name: 'firefox' }],
t
});
await eyes.checkWindow('Main Page');
await t.click('button')
await eyes.checkWindow('Click!');
});
Common methods
open
Creates an Eyes test. This will start a session with the Applitools server.
eyes.open({
appName: '',
testName: '',
t
});
You can pass a config object to open
with all the possible configuration properties. For details, see Advanced configuration.
checkWindow
Generates a screenshot of the current page and adds it to the Eyes Test.
Syntax
eyes.checkWindow(tag)
OR
eyes.checkWindow({ tag: 'your tag', target: 'your target mode' })
Arguments to eyes.checkWindow
tag
Defines a name for the checkpoint in the Eyes Test Manager. The name may be any string and serves to identify the step to the user in the Test manager. You may change the tag value without impacting testing in any way since Eyes does not use the tag to identify the baseline step that corresponds to the checkpoint; Eyes matches steps based on their content and position in the sequences of images of the test.
For more information, see How Eyes compares checkpoints and baseline images in the Eyes Knowledge Center.
target
(optional): Possible values are:
-
window
: This is the default value. Capture the entire window or only the viewport. If set then add fully as sibling to determine weather to capture full screen or viewport. -
region
: Take a screenshot of a region of the page, specified by coordinates or a selector. If set then add region or selector as siblings for specifying the region/s.
fully:
(optional) If the target
is window
, this argument determines whether to capture full page or viewport only. if true
(default) the test captures full page, if false
the test captures viewport.
// capture viewport only
eyes.checkWindow({
target: 'window',
fully: false,
});
selector
(optional) If the target
is region
, this argument should be the actual css, xpath, or a Testcafe Selector to an element, and the screenshot would be the content of that element. For example:
// Using a Testcafe Selector
import {Selector} from 'testcafe';
eyes.checkWindow({
target: 'region',
selector: Selector('.my-region')
});
// Using a Testcafe Selector to reference an element within a shadow DOM
import {Selector} from 'testcafe';
eyes.checkWindow({
target: 'region',
selector: Selector('#has-shadow-root').shadowRoot().find('.my-region')
});
// The shorthand string version defaults to css selectors
eyes.checkWindow({
target: 'region',
selector: '.my-element'
});
// Using a css selector
eyes.checkWindow({
target: 'region',
selector: {
type: 'css',
selector: '.my-element' // or '//button'
}
});
// Using an xpath selector
eyes.checkWindow({
target: 'region',
selector: {
type: 'xpath',
selector: '//button[1]'
}
});
region
(optional) If the target
is region
, this argument should be an object describing the region's coordinates.
Example
eyes.checkWindow({
target: 'region',
region: {top: 100, left: 0, width: 1000, height: 200}
});
region
(optional) If the target
is region
, this argument should be an object describing the region's coordinates.
Example
eyes.checkWindow({
target: 'region',
region: {top: 100, left: 0, width: 1000, height: 200}
});
ignore
(optional): A single or an array of regions to ignore when checking for visual differences.
Example
eyes.checkWindow({
ignore: [
{top: 100, left: 0, width: 1000, height: 100},
{selector: '.some-div-to-ignore'},
{selector: Selector('.some-div')}
]
});
floating
(optional): A single or an array of floating regions to ignore when checking for visual differences. More information see Testing of floating UI elements .
Example
eyes.checkWindow({
floating: [
{top: 100, left: 0, width: 1000, height: 100, maxUpOffset: 20, maxDownOffset: 20, maxLeftOffset: 20, maxRightOffset: 20},
{selector: '.some-div-to-float', maxUpOffset: 20, maxDownOffset: 20, maxLeftOffset: 20, maxRightOffset: 20},
{selector: Selector('.some-div'), maxUpOffset: 20, maxDownOffset: 20, maxLeftOffset: 20, maxRightOffset: 20}
]
});
layout
(optional): A single or an array of regions to match as layout match level.
Example
eyes.checkWindow({
layout: [
{top: 100, left: 0, width: 1000, height: 100},
{selector: '.some-div-to-test-as-layout'},
{selector: Selector('.some-div')}
]
});
strict
(optional): A single or an array of regions to match as strict match level.
Example
eyes.checkWindow({
strict: [
{top: 100, left: 0, width: 1000, height: 100},
{selector: '.some-div-to-test-as-strict'},
{selector: Selector('.some-div')}
]
});
ignorColors
(optional): A single or an array of regions to match as ignore colors match level..
Example
eyes.checkWindow({
ignoreColors: [
{top: 100, left: 0, width: 1000, height: 100},
{selector: '.some-div-to-test-as-content'},
{selector: Selector('.some-div')}
]
});
accessibility
(optional): A single or an array of regions for checking accessibility on.
Example
eyes.checkWindow({
accessibility: [
{accessibilityType: 'RegularText', selector: '.some-div'},
{accessibilityType: 'RegularText', selector: Selector('.some-div-2')},
{accessibilityType: 'LargeText', selector: '//*[@id="main"]/h1', type: 'xpath'},
{accessibilityType: 'BoldText', top: 100, left: 0, width: 1000, height: 100},
]
});
Possible accessibilityType values are: IgnoreContrast
, RegularText
, LargeText
, BoldText
, and GraphicalObject
.
scriptHooks
(optional): A set of scripts to be run by the browser during the rendering. It is intended to be used as a means to alter the page's state and structure at the time of rendering.
An object with the following properties:
-
beforeCaptureScreenshot
: a script that runs after the page is loaded but before taking the screenshot. For example:eyes.checkWindow({
scriptHooks: {
beforeCaptureScreenshot: "document.body.style.backgroundColor = 'gold'"
}
})
sendDom
(optional): Specifies if DOM data should be sent to Eyes for use of Root Cause Analysis. The default value is true
.
eyes.checkWindow({sendDom: false})
ignoreDisplacements
(optional): Specifies whether Test Manager should initially display mismatches for image features that have only been displaced, as opposed to real mismatches.
eyes.checkWindow({ignoreDisplacements: true})
closeAsync
Closes the Eyes test but does not wait for the Eyes server to return a result. This command enables your system to continue running tests while Eyes completes its comparisons in the background. You should call this command at the end of each test, symmetrically to eyes.open
.
After executing all Eyes tests, your code should call Runner.getAllTestResults
to retrieve all test results as a TestResultsSummary
.
eyes.closeAsync();
close
Closes the Eyes test and waits for the Eyes Server to return a single result. The close
command then returns a TestResults
object with detailed test result data. This method takes an optional boolean parameter, if false
it will not throw an exception if the test found differences (default is true
). You should call this command at the end of each test, symmetrically to eyes.open
.
This is a legacy API as it only returns a single result. We recommend using eyes.closeAsync
and eyes.getResult
instead of this API.
eyes.close();
waitForResults
Wait until all tests in the fixture are completed and return their results.
We recommended that the method waits for the results in the TestCafe after()
hook.
await eyes.waitForResults()
waitForResults
receives an argument of throwEx
,
-
If
true
(default) and a visual test fails then reject with anError
(in case of a general error reject as well). If the rejection is not handled then TestCafe fails the fixture. -
If
false
and a visual test fails thenwaitForResults
resolves with anError
. In case of a generalError
reject with theError
.
If all the tests passed, then waitForResults
resolves with the test results. If using tapDirPath
, then a tap file will be written to disk with the results as well.