---
id: api/commands/and
title: and | Cypress Documentation
description: >-
  Create an assertion. Assertions are automatically retried as part of the
  previous command until they pass or time out.
section: api
source_path: docs/api/commands/and.mdx
version: 3cf5b86b3403f604bdf7f3e35025c3bc3865e02c
updated_at: '2026-05-07T17:44:31.931Z'
---
# and

Create an assertion. Assertions are automatically retried as part of the previous command until they pass or time out.

An alias of [`.should()`](/llm/markdown/api/commands/should.md)

**Note:** `.and()` assumes you are already familiar with core concepts such as [assertions](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Assertions)

## Syntax

```
.and(chainers).and(chainers, value).and(chainers, method, value).and(callbackFn)
```

### Usage

**Correct Usage**

```
cy.get('.err').should('be.empty').and('be.hidden') // Assert '.err' is empty & hiddency.contains('Login').and('be.visible') // Assert el is visiblecy.wrap({ foo: 'bar' })  .should('have.property', 'foo') // Assert 'foo' property exists  .and('eq', 'bar') // Assert 'foo' property is 'bar'
```

**Incorrect Usage**

```
cy.and('eq', '42') // Can not be chained off 'cy'cy.get('button').click().and('be.focused') // Should not be chained off// action commands that may update the DOM
```

### Arguments

**chainers _(String)_**

Any valid chainer that comes from [Chai](/llm/markdown/app/references/assertions.md#Chai) or [Chai-jQuery](/llm/markdown/app/references/assertions.md#Chai-jQuery) or [Sinon-Chai](/llm/markdown/app/references/assertions.md#Sinon-Chai).

**value _(String)_**

Value to assert against chainer.

**method _(String)_**

A method to be called on the chainer.

**callbackFn _(Function)_**

Pass a function that can have any number of explicit assertions within it. Whatever was passed to the function is what is yielded.

### Yields [Learn about subject management](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Subject-Management)

*   In most cases, `.and()` yields the same subject it was given.
*   `.and()` is an assertion, and it is _safe_ to chain further commands that use the subject.

```
cy.get('nav') // yields <nav>  .should('be.visible') // yields <nav>  .and('have.class', 'open') // yields <nav>
```

However, some chainers change the subject. In the example below, `.and()` yields the string `sans-serif` because the chainer `have.css, 'font-family'` changes the subject.

```
cy.get('nav') // yields <nav>  .should('be.visible') // yields <nav>  .and('have.css', 'font-family') // yields 'sans-serif'  .and('match', /serif/) // yields 'sans-serif'
```

## Examples

### Chainers

#### Chain assertions on the same subject

```
cy.get('button').should('have.class', 'active').and('not.be.disabled')
```

### Value

#### Chain assertions when yield changes

```
{/* App Code */}<ul>  <li>    <a href="users/123/edit">Edit User</a>  </li></ul>
```

```
cy.get('a')  .should('contain', 'Edit User') // yields <a>  .and('have.attr', 'href') // yields string value of href  .and('match', /users/) // yields string value of href  .and('not.include', '#') // yields string value of href
```

### Method and Value

#### Assert the href is equal to '/users'

```
cy.get('#header a')  .should('have.class', 'active')  .and('have.attr', 'href', '/users')
```

### Function

#### Verify length, content, and classes from multiple `<p>`

Passing a function to `.and()` enables you to assert on the yielded subject. This gives you the opportunity to _massage_ what you'd like to assert.

Be sure _not_ to include any code that has side effects in your callback function.

The callback function will be retried over and over again until no assertions within it throw.

```
<div>  <p class="text-primary">Hello World</p>  <p class="text-danger">You have an error</p>  <p class="text-default">Try again later</p></div>
```

```
cy.get('p')  .should('not.be.empty')  .and(($p) => {    // should have found 3 elements    expect($p).to.have.length(3)    // make sure the first contains some text content    expect($p.first()).to.contain('Hello World')    // use jquery's map to grab all of their classes    // jquery's map returns a new jquery object    const classes = $p.map((i, el) => {      return Cypress.$(el).attr('class')    })    // call classes.get() to make this a plain array    expect(classes.get()).to.deep.eq([      'text-primary',      'text-danger',      'text-default',    ])  })
```

Using a callback function [will not change the subject](#Subjects)

## Notes

### Chai

#### Similarities to Chai

If you've worked in [Chai](http://chaijs.com/) before, you will recognize that `.and()` matches the same fluent assertion syntax.

Take this _explicit_ assertion for example:

```
expect({ foo: 'bar' }).to.have.property('foo').and.eq('bar')
```

`.and()` reproduces this same assertion behavior.

### Subjects

#### How do I know which assertions change the subject and which keep it the same?

The chainers that come from [Chai](/llm/markdown/app/references/bundled-libraries.md#Chai) or [Chai-jQuery](/llm/markdown/app/references/bundled-libraries.md#Chai-jQuery) will always document what they return.

#### Using a callback function will not change what is yielded

Whenever you use a callback function, its return value is always ignored. Cypress always forces the command to yield the value from the previous cy command's yield (which in the example below is `<button>`)

```
cy.get('button')  .should('be.active')  .and(($button) => {    expect({ foo: 'bar' }).to.deep.eq({ foo: 'bar' })    return { foo: 'bar' } // return is ignored, .and() yields <button>  })  .then(($button) => {    // do anything we want with <button>  })
```

### Differences

### What's the difference between `.then()` and `.should()`/`.and()`?

Using `.then()` allows you to use the yielded subject in a callback function and should be used when you need to manipulate some values or do some actions.

When using a callback function with `.should()` or `.and()`, on the other hand, there is special logic to rerun the callback function until no assertions throw within it. You should be careful of side affects in a `.should()` or `.and()` callback function that you would not want performed multiple times.

## Rules

### Requirements [Learn about chaining commands](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Chains-of-Commands)

*   `.and()` requires being chained off a previous command.

### Timeouts [Learn about timeouts](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Timeouts)

*   `.and()` will continue to [retry](/llm/markdown/app/core-concepts/retry-ability.md) its specified assertions until it times out.

```
// timeout here will be passed down to the '.and()'// and it will retry for up to 10 secscy.get('input', { timeout: 10000 })  .should('have.value', '10')  .and('have.class', 'error')
```

```
// timeout here will be passed down to the '.and()'// unless an assertion throws earlier,// ALL of the assertions will retry for up to 10 secscy.get('input', { timeout: 10000 })  .should('have.value', 'US')  .and(($input) => {    expect($input).to.not.be('disabled')    expect($input).to.not.have.class('error')  })
```

## Command Log

**Chain assertions on the same subject**

```
cy.get('.list')  .find('input[type="checkbox"]')  .should('be.checked')  .and('not.be.disabled')
```

The commands above will display in the Command Log as:

When clicking on `assert` within the command log, the console outputs the following:

## See also

*   [`.should()`](/llm/markdown/api/commands/should.md)
*   [Guide: Introduction to Cypress](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Assertions)
*   [Reference: List of Assertions](/llm/markdown/app/references/assertions.md)
