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.
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.
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.
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
})
})
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 })
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 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.
const $cyElement = cy.get('.element') // what is wrong with this line? (answer somewhere below)
- What is Cypress: https://docs.cypress.io/guides/overview/why-cypress.html#Features
- Introduction to Cypress (the most important document. DO NOT SKIP!): https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Cypress-Can-Be-Simple-Sometimes
- Cypress Dashboard (optional): https://docs.cypress.io/guides/dashboard/introduction.html#Features
- Stubbing network requests: https://docs.cypress.io/guides/guides/network-requests.html#Requests
- Environment variables (optional): https://docs.cypress.io/guides/guides/environment-variables.html#Setting
- Stubs, spies & clocks (highly recommended): https://docs.cypress.io/guides/guides/stubs-spies-and-clocks.html#Capabilities
- Web Security (highly recommended): https://docs.cypress.io/guides/guides/web-security.html
- Best Practices (REQUIRED): https://docs.cypress.io/guides/references/best-practices.html
- Example application: https://www.cypress.io/blog/2020/06/11/introducing-the-cypress-real-world-app/
- Unit testing with Cypress: https://github.com/bahmutov/cypress-react-unit-test