Skip to main content
aaronwilliams.me logo

Cypress Getting Started Introduction

Introduction

This is the first post in a multi-part series focused on the core Cypress open-source end-to-end testing features. These posts exclude any paid tools and will be kept concise and focused, starting with this Bronze Series for foundational concepts and progressing through to the Legendary Series, which explores the most advanced levels of core Cypress.

Tip! This is the introductory post; topics will be explored in more detail later in the series.

What is Cypress?

Cypress is an open-source website testing tool written in JavaScript. To use Cypress, you need to write your tests in either JavaScript or TypeScript.

During tests, Cypress runs alongside the application under test using browser automation APIs. This gives you some advantages while writing your tests, such as the ability to mock API responses or access the window or document objects.

Example Cypress Test

In this example, the test checks that a footer section is present, visible, and displays the expected copy.

describe("Footer tests", () => {
  it("should show copyright text", () => {
    cy.visit("/");
    cy.contains("footer", "© 2025 awilliams.me.")
      .should("be.visible");
  });
});

Installing Cypress

To install Cypress, run npm i -D cypress in your project. After that, run npx cypress open to launch the Cypress open mode app where you can run single tests at a time and view a snapshot of the application under test at each step of the test.

jQuery Under the Hood

Cypress tests are written using Cypress commands, such as cy.get('main'). Under the hood, these commands use jQuery and yield a jQuery-wrapped array of DOM elements. You can access properties using cy.invoke() or access the raw DOM node via indexing ([0]).

Cypress Command Chaining

Unlike regular JavaScript, Cypress commands do not execute immediately. Each command is queued to run later, after the test function has finished running.

Cypress commands are chained. Each command yields a result to the next — this yielded value is known as the subject.

cy.get('a')
  .should("have.length.greaterThan", 0);

In this example, the list of a tags is yielded from cy.get() and passed down to the .should() assertion.

Because of Cypress’s command queueing, you can’t directly return a value from a Cypress command. Instead, tests must continue using Cypress’s chaining model.

Retry-ability

One of Cypress's key selling points is its retry-ability feature. It automatically gives querying and assertions retries until they pass or timeout.

For example, jQuery’s $('main') will attempt to find the <main> tag once and return the result immediately. The Cypress equivalent cy.get('main') will, by default, retry for up to 4 seconds until it finds the element, and then yield it to the next command in the chain.

Actionability

Cypress also has actionability, which is a process that takes place when using commands like .click(), .type(), or .clear(). These trigger a series of checks to simulate real user behavior, such as scrolling the element into view and verifying visibility.

Cypress Command Types

Below is a categorized reference of common Cypress commands, grouped by purpose. This isn’t exhaustive but outlines how Cypress commands are structured.


Assertions

Handle chained expectation callbacks for the subject.

  • cy.should()
  • cy.and()

Actions

Actions should be used on a yielded subject. These run through the actionability checks before interacting with the element.

  • cy.click()
  • cy.type()

Aliasing

Assigns the previous subject or request to an alias for later reuse using cy.get('@YOUR_ALIAS_NAME').

  • cy.as()

Querying

Queries on the DOM are automatically retried until they find a selector or alias or timeout.

  • cy.get()
  • cy.find()

Traversal

Traversal helpers to use on the yielded subject.

  • cy.find()
  • cy.children()

Navigation

Navigate within the application under test.

  • cy.visit()
  • cy.reload()

Waiting

It... waits...

  • cy.wait()

Spies, Stubs & Clocks

Spying and stubbing are Sinon wrappers.

  • cy.stub()
  • cy.clock()

Network Requests

Performing or intercepting network requests.

  • cy.request()
  • cy.intercept()

Cookies

Manage browser cookies.

  • cy.setCookie()
  • cy.clearCookies()

Storage

Manage local/session storage per origin.

  • cy.getAllLocalStorage()
  • cy.clearAllSessionStorage()

Window & Document

Query window objects or set the viewport size.

  • cy.document()
  • cy.viewport()

Location

Query the page URL or document location value.

  • cy.url()
  • cy.location()

Origin

Cross-origin commands used with testing multiple domains.

  • cy.origin()

Files & Fixtures

Filesystem I/O commands.

  • cy.readFile()
  • cy.fixture()

Screenshots

Test runner screenshot command.

  • cy.screenshot()

Sessions

Authentication session managed across test run.

  • cy.session()

Task & Exec

Running node code during or before the test run.

  • cy.task()
  • cy.exec()

Utilities & Connectors

Helpers for working with values or chaining logic.

  • cy.wrap()
  • cy.then()

Debugging

Debug with full access to your app and the Cypress command chain.

  • cy.pause()
  • cy.debug()

Limitations

Because of how Cypress works, it comes with a few important limitations to understand. To name some:

  • 🫤 Only supports Chrome, Firefox, and WebKit browsers
  • 🫤 Testing using multiple tabs is not supported
  • 🫤 Testing across multiple domains is limited (possible with workarounds)
  • 🫤 JavaScript alongside Cypress commands can sometimes be challenging

Wrapping Up

Continue through this series to explore more of these topics and explore more of what Cypress has to offer.