Github: https://github.com/railsstudent/image-gallery-native-js
1) yarn add puppeteer mocha chai
yarn add puppeteer mocha chai
2) Create bootstrap.js file to share global variables among tests. Expose chai.expect, chai.assert and an instance of browser
'use strict';
const puppeteer = require('puppeteer');
const chai = require('chai');
const expect = chai.expect;
const globalVariables = {
browser: global.browser,
expect: global.expect
};
// puppeteer options
const opts = {
headless: true,
slowMo: 150,
timeout: 50000
};
// expose variables
before (async function () {
global.expect = expect;
global.browser = await puppeteer.launch(opts);
});
// close browser and reset global variables
after (function () {
global.browser.close();
global.browser = globalVariables.browser;
global.expect = globalVariables.expect;
});
3) Puppeteer creates a headless browser that timeout after 50 seconds and slow down operation by 150 milliseconds.
// puppeteer options
const opts = {
headless: true,
slowMo: 150,
timeout: 50000
};
4) Set up npm script commands in package.json to load the variables in bootstrap.js and execute all UI test cases in test/gallery.test.js directory
"scripts": {
"serve:test": "gulp build && http-server dist/ -p 8000",
"puppeteer": "rm ./test/*.png; SCREEN_SHOT=false mocha test/bootstrap.js test/gallery.test.js",
"puppeteer-screenshot": "rm ./test/*.png; SCREEN_SHOT=true mocha test/bootstrap.js test/gallery.test.js"
}
5) Write mocha test case in test file.
describe('gallery test', function() {
let page;
this.timeout(TIMEOUT);
before(async () => {
try {
page = await browser.newPage();
await page.goto('http://localhost:8000/');
} catch (e) {
console.error(e);
}
});
after(async () => {
await page.close();
});
it('Shows first image src is not blank and has correct caption and visible buttons',
async () => {
try {
await page.waitForSelector('.image:nth-child(1)', { visible: true, timeout: 0 });
await page.screenshot( {
path: './test/test4.png'
});
const imageElement = await page.$('.image:nth-child(1)');
await imageElement.click();
await page.screenshot( {
path: './test/test5.png'
});
const modalHandle = await page.$('.modal.show');
const imageSrc = await page.evaluate((modal) =>
modal.querySelector('#modal-image').src, modalHandle);
const caption = await page.evaluate((modal) =>
modal.querySelector('#caption').innerText, modalHandle);
const [btnCloseDisplay, btnCloseOpacity,
btnLeftDisplay, btnLeftOpacity,
btnRightDisplay, btnRightOpacity
] = await page.evaluate((modal) => {
const { opacity: closeOpacity, display: closeDisplay }
= window.getComputedStyle(modal.querySelector('.close'));
const { opacity: leftOpacity, display: leftDisplay }
= window.getComputedStyle(modal.querySelector('.left-arrow'));
const { opacity: rightOpacity, display: rightDisplay }
= window.getComputedStyle(modal.querySelector('.right-arrow'));
return [
closeDisplay, closeOpacity,
leftDisplay, leftOpacity,
rightDisplay, rightOpacity
];
}, modalHandle);
expect(imageSrc).to.not.equal('');
expect(caption).to.equal(`1 of ${NUM_IMAGES}`);
expect(btnCloseDisplay).to.equal('inline-block');
expect(btnRightDisplay).to.equal('inline-block');
expect(btnLeftDisplay).to.be.equal('block');
expect(btnCloseOpacity).to.equal('1');
expect(btnRightOpacity).to.equal('1');
expect(btnLeftOpacity).to.equal('0');
const closeHandle = await page.$('.modal.show .close');
await closeHandle.click();
closeHandle.dispose();
modalHandle.dispose();
} catch (e) {
console.error(e);
throw e;
}
});
});
6) Build development version and serve website at http://localhost:8000
yarn serve:test
7) Run UI test cases without creating screen shots
yarn puppeteer
8) Run UI test cases that creates screen shots
yarn puppeteer-screenshot
Finally, we are done.