The value of automation testing goes beyond time, money, and effort saved over the course of of a project life cycle. However, one aspect of testing that can be easily forgotten in the scope of letting an automated script test is a simple question: does the application actually look the way that I want to?
"Well of course it does!" A tester might ask themselves. "That's the entire point of making assertions within the test script. How else can we launch a new update or feature to the application?" Unfortunately, the pitfull of the dismissive thought goes down to the basis that visual bugs are rendering issues that fall under rendering validation. An automated script is built and designed in the context of functional testing and validation, but does not necessarily cover rendering or visual defects that could happen when using an application. Angie Jones makes for a good point that even in the real world, an automated test script can miss a glaring visual error that would be easy for anyone to simply look at the state of the application. The straightforward approach in visual/rendering validation would be simply to sit down with the application and check for any bugs… but that is a lot of time to dedicate the manual testing that could be put elsewhere. Another tester might then ask "Okay, so why don't I simply add more assertions that simply covers visual errors as part of functional testing? It can't be that difficult" However, rather than force the tester to discover themselves the Eldricth horror about to be unleashed onto themnselves, it is important to highlight several critical flaws:&*$#%#! I knew there was a missing tear drop!
APPLITOOLS_API_KEY
environment variable depending on your operating system (or hardcode the API KEY within the project's dependancies)
set APPLITOOLS_API_KEY='YOUR_API_KEY'
within the command prompt (make sure to use Admin priviledges as needed for this step)npm ver 10 or 12+
installed globally, execute the initial command> npm init
package.json
that will direct the Cypress installation later down the line, as indicated in the screenshotpackage.json
file> npm install cypress --save-dev
.bin
directory. Run the command from the main project directory to open Cypress> .\node_modules\.bin\cypress open
> npm i -D @applitools/eyes-cypress
> npx eyes-setup
applitools.config.js
in the root directory of the project. The below code sets up concurrency
, apiKey
and the browser x viewports combinations.applitools.config.js
does not need the API Key if already set as an environment variablemodule.exports = { concurrency: 1, apiKey: '[YOUR API KEY]', }
[project directory]>cypress>integration
. Create a new directory and create a file visualtest.js
so the first test can be written./// <reference types="cypress" /> /// <reference types="@applitools/eyes-cypress" /> describe("DemoTest", () => { beforeEach(() => { // Call Open on eyes to initialize a test session cy.eyesOpen({ $ appName: 'Ultranauts Applitools Eyes', $ browser: [ // Add browsers with different viewports {width: 1500, height: 870, name: 'chrome'}, {width: 1500, height: 870, name: 'firefox'}, {width: 1500, height: 870, name: 'edgechromium'}, {width: 1500, height: 870, name: 'safari'}, // Add mobile emulation devices in Landscape mode {deviceName: 'iPhone XR', screenOrientation: 'landscape'}, // Add mobile emulation devices in Portrait mode {deviceName: 'Pixel 2 XL', screenOrientation: 'portrait'} ], // set batch name to the configuration $ batchName: 'Ultranauts.co Demo for Applitools' }); }); it(`Open Main Website`, function () { // Navigate to the url we want to test // âï¸ Note to see visual bugs, changes have to be made on // https://ultranauts.co/' for each additional run after the first run cy.visit('https://ultranauts.co/'); // Ensure several elements are loaded on the Ultranauts Website cy.get('#bluebox2 > .innerherobox').scrollIntoView(); cy.get('#herocol1').should('be.visible'); cy.get('#herocol2').should('be.visible'); cy.get('#herocol3').should('be.visible'); cy.get('#bluebox2 > .innerherobox' , { timeout: 7000 }).should('be.visible'); cy.wait(1500); cy.get(':nth-child(2) > .fusion-column-first > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(2) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(3) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(4) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > .fusion-column-last > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(3) > .fusion-column-first > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(3) > :nth-child(2) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(3) > :nth-child(3) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(3) > :nth-child(4) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(3) > .fusion-column-last > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(4) > .fusion-column-first > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(4) > :nth-child(2) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(4) > :nth-child(3) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(4) > :nth-child(4) > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get(':nth-child(4) > .fusion-column-last > .fusion-column-wrapper > .fusion-imageframe > .img-responsive').should('be.visible'); cy.get('.fusion-builder-row-2').scrollIntoView(); cy.wait(1500); cy.get('.fusion-column-first > .fusion-column-wrapper > a > .casestudy').should('be.visible'); cy.get(':nth-child(2) > .fusion-column-wrapper > a > .casestudy').should('be.visible'); cy.get('.fusion-column-last > .fusion-column-wrapper > a > .casestudy').should('be.visible'); cy.get('.fullwidth-faded').scrollIntoView(); cy.wait(1500); cy.get('.fusion-column-first > .fusion-column-wrapper > a > .service > .serviceholder').should('be.visible'); cy.get(':nth-child(2) > .fusion-column-wrapper > a > .service > .serviceholder').should('be.visible'); cy.get('.fusion-column-first > .fusion-column-wrapper > a > .service > .serviceholder').should('be.visible'); cy.get('.fusion-builder-row-4').scrollIntoView(); cy.wait(1500); cy.get('.content-box-column-1 > .col').should('be.visible'); cy.get('.content-box-column-2 > .col').should('be.visible'); cy.get('.content-box-column-3 > .col').should('be.visible'); cy.get('.fusion-builder-row-5').scrollIntoView(); cy.wait(1500); cy.get('.fusion-builder-row-6').should('be.visible'); cy.get('.fusion-builder-row-6').scrollIntoView(); cy.wait(1500); cy.get(':nth-child(1) > .fusion-column-first > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(1) > :nth-child(2) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(1) > :nth-child(3) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(1) > :nth-child(4) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(1) > .fusion-column-last > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > .fusion-column-first > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(2) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(3) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > :nth-child(4) > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get(':nth-child(2) > .fusion-column-last > .fusion-column-wrapper > .fusion-imageframe > .fusion-no-lightbox > .img-responsive').should('be.visible'); cy.get('.fusion-builder-row-7').scrollIntoView(); cy.wait(1500); cy.get('.fusion-footer-widget-area').scrollIntoView(); cy.wait(1500); // Check the app page cy.eyesCheckWindow({ $ tag: "Homepage", $ target: 'window', $ fully: true }); }); afterEach(() => { // Call Close on eyes to let the server know it should display the results cy.eyesClose(); }); });
visualtest.js
the automation script will run in the designated browser where it will run the assertions, before capturing a screenshot. With the number of devices listed, it may take a minute or so before the batch is fully captured in Applitools.visualtest.js
in Cypress, the script should take time to execute and go through the batch configuration set up in the code.visualtest.js
and display the results of the test run:visualtest.js
we can see some of the attributes are displayed on the dashboard from what we have written in the test script:batchName
An optional argument for cy.eyesOpen(). Configures the label of the batch runs on the left column on the Applitools Dashboard. If you want to differentiate between batch runs this value needs to be changed.
appName
An optional argument for cy.eyesOpen(). Configures the label shown in the column under "App" if the Dashboard is set to display the App column.
testName
An optional argument for cy.eyesOpen(). If this is not specified, the test name will be the title of the it
block where the test is running.
tag
An optional argument for cy.eyesCheckWindow(). This label is visible when showing the image preview and hovering over the image, after the user clicks on a row:
IGNORE
- Applitools will not focus on the region in question when comparing the baseline and checkpint images (use sparingly when possible!)
STRICT
- Applitools will focus on minute differences as observed, much like what the human eye can detect at a glance.
LAYOUT
- Applitools will validate the relative position of elements between the baseline and checkpoint images, ignoring differences in content text, graphics, color, and other style changes.
CONTENT
- Applitools will ignore color and light style changes between the baseline and checkpoint images.
FLOAT
- Applitools will accept an element that shifts within an region boundary. If the element moves beyond the boundary, then the difference will be noted in further test runs.
Annotations
select the region button dropdown to select IGNORE
an apply the region over the video backgroundI | Attachment | Action | Size | Date | Who | Comment |
---|---|---|---|---|---|---|
png | Applitools Beseline and Checkpoint Comparison.png | manage | 1019 K | 08 Dec 2020 - 17:45 | AustinBell | Baseline and Checkpoint Comparison |
png | Applitools Dashboard 2.png | manage | 167 K | 07 Dec 2020 - 15:43 | AustinBell | Applitools Dashboard |
png | Applitools Dashboard Unresolved Test.png | manage | 167 K | 08 Dec 2020 - 16:30 | AustinBell | Unresolved Test in Applitools |
png | Applitools Pass.png | manage | 149 K | 09 Dec 2020 - 17:24 | AustinBell | Applitools Pass |
png | Cypress Fails Applitools.png | manage | 197 K | 07 Dec 2020 - 20:24 | AustinBell | Cypress flags an Applitools Fail |
png | Cypress Pass.png | manage | 255 K | 09 Dec 2020 - 17:20 | AustinBell | Cypress Passes |
png | Cypress application.png | manage | 21 K | 30 Nov 2020 - 16:01 | AustinBell | Cypress |
png | Ignore Region Applied to Mismatch.png | manage | 870 K | 09 Dec 2020 - 16:51 | AustinBell | Ignore Region Applied |
png | Resolving Differences in Batch.png | manage | 150 K | 09 Dec 2020 - 17:01 | AustinBell | Resolving the Batch |
png | applitools install npm package and npx eye-setup.png | manage | 60 K | 30 Nov 2020 - 20:05 | AustinBell | Applitools Dependency |
png | find-10-differences-visual-game-for-children-and-adults-puzzle-game.png | manage | 75 K | 25 Nov 2020 - 14:06 | AustinBell | Spot-The-Difference Game |
png | install cypress.png | manage | 66 K | 30 Nov 2020 - 16:10 | AustinBell | Install Cypress |
png | npm init.png | manage | 61 K | 30 Nov 2020 - 16:00 | AustinBell | NPM INIT |
png | open cypress.png | manage | 37 K | 30 Nov 2020 - 16:21 | AustinBell | Open Cypress Application |
gif | set environment variable system properties.gif | manage | 1 MB | 30 Nov 2020 - 14:04 | AustinBell | System Properties Set Environment Variable |
gif | set environment variable.gif | manage | 1 MB | 30 Nov 2020 - 13:30 | AustinBell | CMD Set Environment Variable |
png | tag label.png | manage | 31 K | 07 Dec 2020 - 16:45 | AustinBell | Showing tag from test script |