Introduction to Cypress - coursehero/ch-react-workshop GitHub Wiki

Cypress is a tool for testing anything that runs in the browser. At Course Hero we use it mainly to write medium tests.

Installation

To get started run npx cypress open. This should open the Electron GUI from which you can launch a browser of your choice and run any of the available tests against your localhost.

First test

describe('My First Test', () => {
  it('Does not do much!', () => {
    expect(true).to.equal(true)
  })
})

All of these functions come from Bundled Tools that Cypress bakes in.

describe and it come from Mocha while expect comes from Chai.

First real test

describe('My Second Test', () => {
  it('finds the "Study Resources" text', () => {
    cy.visit('http://coursehero.com') // visit as a logged out user

    cy.contains('Study Resources') // find a text on the page
  })
})

Visiting a URL

To avoid hardcoding the URL we have configured the default baseUrl in cypress.json. Therefore you can replace cy.visit('https://coursehero.com') with just cy.visit('/'). This allows us to dynamically point to any other location (e.g. your actual website).

cy.visit() supports an additional argument headers.

Example:
const headers = { 
    "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1", // iPhone
}
...
cy.viewport('iphone-5') // visit as a mobile user
cy.visit(url, { headers }) 

Locating elements

cy.get() finds one or more HTML elements by selector or alias.

Examples:
cy.get('input') // finds an input element

cy.get('form').within(() => {
  cy.get('textarea').type('What is the process of meiosis?') // Type a question
  cy.get('input').type('biology') // Type a subject

cy.get('ul li:first').should('have.class', 'active') // Tests css

cy.contains() verifies that there is a text on the page.

Examples:
  <form>
    <div>
      <label>name</label>
      <input name="question" />
    </div>
    <div>
      <label>age</label>
      <input name="subject" />
    </div>
    <input type="submit" value="Enter your question" />
  </form>
cy.get('form').contains(/enter your question/i).click()
💡 Tip: to make sure your tests are resilient (a simple change to text should not break your test) and accessible consider using the built-in Cypress Testing Library plugin.
Examples:

Note: Cypress Testing Library uses .findBy* and not .getBy* version of the queries.

cy.findByRole('button', { name: /Desktop/i }).click() // the upload from Desktop button
cy.findByRole('button', { name: /Desktop/i }).should('exist') // an explicit test
cy.findByRole('button', { name: /Non-existing Button Text/i }).should(
  'not.exist'
)
cy.findByLabelText(/Enter school/i, { timeout: 7000 }).should('exist') // read the official documentation for .findByLabelText() first!

// findAllByText _inside_ a form element
cy.get('form')
  .findByText('button', { name: /subscribe to unlock/i })
  .should('exist')
cy.findByRole('dialog').within(() => {
  cy.findByRole('button', { name: /confirm/i })
})

Cypress Driven Development

Cypress allows you to get to a specific state really quickly and repetitively. This pairs really nicely with the Cypress version of Test Driven Development.

If you've ever developed an experience where a user has to enter in multiple pages of forms and then you get to the success page, developing the success page is a total nightmare because you have to type in all those form inputs. Now you can just use Cypress to type in all type in those form inputs automatically for you, so you can get to that last page quickly.

Anything you can access from the console is also accessible from Cypress: elements, console resources, Chrome extensions etc. For more advanced usage (or if you have previously used Selenium read the Stop using page objects blog post.

Other related topics

Test yourself

const $cyElement = cy.get('.element') // what is wrong with this line? (answer somewhere below)

Recommended reading

Suggested extensions for VS code

Next steps

⚠️ **GitHub.com Fallback** ⚠️