Working with Elements
Clicking and mouse interactions
Section titled “Clicking and mouse interactions”await orbit.click("Login");await orbit.doubleClick("Open");await orbit.rightClick("File");await orbit.hover("Menu");All four accept visible text or any locator. Click actions render a brief red dot at the exact click coordinate, which makes step-debugging and trace screenshots much easier to follow. Disable it per action with await orbit.click("Login", { visualize: false }) if needed.
Checking existence and reading text
Section titled “Checking existence and reading text”Use exists() for yes/no checks. Note the { timeout: 0 } trick when you expect absence; otherwise the call waits for the element to appear before giving up:
expect(await orbit.exists(orbit.css(".success"))).toBe(true);expect(await orbit.exists(orbit.css(".error"), { timeout: 0 })).toBe(false);For reading text, OrbitTest gives you three readers because “the text of an element” means different things in different situations:
| Helper | Returns | Hidden content |
|---|---|---|
| orbit.text(locator) | User-facing text: DOM text, form values, ARIA label, title, alt | May include ARIA sources |
| orbit.visibleText(locator) | Only the text actually rendered on screen | Excluded |
| orbit.domText(locator) | All text in the element tree | Included |
const label = await orbit.visibleText(orbit.css("#save-button"));expect(label).toBe("Save");
const diagnostic = await orbit.domText(orbit.css("#server-message"));expect(diagnostic).toContain("Hidden diagnostic id");visibleText for what users see; domText for what the page contains.
All three trim and normalize whitespace, so you compare against clean strings.
Waiting: the most important habit
Section titled “Waiting: the most important habit”Almost every flaky end-to-end test in the world comes down to the same bug: the test ran faster than the page. The fix is to wait for state, never for time:
// Good: finishes the moment the page is readyawait orbit.waitForText("Dashboard");await orbit.waitFor(orbit.css(".toast"));await orbit.waitFor(orbit.getByRole("button", "Save"));
// With a custom budgetawait orbit.waitForText("Dashboard", { timeout: 10000, interval: 200 });
// Avoid: arbitrary sleep, slow on fast machines, flaky on slow onesawait orbit.wait(2000);orbit.wait(ms) exists for the rare cases where nothing observable changes (an animation you must let finish, a debounce with no signal). Reach for it last, and leave a comment saying why.
Working with all matching elements
Section titled “Working with all matching elements”When one locator matches many elements, orbit.all() (alias: orbit.elements()) returns an array of reusable locator snapshots:
const products = await orbit.all(orbit.css(".product-title"));
for (const product of products) { const name = await orbit.text(product); if (name.includes("iPhone")) { await orbit.click(product); break; }}Iterate, read, and act on a collection.
Each item carries snapshot details you can inspect directly: tag, text, visible, and attributes. The items support the usual actions: click, hover, doubleClick, rightClick, type, exists, waitFor, and the three text readers.
while (await orbit.exists(orbit.css(".delete"), { timeout: 0 })) { const deleteButtons = await orbit.all(orbit.css(".delete")); await orbit.click(deleteButtons[0]);}Safe pattern for lists that change as you click.
Page state and JavaScript evaluation
Section titled “Page state and JavaScript evaluation”const page = await orbit.pageState();expect(page.title).toContain("Dashboard");expect(page.url).toContain("/dashboard");
// Run code inside the page when you need toconst heading = await orbit.evaluate(() => document.title);await orbit.evaluate((text) => console.log(text), "hello");evaluate() is the escape hatch into the page’s own JavaScript. It is great for test setup (stopping an animation clock, reading app state) but resist using it to click or type, that bypasses the user-level behavior your test is supposed to prove.
Frequently asked questions
Section titled “Frequently asked questions”How do I assert that something disappeared?
Section titled “How do I assert that something disappeared?”Combine exists with a zero timeout: expect(await orbit.exists(".spinner", { timeout: 0 })).toBe(false), or wait for it to go with a waitFor on the state that replaces it.
Can I type into a field without clearing it first?
Section titled “Can I type into a field without clearing it first?”type() types into the resolved field. If the field may hold old text, click it and clear it explicitly as part of the flow your user would perform.
Why does my text assertion fail when I can see the text?
Section titled “Why does my text assertion fail when I can see the text?”Usually whitespace or hidden duplicates. Read the value back with visibleText() and log it; the readers normalize whitespace, so compare against the normalized form.
Related pages
Section titled “Related pages”- Locators — Target elements by visible text first, then by role, test ID, CSS, or XPath when needed, and which selectors to avoid.
- Frames & Shadow DOM — Scope tests into iframes and open or closed shadow roots with orbit.frame() and orbit.shadow(), including nested paths.
- Alerts & Windows — Handle alert, confirm, and prompt dialogs, notification permissions, and multi-window flows with waitForWindow.
- Test Basics — How to structure readable end-to-end tests: arrange-act-assert, the orbit object, per-test options, and strong assertions.