0.2.4 • Published 5 years ago
@unic/estatico-jest v0.2.4
@unic/estatico-jest
Puppeteer environment for Jest tests.
Installation
$ npm install --save-dev jest @unic/estatico-jest
Usage
Create
jest.config.js
:const path = require('path'); const dir = path.dirname(require.resolve('@unic/estatico-jest')); module.exports = { globalSetup: path.join(dir, './setup.js'), globalTeardown: path.join(dir, './teardown.js'), testEnvironment: path.join(dir, './environment.js'), testRegex: 'src/.*\\.test\\.js$', // This seems to be the only way for now to pass options to setup.js // https://github.com/facebook/jest/issues/5957#issuecomment-422027349 projects: [{ // We temporarily run a static webserver where Puppeteer can access our HTML puppeteerServer: { port: 3000, dir: './dist', puppeteer: { // Our current Teamcity agents expect Puppeteer to run in no-sandbox mode args: env.ci ? ['--no-sandbox'] : [], }, }, }], };
Recommendation: Add
jest
as npm script:"scripts": { "jest": "jest" }
Optional: Set up Gulp task (requires
strip-ansi
package):/** * JavaScript testing task * Uses Jest with Puppeteer to check for JS errors and run tests * Expects an npm script called "jest" which is running jest * * An alternative would be to use jest.runCLI instead. However, this currently fails * due to the teardown script terminating the process in order to close the static webserver. * * Instead of running this task it is possible to just execute `npm run jest` */ gulp.task('js:test', (done) => { // eslint-disable-line consistent-return // Skip task when skipping tests if (env.skipTests) { return done(); } const { spawn } = require('child_process'); const stripAnsi = require('strip-ansi'); let failed = false; let killed = false; let teardownFailed = false; const tests = spawn('npm', ['run', 'jest'].concat(env.ci ? ['--', '--ci'] : []), { // Add proper output coloring unless in CI env (where this would have weird side-effects) stdio: env.ci ? 'pipe' : ['inherit', 'inherit', 'pipe'], }); tests.stderr.on('data', (data) => { if (stripAnsi(`${data}`).match(/(Test Suites: (.*?) failed|npm ERR!)/m)) { failed = true; } // Don't treat as failure: Travis seems to kill the whole process for whatever reason if (stripAnsi(`${data}`).match(/Killed/m)) { killed = true; } // Don't treat as failure: The web server might have stopped or the process could not be found if (stripAnsi(`${data}`).match(/No process found on port/m)) { teardownFailed = true; } process.stderr.write(data); }); tests.on('close', () => { if (failed && !env.dev && !killed && !teardownFailed) { process.exit(1); } done(); }); });
Add test files to repository (their file name needs to match the
testRegex
above).Recommended: Add
eslint-plugin-jest
withjest/globals
to.eslintrc.js
.
Example test
describe('Slideshow Tests', () => {
let page;
beforeAll(async () => {
const url = `http://localhost:${global.__STATIC_PORT__}/demo/modules/slideshow/slideshow.html`;
page = await global.__BROWSER__.newPage();
page.on('pageerror', console.log);
await page.goto(url, {
waitUntil: ['networkidle2']
});
});
afterEach(async () => {
await page.reload();
});
afterAll(async () => {
await page.close();
});
it('should load without error', async () => {
const text = await page.evaluate(() => document.body.textContent);
expect(text).toContain('Slideshow');
});
it('should return initial image source', async () => {
const src = await page.evaluate(async () => {
const img = document.querySelector('[data-slideshow="slide"] img');
return img.src;
});
expect(src).toBe('http://www.fillmurray.com/600/201');
});
it('should change the active slide on "next" button click', async () => {
const currentItem = await page.evaluate(async () => {
const button = document.querySelector('[data-slideshow="next"]');
const uuid = document.querySelector('[data-init="slideshow"]').dataset.slideshowInstance;
await button.click();
return window.estatico.modules.slideshow.instances[uuid].currentItem;
});
expect(currentItem).toBe(1);
});
});
License
Apache 2.0.