{"id":3168,"date":"2018-09-23T13:24:40","date_gmt":"2018-09-23T13:24:40","guid":{"rendered":"https:\/\/solutionstreet.com\/blog\/?p=3168"},"modified":"2018-09-23T13:24:40","modified_gmt":"2018-09-23T13:24:40","slug":"move-over-selenium-cypress-is-here","status":"publish","type":"post","link":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/","title":{"rendered":"Move Over Selenium, Cypress is Here"},"content":{"rendered":"<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png\" alt=\"runnerguytitlepiccopy\" width=\"768\" height=\"576\" class=\"aligncenter size-medium wp-image-3263\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy.png 768w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>I love pragmatic solutions and if you\u2019ve read some of my prior articles (<a href=\"https:\/\/www.linkedin.com\/pulse\/write-less-code-arthur-frankel\/\" target=\"_blank\" rel=\"noopener\">Write Less Code<\/a>, <a href=\"https:\/\/solutionstreet.com\/blog\/its-getting-better-all-the-time-making-the-complex-simple-using-asyncawait-in-javascript\/#.W5VevJNKgWo\" target=\"_blank\" rel=\"noopener\">Making the Complex Simple&#8230;<\/a>), I often look for tools and solutions that have an easy barrier to entry, avoid complexity, and allow developers to do their jobs. In the world of browser-based end-to-end testing, Selenium has been king. If you mention automated testing you will typically hear Selenium first followed by a few other commercial and open source products. I have used Selenium with various language bindings (Java, JavaScript, Ruby) on different projects and always ran into lots of issues with timeouts, tests taking too long, and strange inconsistencies with results. This may not be everyone\u2019s experience, but it has certainly been mine. This article is not a bashing of Selenium since I do think it\u2019s king for many reasons, but when something comes along that seems better (less complexity and better consistency) then I enjoy sharing the information with others.<\/p>\n<p>&nbsp;<\/p>\n<p>Recently a colleague of mine mentioned that he was using this tool called <a href=\"https:\/\/www.cypress.io\/\" target=\"_blank\" rel=\"noopener\">Cypress<\/a>. I gave it a go and was very impressed. Here is an overview including:<\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li>What is Cypress?<\/li>\n<li>How does it differ from Selenium?<\/li>\n<li>Where does it fall short?<\/li>\n<li>Example tests using a todo application.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>What can you do with Cypress?<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Cypress is a UI end-to-end automation testing framework that is NOT built on Selenium. It actually runs directly in the browser (Chrome browser, more on this later). Developers and\/or QA Engineers can write and run unit tests, integration tests, and end-to-end tests. It\u2019s for developers to do pure <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\" rel=\"noopener\">TDD<\/a> while building an application and then run and record those tests in a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuous_delivery\" target=\"_blank\" rel=\"noopener\">CI\/CD<\/a> environment where failures are easy to debug. Developers write the tests in JavaScript using familiar tools like <a href=\"https:\/\/mochajs.org\/\" target=\"_blank\" rel=\"noopener\">Mocha<\/a> (test framework) and <a href=\"https:\/\/www.chaijs.com\/\" target=\"_blank\" rel=\"noopener\">Chai<\/a> (assertion library) and maybe a not so familiar <a href=\"https:\/\/sinonjs.org\/\" target=\"_blank\" rel=\"noopener\">Sinon<\/a> (mocks, stubs, and spies) and use jQuery selectors for finding elements in the DOM.<\/p>\n<p>&nbsp;<\/p>\n<p> <strong>How is Cypress different from Selenium?<\/strong><\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li>Most importantly, Cypress runs in the browser so it has access to the application and everything in the browser. Because of this, many of the items below are possible.<\/li>\n<li>Cypress allows you to bypass logging into your application (a common delay with testing using Selenium since you typically need to login to your application to have access to functionality). Cypress can extract a cookie and just use it at will for future tests.<\/li>\n<li>With Cypress you can programmatically bring your application to its desired state. For example, instead of logging in and drilling down several pages, you can alter the state to begin where you need to start your testing.<\/li>\n<li>Cypress gives you the ability to really assist with testing during development and beyond including:<\/li>\n<p>a) access to <a href=\"https:\/\/docs.cypress.io\/guides\/guides\/stubs-spies-and-clocks.html#Spies\" target=\"_blank\" rel=\"noopener\">spies<\/a> &#8211; for verifying that a function has been called;<br \/>\nb) <a href=\"https:\/\/docs.cypress.io\/guides\/guides\/stubs-spies-and-clocks.html#Stubs\" target=\"_blank\" rel=\"noopener\">stubs<\/a> &#8211; to change the behavior of functions to aid in testing;<br \/>\nc) control over the browser&#8217;s <a href=\"https:\/\/docs.cypress.io\/guides\/guides\/stubs-spies-and-clocks.html#Clock\" target=\"_blank\" rel=\"noopener\">clock<\/a> &#8211; to allow you to simulate time passing; and<br \/>\nd) intercept and modify HTTP requests &#8211; as in the case to stub out the backend during development.<\/p>\n<li>Very fast &#8211; again because it\u2019s in the browser.<\/li>\n<li>Records video by default when running tests command line &#8211; video of your tests running to allow you to see actual changes and help debug.<\/li>\n<li>No waits or sleeps! Again, since Cypress runs in the browser, these delays or hacks go away.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Let me go into detail with the login process to illustrate the benefits of using Cypress over Selenium. Those of you who have used Selenium or other testing tools are familiar with the additional overhead time required with the full process of logging in a user just to get to the point where you can test a functional page. With Cypress you have the ability to simplify, and more importantly, improve the speed of this process.<\/p>\n<p>&nbsp; <\/p>\n<p>First, let\u2019s take a step back and discuss the various options for dealing with authentication in Cypress:<\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li>Stub requests &#8211; here we can just test the UI on its own and make sure no authenticated requests are being submitted to the server. This requires a bunch of work to do this but may make sense in certain applications.<\/li>\n<li>Seed the server with users.<\/li>\n<li>Dynamically create new users. This can be slow depending upon the server authentication process.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Depending upon your server situation you may use a combination of these three, but for the purposes of this article let\u2019s assume we are going to seed the database with a few different users with different roles and attempt to login with each of those users as quickly as possible.<\/p>\n<p>&nbsp; <\/p>\n<p>First, to seed the users, you have three ways to communicate with the outside world (outside the browser):<\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/exec.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.exec<\/a> &#8211; to execute system command.<\/li>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/request.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.request<\/a> &#8211; to make HTTP request.<\/li>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/task.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.task<\/a> &#8211; to talk directly to Node.js (in plugins).<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>With any of these you can seed your database. We\u2019ll assume that the authentication process from your login page is a typical one:<\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li> Form submit with username and password.<\/li>\n<li> Post values to an API.<\/li>\n<li> On success, saves the token.<\/li>\n<li> All pages requiring a login user checks for the token.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Before we get to code, let\u2019s organize how we are writing tests. Each spec file tests an individual page in isolation. This spec file will contain any number of individual tests for that page. The best practice is to then group these spec files by functional groupings into a folder. With Cypress, there is an index.js file that is loaded first. This is where your commonly used functions are stored (such as a login function).<\/p>\n<p>&nbsp;<\/p>\n<p>Here is an example of a common login function you may have:<\/p>\n<pre lang=\"javascript\" line=\"1\">\nCypress.Commands.add('login', () => {\n  cy.request({\n    method: 'POST',\n    url: 'http:\/\/localhost:3000\/api\/users\/login',\n    body: {\n      user: {\n        email: 'arthur@example.com',\n        password: 'solutionstreet',\n      }\n    }\n  })\n  .then((resp) => {\n    window.localStorage.setItem('jwt', resp.body.user.token)\n  })\n})\n\n<\/pre>\n<p>&nbsp;<\/p>\n<p>You can then call this function from individual specs via cy.login(). The \u201cmagic\u201d here is that we are using cy.request(). The cy.request() makes HTTP requests outside of any security restrictions, but it actually uses the browser&#8217;s user agent and cookie store. In this example we are actually logging in via the server without going to any login page and filling in the form, but you can see how this can be taken further to just set the token in local storage based on one that is valid without calling the API. Of course this may have its own set of issues, but the point is that you have deeper access to deal with bypassing traditional testing requirements to go to the login page, fill out the form, and submit.<\/p>\n<p>&nbsp;<\/p>\n<p>The overriding concept of Cypress is that you have internal control so you can have direct access to any number of things the browser has access to including direct access to a <a href=\"https:\/\/redux.js.org\/api\/store\" target=\"_blank\" rel=\"noopener\">Redux store<\/a> and other internal access points used by single page application architectures.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"padding: 12px; background-color: #eee9e9; line-height: 1.2; margin: 40px; border: 1px solid #ccc; border-radius: 6px; box-shadow: 1px #ccc; border-left: 5px solid #61963D;\"><span style=\"font-size: x-large; color: #61963d;\">\u201c<\/span><em>One of the most powerful aspects of Cypress is that your tests are \u201crecorded\u201d in that you can hover over any step executed in your test code to see the state of the UI at that point. This is powerful for debugging purposes.<\/em><span style=\"font-size: x-large; color: #61963d; line-height: 1.0;\">\u201d<\/span><\/div>\n<p>&nbsp;<\/p>\n<p><strong>Where does Cypress fall short?<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>At this point there are three obvious areas:<\/p>\n<ol>\n<li>Browser support &#8211; Cypress only supports Chrome currently but is expected to expand to other browsers.<\/li>\n<li>Cypress supports only plain JavaScript or Typescript, whereas Selenium supports more languages.<\/li>\n<li>Community &#8211; small community currently.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Additionally, Cypress does not have the ability to do record and playback (convert a recording of you testing in real-time into scripts), something that <a href=\"https:\/\/www.seleniumhq.org\/projects\/ide\/\" target=\"_blank\" rel=\"noopener\">Selenium offers<\/a>. However, I would attest to the fact that this capability is not used often for serious testing. Cypress offers the ability to easily find DOM elements and makes writing tests much easier.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Example &#8211; basic todo app<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>I wanted to test Cypress using a basic web app to get the flavor of what it can do. I chose to download a <a href=\"https:\/\/github.com\/scotch-io\/node-todo\" target=\"_blank\" rel=\"noopener\">basic todo app<\/a> running on Node and using MongoDB. You can follow along as well to see the basics of Cypress. Obviously you can test your own application, but I would warn against testing any public application that is not owned by you (e.g., google.com or facebook.com).<\/p>\n<p>&nbsp;<\/p>\n<p>First, (as taken from the GitHub instructions for the basic todo app) perform the installation of the todo app:<\/p>\n<p>&nbsp;<\/p>\n<p>Requirements &#8211;<\/p>\n<ol>\n<li>You must have Node.js and NPM installed &#8211; you can use any number of methods including <a href=\"https:\/\/nodejs.org\/en\/download\/\" target=\"_blank\" download=\"\" rel=\"noopener\">here<\/a> and <a href=\"http:\/\/blog.teamtreehouse.com\/install-node-js-npm-mac\" target=\"_blank\" rel=\"noopener\">here<\/a>. You may already have these installed &#8211; NPM is installed with Node typically. You can type \u201cnode\u201d and \u201cnpm\u201d in a terminal to make sure you have them.<\/li>\n<li>MongoDB &#8211; make sure you have your own local or remote MongoDB database URI configured in config\/database.js. Again, you may already have MongoDB installed or you can find one set of instructions <a href=\"https:\/\/docs.mongodb.com\/manual\/installation\/\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/li>\n<li><a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Getting-Started-Installing-Git\" target=\"_blank\" rel=\"noopener\">Git<\/a>.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Installation of todo app &#8211;<\/p>\n<ol>\n<li>Clone the repository: <em>git clone git@github.com:scotch-io\/node-todo<\/em><\/li>\n<li>Install the application: <em>npm install<\/em><\/li>\n<li>Place your own MongoDB URI in config\/database.js &#8211; mine looks like this:<\/li>\n<pre lang=\"javascript\" line=\"1\">\nmodule.exports = {\n    localUrl: 'mongodb:\/\/localhost:27017\/todoapp'\n};\n<\/pre>\n<li>Change into the node-todo directory you just cloned and start the server: <em>npm start<\/em><\/li>\n<p>a) Note: in another terminal window you need to have MongoDB running if you don\u2019t have it running in the background (e.g., <em>mongod<\/em>)<\/p>\n<li>View in browser at http:\/\/localhost:8080<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>At this point you should be able to add items to the list and select them (checkbox) to be deleted. It will look something like this:<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3205\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1.png\" alt=\"image1\" width=\"800\" height=\"428\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1.png 1999w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1-300x161.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1-1024x548.png 1024w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1-768x411.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1-1536x822.png 1536w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/image1-1568x839.png 1568w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Now that we have our application to test, we can move on to installing Cypress and testing.<\/p>\n<p>&nbsp;<\/p>\n<p>Installation of Cypress &#8211;<\/p>\n<ol>\n<li>In the node-todo project directory, run: <em>npm install cypress &#8211;save-dev<\/em><\/li>\n<li>Now that you have Cypress installed for this project you can open Cypress via either:<\/li>\n<p>a) <em>npx cypress open<\/em> (if your version of npm &gt; 5.2); or<br \/>\nb) <em>.\/node_modules\/.bin\/cypress open<\/em>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Cypress, like Selenium, is fairly easy to install. At this point your Cypress Test Runner is running and will look something like this (with various example specs already installed).<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3212\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy.png\" alt=\"2figure copy\" width=\"800\" height=\"527\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy.png 1999w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy-300x198.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy-1024x675.png 1024w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy-768x506.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy-1536x1013.png 1536w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/2figure-copy-1568x1034.png 1568w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>You can click on the \u201cRun all specs\u201d button in the upper right hand corner and see several dozen tests running for about a minute.<\/p>\n<p>&nbsp;<\/p>\n<p>At this point let\u2019s add a test:<\/p>\n<ol>\n<li>Open your node-todo project in your favorite editor. I\u2019m using <a href=\"https:\/\/code.visualstudio.com\/\" target=\"_blank\" rel=\"noopener\">Visual Studio Code<\/a>.<\/li>\n<li>In cypress.json at the root of the project, change the contents to be the following:<\/li>\n<pre lang=\"javascript\" line=\"1\">\n{\n  \"baseUrl\": \"http:\/\/localhost:8080\"\n}\n\n<\/pre>\n<p>This will set the base url of our todo application so that we can just reference the application by a basic root of \u201c\/\u201d instead of the full url.<\/p>\n<li>Create an empty js file called \u2018first_spec.js\u2019 under the node-todo\/cypress\/integration directory.<\/li>\n<li>Within the file add the following code:<\/li>\n<pre lang=\"javascript\" line=\"1\">\ndescribe('My First Test', function() {\n  it('Visits my site and verifies text', function() {    \n    cy.visit('\/')\n    cy.contains('Todo-aholic')\n  })\n})\n\n<\/pre>\n<li>Go to the Test Runner (scroll down to the bottom) and double-click on your file \u2018first_spec.js\u2019. This will execute your test in a new Chrome window. Note that at this point your test will constantly be running as you make changes.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>It will look something like this after its successful run:<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3213\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy.png\" alt=\"3 copy\" width=\"800\" height=\"516\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy.png 1999w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy-300x194.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy-1024x661.png 1024w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy-768x496.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy-1536x991.png 1536w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/3-copy-1568x1012.png 1568w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>All we have done here in the test is go to the url and verify the text \u201cTodo-aholic\u201d. Now change the text \u201cTodo-aholic\u201d to something else in your test file and save (e.g., \u201cTodo-aaaaa\u201d. Cypress will automatically run and show you a failure &#8211; takes a few seconds to fail since it\u2019s handling the waiting and timeouts).<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3215\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy.png\" alt=\"4figure copy\" width=\"800\" height=\"515\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy.png 1999w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy-300x193.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy-1024x659.png 1024w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy-768x494.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy-1536x989.png 1536w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/4figure-copy-1568x1010.png 1568w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Now change the contents of \u2018first_spec.js\u2019 to be the following:<\/p>\n<pre lang=\"javascript\" line=\"1\">\ndescribe('My First Test', function() {\n  it('Visits my site and verifies text', function() {\n    cy.exec('mongo todoapp --eval \"db.dropDatabase()\"')\n    \n    cy.visit('\/')\n    cy.contains('Todo-aholic')\n\n    cy.get('.form-control')\n      .type('My First Automated Item')\n    cy.get('.btn').click()\n\n    cy.get('.form-control')\n      .type('My Second Automated Item')\n    cy.get('.btn').click()\n\n    cy.get('.label').should('have.text', '2')\n\n    cy.get(':nth-child(1) > .ng-binding > input').click()\n    cy.get(':nth-child(1) > .ng-binding > input').click()\n\n    cy.get('.label').should('have.text', '0')\n\n    cy.get('.form-control')\n      .type('A really longgggg todo item!!!!!!!!!!!!!!!')\n    cy.get('.btn').click()\n  })\n})\n\n<\/pre>\n<p>After saving, this should execute successfully. Let me discuss a few of these lines:<\/p>\n<ol>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/exec.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.exec<\/a> &#8211; This allows us to execute a system command &#8211; here I\u2019m clearing out the database before each run.<\/li>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/get.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.get<\/a> &#8211; Here I\u2019m finding DOM elements; some simple elements and some more complex.<\/li>\n<li><a href=\"https:\/\/docs.cypress.io\/api\/commands\/type.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.type<\/a> and <a href=\"https:\/\/docs.cypress.io\/api\/commands\/click.html#Syntax\" target=\"_blank\" rel=\"noopener\">cy.click<\/a> &#8211; Typing into fields and clicking buttons.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>A full set of commands are listed <a href=\"https:\/\/docs.cypress.io\/api\/commands\/type.html#Syntax\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>How was I able to identify complex elements? Cypress offers the ability to identify DOM elements easily. Within the Chrome browser that starts from the Test Runner, there is a button on top called \u201cOpen Selector Playground\u201d. After selecting this you can hover over elements and see their selector paths. For example, here I am hovering over the text area where you type in a todo item to see that the selector would be \u2018.form-control\u2019:<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3216\" src=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy.png\" alt=\"5figure copy\" width=\"800\" height=\"514\" srcset=\"https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy.png 1999w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy-300x193.png 300w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy-1024x658.png 1024w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy-768x494.png 768w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy-1536x987.png 1536w, https:\/\/www.solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/5figure-copy-1568x1008.png 1568w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>One of the most powerful aspects of Cypress is that your tests are \u201crecorded\u201d in that you can hover over any step executed in your test code to see the state of the UI at that point. This is powerful for debugging purposes. Cypress should run on all <a href=\"https:\/\/docs.cypress.io\/guides\/guides\/continuous-integration.html#What-is-supported\" target=\"_blank\" rel=\"noopener\">continuous integration<\/a> providers.<\/p>\n<p>&nbsp;<\/p>\n<p>See <a href=\"https:\/\/docs.cypress.io\/guides\/references\/best-practices.html\" target=\"_blank\" rel=\"noopener\">here<\/a> for more information on best practices.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Summary<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Although I didn\u2019t go very deep into many functions and features, you can clearly see the power of the tool. With deeper aspects of stubbing, mocking, and spies, Cypress becomes more powerful in its usage. Cypress is certainly more of a developer\u2019s type of testing tool than Selenium &#8211; which many would consider a QA tool &#8211; but the need for a pragmatic UI-based unit\/integration\/end-to-end testing tool is much needed with today\u2019s complex UIs. There is no question that being in the browser is much better for testing more dynamic UIs with single page application architectures. I don\u2019t know if Cypress will ever take the lead from Selenium, but I do know that I will be suggesting the use of Cypress over Selenium for testing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; I love pragmatic solutions and if you\u2019ve read some of my prior articles (Write Less Code, Making the Complex Simple&#8230;), I often look for tools and solutions that have an easy barrier to entry, avoid complexity, and allow developers to do their jobs. In the world of browser-based end-to-end testing, Selenium has been king. [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3168","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Move Over Selenium, Cypress is Here - Solution Street Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Move Over Selenium, Cypress is Here - Solution Street Blog\" \/>\n<meta property=\"og:description\" content=\"&nbsp; I love pragmatic solutions and if you\u2019ve read some of my prior articles (Write Less Code, Making the Complex Simple&#8230;), I often look for tools and solutions that have an easy barrier to entry, avoid complexity, and allow developers to do their jobs. In the world of browser-based end-to-end testing, Selenium has been king. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/\" \/>\n<meta property=\"og:site_name\" content=\"Solution Street Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-23T13:24:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png\" \/>\n<meta name=\"author\" content=\"Peggy Frankel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Peggy Frankel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/\"},\"author\":{\"name\":\"Peggy Frankel\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4846451eff30e9514b534b2a2e01696\"},\"headline\":\"Move Over Selenium, Cypress is Here\",\"datePublished\":\"2018-09-23T13:24:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/\"},\"wordCount\":2290,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/09\\\/runnerguytitlepiccopy-300x225.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/\",\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/\",\"name\":\"Move Over Selenium, Cypress is Here - Solution Street Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/09\\\/runnerguytitlepiccopy-300x225.png\",\"datePublished\":\"2018-09-23T13:24:40+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4846451eff30e9514b534b2a2e01696\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#primaryimage\",\"url\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/09\\\/runnerguytitlepiccopy-300x225.png\",\"contentUrl\":\"https:\\\/\\\/solutionstreet.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/09\\\/runnerguytitlepiccopy-300x225.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/2018\\\/09\\\/23\\\/move-over-selenium-cypress-is-here\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Move Over Selenium, Cypress is Here\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/\",\"name\":\"Solution Street Blog\",\"description\":\"Quality Software Engineering - Technology and Consulting Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/#\\\/schema\\\/person\\\/c4846451eff30e9514b534b2a2e01696\",\"name\":\"Peggy Frankel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g\",\"caption\":\"Peggy Frankel\"},\"url\":\"https:\\\/\\\/www.solutionstreet.com\\\/blog\\\/author\\\/pfrankel\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Move Over Selenium, Cypress is Here - Solution Street Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/","og_locale":"en_US","og_type":"article","og_title":"Move Over Selenium, Cypress is Here - Solution Street Blog","og_description":"&nbsp; I love pragmatic solutions and if you\u2019ve read some of my prior articles (Write Less Code, Making the Complex Simple&#8230;), I often look for tools and solutions that have an easy barrier to entry, avoid complexity, and allow developers to do their jobs. In the world of browser-based end-to-end testing, Selenium has been king. [&hellip;]","og_url":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/","og_site_name":"Solution Street Blog","article_published_time":"2018-09-23T13:24:40+00:00","og_image":[{"url":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png","type":"","width":"","height":""}],"author":"Peggy Frankel","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Peggy Frankel","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#article","isPartOf":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/"},"author":{"name":"Peggy Frankel","@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/c4846451eff30e9514b534b2a2e01696"},"headline":"Move Over Selenium, Cypress is Here","datePublished":"2018-09-23T13:24:40+00:00","mainEntityOfPage":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/"},"wordCount":2290,"commentCount":0,"image":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#primaryimage"},"thumbnailUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/","url":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/","name":"Move Over Selenium, Cypress is Here - Solution Street Blog","isPartOf":{"@id":"https:\/\/www.solutionstreet.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#primaryimage"},"image":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#primaryimage"},"thumbnailUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png","datePublished":"2018-09-23T13:24:40+00:00","author":{"@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/c4846451eff30e9514b534b2a2e01696"},"breadcrumb":{"@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#primaryimage","url":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png","contentUrl":"https:\/\/solutionstreet.com\/blog\/wp-content\/uploads\/2018\/09\/runnerguytitlepiccopy-300x225.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.solutionstreet.com\/blog\/2018\/09\/23\/move-over-selenium-cypress-is-here\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.solutionstreet.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Move Over Selenium, Cypress is Here"}]},{"@type":"WebSite","@id":"https:\/\/www.solutionstreet.com\/blog\/#website","url":"https:\/\/www.solutionstreet.com\/blog\/","name":"Solution Street Blog","description":"Quality Software Engineering - Technology and Consulting Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.solutionstreet.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.solutionstreet.com\/blog\/#\/schema\/person\/c4846451eff30e9514b534b2a2e01696","name":"Peggy Frankel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/af71ceb16f89d32c9bb825a47f8057da9283b4a27a934bf0c47cdef65ad0eb5d?s=96&d=mm&r=g","caption":"Peggy Frankel"},"url":"https:\/\/www.solutionstreet.com\/blog\/author\/pfrankel\/"}]}},"_links":{"self":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts\/3168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/comments?post=3168"}],"version-history":[{"count":0,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/posts\/3168\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/media?parent=3168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/categories?post=3168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.solutionstreet.com\/blog\/wp-json\/wp\/v2\/tags?post=3168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}