Cypress uses jQuery-style selectors combined with a chainable assertion API. Every command is automatically retried until it passes or times out — no manual waits needed.
Finding Elements
// CSS selectors
cy.get('#submit-btn')
cy.get('input[name="email"]')
cy.get('.nav-link').first()
cy.get('[data-cy="search-box"]') // preferred test attribute
// Text content
cy.contains('Sign In')
cy.contains('button', 'Submit') // tag + text
cy.contains('td', '42')
// Scoped to a parent
cy.get('form').find('input[type="password"]')
cy.get('table tbody tr').eq(2) // 3rd row (0-indexed)
Best practice: add data-cy attributes to your elements so tests don't break when styles change.
<button data-cy="login-btn">Login</button>Assertions with .should()
// Existence & visibility
cy.get('#modal').should('exist')
cy.get('#loader').should('not.exist')
cy.get('button').should('be.visible')
cy.get('[disabled]').should('be.disabled')
// Text
cy.get('h1').should('have.text', 'Dashboard')
cy.get('.error').should('contain', 'Invalid')
// Attributes
cy.get('a').should('have.attr', 'href', '/about')
cy.get('img').should('have.attr', 'src').and('include', 'logo')
// CSS class
cy.get('.alert').should('have.class', 'alert-danger')
// Input value
cy.get('input').should('have.value', 'user@test.com')
// Count
cy.get('li').should('have.length', 5)
cy.get('li').should('have.length.greaterThan', 0)Assertions Practice
Selector and assertion sandbox
Ctrl+Enter
HTML
CSS
JS
Preview
.then() for Custom Logic
cy.get('ul li').then(($items) => {
// $items is a jQuery-wrapped NodeList
const texts = [...$items].map(el => el.textContent)
expect(texts).to.include('Apple')
})Use .then() when you need to extract a value and run custom expectations that .should() can't express.
Aliases
cy.get('[data-cy="submit"]').as('submitBtn')
cy.get('@submitBtn').click()
cy.get('@submitBtn').should('be.disabled')Aliases (as()) let you name elements and reuse them without re-querying the DOM.