{
  "doc": {
    "id": "app/references/migration-guide",
    "title": "Migration Guide | Cypress Documentation",
    "description": "A guide to help you migrate to the latest version of Cypress.",
    "section": "app",
    "source_path": "/llm/markdown/app/references/migration-guide.md",
    "version": "1375fa62d5875962138c8c43f27d7e1235a504a5",
    "updated_at": "2026-04-29T19:28:48.012Z",
    "headings": [
      {
        "id": "app/references/migration-guide#migration-guide",
        "text": "Migration Guide",
        "level": 1
      },
      {
        "id": "app/references/migration-guide#migrating-away-from-cypress-env",
        "text": "Migrating away from Cypress.env()",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#why-cypress-env-is-deprecated",
        "text": "Why Cypress.env() is deprecated",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#whats-the-risk",
        "text": "What's the risk",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#choose-the-right-migration-path",
        "text": "Choose the right migration path",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#use-cy-env-when",
        "text": "Use cy.env() when:",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#use-cypress-expose-when",
        "text": "Use Cypress.expose() when:",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrate-sensitive-values-to-cy-env",
        "text": "Migrate sensitive values to cy.env()",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#read-one-value",
        "text": "Read one value",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#read-multiple-values",
        "text": "Read multiple values",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrate-public-config-to-cypress-expose",
        "text": "Migrate public config to Cypress.expose()",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#via-configuration-file",
        "text": "Via configuration file",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#via-cli-flags",
        "text": "Via CLI flags",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#via-runtime",
        "text": "Via runtime",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#if-you-were-setting-values-with-cypress-env",
        "text": "If you were setting values with Cypress.env()",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#migrate-plugins-that-use-cypress-env",
        "text": "Migrate plugins that use Cypress.env()",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#check-for-plugin-updates",
        "text": "Check for plugin updates",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#plugins-requiring-migration",
        "text": "Plugins requiring migration",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#cypress-code-coverage",
        "text": "@cypress/code-coverage",
        "level": 5
      },
      {
        "id": "app/references/migration-guide#cypress-grep",
        "text": "@cypress/grep",
        "level": 5
      },
      {
        "id": "app/references/migration-guide#lock-it-down-with-allowcypressenv-false",
        "text": "Lock it down with allowCypressEnv: false",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#migration-checklist",
        "text": "Migration Checklist",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-15-0",
        "text": "Migrating to Cypress 15.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#node-js-20-22-and-24-support",
        "text": "Node.js 20, 22 and 24+ support",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#cy-exec-code-property-renamed",
        "text": "cy.exec code property renamed",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#unsupported-linux-distributions",
        "text": "Unsupported Linux Distributions",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#webpack-4-is-no-longer-supported",
        "text": "Webpack 4 is no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#to-continue-using-webpack-4",
        "text": "To continue using Webpack 4",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#component-testing",
        "text": "Component Testing",
        "level": 5
      },
      {
        "id": "app/references/migration-guide#end-to-end-testing",
        "text": "End-to-End Testing",
        "level": 5
      },
      {
        "id": "app/references/migration-guide#cypress-webpack-batteries-included-preprocessor-no-longer-shims-all-built-ins-provided-by-webpack-v4",
        "text": "@cypress/webpack-batteries-included-preprocessor no longer shims all built-ins provided by webpack v4",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#angular-17-ct-no-longer-supported",
        "text": "Angular 17 CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#to-continue-using-angular-below-18-0-0",
        "text": "To continue using Angular below 18.0.0",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#selector-playground-api-changes",
        "text": "Selector Playground API changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-14-0",
        "text": "Migrating to Cypress 14.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#node-js-18-support",
        "text": "Node.js 18+ support",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#unsupported-linux-distributions",
        "text": "Unsupported Linux Distributions",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#minimum-macos-11-big-sur",
        "text": "Minimum macOS 11 (Big Sur)",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#updated-browser-support",
        "text": "Updated Browser Support",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#changes-to-cy-origin",
        "text": "Changes to cy.origin()",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#deprecation-of-resourcetype-on-cy-intercept",
        "text": "Deprecation of resourceType on cy.intercept",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#ct-just-in-time-compile-changes",
        "text": "CT Just in Time Compile changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#disable-jit-compilation",
        "text": "Disable JIT Compilation",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#react-18-ct-no-longer-supported",
        "text": "React <18 CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#to-continue-using-react-below-v18",
        "text": "To continue using React below v18",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#angular-17-2-0-ct-no-longer-supported",
        "text": "Angular <17.2.0 CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#to-continue-using-angular-below-v17-2-0",
        "text": "To continue using Angular below v17.2.0",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#vue-2-ct-no-longer-supported",
        "text": "Vue 2 CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#to-continue-using-vue-2",
        "text": "To continue using Vue 2",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#create-react-app-ct-no-longer-supported",
        "text": "Create React App CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#vue-cli-service-ct-no-longer-supported",
        "text": "@vue/cli-service CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#svelte-3-4-ct-no-longer-supported",
        "text": "Svelte 3 & 4 CT no longer supported",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-13-0",
        "text": "Migrating to Cypress 13.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#cypress-cloud-test-replay",
        "text": "Cypress Cloud Test Replay",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#video-updates",
        "text": "Video updates",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#video-is-set-to-false-by-default",
        "text": "video is set to false by default",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#videouploadonpasses-configuration-option-has-been-removed",
        "text": "videoUploadOnPasses configuration option has been removed",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#videocompression-is-set-to-false-by-default",
        "text": "videoCompression is set to false by default",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#cy-readfile-is-now-a-query-command",
        "text": "cy.readFile() is now a query command",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#readfile-can-no-longer-be-overwritten-with-cypress-commands-overwrite",
        "text": ".readFile() can no longer be overwritten with Cypress.Commands.overwrite()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-12-0",
        "text": "Migrating to Cypress 12.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#node-js-14-support",
        "text": "Node.js 14+ support",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#test-isolation",
        "text": "Test Isolation",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#simulating-pre-test-isolation-behavior",
        "text": "Simulating Pre-Test Isolation Behavior",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#behavior-changes-in-alias-resolution",
        "text": "Behavior Changes in Alias Resolution",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#command-cypress-api-changes",
        "text": "Command / Cypress API Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#cypress-cookies-defaults-and-cypress-cookies-preserveonce",
        "text": "Cypress.Cookies.defaults and Cypress.Cookies.preserveOnce",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#cy-server-cy-route-and-cypress-server-defaults",
        "text": "cy.server(), cy.route() and Cypress.Server.defaults",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#invoke",
        "text": ".invoke()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#should",
        "text": ".should()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#within",
        "text": ".within()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#cypress-commands-overwrite",
        "text": "Cypress.Commands.overwrite()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-11-0",
        "text": "Migrating to Cypress 11.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#component-testing-updates",
        "text": "Component Testing Updates",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#changes-to-mounting-options",
        "text": "Changes to Mounting Options",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#before-cypress-10",
        "text": "Before (Cypress 10)",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#after-cypress-11",
        "text": "After (Cypress 11)",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#react-mounthook-removed",
        "text": "React - mountHook Removed",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#before-cypress-10-and-mounthook",
        "text": "Before - Cypress 10 and mountHook",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#after-cypress-11-and-mount",
        "text": "After - Cypress 11 and mount",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#react-unmount-removed",
        "text": "React - unmount Removed",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#before-cypress-10-and-unmount",
        "text": "Before - Cypress 10 and unmount",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#after-cypress-11-and-unmountcomponentatnode",
        "text": "After - Cypress 11 and unmountComponentAtNode",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#vue-mountcallback-removed",
        "text": "Vue - mountCallback Removed",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#before-cypress-10-and-mountcallback",
        "text": "Before - Cypress 10 and mountCallback",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#after-cypress-11-and-mount",
        "text": "After - Cypress 11 and mount",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#angular-providers-mounting-options-change",
        "text": "Angular - Providers Mounting Options Change",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#vite-dev-server-cypress-vite-dev-server",
        "text": "Vite Dev Server (cypress/vite-dev-server)",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#before-cypress-10-and-viteconfig",
        "text": "Before - Cypress 10 and viteConfig",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#after-cypress-11-and-viteconfig",
        "text": "After - Cypress 11 and viteConfig",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#migrating-to-cypress-10-0",
        "text": "Migrating to Cypress 10.0",
        "level": 2
      },
      {
        "id": "app/references/migration-guide#cypress-changes",
        "text": "Cypress Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#configuration-file-changes",
        "text": "Configuration File Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#plugins-file-removed",
        "text": "Plugins File Removed",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#config-option-changes",
        "text": "Config Option Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#baseurl",
        "text": "baseUrl",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#componentfolder",
        "text": "componentFolder",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#devserver",
        "text": "devServer",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#experimentalstudio",
        "text": "experimentalStudio",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#ignoretestfiles-excludespecpattern",
        "text": "ignoreTestFiles → excludeSpecPattern",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#integrationfolder",
        "text": "integrationFolder",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#pluginsfile",
        "text": "pluginsFile",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#setupnodeevents",
        "text": "setupNodeEvents()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#slowtestthreshold",
        "text": "slowTestThreshold",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#supportfile",
        "text": "supportFile",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#testfiles-specpattern",
        "text": "testFiles → specPattern",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#updated-test-file-locations",
        "text": "Updated Test File Locations",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#generated-files",
        "text": "Generated Files",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#command-cypress-api-changes",
        "text": "Command / Cypress API Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#cy-mount",
        "text": "cy.mount()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#cypress-commands-add",
        "text": "Cypress.Commands.add()",
        "level": 4
      },
      {
        "id": "app/references/migration-guide#component-testing-changes",
        "text": "Component Testing Changes",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#clashing-types-with-jest",
        "text": "Clashing Types with Jest",
        "level": 3
      },
      {
        "id": "app/references/migration-guide#code-coverage-plugin",
        "text": "Code Coverage Plugin",
        "level": 3
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Migration Guide"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating away from Cypress.env()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Starting with Cypress 15.10.0, `Cypress.env()` has been deprecated and will be removed in a future major version. This guide helps you migrate to "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/env.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.env()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " (for sensitive values) or "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/expose.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.expose()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " (for public/non-sensitive values), depending on your use case."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Why Cypress.env() is deprecated"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`Cypress.env()` makes it easy to accidentally expose more data than intended because Cypress hydrates all configured environment variables into the browser context. That includes values your test never reads."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This deprecation is a precaution to reduce the risk of unintentionally exposing secrets in the browser-accessible state when run within the Cypress browser. This is about ensuring safer defaults and preventing accidental exposure of sensitive data."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "What's the risk"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When Cypress environment values are available in the browser, they can be inspected through normal browser tooling and may be accessible to code running in that context (for example, app code, third-party scripts, or extensions). The core issues are:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "All-or-nothing exposure: All environment variables are serialized and sent to the browser where they can be accessed via `Cypress.env()` or inspected in the browser's developer tools."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Cross-origin risks: When using "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/origin.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.origin()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " for cross-origin testing, all environment variables are automatically passed to the cross-origin context, potentially exposing sensitive data to untrusted origins."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Application code access: Since environment variables are available in the browser context when tests run, your application code or third-party scripts could potentially access them if it checks for `window.Cypress` or similar patterns."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Choose the right migration path"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When migrating from `Cypress.env()`, you have two options: `cy.env()` and `Cypress.expose()`. The choice depends on the sensitivity of your configuration values and your access requirements."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Use cy.env() when:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The values are sensitive (API keys, passwords, tokens, credentials, secrets)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You're using the value inside tests/hooks where async Cypress commands are fine"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You want the most conservative exposure model (only request what you need)"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Use Cypress.expose() when:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The value is public/non-sensitive (feature flags, API versions, public URLs, plugin configurations)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You need synchronous access"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "It's acceptable for the value to be accessible in the browser context (e.g. application code, third-party scripts, or extensions)"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Migrate sensitive values to cy.env()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.env()` is read-only and asynchronous."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Read one value"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "describe('API tests', () => {\n  it('makes a request to the API', () => {\n    const apiKey = Cypress.env('apiKey')\n    cy.request({\n      url: 'https://api.example.com/users',\n      headers: { Authorization: `Bearer ${apiKey}` },\n    })\n      .its('status')\n      .should('eq', 200)\n  })\n})"
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "describe('API tests', () => {\n  it('makes a request to the API', () => {\n    cy.env(['apiKey']).then(({ apiKey }) => {\n      cy.request({\n        url: 'https://api.example.com/users',\n        headers: { Authorization: `Bearer ${apiKey}` },\n      })\n        .its('status')\n        .should('eq', 200)\n    })\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Read multiple values"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "describe('API tests', () => {\n  it('makes authenticated requests', () => {\n    const apiUrl = Cypress.env('apiUrl')\n    const apiKey = Cypress.env('apiKey')\n\n    cy.request({\n      url: `${apiUrl}/users`,\n      headers: { Authorization: `Bearer ${apiKey}` },\n    })\n      .its('status')\n      .should('eq', 200)\n  })\n})"
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "describe('API tests', () => {\n  it('makes authenticated requests', () => {\n    cy.env(['apiUrl', 'apiKey']).then(({ apiUrl, apiKey }) => {\n      cy.request({\n        url: `${apiUrl}/users`,\n        headers: { Authorization: `Bearer ${apiKey}` },\n      })\n        .its('status')\n        .should('eq', 200)\n    })\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": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Migrate public config to Cypress.expose()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Use this path only for non-sensitive values. `Cypress.expose()` is synchronous and is designed for configuration that is safe to be available in the browser."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Via configuration file"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "const pluginConfig = Cypress.env('PLUGIN_CONFIG')"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  env: {\n    apiKey: 'secret-key-12345',\n    featureFlag: true,\n    apiVersion: 'v2',\n    publicApiUrl: 'https://api.example.com',\n    pluginConfig: 'development',\n  },\n}"
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "const pluginConfig = Cypress.expose('PLUGIN_CONFIG')"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  expose: {\n    featureFlag: true,\n    apiVersion: 'v2',\n    publicApiUrl: 'https://api.example.com',\n    pluginConfig: 'development',\n  },\n  env: {\n    apiKey: 'secret-key-12345',  // Sensitive - use env, not expose\n  },\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/expose.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress.expose()"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Via CLI flags"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Use the `--expose` or `-x` CLI flags when running Cypress."
          }
        ]
      },
      {
        "type": "code",
        "lang": "shell",
        "meta": null,
        "value": "cypress run --env FEATURE_FLAG=true,API_VERSION=v2,PUBLIC_API_URL=https://api.example.com"
      },
      {
        "type": "code",
        "lang": "shell",
        "meta": null,
        "value": "cypress run --expose FEATURE_FLAG=true,API_VERSION=v2,PUBLIC_API_URL=https://api.example.com"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/expose.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress.expose()"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Via runtime"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can set exposed values at runtime using `Cypress.expose(key, value)` or `Cypress.expose(object)`. Note that these changes only persist for the remainder of the current spec file:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "// Set a single value\nCypress.expose('featureFlag', true)\n\n// Set multiple values\nCypress.expose({\n  featureFlag: true,\n  apiVersion: 'v2',\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/expose.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress.expose()"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "If you were setting values with Cypress.env()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.env()` cannot set values. If you used `Cypress.env()` to write sensitive values at runtime, you can use `cy.task()` to store state in the Cypress config process. These are not environment variables and are not accessible through `cy.env()`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Setup in `cypress.config.js`:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "// cypress.config.js\nexport default defineConfig({\n  e2e: {\n    setupNodeEvents(on, config) {\n      const configProcessScopedVariables = {}\n\n      on('task', {\n        set: (keySet) => {\n          Object.entries(keySet).forEach(([key, value]) => {\n            configProcessScopedVariables[key] = value\n          })\n          return null\n        },\n        get: (keys) => {\n          const variablesToReturn = {}\n          keys.forEach((key) => {\n            variablesToReturn[key] = configProcessScopedVariables[key]\n          })\n          return variablesToReturn\n        },\n      })\n\n      return config\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Usage in your tests:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "// spec.cy.js\ndescribe('API tests', () => {\n  it('stores and retrieves sensitive runtime values', () => {\n    // Get an access token from an API\n    cy.getAccessTokenFromApi().then(({ token }) => {\n      // Store it securely in the config process\n      cy.task('set', { accessToken: token })\n    })\n\n    // Later in the test, retrieve it\n    cy.task('get', ['accessToken']).then(({ accessToken }) => {\n      // Use the token securely\n      cy.request({\n        url: 'https://api.example.com/data',\n        headers: { Authorization: `Bearer ${accessToken}` },\n      })\n    })\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Migrate plugins that use Cypress.env()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're using Cypress plugins that reference `Cypress.env()`, you should check for updated versions that support the new API. When `allowCypressEnv: false` is set, plugins that still use `Cypress.env()` will throw errors."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Check for plugin updates"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before setting `allowCypressEnv: false`, review your installed plugins and update them to their latest versions. Many popular plugins need to be updated to use `Cypress.expose()` or `cy.env()` instead of `Cypress.env()`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Plugins requiring migration"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The following plugins require updates to their latest major versions and migration to the new API:"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "@cypress/code-coverage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Update to version 4.0.0+ of `@cypress/code-coverage` and follow its "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/code-coverage/blob/master/README.md#migrations",
            "children": [
              {
                "type": "text",
                "value": "migration guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " to move from environment variables to `--expose` CLI flags and `expose` config."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "@cypress/grep"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Update to version 6.0.0+ of `@cypress/grep` and follow its "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/tree/develop/npm/grep#migration",
            "children": [
              {
                "type": "text",
                "value": "migration guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " to move from environment variables to `--expose` CLI flags and `expose` config."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Lock it down with allowCypressEnv: false"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Once you've migrated all `Cypress.env()` invocations to either `cy.env()` or `Cypress.expose()`, you should set `allowCypressEnv: false` in your Cypress configuration."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  allowCypressEnv: false,\n  env: {\n    apiUrl: 'https://api.example.com',\n    apiKey: 'secret-key-12345',\n  },\n  e2e: {\n    baseUrl: 'http://localhost:3000',\n  },\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When `allowCypressEnv` is set to `false`:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`Cypress.env()` calls will throw an error"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Test configuration overrides are disabled"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Migration Checklist"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Search your codebase for all `Cypress.env()` calls"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Replace each `Cypress.env()` call with either `cy.env()` or `Cypress.expose()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Update code to handle the asynchronous nature of `cy.env()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Migrate plugins that use `Cypress.env()`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Set `allowCypressEnv: false` in your Cypress configuration"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✅ Verify that no errors are thrown"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 15.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the code changes needed to migrate to Cypress\nversion 15.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#15-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version v15.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Node.js 20, 22 and 24+ support"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress requires "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://nodejs.org/en",
            "children": [
              {
                "type": "text",
                "value": "Node.js"
              }
            ]
          },
          {
            "type": "text",
            "value": " in order to install the Cypress binary and the supported versions are now Node.js 20, 22, 24 and above.\nNode.js versions 18 and 23 are no longer supported.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/nodejs/Release",
            "children": [
              {
                "type": "text",
                "value": "See Node's release schedule"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "cy.exec code property renamed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `code` property on "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/exec.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.exec()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " has been renamed to `exitCode`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "cy.exec('rake db:seed').its('code').should('eq', 0)"
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "cy.exec('rake db:seed').its('exitCode').should('eq', 0)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Unsupported Linux Distributions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Prebuilt binaries for Linux are no longer compatible with Linux distributions based on glibc `<2.31`.\nThis support is in line with Node.js's support for Linux in 20+."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're using a Linux distribution based on glibc `<2.31`, you'll need to\nupdate your system to a newer version to install Cypress 15+.\nTo display which version of glibc your Linux system is running, execute `ldd --version`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Webpack 4 is no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress is no longer supporting Webpack `4` as it is no longer maintained by the core Webpack team and Webpack `5` has been available since Q4 2020. This includes dropping Webpack `4` support for:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`@cypress/webpack-dev-server` for component testing. This use case is most common and will require an update to Webpack `5`."
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`@cypress/webpack-dev-server` also no longer supports "
                          },
                          {
                            "type": "link",
                            "title": null,
                            "url": "https://github.com/webpack/webpack-dev-server/tree/v4.15.2",
                            "children": [
                              {
                                "type": "text",
                                "value": "Webpack Dev Server v4"
                              }
                            ]
                          },
                          {
                            "type": "text",
                            "value": ". We shipped "
                          },
                          {
                            "type": "link",
                            "title": null,
                            "url": "https://github.com/webpack/webpack-dev-server/tree/v5.2.1",
                            "children": [
                              {
                                "type": "text",
                                "value": "Webpack Dev Server v5"
                              }
                            ]
                          },
                          {
                            "type": "text",
                            "value": " as the default in Cypress 14 with `webpack-dev-server@4` being an option."
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`@cypress/webpack-preprocessor` for end-to-end testing. Cypress, by default, uses the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress/blob/@cypress/webpack-batteries-included-preprocessor-v3.0.7/npm/webpack-batteries-included-preprocessor/README.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Webpack Batteries Included Preprocessor"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " to process your files for end-to-end testing, which has used Webpack 5 since Cypress 13. Unless you are already using `@cypress/webpack-preprocessor` as a standalone package, this change likely does not apply."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "To continue using Webpack 4"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "Component Testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from Webpack `4` or Webpack Dev Server `4` and still need to be able to run your component tests with Webpack `4` or Webpack Dev Server `4`, you can install the following packages independently:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/webpack-dev-server@4"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "and configure the dev server within your `cypress.config.js` or `cypress.config.ts` file:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { devServer } from '@cypress/webpack-dev-server'\nimport { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  component: {\n    devServer(devServerConfig) {\n      return devServer({\n        ...devServerConfig,\n        framework: 'react',\n        webpackConfig: require('./webpack.config.js'),\n      })\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this package version is deprecated and no longer supported by Cypress and is intended as a workaround until you can migrate to Webpack `5`. More information on how to configure the dev server ` v4  `can be found in the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/blob/@cypress/webpack-dev-server-v4.0.2/npm/webpack-dev-server/README.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress Webpack Dev Server documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/component-framework-configuration.md#Custom-Dev-Server",
            "children": [
              {
                "type": "text",
                "value": "Custom Dev Server documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "End-to-End Testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from Webpack `4`, need custom end-to-end spec file preprocessing, are already using `@cypress/webpack-preprocessor` as a standalone package, and still need to be able to run your end-to-end tests with Webpack `4`, you can install the following package independently:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/webpack-preprocessor@6"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "and configure the preprocessor within your `cypress.config.js` or `cypress.config.ts` file:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\nimport webpackPreprocessor from '@cypress/webpack-preprocessor'\n\nexport default defineConfig({\n  e2e: {\n    setupNodeEvents(on, config) {\n      on('file:preprocessor', webpackPreprocessor())\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As stated earlier, this is likely unnecessary unless you are already using `@cypress/webpack-preprocessor` as a standalone package. Cypress by default uses the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/blob/@cypress/webpack-batteries-included-preprocessor-v3.0.7/npm/webpack-batteries-included-preprocessor/README.md",
            "children": [
              {
                "type": "text",
                "value": "Webpack Batteries Included Preprocessor"
              }
            ]
          },
          {
            "type": "text",
            "value": " to process your spec files for end-to-end testing."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this package version is deprecated and no longer supported by Cypress and is intended as a workaround until you can migrate to Webpack `5`. More information on how to configure the preprocessor can be found in the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/node-events/preprocessors-api.md#Usage",
            "children": [
              {
                "type": "text",
                "value": "Preprocessors API documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/blob/@cypress/webpack-preprocessor-v6.0.4/npm/webpack-preprocessor/README.md",
            "children": [
              {
                "type": "text",
                "value": "Webpack Preprocessor documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "@cypress/webpack-batteries-included-preprocessor no longer shims all built-ins provided by webpack v4"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The default file preprocessor, `@cypress/webpack-batteries-included-preprocessor`, no longer shims all built-ins that were previously provided by webpack v4. This is mainly to reduce security vulnerabilities and bundle size within the end-to-end file preprocessor."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "However, `@cypress/webpack-batteries-included-preprocessor` still ships with some built-ins, such as `buffer`, `path`, `process`, `os`, and `stream`. If other built-ins are required, install `@cypress/webpack-batteries-included-preprocessor` independently and follow the webpack documentation described in "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://webpack.js.org/configuration/resolve/#resolvefallback",
            "children": [
              {
                "type": "text",
                "value": "webpack's resolve.fallback"
              }
            ]
          },
          {
            "type": "text",
            "value": " to configure the built-ins you need."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For example, the following code shows how to provide the `querystring` built-in to the preprocessor:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "const webpackPreprocessor = require('@cypress/webpack-batteries-included-preprocessor')\n\nfunction getWebpackOptions() {\n  const options = webpackPreprocessor.getFullWebpackOptions()\n\n  // add built-ins as needed\n  // NOTE: for this example, querystring-es3 needs to be installed as a dependency\n  options.resolve.fallback.querystring = require.resolve('querystring-es3')\n  return options\n}\n\nmodule.exports = (on) => {\n  on(\n    'file:preprocessor',\n    webpackPreprocessor({\n      // if using typescript, you will need to set the typescript option to true\n      typescript: true,\n      webpackOptions: getWebpackOptions(),\n    })\n  )\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Angular 17 CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://angular.dev/reference/releases#actively-supported-versions",
            "children": [
              {
                "type": "text",
                "value": "LTS end"
              }
            ]
          },
          {
            "type": "text",
            "value": " for Angular 17, the minimum required Angular version for component testing is now `18.0.0`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "To continue using Angular below 18.0.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from an older Angular version and still need that test harness, it can be installed independently via the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/angular",
            "children": [
              {
                "type": "text",
                "value": "`@cypress/angular`"
              }
            ]
          },
          {
            "type": "text",
            "value": " `3.x.x` package from `npm`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this test harness version is deprecated and no longer supported by Cypress. This version is intended to serve as a temporary workaround to migrate your project to Angular v18.0.0+."
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/angular@3"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Inside your support file (ex: `./cypress/support/component.(js|ts)`), or wherever your mount function is imported, make the following update to add `@`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from `cypress/angular`"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from `@cypress/angular`"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Selector Playground API changes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `Cypress.SelectorPlayground` API has been renamed to\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/element-selector-api.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.ElementSelector`"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Additionally, the `onElement` function has been removed as an option to the `defaults` method."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This change was made in order to reflect its use in features beyond just the Selector Playground - like Cypress Studio."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The following code shows how to migrate from the `Cypress.SelectorPlayground` API to the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/element-selector-api.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.ElementSelector`"
              }
            ]
          },
          {
            "type": "text",
            "value": " API."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "Cypress.SelectorPlayground.defaults({\n  selectorPriority: ['class', 'id'],\n})"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "Cypress.ElementSelector.defaults({\n  selectorPriority: ['class', 'id'],\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 14.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the code changes needed to migrate to Cypress\nversion 14.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#14-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version v14.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Node.js 18+ support"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress comes bundled with its own\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/blob/develop/.node-version",
            "children": [
              {
                "type": "text",
                "value": "Node.js version"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nHowever, installing the `cypress` npm package uses the Node.js version installed\non your system."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/nodejs/Release",
            "children": [
              {
                "type": "text",
                "value": "See Node's release schedule"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Node.js\nversion 16 and 21 will no longer be supported when installing Cypress. The minimum Node.js\nversion supported to install Cypress is Node.js 18+."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Unsupported Linux Distributions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Prebuilt binaries for Linux are no longer compatible with Linux distributions based on glibc `<2.28`.\nThis support is in line with Node.js's support for Linux in 18+."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're using a Linux distribution based on glibc `<2.28`, for example, Ubuntu 14-18, RHEL 7, CentOS 7, Amazon Linux 2, you'll need to\nupdate your system to a newer version to install Cypress 14+."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Minimum macOS 11 (Big Sur)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#14-0-0",
            "children": [
              {
                "type": "text",
                "value": "Cypress 14.0"
              }
            ]
          },
          {
            "type": "text",
            "value": " upgrades Electron to `33.2.1`.\nOn macOS this requires a minimum version of macOS 11 (Big Sur)."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're using a lower version of macOS make sure that you update."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Updated Browser Support"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Starting in Cypress 14, Cypress will officially support "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/launching-browsers.md#Browser-versions-supported",
            "children": [
              {
                "type": "text",
                "value": "the latest 3 major versions of Chrome, Firefox, and Edge"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Older browser versions may still work with Cypress, but we recommend keeping your browsers up to date to ensure compatibility with Cypress."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Changes to cy.origin()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To account for Chrome's "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.chrome.com/blog/document-domain-setter-deprecation",
            "children": [
              {
                "type": "text",
                "value": "impending deprecation"
              }
            ]
          },
          {
            "type": "text",
            "value": " of setting `document.domain`, and to support sites that use "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin-Agent-Cluster",
            "children": [
              {
                "type": "text",
                "value": "origin-keyed agent clusters"
              }
            ]
          },
          {
            "type": "text",
            "value": ",\nCypress no longer injects `document.domain` into `text/html` content by default."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because of this, tests that visit more than one origin (defined as a composite of the URL scheme, hostname, and port) must now use `cy.origin()`.\nWithout `cy.origin()`, interacting with a second origin in the same test will cause the test to fail, even if the two origins\nare in the same superdomain. This means you must now use `cy.origin()` in more situations than before."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "/* prettier-ignore-start */"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Failing Test"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.visit('https://www.cypress.io')\ncy.visit('https://docs.cypress.io')\n// Cypress will not be able to interact with the page, causing the test to fail\ncy.get('[role=\"banner\"]').should('be.visible')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Fixed Test"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.visit('https://www.cypress.io')\ncy.visit('https://docs.cypress.io')\ncy.origin('https://docs.cypress.io', () => {\n  cy.get('[role=\"banner\"]').should('be.visible')\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "/* prettier-ignore-end */"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To ease this transition, Cypress v14.0 introduced the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#injectDocumentDomain",
            "children": [
              {
                "type": "text",
                "value": "\"injectDocumentDomain\" configuration option"
              }
            ]
          },
          {
            "type": "text",
            "value": ". When this option\nis set to true, `cy.origin()` will not be required to navigate between origins, as long as the superdomain matches."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If `injectDocumentDomain` is set to `true`,\nCypress will warn that this option is deprecated."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`injectDocumentDomain` will be removed in a\nfuture version of Cypress."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Setting `injectDocumentDomain` to `true`\nmay cause certain sites to stop working in Cypress. Please read the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#injectDocumentDomain",
            "children": [
              {
                "type": "text",
                "value": "configuration notes"
              }
            ]
          },
          {
            "type": "text",
            "value": " before\nuse."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your test suites require\n`experimentalWebKitSupport`, `injectDocumentDomain` must be set to `true`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Chrome may remove support for\n`document.domain` at any time; if this configuration option is enabled, Cypress\nmay cease to work in Chrome at any time. If this occurs, Chrome will raise an\nissue in its developer tools indicating that the deprecated `document.domain` is\nin use. To resolve this issue, set the `injectDocumentDomain` option to `false`\nand issue any newly necessary `cy.origin()` commands."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Deprecation of resourceType on cy.intercept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `resourceType` option on "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/intercept.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.intercept`"
              }
            ]
          },
          {
            "type": "text",
            "value": " has been deprecated in Cypress 14.0.0. We anticipate the types of the `resourceType` to change in the future or be completely removed\nfrom the API."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Our intention is to replace essential functionality dependent on the `resourceType` within Cypress in a future version (like "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/intercept.md#Disabling-logs-for-a-request",
            "children": [
              {
                "type": "text",
                "value": "hiding network logs that are not fetch/xhr"
              }
            ]
          },
          {
            "type": "text",
            "value": "). If you're using `resourceType` in your tests, please leave feedback on which `resourceType` values are important to you in this "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/issues/30447",
            "children": [
              {
                "type": "text",
                "value": "GitHub issue"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "CT Just in Time Compile changes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress 13.14.0, we released an experimental flag, `experimentalJustInTimeCompile`,\nto enable Just in Time (JIT) compilation for Component Testing with `vite` and `webpack`. The response from this change was positive and we've made a few changes in response:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "JIT compilation is the default behavior for component tests as a "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#component",
                    "children": [
                      {
                        "type": "text",
                        "value": "`justInTimeCompile`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " component configuration option."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "JIT compilation no longer applies with `vite`, since there is no benefit to enabling this with `vite`."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This option will only compile resources directly related to your spec, compiling them 'just-in-time' before spec execution. This should result in improved memory management and performance for component tests in `cypress open` and `cypress run` modes, especially for large test suites."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Disable JIT Compilation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you would like to disable JIT compilation, you can do so by setting "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#component",
            "children": [
              {
                "type": "text",
                "value": "`justInTimeCompile`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to `false` in your component configuration."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  component: {\n    justInTimeCompile: false\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For users with the existing `experimentalJustInTimeCompile` flag set, you can remove this flag from your configuration."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "React <18 CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/reactjs/react.dev/issues/1745#issuecomment-466767389",
            "children": [
              {
                "type": "text",
                "value": "LTS ending"
              }
            ]
          },
          {
            "type": "text",
            "value": " for React 16 and 17 several years ago, the minimum required React version for component testing is now `18.0.0`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Now that the minimum version of React supported for Component Testing is `18.0.0`, Cypress is able to merge the `cypress/react18` test harness into the main `cypress/react` test harness. Because of this, the `@cypress/react18` harness is deprecated and no longer shipped with the binary. Support has been moved to `cypress/react`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To migrate, change the test harness from `cypress/react18` to `cypress/react`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/react18'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/react'"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "To continue using React below v18"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from an older React version and still need that test harness, it can be installed independently via the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/react",
            "children": [
              {
                "type": "text",
                "value": "`@cypress/react`"
              }
            ]
          },
          {
            "type": "text",
            "value": " `8.x.x` package from `npm`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this test harness version is deprecated and no longer supported by Cypress. This version is intended to serve as a temporary workaround to migrate your project to React v18+."
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/react@8"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Inside your support file (ex: `./cypress/support/component.(js|ts)`), or wherever your mount function is imported, make the following update to add `@`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/react'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from '@cypress/react'"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Angular <17.2.0 CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://angular.dev/reference/releases#actively-supported-versions",
            "children": [
              {
                "type": "text",
                "value": "LTS ending"
              }
            ]
          },
          {
            "type": "text",
            "value": " for Angular 16, the minimum required Angular version for component testing is now `17.2.0` in order to support "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/angular/examples.md#Signals",
            "children": [
              {
                "type": "text",
                "value": "signals"
              }
            ]
          },
          {
            "type": "text",
            "value": " as a first class citizen."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Now that the minimum version of Angular supported for Component Testing is `17.2.0`, Cypress is able to merge the `cypress/angular-signals` test harness into the main `cypress/angular` test harness. Because of this, the `@cypress/angular-signals` harness is deprecated and no longer shipped with the binary. Support has been moved to `cypress/angular`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To migrate, just change the test harness from `cypress/angular-signals` to `cypress/angular`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/angular-signals'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/angular'"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "To continue using Angular below v17.2.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from an older Angular version and still need that test harness, it can be installed independently via the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/angular",
            "children": [
              {
                "type": "text",
                "value": "`@cypress/angular`"
              }
            ]
          },
          {
            "type": "text",
            "value": " `2.x.x` package from `npm`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this test harness version is deprecated and no longer supported by Cypress. This version is intended to serve as a temporary workaround to migrate your project to Angular v17.2.0+."
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/angular@2"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Inside your support file (ex: `./cypress/support/component.(js|ts)`), or wherever your mount function is imported, make the following update to add `@`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/angular'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from '@cypress/angular'"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Vue 2 CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "https://v2.vuejs.org/eol/",
            "children": [
              {
                "type": "text",
                "value": "Vue 2 reached end-of-life on December 31st, 2023"
              }
            ]
          },
          {
            "type": "text",
            "value": ". With Cypress 14, Cypress no longer ships the Vue 2 component testing harness with the Cypress binary."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "To continue using Vue 2"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you haven't been able to migrate away from Vue 2 and still need that test harness, it can be installed independently via the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/vue2",
            "children": [
              {
                "type": "text",
                "value": "@cypress/vue2"
              }
            ]
          },
          {
            "type": "text",
            "value": " package."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this test harness is deprecated and no longer supported by Cypress. This package is intended to serve as a temporary workaround to migrate your project to Vue 3. The Cypress launchpad will warn against Component testing mismatched dependencies, but this will not stop you from running your component tests."
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/vue2"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Inside your support file (ex: `./cypress/support/component.(js|ts)`), or wherever your mount function is imported, make the following update to add `@`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/vue2'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from '@cypress/vue2'"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Create React App CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "https://create-react-app.dev/",
            "children": [
              {
                "type": "text",
                "value": "create-react-app"
              }
            ]
          },
          {
            "type": "text",
            "value": " is no longer actively maintained or supported (see "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/facebook/create-react-app/issues/13393",
            "children": [
              {
                "type": "text",
                "value": "CRA issue #13393"
              }
            ]
          },
          {
            "type": "text",
            "value": "). Your component tests will now need a bundler to run. If still using "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://create-react-app.dev/",
            "children": [
              {
                "type": "text",
                "value": "create-react-app"
              }
            ]
          },
          {
            "type": "text",
            "value": ", you'll either need to:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://create-react-app.dev/docs/available-scripts/#npm-run-eject",
                    "children": [
                      {
                        "type": "text",
                        "value": "Eject"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " the configuration to bundle with webpack."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Leverage "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://vite.dev/guide/",
                    "children": [
                      {
                        "type": "text",
                        "value": "vite"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " to bundle your component tests (quick setup with "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/vitejs/vite/tree/main/packages/create-vite",
                    "children": [
                      {
                        "type": "text",
                        "value": "create-vite"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ")."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After selecting a bundler, change the `framework` option in your Cypress config from `create-react-app` to `react`. If ejecting the `create-react-app`, change your cypress config to look something like this:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "process.env.NODE_ENV = 'development'\nconst { defineConfig } = require('cypress')\nconst webpackConfig = require('./config/webpack.config.js')\n\nmodule.exports = defineConfig({\n  component: {\n    devServer: {\n      framework: 'react',\n      bundler: 'webpack',\n      webpackConfig: webpackConfig('development'),\n    },\n  },\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "@vue/cli-service CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`@vue/cli-service` is in "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://cli.vuejs.org/guide/cli-service.html",
            "children": [
              {
                "type": "text",
                "value": "maintenance mode"
              }
            ]
          },
          {
            "type": "text",
            "value": " and is no longer maintained by the Vue core team. Your component tests will now need a bundler to run. If still using "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://cli.vuejs.org/",
            "children": [
              {
                "type": "text",
                "value": "Vue CLI"
              }
            ]
          },
          {
            "type": "text",
            "value": ", you will either need to:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Migrate to webpack ("
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress-component-testing-apps/tree/main/vue3-webpack-ts",
                    "children": [
                      {
                        "type": "text",
                        "value": "see example"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ")."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Leverage "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://vite.dev/guide/",
                    "children": [
                      {
                        "type": "text",
                        "value": "vite"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ". The Vue team recommends migrating to using `create-vue` to scaffold a "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://vite.dev/",
                    "children": [
                      {
                        "type": "text",
                        "value": "Vite"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "-based project."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After selecting a bundler, change the `framework` option in your Cypress config from `\"vue-cli\"` to `\"vue\"`. Your Cypress configuration should change as outlined below."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  component: {\n    devServer: {\n      framework: 'vue-cli',\n      bundler: 'webpack',\n    },\n  }\n}"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  component: {\n    devServer: {\n      framework: 'vue',\n      bundler: 'vite', // or 'webpack'\n    },\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Svelte 3 & 4 CT no longer supported"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With Cypress 14, Cypress no longer ships the Svelte 3 and 4 component testing harness with the Cypress binary."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "However, if you have not been able to upgrade Svelte and still need the Cypress Svelte 3 and 4 test harness, it can be installed independently via version 2.x.x of the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.npmjs.com/package/@cypress/svelte",
            "children": [
              {
                "type": "text",
                "value": "@cypress/svelte"
              }
            ]
          },
          {
            "type": "text",
            "value": " package."
          }
        ]
      },
      {
        "type": "code",
        "lang": "sh",
        "meta": null,
        "value": "npm install --save-dev @cypress/svelte@2"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that this version of the test harness is deprecated and no longer actively supported by Cypress and is intended to serve as a temporary work around until you are able to migrate your project to Svelte 5+. The Cypress launchpad will also warn against Component testing mismatched dependencies, but this will not stop you from running your component tests."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To update, inside your support file (ex: `./cypress/support/component.(js|ts)`) or wherever your mount function is imported, change"
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from 'cypress/svelte'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "to"
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import { mount } from '@cypress/svelte'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Your code should now look like this:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import MySvelteComponent from './MySvelteComponent'\nimport { mount } from '@cypress/svelte'\n\nit('renders', () => {\n  cy.mount(MySvelteComponent)\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 13.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the changes and how to change your code to migrate to Cypress\nversion 13.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#13-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version v13.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cypress Cloud Test Replay"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/test-replay.md",
            "children": [
              {
                "type": "text",
                "value": "Test Replay"
              }
            ]
          },
          {
            "type": "text",
            "value": " is enabled by default in `v13` of the Cypress App."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You may need to allowlist `capture.cypress.io` if you work with a strict VPN. See our FAQ section about "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/faq.md#Im-working-with-a-restrictive-VPN-Which-subdomains-do-I-have-to-allow-on-my-VPN-for-Cypress-Cloud-to-work-properly",
            "children": [
              {
                "type": "text",
                "value": "VPN subdomain allowlisting"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With Test Replay enabled, the Cypress Runner UI is hidden by default when recording a run to the Cloud. If the Runner UI is needed during the run, you can enable it by passing "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/command-line.md#cypress-run-runner-ui",
            "children": [
              {
                "type": "text",
                "value": "`--runner-ui`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/command-line.md#cypress-run",
            "children": [
              {
                "type": "text",
                "value": "`cypress run`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/test-replay.md#Opt-out-of-Test-Replay",
            "children": [
              {
                "type": "text",
                "value": "opt-out"
              }
            ]
          },
          {
            "type": "text",
            "value": " of this feature in Cloud project-level settings."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Video updates"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "video is set to false by default"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can continue recording video by setting `video` to `true` either in your Cypress configuration or via "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Overriding-Options",
            "children": [
              {
                "type": "text",
                "value": "overriding options"
              }
            ]
          },
          {
            "type": "text",
            "value": ". This can be useful if you want video locally or want video for some other reason, like in non-Chromium browsers where "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/cloud/features/test-replay.md",
            "children": [
              {
                "type": "text",
                "value": "Test Replay"
              }
            ]
          },
          {
            "type": "text",
            "value": " is not available."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  video: true\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "videoUploadOnPasses configuration option has been removed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Most users used `videoUploadOnPasses` as a way to skip the time to compress and upload videos to the Cloud. Since we're turning off `videoCompression` by default, this configuration option does not offer the time saving value that it once would."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you want to prevent a passing test from uploading to the Cloud, we recommend deleting the video using our "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/screenshots-and-videos.md#Control-which-videos-to-keep-and-upload-to-Cypress-Cloud",
            "children": [
              {
                "type": "text",
                "value": "guide with code examples to discard captured video of passing tests"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "videoCompression is set to false by default"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress has the capability to compress recorded videos after a run to reduce the video file size. By default, compression is now turned off. This results in a reduced run time by removing the time to compress the video, a larger video file size and better video quality."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can enable this with the `videoCompression` "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Videos",
            "children": [
              {
                "type": "text",
                "value": "configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": " option if you'd like to reduce the video file size for any reason. This will also reduce the video quality and take slightly longer to process and complete the run."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  // value can be true/false -or- an integer between 0 and 51\n  videoCompression: true,\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "cy.readFile() is now a query command"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress `v13`, the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/readfile.md",
            "children": [
              {
                "type": "text",
                "value": "`.readFile()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command is now a query.\nTests written using it should continue to operate exactly as before; no changes\nare necessary."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`readFile()` will re-read the file from disk if any upcoming command in the same\nchain fails. Assertions no longer have to be directly attached."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.readFile(`users.json`).its('users.123.fullName').should('eq', 'John Doe')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Beginning with Cypress `v13`, the above test will re-read the file until the file\nexists, it has the requested property, and it passes the assertion."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In previous versions of Cypress, the above command would retry until the file\nexisted, but would not re-read it from disk if the file didn't have the\nrequested property or the contents didn't match."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": ".readFile() can no longer be overwritten with Cypress.Commands.overwrite()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Queries must be overwritten using `Cypress.Commands.overwriteQuery()`. If you\nwere previously overwriting `cy.readFile()`, you will need to update your code\nto use `Cypress.Commands.overwriteQuery('readFile', function() { ... })` rather\nthan `Cypress.Commands.overwrite('readFile', () => { ... })`. For more details\non overwriting queries, see the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-queries.md#Overwriting-Existing-Queries",
            "children": [
              {
                "type": "text",
                "value": "Overwriting Existing Queries"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 12.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the changes and how to change your code to migrate to Cypress\nversion 12.0.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#12-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version 12.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The Session and Origin experiment has been released as General Availability\n(GA), meaning that we have deemed this experiment to be feature complete and\nfree of issues in the majority of use cases. With releasing this as GA, the\n`experimentalSessionAndOrigin` flag has been removed, the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/session.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.session()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " commands are generally available and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Test-Isolation",
            "children": [
              {
                "type": "text",
                "value": "Test Isolation"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nis enabled by default."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Node.js 14+ support"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress comes bundled with its own\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/blob/develop/.node-version",
            "children": [
              {
                "type": "text",
                "value": "Node.js version"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nHowever, installing the `cypress` npm package uses the Node.js version installed\non your system."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Node.js 12 reached its end of life on April 30, 2022.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/nodejs/Release",
            "children": [
              {
                "type": "text",
                "value": "See Node's release schedule"
              }
            ]
          },
          {
            "type": "text",
            "value": ". This Node.js\nversion will no longer be supported when installing Cypress. The minimum Node.js\nversion supported to install Cypress is Node.js 14+."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Test Isolation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Test-Isolation",
            "children": [
              {
                "type": "text",
                "value": "`testIsolation`"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nconfig option is enabled by default. This means Cypress resets the browser\ncontext before each test by:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "clearing the dom state by visiting `about:blank`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "clearing "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/cypress-api/cookies.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "cookies"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " in all domains"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "clearing\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage",
                    "children": [
                      {
                        "type": "text",
                        "value": "`localStorage`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "\nin all domains"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "clearing\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage",
                    "children": [
                      {
                        "type": "text",
                        "value": "`sessionStorage`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "\nin all domains"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Test suites that relied on the application to persist between tests may have to\nbe updated to revisit their application and rebuild the browser state for each\ntest that needs it."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before this change, it was possible to write tests such that you could rely on\nthe application (i.e. DOM state) to persist between tests. For example you could\nlog in to a CMS in the first test, change some content in the second test,\nverify the new version is displayed on a different URL in the third, and log out\nin the fourth."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Here's a simplified example of such a test strategy."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": " Multiple small tests against different\norigins"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('logs in', () => {\n  cy.visit('https://example.cypress.io')\n  cy.get('input#password').type('Password123!')\n  cy.get('button#submit').click()\n})\n\nit('updates the content', () => {\n  // already on page redirect from clicking button#submit\n  cy.get('#current-user').contains('logged in')\n  cy.get('button#edit-1').click()\n  cy.get('input#title').type('Updated title')\n  cy.get('button#submit').click()\n  cy.get('.toast').contains('Changes saved!')\n})\n\nit('validates the change', () => {\n  cy.visit('/items/1')\n  cy.get('h1').contains('Updated title')\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After migrating, when `testIsolation=true` by default, this flow would need to\nbe contained within a single test. While the above practice has always been\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Having-Tests-Rely-On-The-State-Of-Previous-Tests",
            "children": [
              {
                "type": "text",
                "value": "discouraged"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nwe know some users have historically written tests this way, often to get around\nthe `same-origin` restrictions. But with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nyou no longer need these kind of brittle hacks, as your multi-origin logic can\nall reside in a single test, like the following."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": " One big test using `cy.origin()`"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('securely edits content', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('https://example.cypress.io')\n    cy.get('input#password').type('Password123!')\n    cy.get('button#submit').click()\n  })\n\n  cy.origin('cypress-dx.com', () => {\n    cy.url().should('contain', 'cms')\n    cy.get('#current-user').contains('logged in')\n    cy.get('button#edit-1').click()\n    cy.get('input#title').type('Updated title')\n    cy.get('button#submit').click()\n    cy.get('.toast').contains('Changes saved!')\n  })\n\n  cy.visit('/items/1')\n  cy.get('h1').contains('Updated title')\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The just-released `cy.session()` command can be used to setup and cache cookies,\nlocal storage and session storage between tests to easily re-establish the\nprevious (or common) browser contexts needed in a suite. This command will run\nsetup on its initial execution and will restore the saved browser state on each\nsequential command execution. This command reduces the need for repeated\napplication logins, while users also benefit from the test isolation guardrails\nto write independent, reliable and deterministic tests from the start."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If for whatever reason you still need to persist the dom and browser context\nbetween tests, you can disable test isolation by setting `testIsolation=false`\non the root configuration or at the suite-level. For example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "describe('workflow', { testIsolation: false }, () => {\n  ...\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "It is important to note that while disabling test isolation may improve the\noverall performance of end-to-end tests, it can cause state to \"leak\" between\ntests. This can make later tests dependent on the results of earlier tests, and\npotentially cause misleading test failures. It is important to be extremely\nmindful of how tests are written when using this mode, and ensure that tests\ncontinue to run independently of one another."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": " the following tests are not independent\nnor deterministic:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "describe('workflow', { testIsolation: false }, () => {\n  it('logs in', () => {\n    cy.visit('https://example.cypress.io/log-in')\n    cy.get('username').type('User1')\n    cy.task('getSecret', 'USER1_PASSWORD').then((password) => {\n      cy.get('password').type(password)\n    })\n    cy.get('button#login').click()\n    cy.contains('User1')\n  })\n\n  it('clicks user profile', () => {\n    cy.get('User1').find('#profile_avatar').click()\n    cy.contains('Email Preferences')\n  })\n\n  it('updates profile', () => {\n    cy.get('button#edit')\n    cy.get('email').type('user1@email.com')\n    cy.get('button#save').click()\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In the above example, each test is relying on the previous test to be\nsuccessful to correctly execute. If at any point, the first or second test\nfails, the sequential test(s) will automatically fail and provide unreliable\ndebugging errors since the errors are representative of the previous test."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The best way to ensure your tests are independent is to add a `.only()` to your\ntest and verify it can run successfully without the test before it."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Simulating Pre-Test Isolation Behavior"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Test isolation did not truly exist pre-12. Pre-Cypress 12, the behavior was a\nhybrid of both `testIsolation` enabled and disabled. All local storage and\ncookies on the current domain were cleared, but Cypress did not clear session\nstorage and the page always persisted."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress 12+ when `testIsolation` is enabled, local storage, session storage\nand cookies in all domains are cleared and the page is cleared. When\n`testIsolation` is disabled, nothing is cleared before the next test so all\nlocal storage, session storage and cookies & the page persists."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you wanted to match pre-Cypress 12 behavior, you need to disable\n`testIsolation`, then run `cy.clearLocalStorage()` and `cy.clearCookies()` in a\nbeforeEach hook to clear the local storage and cookies in the current domain."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "describe('match pre-12 behavior', { testIsolation: false }, () => {\n  beforeEach(() => {\n    cy.clearLocalStorage()\n    cy.clearCookies()\n    // other beforeEach logic to restore the expected local storage or cookies needed on the client.\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Many of the issues test isolation solved were around cookie management with\ntests trying to save and persist cookies because the page was still available,\nbut the cookies on the domain were unexpectedly cleared which broke interactions\nwith the application. It wasn’t obvious Cypress was doing a partial browser\nclean up. Explicitly setting test isolation to enabled or disabled allows you to\nchoose what is right for your tests."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Behavior Changes in Alias Resolution"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress always re-queries aliases when they are referenced. This can result in\ncertain tests that used to pass could start to fail. For example,"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.findByTestId('popover')\n  .findByRole('button', { expanded: true })\n  .as('button')\n  .click()\n\ncy.get('@button').should('have.attr', 'aria-expanded', 'false')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "previously passed, because the initial button was collapsed when first queried,\nand then later expanded. However, in Cypress 12, this test fails because the\nalias is always re-queried from the DOM, effectively resulting in the following\nexecution:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.findByTestId('popover').findByRole('button', { expanded: true }).click()\n\ncy.findByTestId('popover')\n  .findByRole('button', { expanded: true }) // A button which matches here (is expanded)...\n  .should('have.attr', 'aria-expanded', 'false') // ...will never pass this assertion."
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can rewrite tests like this to be more specific; in our case, we changed the\nalias to be the first button rather than the unexpanded button."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.findByTestId('popover').findAllByRole('button').first().as('button')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you want to alias a static value, such that it is never re-queried, you will\nneed Cypress "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#12-3-0",
            "children": [
              {
                "type": "text",
                "value": "12.3.0"
              }
            ]
          },
          {
            "type": "text",
            "value": " or later, which\nintroduced the `type` option for "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/as.md",
            "children": [
              {
                "type": "text",
                "value": "`.as()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to opt into the old\nbehavior."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('.username').invoke('val').as('username', { type: 'static' })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/as.md",
            "children": [
              {
                "type": "text",
                "value": "`.as()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Command / Cypress API Changes"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Cypress.Cookies.defaults and Cypress.Cookies.preserveOnce"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `Cypress.Cookies.defaults` and `Cypress.Cookies.preserveOnce` APIs been\nremoved. Use the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/session.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.session()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command to preserve\ncookies (and local and session storage) between tests."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you were using `Cypress.Cookies.preserveOnce` to preserve a specific cookie\nwithin a single spec, this might look like the following:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "describe('Dashboard', () => {\n  beforeEach(() => {\n-    cy.login()\n-    Cypress.Cookies.preserveOnce('session_id', 'remember_token')\n+    cy.session('unique_identifier', cy.login, {\n+       validate () {\n+        cy.getCookies().should('have.length', 2)\n+       },\n+    })\n  })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you were using `Cypress.Cookies.defaults` to preserve a cookie or set of\ncookies across test, this might look like the following:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "describe('Dashboard', () => {\n  beforeEach(() => {\n-    cy.login()\n-    Cypress.Cookies.defaults({\n-       preserve: ['session_id', 'remember_token']\n-    })\n+    cy.session('unique_identifier', cy.login, {\n+       validate () {\n+        cy.getCookies().should('have.length', 2)\n+       },\n+       cacheAcrossSpecs: true\n+    })\n  })"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "cy.server(), cy.route() and Cypress.Server.defaults"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The`  cy.server() ` and`  cy.route() ` commands and the `Cypress.server.defaults`\nAPI has been removed. Use the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/intercept.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.intercept()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "\ncommand instead."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "  it('can encode + decode headers', () => {\n-   Cypress.Server.defaults({\n-     delay: 500,\n-     method: 'GET',\n-   })\n-   cy.server()\n-   cy.route(/api/, () => {\n-      return {\n-        'test': 'We’ll',\n-      }\n-    }).as('getApi')\n+   cy.intercept('GET', /api/, (req) => {\n+      req.on('response', (res) => {\n+        res.setDelay(500)\n+      })\n+      req.body.'test': 'We’ll'\n+    }).as('getApi')\n    cy.visit('/index.html')\n    cy.window().then((win) => {\n      const xhr = new win.XMLHttpRequest\n      xhr.open('GET', '/api/v1/foo/bar?a=42')\n      xhr.send()\n    })\n\n    cy.wait('@getApi')\n-   .its('url').should('include', 'api/v1')\n+   .its('request.url').should('include', 'api/v1')\n  })"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": ".invoke()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/invoke.md",
            "children": [
              {
                "type": "text",
                "value": "`.invoke()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command now throws an error if the\nfunction returns a promise. If you wish to call a method that returns a promise\nand wait for it to resolve, use "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "`.then()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " instead of\n`.invoke()`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "cy.wrap(myAPI)\n-  .invoke('makeARequest', 'http://example.com')\n+  .then(api => api.makeARequest('http://example.com'))\n   .then(res => { ...handle response... })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If `.invoke()` is followed by additional commands or assertions, it will call\nthe named function multiple times. This has the benefit that the chained\nassertions can more reliably use the function's return value."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If this behavior is undesirable because you expect the function to be invoked\nonly once, break the command chain and move the chained commands and/or\nassertions to their own chain. For example, rewrite"
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "- cy.get('input').invoke('val', 'text').type('newText')\n+ cy.get('input').invoke('val', 'text')\n+ cy.get('input').type('newText')"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": ".should()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " assertion now throws an error if Cypress\ncommands are invoked from inside a `.should()` callback. This previously\nresulted in unusual and undefined behavior. If you wish to execute a series of\ncommands on the yielded value, use`.then()` instead."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "cy.get('button')\n-  .should(($button) => {\n\n    })\n+  .then(api => api.makeARequest('http://example.com'))\n   .then(res => { ...handle response... })"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": ".within()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/within.md",
            "children": [
              {
                "type": "text",
                "value": "`.within()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command now throws an error if it is\npassed multiple elements as the subject. This previously resulted in\ninconsistent behavior, where some commands would use all passed in elements,\nsome would use only the first and ignore the rest, and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/screenshot.md",
            "children": [
              {
                "type": "text",
                "value": "`.screenshot()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " would throw an error if used inside\na `.within()` block with multiple elements."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you were relying on the old behavior, you have several options depending on\nthe desired result."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The simplest option is to reduce the subject to a single element."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "cy.get('tr')\n+  .first() // Limit the subject to a single element before calling .within()\n  .within(() => {\n    cy.contains('Edit').click()\n  })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you have multiple subjects and wish to run commands over the collection as a\nwhole, you can alias the subject rather than use `.within()`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "cy.get('tr')\n-  .within(() => {\n-    cy.get('td').should('have.class', 'foo')\n-    cy.get('td').should('have.class', 'bar')\n-  })\n+  .as('rows') // Store multiple elements as an alias\n\n+cy.get('@rows').find('td').should('have.class', 'foo')\n+cy.get('@rows').find('td').should('have.class', 'bar')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Or if you have a collection and want to run commands over every element, use\n`.each()` in conjunction with `.within()`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "diff",
        "meta": null,
        "value": "cy.get('tr')\n-  .within(() => {\n-    cy.contains('Edit').should('have.attr', 'disabled')\n-  })\n+  .each($tr => {\n+    cy.wrap($tr).within(() => {\n+      cy.contains('Edit').should('have.attr', 'disabled')\n+    })\n+  })"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Cypress.Commands.overwrite()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress 12.0.0, we introduced a new command type, called queries. A query is\na small and fast command for getting data from the window or DOM. This\ndistinction is important because Cypress can retry chains of queries, keeping\nthe yielded subject up-to-date as a page rerenders."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With the introduction of query commands, the following commands have been\nre-categorized and can no longer be overwritten with\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-commands.md#Overwrite-Existing-Commands",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.Commands.overwrite()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ":"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/as.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.as()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/children.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.children()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/closest.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.closest()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.contains()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/debug.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.debug()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/document.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.document()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/eq.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.eq()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/filter.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.filter()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/find.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.find()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/first.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.first()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/focused.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.focused()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/get.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.get()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/hash.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.hash()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/its.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.its()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/last.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.last()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/location.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.location()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/next.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.next()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/nextall.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.nextAll()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/not.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.not()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/parent.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.parent()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/parents.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.parents()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/parentsuntil.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.parentsUntil()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/prev.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.prev()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/prevuntil.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.prevUntil()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/root.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.root()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/shadow.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.shadow()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/siblings.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.siblings()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/title.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.title()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/url.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.url()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/window.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.window()`"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you were previously overwriting one of the above commands, try adding your\nversion as a new command using\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-commands.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.Commands.add()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " under a different\nname."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 11.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the changes and how to change your code to migrate to Cypress\nversion 11.0.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#11-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version 11.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Component Testing Updates"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As of Cypress 11, Component Testing is now generally available. There are some\nminor breaking changes. Most projects should be able to migrate without any code\nmodifications."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Changes to Mounting Options"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each major library we support has a `mount` function with two arguments:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The component"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Mounting Options"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Mounting options previously had several properties that are now removed:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cssFile, cssFiles"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "style, styles"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "stylesheet, stylesheets"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Read more about the rationale\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nWe recommend writing test-specific styles in a separate `css` file you import in\nyour test, or in your `supportFile`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Before (Cypress 10)"
          }
        ]
      },
      {
        "type": "code",
        "lang": "jsx",
        "meta": null,
        "value": "import { mount } from 'cypress/react'\nimport { Card } from './Card'\n\nit('renders some content', () => {\n  cy.mount(<Card title=\"title\" />, {\n    styles: `\n      .card { width: 100px; }\n    `,\n    stylesheets: [\n      'https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css',\n    ],\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "After (Cypress 11)"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "/** style.css */\n@import \"https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css\";\n.card { width: 100px }\n\n/** Card.cy.jsx */\nimport { mount } from 'cypress/react'\nimport { Card } from './Card'\nimport './styles.css' // contains CDN link and custom styling.\n\nit('renders some content', () => {\n  cy.mount(<Card title=\"title\" />)\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "React - mountHook Removed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`mountHook` from `cypress/react` has been removed. Read more about the rationale\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We recommend simply replacing it with `mount` and a component."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Consider the following `useCounter` hook:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { useState, useCallback } from 'react'\n\nfunction useCounter() {\n  const [count, setCount] = useState(0)\n  const increment = useCallback(() => setCount((x) => x + 1), [])\n\n  return { count, increment }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Before - Cypress 10 and mountHook"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { mountHook } from 'cypress/react'\nimport { useCounter } from './useCounter'\n\nit('increments the count', () => {\n  mountHook(() => useCounter()).then((result) => {\n    expect(result.current.count).to.equal(0)\n    result.current.increment()\n    expect(result.current.count).to.equal(1)\n    result.current.increment()\n    expect(result.current.count).to.equal(2)\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "After - Cypress 11 and mount"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { useCounter } from './useCounter'\n\nit('increments the count', () => {\n  function Counter() {\n    const { count, increment } = useCounter()\n    return (\n      <>\n        <h1 name=\"count\">Count is {{ count }}</h1>\n        <button onClick={increment}>Increment</button>\n      </>\n    )\n  }\n\n  cy.mount(<Counter />).then(() => {\n    cy.get('[name=\"count\"]')\n      .should('contain', 0)\n      .get('button')\n      .click()\n      .get('[name=\"count\"]')\n      .should('contain', 1)\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "React - unmount Removed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`unmount` from `cypress/react` has been removed. Read more about the rationale\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nWe recommend using the API React provides for unmounting components,\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://reactjs.org/docs/react-dom.html#unmountcomponentatnode",
            "children": [
              {
                "type": "text",
                "value": "unmountComponentAtNode"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Before - Cypress 10 and unmount"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { unmount } from 'cypress/react'\n\nit('calls the prop', () => {\n  cy.mount(<Comp onUnmount={cy.stub().as('onUnmount')} />)\n  cy.contains('My component')\n\n  unmount()\n\n  // the component is gone from the DOM\n  cy.contains('My component').should('not.exist')\n  cy.get('@onUnmount').should('have.been.calledOnce')\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "After - Cypress 11 and unmountComponentAtNode"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { getContainerEl } from 'cypress/react'\nimport ReactDom from 'react-dom'\n\nit('calls the prop', () => {\n  cy.mount(<Comp onUnmount={cy.stub().as('onUnmount')} />)\n  cy.contains('My component')\n\n  cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl()))\n\n  // the component is gone from the DOM\n  cy.contains('My component').should('not.exist')\n  cy.get('@onUnmount').should('have.been.calledOnce')\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Vue - mountCallback Removed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`mountCallback` from `cypress/vue` has been removed. Read more about the\nrationale\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nWe recommend using `mount`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Before - Cypress 10 and mountCallback"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { mountCallback } from 'cypress/vue'\n\nbeforeEach(mountCallback(MessageList))\n\nit('shows no messages', () => {\n  getItems().should('not.exist')\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "After - Cypress 11 and mount"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "beforeEach(() => cy.mount(MessageList))\n\nit('shows no messages', () => {\n  getItems().should('not.exist')\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Angular - Providers Mounting Options Change"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "There is one breaking change for Angular users in regards to providers. In\nCypress 10, we took any providers passed as part of the Mounting Options and\noverrode the component providers via the `TestBed.overrideComponent` API."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress 11, providers passed as part of the Mounting Options will be assigned\nat the module level using the `TestBed.configureTestingModule` API."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This means that module-level providers (resolved from imports or\n`@Injectable({ providedIn: 'root' })` can be overridden, but providers specified\nin `@Component({ providers: [...] })` will not be overridden when using\n`cy.mount(MyComponent, { providers: [...] })`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To override component-level providers, use the `TestBed.overrideComponent` API."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See a concrete example\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.cypress.io/blog/2022/11/04/upcoming-changes-to-component-testing/#angularproviders-priority",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Vite Dev Server (cypress/vite-dev-server)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When providing an inline `viteConfig` inside of `cypress.config`, any\n`vite.config.js` file is not automatically merged."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Before - Cypress 10 and viteConfig"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  component: {\n    devServer: {\n      framework: 'react',\n      bundler: 'vite',\n      viteConfig: {\n        // ... custom vite config ...\n        // result merged with `vite.config` file if present\n      },\n    },\n  },\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "After - Cypress 11 and viteConfig"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\nimport viteConfig from './vite.config'\n\nexport default defineConfig({\n  component: {\n    devServer: {\n      framework: 'react',\n      bundler: 'vite',\n      viteConfig: {\n        ...viteConfig,\n        // ... other overrides ...\n      },\n    },\n  },\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Vite 3+ users could make use of the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://vitejs.dev/guide/api-javascript.html#mergeconfig",
            "children": [
              {
                "type": "text",
                "value": "`mergeConfig`"
              }
            ]
          },
          {
            "type": "text",
            "value": " API."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Migrating to Cypress 10.0"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide details the changes and how to change your code to migrate to Cypress\nversion 10.0.\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#10-0-0",
            "children": [
              {
                "type": "text",
                "value": "See the full changelog for version 10.0"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cypress Changes"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The \"Run all specs\" and \"Run filtered specs\" functionality have been removed."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The experimental \"Cypress Studio\" has been removed and will be\nrethought/revisited in a later release."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Unsupported browser versions can no longer be run via `cypress run` or\n`cypress open`. Instead, an error will display."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "In 9.x and earlier versions, `cypress open` would bring you directly to the\nproject specs list. In 10.0.0, you must pass `--browser` and `--e2e` or\n`--component` as well to launch Cypress directly to the specs list."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Configuration File Changes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress now supports JavaScript and TypeScript configuration files. By default,\nCypress will automatically load a `cypress.config.js` or `cypress.config.ts`\nfile in the project root if one exists. The\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md",
            "children": [
              {
                "type": "text",
                "value": "Configuration guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " has been updated to\nreflect these changes, and explains them in greater detail."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because of this, support for `cypress.json` has been removed since Cypress `v10`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Related notes:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "If no config file exists when you open Cypress, the automatic set up process\nwill begin and either a JavaScript or TypeScript config file will be created\ndepending on what your project uses."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You may use the `--config-file` command line flag or the `configFile`\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/module-api.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "module API"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " option to specify a `.js` or `.ts`\nfile. JSON config files are no longer supported."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Cypress now requires a config file, so specifying `--config-file false` on the\ncommand line or a `configFile` value of `false` in the module API is no longer\nvalid."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You can't have both `cypress.config.js` and `cypress.config.ts` files. This\nwill result in an error when Cypress loads."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#Intelligent-Code-Completion",
                    "children": [
                      {
                        "type": "text",
                        "value": "`defineConfig()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "\nhelper function is now exported by Cypress, which provides automatic code\ncompletion for configuration in many popular code editors. For TypeScript\nusers, the `defineConfig` function will ensure the configuration object passed\ninto it satisfies the type definition of the configuration file."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Many pages and examples throughout the documentation have been updated to show\nconfiguration using `cypress.config.js` and `cypress.config.ts` vs the older\n`cypress.json`. For example:"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  e2e: {\n    baseUrl: 'http://localhost:1234',\n  },\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Plugins File Removed"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because Cypress now supports JavaScript and TypeScript configuration files, a\nseparate \"plugins file\" (which used to default to `cypress/plugins/index.js`) is\nno longer needed."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Support for the plugins file has been removed, and it has been replaced with the\nnew "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#setupNodeEvents",
            "children": [
              {
                "type": "text",
                "value": "`setupNodeEvents()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#devServer",
            "children": [
              {
                "type": "text",
                "value": "`devServer`"
              }
            ]
          },
          {
            "type": "text",
            "value": " config options."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Related notes:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The `cypress/plugins/index.js` plugins file is no longer automatically loaded\nby Cypress."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#setupNodeEvents",
                    "children": [
                      {
                        "type": "text",
                        "value": "`setupNodeEvents()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "\nconfig option is functionally equivalent to the function exported from the\nplugins file; it takes the same `on` and `config` arguments, and should return\nthe same value. See the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#setupNodeEvents",
                    "children": [
                      {
                        "type": "text",
                        "value": "Config option changes section"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " of\nthis migration guide for more details."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#devServer",
                    "children": [
                      {
                        "type": "text",
                        "value": "`devServer`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " config option is\nspecific to component testing, and offers a much more streamlined and\nconsistent way to configure a component testing dev server than using the\nplugins file. See the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#devServer",
                    "children": [
                      {
                        "type": "text",
                        "value": "Config option changes section"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " of this\nmigration guide for more details."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Many pages and examples throughout the documentation have been updated to show\nconfiguration in `setupNodeEvents` as well as the legacy plugins file. For\nexample:"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "// bind to the event we care about\non('<event>', (arg1, arg2) => {\n  // plugin stuff here\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Config Option Changes"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "baseUrl"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `baseUrl` config option is no longer valid at the top level of the\nconfiguration, and may only be defined inside the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#e2e",
            "children": [
              {
                "type": "text",
                "value": "`e2e`"
              }
            ]
          },
          {
            "type": "text",
            "value": " configuration object."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `baseUrl` config option at the top level of the\nconfiguration will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "componentFolder"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `componentFolder` config option is no longer used, as it has been replaced\nby the `specPattern`\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "testing-type specific option"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `componentFolder` config option will result in an error\nwhen Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "devServer"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All functionality related to starting a component testing dev server previously\nin the `pluginsFile` has moved here. These options are not valid at the\ntop-level, and may only be defined in the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#component",
            "children": [
              {
                "type": "text",
                "value": "`component`"
              }
            ]
          },
          {
            "type": "text",
            "value": " configuration object."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Related notes:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Do not configure your dev server inside `setupNodeEvents()`, use the\n`devServer` config option instead."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "See the dev server documentation for the UI framework you're using for more\nspecific instructions on what the `devServer` should be for that framework. Some\nexamples can be found in our\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/component-framework-configuration.md",
            "children": [
              {
                "type": "text",
                "value": "framework documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Variant 1 (webpack & vite dev servers)"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": "title=\"cypress/plugins/index.js\"",
        "value": "const { startDevServer } = require('@cypress/webpack-dev-server')\nconst webpackConfig = require('../../webpack.config.js')\n\nmodule.exports = (on, config) => {\n  if (config.testingType === 'component') {\n    on('dev-server:start', async (options) =>\n      startDevServer({ options, webpackConfig })\n    )\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Variant 2 (react plugin dev servers)"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "const devServer = require('@cypress/react/plugins/react-scripts')\n\nmodule.exports = (on, config) => {\n  if (config.testingType === 'component') {\n    injectDevServer(on, config, {})\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "experimentalStudio"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This option is no longer used. The experimental \"Cypress Studio\" has been\nremoved and will be rethought/revisited in a later release."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `experimentalStudio` config option will result in an error\nwhen Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "ignoreTestFiles → excludeSpecPattern"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `ignoreTestFiles` option is no longer used, and has been replaced with the\n`excludeSpecPattern`\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "testing-type specific option"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Default values"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e.excludeSpecPattern` default value is `*.hot-update.js` (same as pervious\nignore value)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`component.excludeSpecPattern` default value is\n`['/snapshots/*', '/image_snapshots/*']` updated from `*.hot-update.js`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The `**/node_modules/**` pattern is automatically added to both\n`e2e.specExcludePattern` and `component.specExcludePattern`, and does not need\nto be specified (and can't be overridden)."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  \"ignoreTestFiles\": \"path/to/**/*.js\"\n}"
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  component: {\n    excludeSpecPattern: \"path/to/**/*.js\"\n  },\n  e2e: {\n    excludeSpecPattern: \"other/path/to/**/*.js\"\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `ignoreTestFiles` config option will result in an error\nwhen Cypress loads."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Also, attempting to set the `excludeSpecPattern` config option at the top level\nof the configuration will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "integrationFolder"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This option is no longer used, as it has been replaced by the `specPattern`\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "testing-type specific option"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `integrationFolder` config option will result in an error\nwhen Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "pluginsFile"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This option is no longer used, and all plugin file functionality has moved into\nthe "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#setupNodeEvents",
            "children": [
              {
                "type": "text",
                "value": "`setupNodeEvents()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#devServer",
            "children": [
              {
                "type": "text",
                "value": "`devServer`"
              }
            ]
          },
          {
            "type": "text",
            "value": " options. See the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "#Plugins-File-Removed",
            "children": [
              {
                "type": "text",
                "value": "Plugins file removed"
              }
            ]
          },
          {
            "type": "text",
            "value": " section of this migration guide\nfor more details."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `pluginsFile` config option will result in an error when\nCypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "setupNodeEvents()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All functionality related to setting up events or modifying the config,\npreviously done in the plugins file, has moved into the `setupNodeEvents()`\nconfig options. This option is not valid at the top level of the config, and may\nonly be defined inside the `component` or `e2e`\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "configuration objects"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "More information can be found in the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/node-events/overview.md",
            "children": [
              {
                "type": "text",
                "value": "Node Events Overview"
              }
            ]
          },
          {
            "type": "text",
            "value": " and the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/node-events/configuration-api.md#Usage",
            "children": [
              {
                "type": "text",
                "value": "Configuration API documentation"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": " `cypress/plugins/index.js`"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "module.exports = (on, config) => {\n  if (config.testingType === 'component') {\n    // component testing dev server setup code\n    // component testing node events setup code\n  } else {\n    // e2e testing node events setup code\n  }\n}"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  component: {\n    devServer(cypressConfig) {\n      // component testing dev server setup code\n    },\n    setupNodeEvents(on, config) {\n      // component testing node events setup code\n    },\n  },\n  e2e: {\n    setupNodeEvents(on, config) {\n      // e2e testing node events setup code\n    },\n  },\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Alternately, you can continue to use an external plugins file, but you will need\nto load that file explicitly, and also update it to move any component testing\ndev server code into the "
          },
          {
            "type": "link",
            "title": null,
            "url": "#devServer",
            "children": [
              {
                "type": "text",
                "value": "`devServer`"
              }
            ]
          },
          {
            "type": "text",
            "value": " config option."
          }
        ]
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "import setupNodeEvents from './cypress/plugins/index.js'"
      },
      {
        "type": "code",
        "lang": "ts",
        "meta": null,
        "value": "{\n  component: {\n    devServer(cypressConfig) {\n      // component testing dev server setup code\n    },\n    setupNodeEvents,\n  },\n  e2e: {\n    setupNodeEvents,\n  },\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "slowTestThreshold"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `slowTestThreshold` configuration option is no longer valid at the top level\nof the configuration, and is now a\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "testing-type specific option"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that the default values are unchanged (`10000` for `e2e` and `250` for\n`component`)."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `slowTestThreshold` config option at the top level of the\nconfiguration will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "supportFile"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `supportFile` configuration option is no longer valid at the top level of\nthe configuration, and is now a\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Testing-Type-Specific-Options",
            "children": [
              {
                "type": "text",
                "value": "testing-type specific option"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nMore information can be found in the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Support-file",
            "children": [
              {
                "type": "text",
                "value": "support file docs"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  \"supportFile\": \"cypress/support/index.js\"\n}"
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  component: {\n    supportFile: 'cypress/support/component.js'\n  },\n  e2e: {\n    supportFile: 'cypress/support/e2e.js'\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `supportFile` config option at the top level of the\nconfiguration will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Also, for a given testing type, multiple matching `supportFile` files will\nresult in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "testFiles → specPattern"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `testFiles` option is no longer used, and has been replaced with the\n`specPattern` option, which must be defined inside the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#component",
            "children": [
              {
                "type": "text",
                "value": "`component`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#e2e",
            "children": [
              {
                "type": "text",
                "value": "`e2e`"
              }
            ]
          },
          {
            "type": "text",
            "value": " configuration objects."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Default values:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "No longer matches with `.coffee` or `.cjsx`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`e2e.specPattern` default value is `cypress/e2e/**/*.cy.{js,jsx,ts,tsx}`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`component.specPattern` default value is `**/*.cy.{js,jsx,ts,tsx}`."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Important note about matching:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "E2E tests will be found using the `e2e.specPattern` value."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Component tests will be found using the `component.specPattern` value but any\ntests found matching the `e2e.specPattern` value will be automatically\nexcluded."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set the `testFiles` config option will result in an error when\nCypress loads."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Also, attempting to set the `specPattern` config option at the top level of the\nconfiguration will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Updated Test File Locations"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Previously, you could specify the locations of test files and folders using the\nconfiguration options: `componentFolder`, or `integrationFolder`, and\n`testFiles`. These options have been replaced with `specPattern`, which is not\nvalid at the top-level, but within the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#component",
            "children": [
              {
                "type": "text",
                "value": "`component`"
              }
            ]
          },
          {
            "type": "text",
            "value": " or\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#e2e",
            "children": [
              {
                "type": "text",
                "value": "`e2e`"
              }
            ]
          },
          {
            "type": "text",
            "value": " configuration objects. For\nexample:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  \"componentFolder\": \"src\",\n  \"integrationFolder\": \"cypress/integration\",\n  \"testFiles\": \"**/*.cy.js\"\n}"
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "{\n  component: {\n    specPattern: 'src/**/*.cy.js'\n  },\n  e2e: {\n    specPattern: 'cypress/integration/**/*.cy.js'\n  }\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Attempting to set `componentFolder`, `integrationFolder`, or `testFiles` in the\nconfig will result in an error when Cypress loads."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For Cypress Cloud users, changing your `specPattern` and files names or\nextensions of your spec files will result in a loss of data in Cypress Cloud.\nBecause of this, if we detect your project is using Cypress Cloud during\nautomatic migration, we won't suggest changing your spec files. We also don't\nrecommend doing it manually if you are a Cypress Cloud user."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Generated Files"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Generated screenshots and videos will still be created inside their respective\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Folders--Files",
            "children": [
              {
                "type": "text",
                "value": "folders"
              }
            ]
          },
          {
            "type": "text",
            "value": " (`screenshotsFolder`,\n`videosFolder`). However, the paths of generated files inside those folders will\nbe stripped of any common ancestor paths shared between all spec files found by\nthe `specPattern` option (or via the `--spec` command line option or `spec`\nmodule API option, if specified)."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Here are a few examples, assuming the value of `videosFolder` is\n`cypress/videos`, `screenshotsFolder` is `cypress/screenshots` and\n`cy.screenshot('my-screenshot')` is called once per spec file:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Example 1"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Spec file found"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/e2e/path/to/file/one.cy.js`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Common ancestor paths (calculated at runtime)"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/e2e/path/to/file`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Generated screenshot file"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/screenshots/one.cy.js/my-screenshot.png`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Generated video file"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/videos/one.cy.js.mp4`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Example 2"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Spec files found"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/e2e/path/to/file/one.cy.js`"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/e2e/path/to/two.cy.js`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Common ancestor paths (calculated at runtime)"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/e2e/path/to`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Generated screenshot files"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/screenshots/file/one.cy.js/my-screenshot.png`"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/screenshots/two.cy.js/my-screenshot.png`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Generated video files"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/videos/file/one.cy.js.mp4`"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "`cypress/videos/two.cy.js.mp4`"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Command / Cypress API Changes"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "cy.mount()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you set up your app using the automatic configuration wizard, a basic\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/mount.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.mount()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command will be imported for you in your\nsupport file from one our supported frameworks."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Cypress.Commands.add()"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-commands.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.Commands.add()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " has been updated to\nallow the built-in \"placeholder\" custom `mount` and `hover` commands to be\noverwritten without needing to use `Cypress.Commands.overwrite()`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Component Testing Changes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Component Testing has moved from experimental to beta status in 10.0.0."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Component Testing can now be ran from the main app, and launching into component\ntesting via the command `cypress open-ct` is now deprecated. To launch directly\ninto component testing, use the `cypress open --component` command instead."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All the Component Testing dev servers are now included in the main `cypress` npm\npackage. Configuring them is done via specifying a framework and bundler in the\n`devServer` config option, and the packages are no longer directly importable.\nSee\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/component-framework-configuration.md",
            "children": [
              {
                "type": "text",
                "value": "Framework Configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nfor more info."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The mount libraries for React and Vue have also been included in the main\n`cypress` package and can be imported from `cypress/react` and `cypress/vue`\nrespectively."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Any previous dev servers or mounting libraries from the `@cypress` namespace\nshould be uninstalled in Cypress 10."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Clashing Types with Jest"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You may want to consider configuring your app with a separate `tsconfig.json` to solve\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/tooling/typescript-support.md#Clashing-types-with-Jest",
            "children": [
              {
                "type": "text",
                "value": "clashing types with jest"
              }
            ]
          },
          {
            "type": "text",
            "value": ".\nYou will need to exclude `cypress.config.ts`, `cypress`, `node_modules` in your\nroot `tsconfig.json` file."
          }
        ]
      },
      {
        "type": "code",
        "lang": "json",
        "meta": null,
        "value": "{\n  \"exclude\": [\"cypress.config.ts\", \"cypress\", \"node_modules\"]\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Code Coverage Plugin"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/code-coverage#readme",
            "children": [
              {
                "type": "text",
                "value": "Cypress Code Coverage"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nplugin will need to be updated to version >= 3.10 to work with Cypress 10. Using\na previous version will result in an error when tests are ran with code coverage\nenabled."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "--"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For earlier migration guides, see the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress-documentation/blob/main/docs/app/references/migration-guide.mdx",
            "children": [
              {
                "type": "text",
                "value": "documentation's repo history for this file"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      }
    ]
  },
  "token_estimate": 12517
}