This lesson walks through writing a complete, realistic Cypress test from scratch: visiting a login page, filling in a form, submitting it, and asserting on the outcome.
Planning the Test
A good first test targets a small, well-understood user flow. Logging into an application is a common starting point because it exercises visiting a page, typing into inputs, clicking a button, and asserting on a resulting URL or piece of UI.
Before writing any Cypress code, it helps to write the steps in plain English first, then translate each step into one or two Cypress commands.
// Plain English plan:
// 1. Visit the login page
// 2. Type an email and password
// 3. Click the submit button
// 4. Assert the URL changes to /dashboard
Writing the plan in plain English first makes the Cypress code almost write itself.
cy.visit() loads the target page and waits for it to finish loading.
cy.get() finds an element; .type() simulates real keystrokes into it.
.click() simulates a real mouse click on the found element.
cy.url().should(...) asserts on the current page URL after the action.
First Test Command Reference
The small set of commands that make up most beginner-friendly Cypress tests.
Command
Example
What It Does
Visit
cy.visit('/login')
Load a page
Find
cy.get('[data-cy="email"]')
Locate an element
Type
.type('hello@x.com')
Simulate typing
Click
.click()
Simulate a click
Assert URL
cy.url().should('include', '/x')
Check the current URL
Assert text
.should('contain', 'Welcome')
Check visible text
Running the Test
Save the spec file inside cypress/e2e/, then run npx cypress open and select the file from the Test Runner, or run it headlessly with npx cypress run --spec "cypress/e2e/login.cy.js".
The interactive Test Runner shows each command as it executes, along with a live preview of the application and a snapshot of the DOM at every step, which is invaluable while a test is still being written.
Interactive mode (cypress open) is best while writing and debugging a new test.
Headless mode (cypress run) is best for CI and quick full-suite checks.
Cypress automatically reloads and reruns a test whenever you save the spec file.
Reading Your First Failure
When an assertion fails, Cypress shows a clear error in the Test Runner, including the expected versus actual value, and highlights the exact command that failed in the command log on the left side of the interface.
AssertionError: expected 'http://localhost:3000/login'
to include '/dashboard'
This kind of message usually means either the login request failed, or the redirect has not happened yet, both worth investigating in the app itself.
Common Mistakes
Writing a test that depends on a previous test's state instead of visiting a fresh page in every test.
Clicking a submit button before Cypress has finished typing into every required field.
Asserting on brittle implementation details (like exact pixel positions) instead of meaningful outcomes.
Not giving the login form's elements stable data-cy attributes before writing the test.
Key Takeaways
Plan a test in plain English before translating it into Cypress commands.
A typical first test combines cy.visit(), cy.get(), .type(), .click(), and an assertion.
The interactive Test Runner is the best environment for writing and debugging new tests.
Cypress failure messages clearly show expected versus actual values and the failing command.
Pro Tip
Write the assertion first, even before the rest of the test. Deciding exactly what "success" looks like up front keeps the rest of the test focused and prevents scope creep into testing unrelated behavior.
You have written and run your first Cypress test. Next, see how Cypress compares to Selenium in Cypress vs Selenium.