Every test is made of two things: actions and checks. You have seen checks already. Now let's cover the actions, because these four will handle almost everything a real user does:
cy.get('[data-testid="email-input"]').type('demo@nimbus.app'); // type into a field
cy.get('[data-testid="login-button"]').click(); // click
cy.get('[data-testid="status-filter"]').select('Customer'); // choose from a <select>
cy.get('[data-testid="terms"]').check(); // tick a checkbox
Two things happen before any action runs, and both protect you:
Cypress waits for the element first. cy.get retries until the element exists (up to a timeout). You do not write "wait for the button, then click". The get-then-click chain is that.
Cypress checks the element can receive the action. It must be visible and not disabled. If your click lands on a button that is covered by a modal, Cypress fails and tells you, which is what a user would experience too. An action failing for this reason is usually a real finding, not a test problem.
A few details that will save you time:
.type()appends. If the field already has text, clear it first:cy.get(...).clear().type('new value')..type()accepts special keys:cy.get(...).type('{enter}')submits many forms..click()needs one element. If your selector matches many, narrow it first (.first(), or better: a more specific selector).- Actions are user intent. If you cannot do it with a mouse and keyboard, a plain action is the wrong tool. That is a sign to re-think the test.
Full reference for how Cypress decides an element is ready: Interacting with elements.
The problem below is pure actions-and-assertions: remove the last item from the cart and prove the empty state appears.