End-to-End Testing Vue.js Apps with TestCafe

Published on March 7, 2017

Joshua Bemenderfer

End-to-End Testing Vue.js Apps with TestCafe

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

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.)


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.

To begin using it in your Vue app, install testcafe via Yarn or NPM. You might also consider using the vuepack template for vue-cli if you’re starting a new project.

# Yarn
$ yarn add testcafe -D

$ npm install testcafe --save-dev


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.

// A fixture must be created for each group of tests.
fixture(`Index page`)
  // Load the URL your development server runs on.

// 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!');


TestCafe can do quite a bit more. They also provide some interesting conventions for reducing test duplication. To learn more, visit their official site.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Joshua Bemenderfer


Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel