Table of Contents
URL: https://www.progressiverobot.com/vuejs-e2e-testing-testcafe/
End-to-end testing is one of the most valuable tools in your testing arsenal, allowing you to simulate what your user would do as they move through your app and determine if your app is responding correctly to that. Unfortunately, it's also one of the most difficult and time-consuming test methods as well, and the usual tools to do so require a decent amount of configuration and setup, further complicating the process. Thankfully, there are some relatively simple solutions. Here we'll demonstrate one of them, <^>TestCafe<^>, and show you how to do end-to-end testing with your Vue.js app. (That said, you can use these methods with any framework or site.)
Installation
Unlike traditional solutions that generally involve a near-unmanageable amount of dependencies, such as <^>Selenium / WebDriver<^> + <^>Browser Drivers<^> + <^>Client Libraries<^>, the entirety of <^>TestCafe<^> is node-based and installable in one package. It's also a zero-configuration tool. The required options are passed via the command line. As such, it's best used through NPM scripts.
# Yarn
$ yarn add testcafe -D
# NPM
$ npm install testcafe --save-dev
Setup
It is assumed from here that your app has a development server that can be run with <^>npm run dev<^>. <^>webpack-dev-server<^> works fine.
Add a new script to your <^>package.json<^> <^>scripts<^> object that starts testcafe.
"scripts": {
"dev": "...",
"test": "testcafe all tests/*.test.js --app \"npm run dev\" --app-init-delay 10000 -S -s screenshots",
}
This tells <^>testcafe<^> to:
all– Run tests in all browsers that it can find on the system. Optionally, set this to a comma-separated list of browser names.
tests/*.test.js– Run all files as tests that end with <^>.test.js<^> in the tests folder.
--app \"npm run dev\"– The command to start your app server.
--app-init-delay 10000– To delay starting the test suite for ten seconds to wait for your app server to load.
-S– Take screenshots when tests fail.
-s screenshots– Store screenshots in the <^>screenshots<^> folder relative to the project root.
Now we're ready to start writing end-to-end tests.
Your First Test
Let's assume for a moment that the entirety of your app is simply a paragraph element inside <^><body><^> that contains the words "Hello World!". Here's how we would ensure that is indeed the case.
Anything that has to communicate with the browser returns a promise. Using <^>async / await<^> to manage calls to the browser makes your tests much easier to grok. TestCafe handles any needed transpilation.
[label test/example.test.js]
// A fixture must be created for each group of tests.
fixture(`Index page`)
// Load the URL your development server runs on.
.page('http://localhost:8080');
// Create a new test(description, function(testController): <Promise>)
test('Body > Paragraph contains "Hello World!"', async testController => {
// Select the paragraph element under the body.
// Must use promises (async / await here) for communication with the browser.
const paragraphSelector = await new Selector('body > p');
// Assert that the inner text of the paragraph is "Hello World!"
await testController.expect(paragraphSelector.innerText).eql('Hello World!');
});
Controlling User Input
Now to do any half-decent end-to-end testing, you need to be able to simulate user actions and input. Like any good testing suite, TestCafe provides the necessary methods to handle this use-case.
test('Typing in an input', async testController => {
// Select the input element (Assumes <body><input type="text/></body>")
const inputSelector = await new Selector('body > input[type="text"]');
await testController
// Type the last word of "Hello World!"
.typeText(inputSelector, 'World!')
// Click the beginning of the element. caretPos is the position of the text cursor we want the click to be at.
.click(inputSelector, { caretPos: 0 })
// Type the keys, SHIFT+H, e, l, l, o, and SPACE in order to write "Hello ".
.keyPress('H e l l o space')
// The resulting value should now be "Hello World!"
.expect(inputSelector.value).eql('Hello World!');
});
Reference
TestCafe can do quite a bit more. They also provide some interesting conventions for reducing test duplication. To learn more, visit their official site.