Automated End-to-End Testing With Selenium and Cypress.io

At ThinkCru building stable applications that are well tested is our #1 priority.  At first pass, we do Quality Assurance (QA) testing manually to ensure we are initially meeting our client's requirements.  However, at some point, as the application grows in complexity, manual testing is no longer sustainable.  In order to scale up testing as new features are added we deploy automated end-to-end (e2e) testing for using both Selenium and Cypress frameworks.  

Key Differences

The purpose of this post is to explore some of the key differences between the Selenium and Cypress frameworks.  Bellow is just a brief comparison

Framework Selenium WebDriver Cypress.io
Supported Languages Java, C#, Java Script, Python, Ruby, Onjective-C Java Script
Framework supported Supports multiple frameworks based on specific programming languages. (For e.g: JUnit for Java, Cucumber for JavaScript, etc.) Supports only Mocha JS
Browsers Supported Chrome, IE, Safari Edge, Firefox, Opera Chrome, Edge, Firefox Electron
Issues in GitHub Open - 287, Closed - 6513 Open - 1295, Closed - 5196
iFrame Support Yes No

Selenium

How Selenium works?

Selenium is driven by a variety of languages (Java, C#, Java Script, Python, Ruby, Objective-C) using an API that communicates with the WebDriver binary.

Curtesy of Browserstack.com
  1. Using the API, the Selenium commands creates an HTTP Request for each Selenium command and sends it to the browser driver.
  2. An HTTP request is then sent to the server using a specific Browser Driver (Chrome Driver, Firefox Driver, IE Driver, MS Edge Driver, etc).
  3. Then the steps are executed on the HTTP server.
  4. The execution status is sent to the HTTP server which is then captured by the Selenium script.

Advantages of Selenium

  1. Robust community, multiple bindings, and allows engineers to use best practices
  2. Mobile testing support
  3. Compared to Cypress, Selenium can work with iFrame elements and browser tabs

Limitations of Selenium

  1. No built-in command for automatic generation of test results.
  2. Handling page load or element load is difficult.
  3. Creating test cases is time-consuming as compared to Cypress
  4. Difficult to set up test environment as compared to Cypress

Multiple Tabs

To work with browser you should get an array of your tabs and select one:

WebDriver driver = new ChromeDriver();

ArrayList<String> tabs = new ArrayList<String>
(driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));

iFrames

Selenium purpose 3 methods to enter into iFrame:

driver.switchTo().frame(0);
driver.switchTo().frame("frameName");
driver.switchTo().frame(webElement);

Now you are able to work with html elements into selected iFrame. Also you can enter into new iFrame if it's located into entered iFrame.

But there is only one way to get out from iFrame:

driver.switchTo().defaultContent();

Cypress

How Cypress works?

Cypress developers created a new architecture from the ground up. Whereas Selenium executes remote commands through the network, Cypress runs in the same run-loop as your application. Behind Cypress is a Node.js server process. Cypress and the Node.js process constantly communicate, synchronize, and perform tasks on behalf of each other. Having access to both parts (front and back) gives us the ability to respond to your application's events in real time, while at the same time work outside of the browser for tasks that require a higher privilege.

Advantages of Cypress

  1. Easy to setup and start
  2. Good documentation and code samples
  3. Cypress captures snapshots at the time of test execution. This allows QAs or developers to hover over a specific command in the Command Log to see exactly what happened at that particular step. See more https://docs.cypress.io/guides/core-concepts/test-runner.html
  4. One doesn’t need to add explicit or implicit wait commands in test scripts, unlike Selenium. Cypress waits automatically for commands and assertions.
  5. As the programmer writes commands, Cypress executes them in real-time, providing visual feedback as they run.

Limitations of Cypress

  1. One cannot use Cypress to drive two browsers at the same time
  2. It doesn’t provide support for multi-tabs
  3. Cypress doesn’t provide support for browsers like Safari and IE at the moment
  4. Limited support for iFrames. See https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/

Coding

Example Test Case:

  1. Clone the example repo git clone git@github.com:thinkcru/selenium-test-project.git
  2. Open https://www.xe.com/
  3. Enter '100' in the Amount field
  4. Click the 'Convert' button
  5. Check that convert result more than '84'

Selenium (Java) Project

  1. Download and install JDK (https://www.oracle.com/java/technologies/javase-downloads.html)
  2. Download and install IDE (f.e. IntelliJ IDEA https://www.jetbrains.com/idea/download)
  3. Open IDE and create a project

4.   By default pom.xml file doesn't contain any dependencies. For our example we will need some dependencies (Selenium, WebDriverManager, TestNG). See more maven dependencies on https://mvnrepository.com/

5.   Create a package and java class

6.   For now you need to initialize WebDriver. There are two ways to do it: manually download WebDriver for a browser or use WebDriverManager (https://github.com/bonigarcia/webdrivermanager). To use WebDriverManager you need to add a dependency to pom.xml file.

WebDriver initialization without WebDriverMaganer
WebDriver initialization with WebDriverMaganer

7.   The following code example is how to implement the chromeDriver() to send an input with the amount of 100 into the text field.  The driver will then click() on the button associated with form submission.  An assertion assertTrue() will wait for the text to resolve the amount to 84.0.


Cypress project

  1. Clone the example project from the repo git clone git@github.com:thinkcru/cypress-io-test-project.git
  2. Download Node.js (https://nodejs.org/en/download/)
  3. Download IDE: WebStorm or Visual Studio Code. I will user VSC in this example.
  4. Create a folder for Cypress project
  5. Open the folder in cmd and run the following command to install Cypress

5.   Add package.json file to open Cypress. Now we can open Cypress by clicking cypress:open

6.   Click cypress:open to open Cypress. After the first launch test examples will be generated

7.    Create a folder in cypress/integration/ and spec.js file

8.    Create the example code and is quick and easy to implement the tests much like how a Unit Test is written.  In about 4 lines of code we can use the cy library to add the amount and invoke an expectation from what is returned in the browser.

Conclusion

Cypress and Selenium serve a similar purpose that is achieved in two different ways. A key difference is that Cypress ideal for introducing developers to test automation rather than just a replacement for Selenium. This is why Cypress is among the fastest-growing automation tools in the world. On the other hand, Selenium is a more general-purpose tool targeted at a broader audience.

Needless to say, prior to choosing an automation tool, one must weigh the pros and cons of every option.   If you are a beginner and are comfortable with Javascript then Cypress may be a good option.  On the other hand, if you have more complex needs, Selenium may be worth to try at first if loading up the driver is not too much effort.

Another thing to keep in mind is that if you look at how Cypress is built, it is largely a unit testing tool that is ideal for Javascript-focused development teams. Once you stray from these details and your team decides to experiment with other methods of test automation, you’ll find that Selenium can better accommodate those growing pains.