Automated Testing with Cypress

In a previous blog, we explored about using Selenium with Ruby to automate tasks. We ran basic commands like navigating to a webpage, entering data into a search bar, clicking on a button. However we did not discuss the testing aspect of it. Today we will take a look at a similar tool called Cypress, which is also used for web app testing.

To install Cypress, make sure Node and NPM are installed on your machine. From your project folder, it’s then as simple as running npm init and npm install cypress.

The test website we will be using is Ms.Meaghan Lewis’ Formy-Project. It has a complete set of DOM elements that we can interactive with. In your project folder, this is what you should have so far after installing Cypress:

Next run the command node_modules/.bin/cypress open from your project folder. This will create a cypress folder as well as launch the Test Runner like so:

Cypress Test Runner

As you can see from above, the actual tests are JavaScript files (as Cypress is Node.js based, and Node.js is a JavaScript runtime) are stored in the integration folder. Let’s create a MyTest folder and inside of it, a test1.js file.

The first line is a directive that allows for IntelliSense when you type your code. It’s optional but you might find it very helpful. Then we have a describe block where you can have multiple it blocks that contain tests. Let’s see how this actually works by telling Cypress to launch our Chrome browser and go to the Formy Project website and run a simple test to check the url.

On line 6, the cy.visit() method is self explanatory. It goes to the url that’s passed in as argument. The next line, cy.url() returns the current url, and our test condition is it should equal to the second argument.

Save the file, and open the Test Runner, your test1.js file should be available. If you click on it, Cypress will launch Chrome, attempts to navigate to the Formy Project site, and finally it shows the test passed. Notice if you don’t have Chrome installed, Cypress will open a browser called Electron will comes bundled in.

Looking at the Formy webpage, there’s a link all the way on the bottom of the page called Complete Web Form, which takes you to another page, where you can enter various data and submit the form. Let’s see how we can use Cypress to accomplish this.

Remember in Selenium, the workflow was selecting some DOM element with its id, class, or XPATH, perform some actions on it, such as click, enter data, check it. This step is the same in Cypress.

If we inspect the link and show its HMTL in Developer Tools in Chrome, we can see it’s an <li>, inside of it, a <a> that has some attributes and text content. The cy.contains() method allows us to search element by their content.

If you simply try to do cy.get(‘li a’).contains(‘Complete Web Form’), Test Runner will throw an error stating such element is not visible. The reason for this is on top of the page, if you click on Components, you can see a dropdown list of links. They are the same links as those on the body of the page. They are also <a> tags inside of an <li>. However the dropdown list is not accessible (or visible) without first clicking on it. You can force a click with click( {force: true }), but in this case, we have another readily accessible link which we can use.

The Web Form page has several fields. Starting from the top, it has three inputs with an id of first-name, last-name, and job-title. Let’s fill those in now.

I’ve located the inputs in three different ways: tagName#ID, #ID, and attribute=value pair. Tag names are always optional. To enter an ID, simply prefix it with #. And an attribute=value pair should be wrapped inside of a single or double quotes and brackets.

To input keystrokes, we can call the type() method and pass in whatever data we want to put in.

And the result so far:

Next up we have radio buttons and checkboxes. On this particular web form, we cannot uncheck any radio buttons, and we can check more than one checkboxes for Sex. For our example, we will only check one radio button, and use a loop to check all three checkboxes.

Upon inspecting the elements, we can see the radio buttons have IDs and values of radio-button-1, radio-button-2, and radio-button-3, with text contents of High School, College, and Grad School. The method to use here is cy.check(). If the radio buttons were uncheckable, you could use cy.uncheck() to reverse the operation. However it’s not possible here.

Since we have three checkboxes on the page, writing cy.get(‘input[type=”checkbox”]’) will yield three results. From there, we can click on each one consecutively.

To uncheck a checkbox, we can use uncheck() like so:

Next we have a static dropdown for years of experience. After locating the element, we can use select() to select whichever value we want:

We can see each option has a value from 1 to 4, and a text content associated with it. We can use the value or the text content to select an option:

For the date picker, we can simply locate the element and type in a date:

Clicking on the Submit button will redirect us to another page:

For our test, let’s click on the Submit button and see if we have a <div> that contains the text “The form was successfully submitted!” In the code, you need to add a newline to the beginning and the end of the text. After the newline character in the beginner, there should be two spaces. It’s not obvious just by looking at the HTML code in the Developer tools, but when you run your test and it fails, the error messages will be helpful in determining what went wrong.

Running the test now will be a success.

Hopefully you get a chance to try out some of the useful commands covered here today. See you next week!