# Commands and Chaining — Playwright & Cypress

Source: https://www.skillbyai.com/en/e2e-testing/cy-commands

> cy.visit, cy.get, cy.contains.

## A queue, not promises

Cypress tests use Mocha-style `describe` and `it`. Calls such as `cy.visit('/')`, `cy.get('[data-cy=email]')`, `cy.contains('button', 'Save')`, `.type()` and `.click()` do not run immediately: they are **enqueued** and executed in order after the test function returns. Each command yields a **subject** to the next one in the chain. Because commands are not promises, you cannot `await` them or assign their result to a variable; use `.then()` to work with a yielded value, or **aliases** (`.as('name')`) to refer to it later. `cy.get` searches the whole document, while `.find()` and `.within()` scope to the current subject.

## Commands that queue, assertions that retry

Cypress tests chain commands that run in order inside the browser, retrying queries until assertions pass.

![Three ideas: commands and chaining, retry-ability and should, cy.intercept.](assets/figures/e2e-testing/section-4-map.svg) — Figure 4.1 — The Cypress command queue, retries and intercepted requests.

## A login flow

Chaining, scoping and reading a value with then.

```typescript
// cypress/e2e/login.cy.ts
describe('login', () => {
  it('signs in and greets the user', () => {
    cy.visit('/login');
    cy.get('[data-cy=email]').type('asha@example.com');
    cy.get('[data-cy=password]').type('correct horse', { log: false });
    cy.contains('button', 'Sign in').click();

    cy.location('pathname').should('eq', '/dashboard');
    cy.get('nav').within(() => {
      cy.contains('Asha').should('be.visible');
    });

    cy.get('[data-cy=plan]').invoke('text').then((plan) => {
      expect(plan.trim()).to.match(/Free|Pro/);
    });
  });
});
```

## Writing a to-do list for a helper

Your test function writes a list of instructions and hands it over; the helper then works through it step by step. Asking "what did step three return?" while you are still writing the list makes no sense.

**Quiz:** Why can you not write `const el = await cy.get('button')`?

- [x] Cypress commands are enqueued and are not promises
- [ ] cy.get only works in component tests
- [ ] TypeScript forbids await in tests
- [ ] cy.get returns a plain string

*Answer:* Cypress commands are enqueued and are not promises. Use .then() or aliases to work with yielded values.
