Summary of problem: I'm writing several test suites (using Jest and Puppeteer) to automate tests for my AngularJS app's index.html page. Unfortunately, I'm seeing some odd behavior when I run my tests, which I think is related to the order in which Jest runs my various test suites.
Background: I'm using Jest (v24.8.0) as my testing framework. I'm using Puppeteer (v1.19.0) to spin up and control a Chromium browser on which to perform my tests.
My Code:
<!-- index.html -->
<div ng-app="myApp" ng-controller="myCtrl as ctrl">
<form name="form1">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name1"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
<form name="form2">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name2"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
</div>
// index.spec.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://my-site.com');
describe('form 1', async () => {
test('populate form 1', async () => {
let formSelector = 'form[name="form1"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('casey');
let submitButtonSelector = 'form[name="form1"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
describe('form 2', async () => {
test('populate form 2', async () => {
let formSelector = 'form[name="form2"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('jackie');
let submitButtonSelector = 'form[name="form2"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
await browser.close();
})();
Test Behavior:
Sometimes when I run npm test
it seems that my two test suites, 'form1'
and 'form2'
(which I defined with describe
), are being run in parallel (although I know that's not possible in Javascript, so I am assuming Jest runs different test suites asynchronously). Either way, when I run my tests in non-headless mode, I can see that form1
's name input is populated with 'jackie'
, even though it should be 'casey'
. After that happens, form2
is never filled out (even though my second test suite is supposed to do just that) and the tests complete, after which Jest informs me that 'populate form 2'
has failed. Again, this doesn't happen every time I run my tests, so you may not be able to replicate my problem.
My Questions:
Does Jest run test suites in parallel/asynchronously? Note: I'm not talking about individual test's defined with
test
within the test suites, I know that those are run asynchronously if I pass them anasync
function.If Jest does run test suites asynchronously, how do I disable that? Or better yet, is smart/conventional/optimal to give different test suites different
browser
instances so that they are run in completely separate windows? Are there any other methods for ensuring test suites are run separately and/or synchronously?If Jest does not run test suites asynchronously, then why do you think I'm seeing this behavior?
I'm asking because I'd like to find a way to ensure that all my tests pass all of the time, instead of just some of the time. This will make it easier in the long run to determine whether or not my changes during development have broken anything.
Thanks in advance to all you Jest/Puppeteer hackers out there!