Add this to uitest.js:
describe('Add Note', function() {
// before(async function() { ... });
it('should see Add Note button', async function() {
const btnAddNote = await page.waitForSelector('#btnAddNote');
await btnAddNote.click();
});
it('should fill in Add Note form', async function() {
const formAddEditNote = await
page.waitForSelector('#formAddEditNote');
await page.type('#notekey', 'key42');
await page.type('#title', 'Hello, world!');
await page.type('#body', 'Lorem ipsum dolor');
await page.click('#btnSave');
});
it('should view note', async function() {
await page.waitForSelector('#noteView');
const shownKey = await page.$eval('#showKey', el =>
el.innerText);
assert.exists(shownKey);
assert.isString(shownKey);
assert.include(shownKey, 'key42');
const shownTitle = await page.$eval('#notetitle', el =>
el.innerText);
assert.exists(shownTitle);
assert.isString(shownTitle);
assert.include(shownTitle, 'Hello, world!');
const shownBody = await page.$eval('#notebody', el =>
el.innerText);
assert.exists(shownBody);
assert.isString(shownBody);
assert.include(shownBody, 'Lorem ipsum dolor');
});
it('should go to home page', async function() {
await page.waitForSelector('#btnGoHome');
await page.goto(process.env.NOTES_HOME_URL);
// await page.click('#btnGoHome');
await page.waitForSelector('#notesHomePage');
const titles = await page.$('#notetitles');
assert.exists(titles);
const key42 = await page.$('#key42');
assert.exists(key42);
const btnLogout = await page.$('#btnLogout');
assert.exists(btnLogout);
const btnAddNote = await page.$('#btnAddNote');
assert.exists(btnAddNote);
});
// after(async function() { ... });
});
This is a more involved scenario, in which we:
- Click on the ADD Note button
- Wait for the note edit screen to show up
- Fill in the text for the note and click the Save button
- Validate the note view page to ensure that's correct
- Validate the home page to ensure that's correct.
Most of this is using the same Puppeteer functions as before, but with a couple of additions.
The $eval function looks for the element matching the CSS selector, and invokes the callback function on that element. If no element is found an error is thrown instead. As used here, we are retrieving the text from certain elements on the screen, and validating that it matches what the test entered as the note. That's an end-to-end test of adding and retrieving notes.
The next difference is using goto instead of clicking on #btnGoHome.
As you add test scenarios to the test script, you'll find it easy for Puppeteer to have a spurious timeout, or for the login process to mysteriously not work, or other spurious errors.
Rather than go over the remaining scenarios, we'll spend the next section discussing how to mitigate such issues. But first we need to prove the scenario does work even if we have to run the test 10 times to get this result:
$ NOTES_HOME_URL=http://localhost:3000 ./node_modules/.bin/mocha --no-timeouts uitest3.js
Notes
Login
√ should click on login button (50ms)
√ should fill in login form (160ms)
√ should return to home page (281ms)
Add Note
√ should see Add Note button
√ should fill in Add Note form (1843ms)
√ should view note
√ should go to home page (871ms)
7 passing (5s)