Interacting With Elements: Type, Click, Check¶
What was run¶
A real Cypress spec against the local /elements.html page, exercising .type(), .check()/.uncheck(),
and .click() against real form elements — including a deliberate attempt to click a real disabled
button, to see exactly what Cypress actually does rather than assuming.
it("types into a real text input", () => {
cy.visit("/elements.html");
cy.get("#text-input").type("real cypress text");
cy.get("#text-input").should("have.value", "real cypress text");
});
it("checks and unchecks a real checkbox", () => {
cy.visit("/elements.html");
cy.get("#checkbox-1").should("not.be.checked");
cy.get("#checkbox-1").check();
cy.get("#checkbox-1").should("be.checked");
cy.get("#checkbox-1").uncheck();
cy.get("#checkbox-1").should("not.be.checked");
});
it("clicks a real enabled button and updates real state", () => {
cy.visit("/elements.html");
cy.get("#action-btn").click();
cy.get("#status-text").should("have.text", "action button clicked");
});
✓ types into a real text input (214ms)
✓ checks and unchecks a real checkbox (175ms)
✓ clicks a real enabled button and updates real state (94ms)
All three commands worked exactly as expected against real, interactable elements.
A real, deliberate click on a disabled button¶
CypressError: Timed out retrying after 4050ms: `cy.click()` failed because this element is `disabled`:
`<button id="disabled-btn" disabled="" ...>Disabled</button>`
Fix this problem, or use `{force: true}` to disable error checking.
This is a genuinely different real result from this network's own
Selenium Mastery Path,
which found that Selenium's .click() on an identical disabled button raises no exception at all and
simply does nothing silently. Cypress's real .click() actively checks an element's actionability
(visible, not disabled, not covered) before clicking, retried for a real 4050ms, and failed loudly with a
specific, actionable error — rather than succeeding at nothing and leaving you to notice the lack of effect
yourself.
How It Actually Works¶
Cypress's interaction commands (.type(), .click(), .check()) all perform a real actionability check
before acting: is the element visible, not disabled, not detached from the DOM, and not covered by another
element? Selenium's .click(), demonstrated as not performing this check in the sibling Selenium course,
sends the click command regardless and lets the browser's own native click handling decide what happens
(which, for a genuinely disabled button, is nothing). Cypress's own in-browser architecture
(Lesson 1) is exactly what makes this proactive check possible — Cypress's
test code is running right there in the browser and can inspect the real element's actual state before
deciding whether to proceed, rather than firing a command blind over a wire protocol.
.check() and .uncheck() are themselves thin wrappers that assert the element is a checkbox or radio
input, then click it if its checked state doesn't already match the real target state — which is why calling
.check() on an already-checked box is a safe no-op rather than a toggle.
Common mistakes¶
- Assuming
cy.click()'s silence on success means it behaves like Selenium's silence on a disabled-button no-op — the two are opposite outcomes that happen to both be "no visible error" in casual reading; always check what state actually changed, not just whether an exception was thrown. - Reaching for
{ force: true }immediately after a real actionability failure, without first checking whether the element is disabled on purpose (as this lesson's real button genuinely is) — forcing a click past a real, intentional disabled state usually indicates a test bug, not a Cypress limitation. - Calling
.check()expecting toggle behavior — it only ever moves toward checked; use.uncheck()explicitly for the other direction, as this lesson's test does.
Exercise¶
Change #disabled-btn in elements.html to remove the disabled attribute, restart the real Express
server, and re-run this lesson's click test with { force: false } still set. Confirm the real test now
passes and that #status-text genuinely updates — directly observing that Cypress's actionability check is
tied to the element's real, current state, not a cached assumption from an earlier page load.