# Cypress Rules

Follow these rules unless requested otherwise:

## Documentation

You MUST read and follow [../documentation/documentation-rules.md](../documentation/documentation-rules.md) when citing or looking up Cypress API and concepts.

## Understand
- Look for a Cypress config file (`cypress.config.js`/`cypress.config.ts`).
- Review the Cypress support file if one exists for the targeted testing type.
- Review the project's `package.json` to understand available libraries and the version of Cypress being used.
  - If the Cypress version cannot be determined run `npx cypress --version` in the project root. As a fallback, assume the newest version of Cypress is being used.
- If there are existing Cypress tests in the project:
  - Look for an existing spec file for the targeted area or component. Prefer updating or extending an existing spec file over creating a new spec file unless the user specified otherwise.
  - If no existing test file is found, look for Cypress tests closely related to the task being accomplished. Attempt to identify one to three examples closely related to the feature, behavior, or component you are writing tests for.
- When reviewing existing project content, including files suggested by agent configuration, always prefer searching for specific content inside files (`grep`) rather than reading the entire file.

## Style
- Use clear, concise, and descriptive test titles in Cypress. 
  - When creating or updating a test, summarize the user behavior and expected outcome in plain language, avoiding implementation details.
  - Prefer the format: "[action] → [expected result]".
  - If updating an existing title, remove ambiguity and ensure it reflects the current test logic.
- Add explicit assertions.
- Keep tests deterministic and stable.
- Match the formatting, style, and conventions of any related Cypress tests that were identified.
- Match the project's language (TypeScript vs JavaScript) and existing type patterns (e.g. typed custom commands, Cypress types)
- Attempt to reuse existing helpers, including Cypress Custom Commands
- Look for existing Cypress fixture files - consider using or generating to match existing project conventions.
- Attempt to determine the version of Cypress being used. Suggest only logic and commands available in the version of Cypress being used in the project.
- Include code comments to aid a future maintainer.

## Test Structure
- Tests must be independent and runnable in isolation.
- Never depend on state from other tests.
- Extract repeated setup logic into before() or beforeEach() blocks.
- Prefer fewer tests with multiple assertions rather than many tiny tests.

## State Management
- Programmatically prepare application state whenever possible.
- Prefer cy.request(), cy.task(), or API setup instead of UI flows.
- Avoid UI logins unless the login UI itself is being tested.
- Reset state before tests rather than cleaning up after.
- Use aliases (.as()) or closures (.then()) to access results, never assign Cypress command results to variables

## Element Identification
- Review existing Cypress tests for `Cypress.ElementSelector` configuration. Always prioritize selectors by the order configured here.
- Otherwise, prefer stable selectors in this order:
  1. `data-cy`, `data-test`, `data-testid`, `data-test-id`, `data-qa` attributes
  2. `id`, `name` attributes
  3. Other attributes
  4. Element type and order
- Use `cy.contains()` when identifying visible text
- Avoid selectors based on CSS classes, DOM structure, or attributes that appear to be autogenerated or unstable.
- If the generated selector is low-quality or unstable suggest an update to the underlying code to add a meaningful `data-cy` attribute
- When testing UI that affects accessibility, prefer selectors that reflect accessible names or roles where it doesn't conflict with stability

## Waiting
- Never use arbitrary waits like `cy.wait(5000)`.
- Use:
  - implicit retries
  - `cy.intercept()` + `cy.wait('@alias')`
  - assertions that retry automatically
  - assertions that verify the next state of the application with an increased `timeout` configuration (e.g. `cy.get('[data-cy="title"]', { timeout: 10000 })`)

## Network
- Stub or intercept network requests when useful.
- Use `cy.intercept()` for controlling responses or waiting for calls.

## Configuration
- Prefer extracting configuration into the `cypress.config.js|ts` file
- Prefer configuring `baseUrl` and using `cy.visit('/path')` instead of full URLs.

## Security
- Use cy.env() for credentials, passwords, or secrets.

## Guidelines
- You must read and follow [./async.md](./async.md) if using Promises or `async`/`await`.
- You must read and follow [./reusability.md](./reusability.md).
- You must read and follow [./prompt.md](./prompt.md).
