{
  "doc": {
    "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress",
    "title": "Migrate from Playwright to Cypress: complete migration guide",
    "description": "Step-by-step guide to migrate end-to-end and component tests from Playwright to Cypress. Compare syntax, learn retry-ability, network stubbing, auth patterns, CI parallelization, and Cloud features.",
    "section": "app",
    "source_path": "/llm/markdown/app/get-started/migrate-from-another-tool/playwright-to-cypress.md",
    "version": "066c46e056f0f322a0670d2d3aa4e6adaebfe717",
    "updated_at": "2026-09-10T13:30:12.426Z",
    "headings": [
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#migrating-from-playwright-to-cypress",
        "text": "Migrating from Playwright to Cypress",
        "level": 1
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#quick-conversion-example",
        "text": "Quick conversion example",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#installing-cypress",
        "text": "Installing Cypress",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#configuration-migration",
        "text": "Configuration migration",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#config-file-structure",
        "text": "Config file structure",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#common-translations",
        "text": "Common translations",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#cli-command-line-migration",
        "text": "CLI/Command line migration",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#base-commands",
        "text": "Base commands",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#common-flag-translations",
        "text": "Common flag translations",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#passing-environment-variables",
        "text": "Passing environment variables",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#browser-installation",
        "text": "Browser installation",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#how-each-framework-handles-browsers",
        "text": "How each framework handles browsers",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#browser-versions-and-ci",
        "text": "Browser versions and CI",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#docker-images",
        "text": "Docker images",
        "level": 4
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#circleci-orb",
        "text": "CircleCI orb",
        "level": 4
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#browser-launch-options",
        "text": "Browser launch options",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#launch-arguments-extensions-and-preferences",
        "text": "Launch arguments, extensions, and preferences",
        "level": 4
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#starting-your-application-under-test",
        "text": "Starting your application under test",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#test-structure-and-syntax-migration",
        "text": "Test structure and syntax migration",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#execution-model-and-retry-ability",
        "text": "Execution model and retry-ability",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#async-await-vs-command-chaining",
        "text": "Async/await vs command chaining",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#choosing-a-selector-strategy",
        "text": "Choosing a selector strategy",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#locators-and-selectors",
        "text": "Locators and selectors",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#prefer-stable-selectors",
        "text": "Prefer stable selectors",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#getbyrole-and-getbylabel",
        "text": "getByRole() and getByLabel()",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#interactions",
        "text": "Interactions",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#click-type-and-clear",
        "text": "Click, type, and clear",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#checkboxes-radios-and-selects",
        "text": "Checkboxes, radios, and selects",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#hover",
        "text": "Hover",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#mobile-viewport-testing",
        "text": "Mobile viewport testing",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#assertions",
        "text": "Assertions",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#visibility-and-existence",
        "text": "Visibility and existence",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#text-attributes-and-url",
        "text": "Text, attributes, and URL",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#waiting-retries-and-timeouts",
        "text": "Waiting, retries, and timeouts",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#network-spying-and-stubbing",
        "text": "Network spying and stubbing",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#spy",
        "text": "Spy",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#stub-a-response",
        "text": "Stub a response",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#modify-a-response",
        "text": "Modify a response",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#authentication-patterns",
        "text": "Authentication patterns",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#cross-origin",
        "text": "Cross-origin",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#screenshots",
        "text": "Screenshots",
        "level": 1
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#file-uploads-and-downloads",
        "text": "File uploads and downloads",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#upload",
        "text": "Upload",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#downloads",
        "text": "Downloads",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#clock-and-time-control",
        "text": "Clock and time control",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#advancing-time",
        "text": "Advancing time",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#pausing-at-a-specific-time",
        "text": "Pausing at a specific time",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#changing-the-system-time-mid-test",
        "text": "Changing the system time mid-test",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#overriding-only-specific-functions",
        "text": "Overriding only specific functions",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#multiple-tabs-and-windows",
        "text": "Multiple tabs and windows",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#iframes",
        "text": "Iframes",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#shadow-dom",
        "text": "Shadow DOM",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#dialogs",
        "text": "Dialogs",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#alert",
        "text": "alert()",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#confirm",
        "text": "confirm()",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#prompt",
        "text": "prompt()",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#beforeunload",
        "text": "beforeunload",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#print-dialogs",
        "text": "print dialogs",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#api-testing",
        "text": "API testing",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#test-generation",
        "text": "Test generation",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#component-testing",
        "text": "Component Testing",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#framework-and-bundler-support",
        "text": "Framework and bundler support",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#reusable-code-patterns",
        "text": "Reusable code patterns",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#page-object-model",
        "text": "Page object model",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#parameterized-tests",
        "text": "Parameterized tests",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#custom-commands",
        "text": "Custom commands",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#ci-parallelization",
        "text": "CI parallelization",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#key-architectural-difference",
        "text": "Key architectural difference",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#smart-orchestration-in-cypress-cloud",
        "text": "Smart Orchestration in Cypress Cloud",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#debugging-with-test-replay",
        "text": "Debugging with Test Replay",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#handling-flaky-tests",
        "text": "Handling flaky tests",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#flaky-test-management-in-cypress-cloud",
        "text": "Flaky test management in Cypress Cloud",
        "level": 3
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#accessibility-testing",
        "text": "Accessibility testing",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#features-without-a-direct-equivalent",
        "text": "Features without a direct equivalent",
        "level": 2
      },
      {
        "id": "app/get-started/migrate-from-another-tool/playwright-to-cypress#cheat-sheet",
        "text": "Cheat sheet",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Migrating from Playwright to Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide helps you translate Playwright tests to Cypress. It covers the core execution model differences, syntax mappings, and patterns for auth, networking, and CI."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Most migrations are incremental. You do not need to migrate all tests at once. Cypress and Playwright can coexist in the same repository during a transition."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Jump to the "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Cheat-sheet",
            "children": [
              {
                "type": "text",
                "value": "cheat sheet"
              }
            ]
          },
          {
            "type": "text",
            "value": " for a quick reference."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Quick conversion example"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Here's a side-by-side comparison showing how Playwright tests translate to Cypress:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { test, expect } from '@playwright/test'\n\ntest.describe('Authorization', () => {\n  test('signs up', async ({ page }) => {\n    // Navigate\n    await page.goto('/signup')\n\n    // Fill form\n    await page.getByLabel('Email').fill('user@email.com')\n    await page.getByLabel('Confirm Email').fill('user@email.com')\n    await page.getByLabel('Password').fill('testPassword1234')\n\n    // Submit\n    await page.getByRole('button', { name: 'Create new account' }).click()\n\n    // Assert navigation\n    await expect(page).toHaveURL(/\\/signup\\/success$/)\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "describe('Authorization', () => {\n  it('signs up', () => {\n    // Navigate\n    cy.visit('/signup')\n\n    // Fill form\n    cy.get('[data-testid=\"email\"]').type('user@email.com')\n    cy.get('[data-testid=\"confirm-email\"]').type('user@email.com')\n    cy.get('[data-testid=\"password\"]').type('testPassword1234')\n\n    // Submit\n    cy.contains('button', 'Create new account').click()\n\n    // Assert navigation\n    cy.url().should('include', 'signup/success')\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Installing Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before migrating your tests, add Cypress to your project as a dev dependency."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "npm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Yarn"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "pnpm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Bun"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npm install cypress --save-dev"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "yarn add cypress --dev"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "pnpm add --save-dev cypress"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "bun add --dev cypress"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Unlike Playwright, Cypress does not download its own browser binaries. It uses the browsers already installed on your machine, such as Chrome. Once installed, open the Cypress app to complete initial configuration:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "npm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Yarn"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "pnpm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Bun"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npx cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "yarn cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "pnpm cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "bunx cypress open"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The Cypress App will walk you through choosing a testing type (end-to-end or component) and generating a starter configuration file. After setup, Cypress creates a `cypress.config.js` (or `.ts`) file and a `cypress/` directory in your project root."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your Playwright tests are written in TypeScript, add a `tsconfig.json` inside the `cypress/` folder so Cypress globals (`cy`, `Cypress`) type-check:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress/tsconfig.json"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"compilerOptions\": {\n    \"types\": [\"cypress\", \"node\"]\n  },\n  \"include\": [\"**/*.ts\"]\n}"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Configuration migration"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Both Playwright and Cypress use a `defineConfig`-based configuration file at the root of your project. The key structural difference is that Cypress scopes most E2E-specific options under an `e2e` object, rather than a flat `use` block."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Config file structure"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The configuration file location is configurable using the `--config-file` command line flag or the `configFile` Module API option."
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Configuration"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default config file"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`playwright.config.ts`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cypress.config.ts`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Test files"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`testDir: './tests'`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e.specPattern` (glob)"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "E2E-specific options"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use: { ... }`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e: { ... }`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Node event hooks"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`globalSetup` / `globalTeardown`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e.setupNodeEvents`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "playwright.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from '@playwright/test'\n\nexport default defineConfig({\n  testDir: './tests',\n  outputDir: './test-results',\n  retries: process.env.CI ? 2 : 0,\n  timeout: 30000,\n  reporter: 'html',\n  use: {\n    baseURL: 'http://localhost:3000',\n    viewport: { width: 1280, height: 720 },\n    video: 'off',\n    screenshot: 'only-on-failure',\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  viewportWidth: 1280,\n  viewportHeight: 720,\n  video: false,\n  videosFolder: './test-results/videos',\n  reporter: 'html',\n  screenshotsFolder: './test-results/screenshots',\n  e2e: {\n    baseUrl: 'http://localhost:3000',\n    specPattern: 'tests/**/*.cy.ts',\n    retries: {\n      runMode: 2,\n      openMode: 0,\n    },\n    defaultCommandTimeout: 30000,\n    screenshotOnRunFailure: true,\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the full option reference."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Common translations"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Notes"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`forbidOnly`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "use `mocha/no-exclusive-tests` lint rule"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://www.npmjs.com/package/eslint-plugin-mocha",
                    "children": [
                      {
                        "type": "text",
                        "value": "eslint-plugin-mocha"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`headless`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--headless` or `--headed` CLI flag"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default headless in `cypress run`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`outputDir`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`screenshotsFolder` / `videosFolder`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Separate options per asset type"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`reporter`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`reporter`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "See "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/tooling/reporters.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Reporters"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`retries`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`retries.runMode` / `retries.openMode`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress separates CI and interactive mode retries"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`testDir`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`specPattern`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress uses a glob, not a path."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`testIgnore`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`excludeSpecPattern`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Glob string or array of globs."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`timeout`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`defaultCommandTimeout`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#Timeouts",
                    "children": [
                      {
                        "type": "text",
                        "value": "`defaultCommandTimeout`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " is per command, not test."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.baseURL`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e.baseUrl`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Must be under `e2e`, not top-level"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.channel`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--browser <name>:<channel>` on the CLI"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "See "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/launching-browsers.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Launching Browsers"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.proxy`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "OS environment variables"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "See "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/proxy-configuration.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Proxy Configuration"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.screenshot`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`screenshotOnRunFailure`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default is `true`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.video`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`video`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default is `false`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use.viewport`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`viewportWidth` / `viewportHeight`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Set at top level or scoped under testing type"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For Cypress-specific anti-patterns not covered by configuration options — such as hard-coded `cy.wait()` calls, assigning command return values, and unsafe chaining — the official "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/eslint-plugin-cypress",
            "children": [
              {
                "type": "text",
                "value": "`eslint-plugin-cypress`"
              }
            ]
          },
          {
            "type": "text",
            "value": " provides lint rules that catch these issues in-editor. See the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/eslint-plugin-cypress#rules",
            "children": [
              {
                "type": "text",
                "value": "full rules list"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "CLI/Command line migration"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright and Cypress use different commands and flag structures. This section covers the most common translations."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Base commands"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Task"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Run all tests (headless)"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`npx playwright test`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cypress run`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Open interactive mode"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`npx playwright test --ui`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cypress open`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Run in headed mode"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`npx playwright test --headed`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cypress run --headed`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Common flag translations"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--config=playwright.config.ts`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--config-file cypress.config.ts`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`npx playwright test todo.spec.ts`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cypress run --spec \"todo.cy.ts\"`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--fail-on-flaky-tests`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`detect-flake-but-always-fail` in config with "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/experiments.md#Experimental-Test-Retries",
                    "children": [
                      {
                        "type": "text",
                        "value": "Experimental Test Retries"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--forbid-only`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`mocha/no-exclusive-tests` "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://www.npmjs.com/package/eslint-plugin-mocha",
                    "children": [
                      {
                        "type": "text",
                        "value": "eslint-plugin-mocha"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " rule"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--grep \"pattern\"`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--expose grep=\"pattern\"` from "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress/tree/develop/npm/grep",
                    "children": [
                      {
                        "type": "text",
                        "value": "`@cypress/grep`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--grep-invert \"pattern\"`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--expose grep=\"-pattern\"` from "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress/tree/develop/npm/grep",
                    "children": [
                      {
                        "type": "text",
                        "value": "`@cypress/grep`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--last-failed`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/cloud/features/smart-orchestration/spec-prioritization.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Spec Prioritization"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--max-failures=5`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--auto-cancel-after-failures=5`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--project=chromium`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/command-line.md#cypress-open-project-lt-project-path-gt",
                    "children": [
                      {
                        "type": "text",
                        "value": "`--project='./front-end'`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--quiet`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--quiet`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--retries=2`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--config retries=2`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--reporter=html`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--reporter html`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--shard=1/4`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--record --parallel` (requires "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/cloud/get-started/introduction.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress Cloud"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ")"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--fully-parallel`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--record --parallel` (requires "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/cloud/get-started/introduction.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress Cloud"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ")"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--workers=4`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--record --parallel` (requires "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/cloud/get-started/introduction.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress Cloud"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ")"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--trace on`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`--record` automatically records "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/cloud/features/test-replay.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Test Replay"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Passing environment variables"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, use `cy.env()` for sensitive values (credentials, tokens, secrets) or `Cypress.expose()` for non-sensitive configuration (feature flags, public URLs, API versions). These are set via the top-level `env` and `expose` keys in your Cypress configuration file. Both APIs require Cypress 15.10.0 or newer."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "test('logs in', async ({ page }) => {\n  await page.getByLabel('User Name').fill(process.env.USER_NAME)\n  await page.getByLabel('Password').fill(process.env.PASSWORD)\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default defineConfig({\n  expose: {\n    API_VERSION: 'v2',\n  },\n  env: {\n    USER_NAME: process.env.USER_NAME,\n    PASSWORD: process.env.PASSWORD,\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "it('logs in', () => {\n  cy.env(['USER_NAME', 'PASSWORD']).then(({ USER_NAME, PASSWORD }) => {\n    const apiVersion = Cypress.expose('API_VERSION')\n    cy.visit(`/login/${apiVersion}`)\n    cy.get('[data-testid=\"username\"]').type(USER_NAME)\n    cy.get('[data-testid=\"password\"]').type(PASSWORD)\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/env.md",
            "children": [
              {
                "type": "text",
                "value": "cy.env()"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/expose.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress.expose()"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the full reference."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Browser installation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright and Cypress take different approaches to browser management. Understanding the difference will help you set up CI correctly."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "How each framework handles browsers"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright downloads and manages its own isolated browser binaries. Running `npx playwright install` fetches Playwright-specific builds of Chromium, Firefox, and WebKit that are separate from any browsers installed on your system."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress uses browsers already installed on the machine. There are no browser binaries to download. If Chrome is installed locally, Cypress will find and use it. This means browser setup is a CI concern rather than a per-project dependency."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npx playwright install chromium webkit"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To verify which browsers Cypress can find:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": " cypress info"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Browser versions and CI"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because Cypress uses system browsers, you have explicit control over which browser version your tests run against."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Docker images"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress publishes official Docker images with specific browser versions pre-installed. Image tags encode the exact versions of Node, Chrome, Firefox, and Edge, so your CI environment is reproducible and version changes are explicit."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Node + browsers, without Cypress"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cypress/browsers:node-22.19.0-chrome-139.0.7258.154-1-ff-142.0.1-edge-139.0.3405.125-1"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Node + browsers + Cypress pre-installed"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cypress/included:cypress-15.1.0-node-22.19.0-chrome-139.0.7258.154-1-ff-142.0.1-edge-139.0.3405.125-1"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Use `cypress/browsers` when you want to control the Cypress version through your `package.json`. Use `cypress/included` when you want a fully self-contained image. If you need a specific combination of versions not covered by the published images, use "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress-docker-images/tree/master/factory",
            "children": [
              {
                "type": "text",
                "value": "`cypress/factory`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to build a custom image."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress-docker-images",
            "children": [
              {
                "type": "text",
                "value": "cypress-docker-images"
              }
            ]
          },
          {
            "type": "text",
            "value": " for all available tags."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "CircleCI orb"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you use CircleCI, the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/circleci-orb",
            "children": [
              {
                "type": "text",
                "value": "Cypress CircleCI orb"
              }
            ]
          },
          {
            "type": "text",
            "value": " handles installation, caching, and test execution. Pass `install-browsers: true` to install Chrome, Firefox, and Edge into the CI environment."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": ".circleci/config.yml"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "version: 2.1\norbs:\n  cypress: cypress-io/cypress@6\nworkflows:\n  build:\n    jobs:\n      - cypress/run:\n          install-browsers: true\n          start-command: 'npm start'\n          cypress-command: 'npx cypress run --browser chrome'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/continuous-integration/circleci.md",
            "children": [
              {
                "type": "text",
                "value": "CircleCI"
              }
            ]
          },
          {
            "type": "text",
            "value": " for full setup documentation."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Browser launch options"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright's `launchOptions` in `playwright.config.ts` maps to the `before:browser:launch` event in Cypress, which you configure inside `setupNodeEvents` of your Cypress configuration file. Both let you modify how the browser starts. See the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/node-events/browser-launch-api.md",
            "children": [
              {
                "type": "text",
                "value": "Browser Launch Event"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the full reference."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Launch arguments, extensions, and preferences"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress exposes the `before:browser:launch` event."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "playwright.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default defineConfig({\n  use: {\n    launchOptions: {\n      args: ['--disable-gpu'],\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default defineConfig({\n  e2e: {\n    setupNodeEvents(on) {\n      on('before:browser:launch', (browser, launchOptions) => {\n        if (browser.family === 'chromium' && browser.name !== 'electron') {\n          launchOptions.args.push('--disable-gpu')\n        }\n        return launchOptions\n      })\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `launchOptions` object exposes three properties depending on the browser:"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Capability"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Browser launch arguments"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`launchOptions.args`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`launchOptions.args` via `before:browser:launch`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Firefox preferences"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`launchOptions.firefoxUserPrefs`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`launchOptions.preferences` via `before:browser:launch`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Chrome/Edge extensions"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`args` flags in `launchPersistentContext()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`launchOptions.extensions` via `before:browser:launch`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/node-events/browser-launch-api.md",
            "children": [
              {
                "type": "text",
                "value": "Browser Launch Event"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the full reference and per-browser examples."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Starting your application under test"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright's config can start your dev server automatically through the `webServer` option. Cypress does not start your application for you — it assumes the app is already running at the `baseUrl` you configured."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The standard solution is "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/bahmutov/start-server-and-test",
            "children": [
              {
                "type": "text",
                "value": "`start-server-and-test`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", which boots your server, waits for the URL to respond, runs Cypress, then shuts the server down."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "playwright.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default defineConfig({\n  webServer: {\n    command: 'npm run start',\n    url: 'http://localhost:3000',\n    reuseExistingServer: !process.env.CI,\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "package.json"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"scripts\": {\n    \"cy:run\": \"start-server-and-test start http://localhost:3000 'cypress run'\"\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Test structure and syntax migration"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright imports `test` from `@playwright/test`. Cypress uses Mocha's BDD interface, which provides `it()` and `describe()` globally. `test` is not available in Cypress and must be replaced."
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test('name', () => {})`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`it('name', () => {})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test.only('name', () => {})`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`it.only('name', () => {})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test.skip('name', () => {})`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`it.skip('name', () => {})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test.describe('group', () => {})`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`describe('group', () => {})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test.describe.only('group', () => {})`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`describe.only('group', () => {})`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { test, expect } from '@playwright/test'\n\ntest.describe('checkout', () => {\n  test('completes purchase', async ({ page }) => { ... })\n  test.only('applies discount', async ({ page }) => { ... })\n  test.skip('handles expired card', async ({ page }) => { ... })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "describe('checkout', () => {\n  it('completes purchase', () => { ... })\n  it.only('applies discount', () => { ... })\n  it.skip('handles expired card', () => { ... })\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Execution model and retry-ability"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright code typically awaits each action and may use explicit waits for specific conditions. Cypress commands are enqueued and automatically retry assertions until they pass or timeout."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "What this means for your tests:"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`await page.waitForSelector(...)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(...)` retries until it finds the element"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`await expect(locator)...`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(...).should(...)` retries automatically"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByTestId('submit').click()\nawait page.waitForSelector('[data-testid=\"toast\"]')\nawait expect(page.getByTestId('toast')).toHaveText('Saved!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"submit\"]').click()\ncy.get('[data-testid=\"toast\"]').should('have.text', 'Saved!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Learn more about Cypress "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "retry-ability"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Async/await vs command chaining"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright uses async/await patterns."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const button = await page.getByRole('button', { name: 'Submit' })\nawait button.click()\nconst toast = await page.getByTestId('toast')\nawait expect(toast).toHaveText('Success')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress uses command chaining without async/await."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('button').contains('Submit').click()\ncy.get('[data-testid=\"toast\"]').should('have.text', 'Success')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See Cypress's command model in the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/introduction-to-cypress.md#The-Cypress-Command-Queue",
            "children": [
              {
                "type": "text",
                "value": "Introduction to Cypress"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Choosing a selector strategy"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright suites lean on semantic locators — `getByRole()`, `getByLabel()`, and `getByText()`. Before translating tests, decide how these map to Cypress, because the choice affects nearly every test."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Option A — Cypress Testing Library (lowest friction, no app changes). Install "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/testing-library/cypress-testing-library",
            "children": [
              {
                "type": "text",
                "value": "`@testing-library/cypress`"
              }
            ]
          },
          {
            "type": "text",
            "value": " for a near 1:1 replacement of Playwright's semantic locators:"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress (Testing Library)"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`getByRole('button', { name })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`findByRole('button', { name })`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`getByLabel('Email')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`findByLabelText('Email')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`getByText('Welcome')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`findByText('Welcome')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`getByPlaceholder('Search')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`findByPlaceholderText('Search')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`getByTestId('submit')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`findByTestId('submit')`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Option B — `data-*` attributes (Cypress best practice for new code). Add `data-testid` (or `data-cy`) attributes to your application and select with `cy.get('[data-testid=\"...\"]')`, as described in "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Selecting-Elements",
            "children": [
              {
                "type": "text",
                "value": "Best Practices"
              }
            ]
          },
          {
            "type": "text",
            "value": ". This is the most resilient long-term strategy, but it requires editing your application source."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The examples in this guide use `data-testid` for brevity. If your Playwright suite relies on semantic locators and you don't already have test attributes, Option A is the fastest path to parity without touching application code."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Locators and selectors"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Prefer stable selectors"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Use a stable selector strategy (often `data-*`) as described in Cypress "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Selecting-Elements",
            "children": [
              {
                "type": "text",
                "value": "Best Practices"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByTestId('email').fill('user@email.com')\nawait page.getByRole('button', { name: 'Sign in' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"email\"]').type('user@email.com')\ncy.contains('button', 'Sign in').click()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "getByRole() and getByLabel()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you want `getByRole()`/`getByLabel()` ergonomics in Cypress, install "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/testing-library/cypress-testing-library",
            "children": [
              {
                "type": "text",
                "value": "Cypress Testing Library"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByRole('button', { name: 'Save' }).click()\nawait page.getByLabel('First name').fill('Jane')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.findByRole('button', { name: 'Save' }).click()\ncy.findByLabelText('First name').type('Jane')"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Interactions"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Click, type, and clear"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.locator('#username').fill('jane')\nawait page.locator('#password').fill('secret')\nawait page.getByRole('button', { name: 'Log in' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('#username').clear()\ncy.get('#username').type('jane')\ncy.get('#password').clear()\ncy.get('#password').type('secret')\ncy.contains('button', 'Log in').click()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Checkboxes, radios, and selects"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByLabel('Subscribe').check()\nawait page.getByLabel('Daily').check()\nawait page.getByLabel('Country').selectOption('US')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"subscribe\"]').check()\ncy.get('[data-testid=\"daily\"]').check()\ncy.get('[data-testid=\"country\"]').select('US')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Hover"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByTestId('menu').hover()\nawait page.getByRole('menuitem', { name: 'Settings' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"menu\"]').trigger('mouseover')\ncy.contains('[role=\"menuitem\"]', 'Settings').click()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Mobile viewport testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.setViewportSize({ width: 375, height: 812 })\nawait page.goto('/')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.viewport(375, 812)\ncy.visit('/')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/viewport.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.viewport()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Assertions"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Visibility and existence"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await expect(page.getByText('Welcome')).toBeVisible()\nawait expect(page.getByTestId('spinner')).toBeHidden()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.contains('Welcome').should('be.visible')\ncy.get('[data-testid=\"spinner\"]').should('not.be.visible')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Text, attributes, and URL"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await expect(page.getByTestId('toast')).toHaveText('Saved!')\nawait expect(page.getByRole('button', { name: 'Save' })).toBeDisabled()\nawait expect(page).toHaveURL(/\\/dashboard$/)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"toast\"]').should('have.text', 'Saved!')\ncy.contains('button', 'Save').should('be.disabled')\ncy.url().should('match', /\\/dashboard$/)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See Cypress assertions at "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/assertions.md",
            "children": [
              {
                "type": "text",
                "value": "Assertions"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Waiting, retries, and timeouts"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright often uses explicit waits. Cypress will retry most DOM queries and assertions until they pass or time out."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.getByRole('button', { name: 'Save' }).click()\nawait page.waitForResponse('**/api/profile')\nawait expect(page.getByTestId('toast')).toHaveText('Saved!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.intercept('POST', '/api/profile').as('saveProfile')\ncy.contains('button', 'Save').click()\ncy.wait('@saveProfile')\ncy.get('[data-testid=\"toast\"]').should('have.text', 'Saved!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Learn more about Cypress retry-ability at "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "Retry-ability"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Network spying and stubbing"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Spy"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const [response] = await Promise.all([\n  page.waitForResponse('**/api/users'),\n  page.getByRole('button', { name: 'Load users' }).click(),\n])\nexpect(response.ok()).toBeTruthy()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.intercept('GET', '/api/users').as('users')\ncy.contains('button', 'Load users').click()\ncy.wait('@users').its('response.statusCode').should('eq', 200)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Stub a response"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.route('**/api/projects', async (route) => {\n  await route.fulfill({\n    status: 200,\n    contentType: 'application/json',\n    body: JSON.stringify([{ id: '1' }, { id: '2' }]),\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.intercept('GET', '/api/projects', {\n  statusCode: 200,\n  body: [{ id: '1' }, { id: '2' }],\n}).as('projects')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Modify a response"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.route('**/api/profile', async (route) => {\n  const response = await route.fetch()\n  const json = await response.json()\n  json.plan = 'enterprise'\n  await route.fulfill({ response, json })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.intercept('GET', '/api/profile', (req) => {\n  req.continue((res) => {\n    res.body.plan = 'enterprise'\n  })\n}).as('profile')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/network-requests.md",
            "children": [
              {
                "type": "text",
                "value": "Network Requests"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/intercept.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.intercept()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Authentication patterns"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright commonly reuses auth via `storageState`. In Cypress, use "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/session.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.session()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to cache cookies and storage between tests."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "playwright.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from '@playwright/test'\n\nexport default defineConfig({\n  use: {\n    storageState: 'storageState.json',\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "auth.setup.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { test as setup } from '@playwright/test'\n\nsetup('authenticate', async ({ page }) => {\n  await page.goto('/login')\n  await page.getByLabel('Username').fill('jane')\n  await page.getByLabel('Password').fill('secret')\n  await page.getByRole('button', { name: 'Log in' }).click()\n\n  await page.context().storageState({ path: 'storageState.json' })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress/support/e2e.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const login = () => {\n  cy.visit('/login')\n  cy.get('#username').type('jane')\n  cy.get('#password').type('secret')\n  cy.contains('button', 'Log in').click()\n}\n\nbeforeEach(() => {\n  cy.session('jane', login)\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Cross-origin"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress enforces a same-origin policy by default. Use `cy.origin()` to run commands against a different origin within the same test. Any commands targeting a secondary origin must be scoped inside the `cy.origin()` callback."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.goto('https://site-a.example')\nawait page.goto('https://site-b.example')\nawait expect(page.getByRole('banner')).toBeVisible()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('https://site-a.example')\ncy.origin('https://site-b.example', () => {\n  cy.visit('https://site-b.example')\n  cy.get('[role=\"banner\"]').should('be.visible')\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " for complete documentation."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Screenshots"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.screenshot({ path: 'after-signup.png' })\nawait page.locator('[data-testid=\"toast\"]').screenshot({ path: 'toast.png' })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.screenshot('after-signup')\ncy.get('[data-testid=\"toast\"]').screenshot('toast')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/screenshots-and-videos.md",
            "children": [
              {
                "type": "text",
                "value": "Screenshots and Videos"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "File uploads and downloads"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Upload"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.setInputFiles('input[type=\"file\"]', 'fixtures/avatar.png')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('input[type=\"file\"]').selectFile('cypress/fixtures/avatar.png')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/selectfile.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.selectFile()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Downloads"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, a common approach is to trigger the download, then assert the file exists in the configured downloads folder."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const download = await page.waitForEvent('download')\nawait page.getByRole('button', { name: 'Export CSV' }).click()\nconst path = await download.path()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.contains('button', 'Export CSV').click()\ncy.readFile('cypress/downloads/export.csv')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/readfile.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.readFile()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Clock and time control"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Both Playwright and Cypress let you replace native browser time functions with a fake clock that you control. This allows tests to set a specific date, skip waiting for timers, and test time-sensitive UI behavior without real delays. The two tools take different approaches to time control."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.clock.setFixedTime(new Date('2024-02-02T10:00:00'))\nawait page.goto('/')\nawait expect(page.getByTestId('current-time')).toHaveText(\n  '2/2/2024, 10:00:00 AM'\n)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.clock(new Date('2024-02-02T10:00:00'))\ncy.visit('/')\ncy.get('[data-testid=\"current-time\"]').should(\n  'have.text',\n  '2/2/2024, 10:00:00 AM'\n)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Advancing time"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To simulate the passage of time and trigger scheduled timers, Playwright uses `fastForward` or `runFor`. Cypress uses `cy.tick()`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.clock.install()\nawait page.goto('/')\nawait page.getByRole('button').click()\n\n// Skip forward 5 minutes, firing all timers that fall within the window\nawait page.clock.fastForward('05:00')\n\nawait expect(page.getByText('Session expired')).toBeVisible()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.clock()\ncy.visit('/')\ncy.get('button').click()\n\n// cy.tick() takes milliseconds; 5 minutes = 300,000 ms\ncy.tick(5 * 60 * 1000)\n\ncy.contains('Session expired').should('be.visible')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Pausing at a specific time"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright supports `pauseAt`, which lets the clock run naturally from its installed time and then pause automatically when it reaches a target timestamp. For Cypress to reach a specific point in time, calculate the delta between the installed time and the target time and pass that to `cy.tick()`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.clock.install({ time: new Date('2024-02-02T08:00:00') })\nawait page.goto('/')\n\n// Clock runs naturally until it reaches 10:00 AM, then pauses\nawait page.clock.pauseAt(new Date('2024-02-02T10:00:00'))\nawait expect(page.getByTestId('current-time')).toHaveText(\n  '2/2/2024, 10:00:00 AM'\n)\n\n// Advance another 30 minutes manually\nawait page.clock.fastForward('30:00')\nawait expect(page.getByTestId('current-time')).toHaveText(\n  '2/2/2024, 10:30:00 AM'\n)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.clock(new Date('2024-02-02T08:00:00'))\ncy.visit('/')\n\n// Advance 2 hours (from 08:00 to 10:00) manually\ncy.tick(2 * 60 * 60 * 1000)\ncy.get('[data-testid=\"current-time\"]').should(\n  'have.text',\n  '2/2/2024, 10:00:00 AM'\n)\n\n// Advance another 30 minutes\ncy.tick(30 * 60 * 1000)\ncy.get('[data-testid=\"current-time\"]').should(\n  'have.text',\n  '2/2/2024, 10:30:00 AM'\n)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Changing the system time mid-test"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Both tools allow you to change the current time without triggering timers. In Playwright this is `page.clock.setSystemTime()`. In Cypress it is `clock.setSystemTime()` on the yielded clock object."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.clock.install({ time: new Date('2024-02-02T10:00:00') })\nawait page.goto('/')\n\n// Jump to a new time without firing any scheduled timers\nawait page.clock.setSystemTime(new Date('2024-02-02T10:30:00'))"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.clock(new Date('2024-02-02T10:00:00'))\ncy.visit('/')\n\ncy.clock().then((clock) => {\n  // Jump to a new time without firing any scheduled timers\n  clock.setSystemTime(new Date('2024-02-02T10:30:00'))\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Overriding only specific functions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress allows you to limit which native functions the clock replaces. This is useful when you only need to control `Date` without affecting timer behavior, or vice versa."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Override only Date, leave setTimeout and setInterval running normally\ncy.clock(Date.UTC(2024, 1, 2), ['Date'])\n\n// Override only timers, leave Date as the system clock\ncy.clock(null, ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'])"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Multiple tabs and windows"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can handle multi-tab workflows using the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/puppeteer",
            "children": [
              {
                "type": "text",
                "value": "`@cypress/puppeteer`"
              }
            ]
          },
          {
            "type": "text",
            "value": " plugin, which gives Cypress access to the underlying browser via Puppeteer. This approach requires Puppeteer as a dependency."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Start waiting for the new tab before clicking.\nconst newPagePromise = page.context().waitForEvent('page')\nawait page.getByText('open new tab').click()\nconst newPage = await newPagePromise\n\nawait newPage.waitForLoadState()\nawait newPage.getByRole('button', { name: 'Confirm' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\nimport { setup, retry } from '@cypress/puppeteer'\n\nexport default defineConfig({\n  e2e: {\n    setupNodeEvents(on) {\n      setup({\n        on,\n        onMessage: {\n          async switchToTabAndGetContent(browser) {\n            const page = await retry(async () => {\n              const pages = await browser.pages()\n              const page = pages.find((p) => p.url().includes('page-2.html'))\n              if (!page) throw new Error('Could not find page')\n              return page\n            })\n\n            await page.bringToFront()\n            const paragraph = await page.waitForSelector('p')\n            return await page.evaluate((el) => el.textContent, paragraph)\n          },\n        },\n      })\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In your support file, import the command once:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// cypress/support/e2e.ts\nimport '@cypress/puppeteer/support'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('/')\ncy.contains('button', 'Open new tab').click()\n\ncy.puppeteer('switchToTabAndGetContent').should(\n  'equal',\n  'You said: Hello from Page 1'\n)"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Iframes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress has no equivalent single command. The standard approach is to get the iframe element, access its `contentDocument.body`, and then wrap that body element with `cy.wrap()` so you can use Cypress commands on its contents. The `.should('not.be.empty')` assertion ensures Cypress waits for the frame's document to load before proceeding."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Locate and fill a field inside an iframe\nconst frame = page.frameLocator('#payment-frame')\nawait frame.getByLabel('Card number').fill('4242424242424242')\nawait frame.getByLabel('Expiry').fill('12/26')\nawait frame.getByRole('button', { name: 'Pay now' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('#payment-frame')\n  .its('0.contentDocument.body')\n  .should('not.be.empty')\n  .then(cy.wrap)\n  .within(() => {\n    cy.get('input[aria-label=\"Card number\"]').type('4242424242424242')\n    cy.get('input[aria-label=\"Expiry\"]').type('12/26')\n    cy.contains('button', 'Pay now').click()\n  })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you interact with the same iframe across multiple tests, extract the frame access into a custom command to avoid repeating the boilerplate:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress/support/commands.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "declare global {\n  namespace Cypress {\n    interface Chainable {\n      getIframeBody(selector: string): Chainable<JQuery<HTMLElement>>\n    }\n  }\n}\n\nCypress.Commands.add('getIframeBody', (selector: string) => {\n  return cy\n    .get(selector)\n    .its('0.contentDocument.body')\n    .should('not.be.empty')\n    .then(cy.wrap)\n})\n\n// In your test\ncy.getIframeBody('#payment-frame').within(() => {\n  cy.contains('button', 'Pay now').click()\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This works for same-origin iframes. Unlike Playwright's `frameLocator`, Cypress cannot reach into a cross-origin iframe unless you set "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Browser",
            "children": [
              {
                "type": "text",
                "value": "`chromeWebSecurity`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to `false` in Chromium-family browsers. See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/faq.md#How-do-I-test-elements-inside-an-iframe",
            "children": [
              {
                "type": "text",
                "value": "How do I test elements inside an iframe?"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the full details and restrictions."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Shadow DOM"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For Shadow DOM in Cypress, you can traverse explicitly:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('[data-testid=\"shadow-host\"]').shadow().find('button').click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/shadow.md",
            "children": [
              {
                "type": "text",
                "value": "`.shadow()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Dialogs"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "alert()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress always accepts `alert()` dialogs."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Register a handler to inspect the alert text before accepting\npage.on('dialog', async (dialog) => {\n  expect(dialog.type()).toBe('alert')\n  expect(dialog.message()).toBe('Unsaved changes will be lost.')\n  await dialog.accept()\n})\n\nawait page.getByRole('button', { name: 'Leave page' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Cypress auto-accepts alerts. Listen to assert on the message.\ncy.on('window:alert', (message) => {\n  expect(message).to.eq('Unsaved changes will be lost.')\n})\n\ncy.get('button').contains('Leave page').click()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "confirm()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Accept the confirmation\npage.on('dialog', (dialog) => dialog.accept())\nawait page.getByRole('button', { name: 'Delete account' }).click()\nawait expect(page.getByText('Account deleted')).toBeVisible()\n\n// Dismiss the confirmation\npage.on('dialog', (dialog) => dialog.dismiss())\nawait page.getByRole('button', { name: 'Delete account' }).click()\nawait expect(page.getByText('Account deleted')).not.toBeVisible()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Cypress auto-accepts confirm(). No handler needed to test the accepted path.\ncy.get('button').contains('Delete account').click()\ncy.contains('Account deleted').should('be.visible')\n\n// Return false to dismiss the confirmation\ncy.on('window:confirm', () => false)\ncy.get('button').contains('Delete account').click()\ncy.contains('Account deleted').should('not.exist')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you need to assert on the confirmation message text and control acceptance in the same test, combine both:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.on('window:confirm', (message) => {\n  expect(message).to.eq('Are you sure you want to delete your account?')\n  return false // return true or omit the return to accept\n})\n\ncy.get('button').contains('Delete account').click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For tests that need to verify the stub was called, use `cy.stub()` instead of `cy.on()`. This lets you use Sinon assertions to confirm the dialog was triggered the expected number of times."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const confirmStub = cy.stub().as('confirmDialog').returns(false)\ncy.on('window:confirm', confirmStub)\n\ncy.get('button').contains('Delete account').click()\ncy.get('@confirmDialog').should('have.been.calledOnce')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "prompt()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, you must stub `window.prompt` before the page loads using the `onBeforeLoad` callback in `cy.visit()`. This gives you full control over the return value and lets you assert that the prompt was called."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "page.on('dialog', async (dialog) => {\n  expect(dialog.type()).toBe('prompt')\n  expect(dialog.message()).toBe('Enter your name:')\n  await dialog.accept('Ada Lovelace')\n})\n\nawait page.getByRole('button', { name: 'Set name' }).click()\nawait expect(page.getByTestId('greeting')).toHaveText('Hello, Ada Lovelace!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('/', {\n  onBeforeLoad(win) {\n    cy.stub(win, 'prompt').as('promptDialog').returns('Ada Lovelace')\n  },\n})\n\ncy.get('button').contains('Set name').click()\ncy.get('[data-testid=\"greeting\"]').should('have.text', 'Hello, Ada Lovelace!')\ncy.get('@promptDialog').should('have.been.calledWith', 'Enter your name:')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To simulate the user cancelling the prompt (equivalent to `dialog.dismiss()` in Playwright), return `null` from the stub:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('/', {\n  onBeforeLoad(win) {\n    cy.stub(win, 'prompt').returns(null)\n  },\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "beforeunload"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your tests need to verify that a `beforeunload` handler is registered and sets a `returnValue`, use the `window:before:unload` event to assert on the event object directly:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "page.on('dialog', async (dialog) => {\n  expect(dialog.type()).toBe('beforeunload')\n  await dialog.dismiss()\n})\n\nawait page.close({ runBeforeUnload: true })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Assert that the beforeunload handler fired and set a returnValue\ncy.on('window:before:unload', (event) => {\n  expect(event.returnValue).to.eq('')\n})\n\n// Trigger navigation to fire beforeunload\ncy.get('a').contains('Leave').click()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "print dialogs"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, stub `window.print` using `onBeforeLoad` in `cy.visit()` and assert that the stub was called."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "await page.goto('/')\nawait page.evaluate(\n  '(() => { window.waitForPrint = new Promise(f => window.print = f) })()'\n)\n\nawait page.getByRole('button', { name: 'Print invoice' }).click()\nawait page.waitForFunction('window.waitForPrint')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('/', {\n  onBeforeLoad(win) {\n    cy.stub(win, 'print').as('printDialog')\n  },\n})\n\ncy.get('button').contains('Print invoice').click()\ncy.get('@printDialog').should('have.been.calledOnce')"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "API testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// APIRequestContext (Playwright)\nconst res = await request.get('/api/health')\nexpect(res.ok()).toBeTruthy()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.request('/api/health').its('status').should('eq', 200)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Test generation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cypress-studio.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Studio"
              }
            ]
          },
          {
            "type": "text",
            "value": " lets you generate test code by interacting with your application in the Cypress app. It records actions like clicks and form inputs and writes the corresponding Cypress commands. Cypress Studio is a replacement for Playwright's `playwright codegen`. With a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/get-started/introduction.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Cloud"
              }
            ]
          },
          {
            "type": "text",
            "value": " account, you also get Studio AI, AI-powered assertion recommendations as you record."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Component Testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright Component Testing is experimental and uses a `mount` fixture (for example via `@playwright/experimental-ct-react`). Cypress Component Testing uses `cy.mount()`, typically scaffolded in your Cypress support file."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Framework and bundler support"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Capability"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright Component Testing"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress Component Testing"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Frameworks"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Experimental packages for React, Vue, and Svelte"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Official mounting libraries for "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/component-testing/react/overview.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "React"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/component-testing/vue/overview.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Vue"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/component-testing/angular/overview.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Angular"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", and "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/component-testing/svelte/overview.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Svelte"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Bundlers"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Vite"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Vite & Webpack"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/get-started.md",
            "children": [
              {
                "type": "text",
                "value": "Component Testing"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "button.test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { test, expect } from '@playwright/experimental-ct-react'\nimport { Button } from './Button'\n\ntest('renders', async ({ mount }) => {\n  const component = await mount(<Button>Save</Button>)\n  await expect(component).toContainText('Save')\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "button.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { Button } from './Button'\n\ndescribe('Button', () => {\n  it('renders', () => {\n    cy.mount(<Button>Save</Button>)\n    cy.contains('button', 'Save').should('be.visible')\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/get-started.md",
            "children": [
              {
                "type": "text",
                "value": "Component Testing"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/mount.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.mount()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Reusable code patterns"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Page object model"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're using Page Object Model (POM) in Playwright, the same pattern works in Cypress:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "loginPage.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export class LoginPage {\n  constructor(private page: Page) {}\n\n  async login(username: string, password: string) {\n    await this.page.getByLabel('Username').fill(username)\n    await this.page.getByLabel('Password').fill(password)\n    await this.page.getByRole('button', { name: 'Login' }).click()\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "loginPage.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export class LoginPage {\n  login(username: string, password: string) {\n    cy.get('[data-testid=\"username\"]').type(username)\n    cy.get('[data-testid=\"password\"]').type(password)\n    cy.contains('button', 'Login').click()\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Parameterized tests"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Both Playwright and Cypress support generating tests from a data array using standard JavaScript. The pattern is the same in both tools: call `.forEach()` on your dataset outside of or inside a `describe` block, and generate one test per entry."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": ";[\n  { name: 'Maya', expected: 'Hello, Maya!' },\n  { name: 'Theo', expected: 'Hello, Theo!' },\n  { name: 'Nora', expected: 'Hello, Nora!' },\n].forEach(({ name, expected }) => {\n  test(`testing with ${name}`, async ({ page }) => {\n    await page.goto(`https://example.com/greet?name=${name}`)\n    await expect(page.getByRole('heading')).toHaveText(expected)\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": ";[\n  { name: 'Maya', expected: 'Hello, Maya!' },\n  { name: 'Theo', expected: 'Hello, Theo!' },\n  { name: 'Nora', expected: 'Hello, Nora!' },\n].forEach(({ name, expected }) => {\n  it(`testing with ${name}`, () => {\n    cy.visit(`/greet?name=${name}`)\n    cy.get('h1').should('have.text', expected)\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Custom commands"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "fixtures/auth.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export const test = base.extend({\n  authenticatedPage: async ({ page }, use) => {\n    await page.goto('/login')\n    await page.getByLabel('Username').fill('user')\n    await page.getByLabel('Password').fill('pass')\n    await page.getByRole('button', { name: 'Login' }).click()\n    await use(page)\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress/support/commands.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "declare global {\n  namespace Cypress {\n    interface Chainable {\n      login(username: string, password: string): Chainable<void>\n    }\n  }\n}\n\nCypress.Commands.add('login', (username: string, password: string) => {\n  cy.session([username, password], () => {\n    cy.visit('/login')\n    cy.get('[data-testid=\"username\"]').type(username)\n    cy.get('[data-testid=\"password\"]').type(password)\n    cy.contains('button', 'Login').click()\n    cy.url().should('include', '/dashboard')\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-commands.md",
            "children": [
              {
                "type": "text",
                "value": "Custom Commands"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "CI parallelization"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Key architectural difference"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Playwright parallelizes tests locally using workers and across machines using manual sharding. You define the split strategy in config or at the command line."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Worker count controlled via config (`workers: 4`) or CLI (`--workers=4`)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Sharding splits tests across machines (`--shard=1/4`)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You define the split strategy upfront"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "playwright test --shard=2/4 # Machine 2\nplaywright test --shard=3/4 # Machine 3\nplaywright test --shard=4/4 # Machine 4"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress parallelizes tests across machines through "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/get-started/introduction.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Cloud"
              }
            ]
          },
          {
            "type": "text",
            "value": ", which distributes specs dynamically based on historical run durations. This requires a Cypress Cloud account."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Parallelization happens in CI through Cypress Cloud."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Specs are distributed dynamically based on historical run data."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "No manual sharding required."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress Cloud"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cypress run --record --parallel"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Smart Orchestration in Cypress Cloud"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When you use Cypress Cloud, you gain Smart Orchestration features that go beyond simple parallelization:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/smart-orchestration/load-balancing.md",
            "children": [
              {
                "type": "text",
                "value": "Load Balancing"
              }
            ]
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Distributes specs across machines based on previous run durations"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Minimizes overall run time automatically"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "No need to manually configure shards or splits"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/smart-orchestration/spec-prioritization.md",
            "children": [
              {
                "type": "text",
                "value": "Spec Prioritization"
              }
            ]
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Runs specs that failed in the previous run first"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Provides faster feedback on fixes"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Reduces time to detect persistent failures"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/smart-orchestration/run-cancellation.md",
            "children": [
              {
                "type": "text",
                "value": "Auto Cancellation"
              }
            ]
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Cancels remaining specs after a threshold of failures"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Avoids wasting CI time on runs that can't pass"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Configurable failure thresholds"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/smart-orchestration/parallelization.md",
            "children": [
              {
                "type": "text",
                "value": "Parallelization"
              }
            ]
          },
          {
            "type": "text",
            "value": " for setup details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Debugging with Test Replay"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Test Replay is available on all Cypress Cloud plans at no additional cost. It records a full, interactive replay of every test run, including network requests, console output, and DOM snapshots. Replays are shareable via link and do not require a local trace file."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "playwright test --trace on"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npx playwright show-trace test-results/**/trace.zip"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cypress run --record --key <record_key>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/test-replay.md",
            "children": [
              {
                "type": "text",
                "value": "Test Replay"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Handling flaky tests"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Flaky tests are a common challenge in testing. Both frameworks offer retry mechanisms, but Cypress Cloud adds intelligent flake detection and management."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Playwright"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "playwright.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default {\n  retries: process.env.CI ? 2 : 0,\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: Cypress"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress.config.ts"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "export default {\n  retries: {\n    runMode: 2,\n    openMode: 0,\n  },\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Flaky test management in Cypress Cloud"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Beyond basic retries, Cypress Cloud provides:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/flaky-test-management.md",
            "children": [
              {
                "type": "text",
                "value": "Flaky test management"
              }
            ]
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Automatically identifies tests that pass after retry"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Tracks flake rate over time"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Provides analytics on which specs are most flaky"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Helps prioritize stability improvements"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Accessibility testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you record test runs to Cypress Cloud, "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/accessibility/get-started/introduction.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Accessibility"
              }
            ]
          },
          {
            "type": "text",
            "value": " provides automated accessibility scanning across your entire test suite with no changes to your test code."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Rather than requiring `checkA11y()` calls in each test, Cypress Accessibility captures DOM snapshots during test execution server-side, using the same protocol as Test Replay. Every distinct state your tests interact with is scanned automatically. This means pages and components that your tests visit but do not explicitly instrument are still checked."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Learn more about "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/accessibility/get-started/introduction.md",
            "children": [
              {
                "type": "text",
                "value": "Accessibility testing"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Features without a direct equivalent"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A few Playwright features have no built-in Cypress counterpart. Identify these up front so you can plan alternatives rather than discovering them mid-migration."
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright feature"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress equivalent"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`toHaveScreenshot()` / `toMatchSnapshot()` visual snapshots"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "No built-in visual diffing. See "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/tooling/visual-testing.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Visual Testing"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " for plugin options."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect.soft()` (soft assertions)"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "No equivalent. Cypress fails on the first failed assertion; split into separate assertions or tests."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`test.step()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "No direct equivalent. Group related commands and annotate with "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/log.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.log()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " or nested `context()` blocks."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`toMatchAriaSnapshot()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "No equivalent. Assert roles and labels individually, or use "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/accessibility/get-started/introduction.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress Accessibility"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " for automated scanning."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Cheat sheet"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `await` required in Playwright is not included in the cheat sheet for readability."
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Playwright"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator('css')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get('css')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.getByTestId('submit')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get('[data-testid=\"submit\"]')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.goto('/path')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.visit('/path')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.reload()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.reload()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.title()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.title()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.url()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.url()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.waitForResponse(...)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.intercept(...).as('x'); cy.wait('@x')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.setInputFiles(selector, 'file.png')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).selectFile('file.png')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).click()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).click()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).click({ force: true })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).click({force: true})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).click({ button: 'right' })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).rightclick()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).click({ modifiers: ['Shift'] })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).click({shiftKey: true})`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).dblclick()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).dblclick()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).hover()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).trigger('mouseover')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).fill('text')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).clear().type('text')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).focus()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).focus()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).press('Tab')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).focus(); cy.press(Cypress.Keyboard.Keys.TAB)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).selectOption('blue')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).select('blue')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).scrollIntoViewIfNeeded()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).scrollIntoView()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).screenshot()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).screenshot()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.route('**/api', ...)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.intercept('/api', ...)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.screenshot()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.screenshot()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`use: { storageState: 'state.json' }`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.session('user', login)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.clock.setFixedTime(date)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.clock(now)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.clock.install({ time })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.clock(now)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.clock.fastForward(duration)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.tick(ms)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.clock.runFor(duration)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.tick(ms)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.clock.setSystemTime(date)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`clock.setSystemTime(date)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.on('dialog', dialog => dialog.accept())`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Auto-accepted by default"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.on('dialog', dialog => dialog.dismiss())`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.on('window:confirm', () => false)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.on('dialog', dialog => dialog.accept('x'))`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.stub(win, 'prompt').returns('x')` in `onBeforeLoad`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.on('dialog')` with `beforeunload`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.on('window:before:unload', event => ...)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(page).toHaveURL(/re/)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.url().should('match', /re/)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toHaveText('Yes!')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.text', 'Yes!')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toHaveAttribute('href')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.attr', 'href')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeChecked()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('be.checked')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeDisabled()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('be.disabled')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeVisible()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('be.visible')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeHidden()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('be.hidden')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeEnabled()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('be.enabled')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeAttached()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('exist')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toBeFocused()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.focus')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toHaveValue('123')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.value', '123')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toContainText('Yes!')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('contain', 'Yes!')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toContainClass('light')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.class', 'light')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`expect(locator).toHaveCSS('color', 'red')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).should('have.css', 'color', 'red')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`browserContext.cookies()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getCookies()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`browserContext.clearCookies()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.clearCookies()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`browserContext.addCookies(cookie)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.setCookie(name, value)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).first()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).first()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).last()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).last()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).nth(n)`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).eq(n)`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.locator(selector).filter({ hasText: 'x' })`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.get(selector).filter(':contains(\"x\")')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.waitForURL('**/dashboard')`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.url().should('include', '/dashboard')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.goBack()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.go('back')`"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`page.goForward()`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.go('forward')`"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 7716
}