OpenSource-Hub

cypress

프레임워크

cypress-io/cypress

빠르고, 간단하고, 신뢰할 수 있는 브라우저 측 테스트 도구.

개요

Cypress는 모던 웹을 위해 구축된 프런트엔드 테스트 도구로, 엔드투엔드, 컴포넌트 및 통합 테스트를 지원합니다. 실시간 리로드, 타임 트래블 디버깅, 자동 대기 기능을 제공하여 테스트 프로세스를 간소화하고 신뢰할 수 있는 결과를 생성합니다.

README 미리보기

\n  \n    \n      \n      \n      \n    \n  \n\n\n  Documentation |\n  Changelog |\n  Roadmap\n\n\n\n  The web has evolved. Finally, testing has too.\n\n\n\n  Fast, easy and reliable testing for anything that runs in a browser.\n\n\n  Join us, we're hiring.\n\n\n\n  \n    \n  \n  \n    \n  \n    \n    \n  \n\n\n## What is Cypress?\n\n\n  \n    \n  \n\n\n## Installing\n\n[](https://badge.fury.io/js/cypress)\n\nInstall Cypress for Mac, Linux, or Windows, then [get started](https://on.cypress.io/install).\n\n```bash\nnpm install cypress --save-dev\n```\nor\n```bash\nyarn add cypress --dev\n```\nor\n```bash\npnpm add cypress --save-dev\n```\n\n\n\n## Contributing\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n[](https://circleci.com/gh/cypress-io/cypress/tree/develop) -  `develop` branch\n\nPlease see our [Contributing Guideline](./CONTRIBUTING.md) which explains repo organization, linting, testing, and other steps.\n\n## License\n\n[](https://github.com/cypress-io/cypress/blob/develop/LICENSE)\n\nThis project is licensed under the terms of the [MIT license](/LICENSE).\n\n## Badges\n\nConfigure a badge for your project's README to show your test status or test count in the [Cypress Cloud](https://www.cypress.io/cloud).\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n\n[](https://cloud.cypress.io/projects/ypt4pf/runs)\n\nOr let the world know your project is using Cypress with the badge below.\n\n[](https://www.cypress.io/)\n\n```\n[](https://www.cypress.io/)\n```\n

FAQ (5)

문제 해결
Cypress 16의 clientCertificates로 인해 open 모드에서 Chrome 인증서 선택 창이 표시되거나 run 모드에서 멈추는 문제를 해결하는 방법은?

Cypress 16에서 Chrome은 기본적으로 네이티브 HTTP/2 네트워크 경로를 사용하며, 이 경로는 mTLS에 대해 clientCertificates를 제공하지 않습니다. cypress.config.ts에서 forceHttp1: true를 설정하여 레거시 HTTP/1 네트워크 스택을 강제로 사용하세요:

import { defineConfig } from 'cypress'

export default defineConfig({
  forceHttp1: true,
  clientCertificates: [
    {\n      url: 'https://test.com',
      ca: [],
      certs: [
        {\n          cert: 'certs/client.crt',
          key: 'certs/client.key',
        },
      ],
    },
  ],
})

또는 CLI 플래그를 사용하여 Cypress를 실행하세요:

cypress run --browser chrome --force-http1

Firefox 및 기타 Chromium이 아닌 브라우저는 계속 레거시 네트워크 스택을 사용합니다. 이 해결 방법을 사용할 수 없는 경우 Cypress 15.21.1로 다운그레이드하세요. 브라우저 네트워크 경로에서 클라이언트 인증서를 제공하는 Cypress PR에서 영구적인 수정 사항이 추적되고 있습니다.

원본 Issue #34807
문제 해결
Chrome에서 302 리다이렉트가 발생하는 fetch POST에 대해 Cypress 16 cy.wait()가 undefined 응답을 반환하는 문제를 해결하는 방법은?

이것은 서버가 302를 반환할 때 redirect: 'follow'로 수행되는 동일 출처(same-origin) fetch() POST 요청에 영향을 미치는 Cypress 16.1.0 네이티브 네트워크/CDP Fetch 버그입니다. 인터셉션은 응답 단계에서 Fetch.requestPaused를 기다리지만 이를 수신하지 못하고, 30초 후 Timed out waiting for CDP Fetch response pause 오류와 함께 실패합니다. 브라우저가 리디렉션을 성공적으로 따라가더라도 interception.response는 undefined입니다.

해결 방법: cypress.config.js에서 forceHttp1을 활성화하여 Cypress 15에서 사용하던 레거시 프록시 경로를 사용하세요:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  forceHttp1: true,
})

ESM 설정의 경우:

import { defineConfig } from 'cypress'

export default defineConfig({
  forceHttp1: true,
})

설정을 변경한 후 Cypress를 재시작하세요. 이 옵션을 활성화하면 cy.wait('@alias')가 30초 지연 없이 해결되며, 예상대로 POST 홉의 302 상태 코드와 Location 헤더를 반환합니다. 일반 GET 요청은 영향을 받지 않으며, 이 문제는 Cypress 16의 Chrome 네이티브 네트워크 경로에서 리디렉션되는 fetch POST 요청에 국한됩니다.

원본 Issue #34905
문제 해결
`cy.request()`가 세션 쿠키를 갱신한 후 Cypress가 오래된 쿠키를 전송하는 문제를 해결하는 방법

이는 Cypress 15.20.0+의 리그레션입니다: cy.request()가 브라우저 쿠키는 업데이트하지만 Cypress의 서버 측 cookie jar는 업데이트하지 않아, 다음 AUT 프레임 문서 탐색 시 이전의 오래된(stale) 쿠키가 전송됩니다. XHR/fetch 요청은 영향을 받지 않습니다.

임시 해결 방법: 로그인 요청을 cy.session()으로 감싸면 cookie jar가 초기화/재설정됩니다:

beforeEach(() => {
  cy.session('login', () => {
    cy.request('POST', '/login')
  })

  cy.visit('/account')
})

또는 Cypress 15.19.x로 다운그레이드하세요. 근본적인 해결 방법은 "fix: keep the cookie jar in sync when cookies are set outside the proxy." PR이 포함된 릴리스로 업그레이드하는 것입니다.

원본 Issue #34891
문제 해결
cy.server() 사용 시 CypressError: sinon.js was not found in the remote iframe's window 오류를 해결하는 방법

이 문제는 Cypress가 현재 페이지를 cy.visit()으로 직접 로드하지 않았을 때 발생하며, 보통 일반 링크를 클릭한 후에 나타납니다. XHR을 스터빙하기 전에 Cypress로 대상 URL을 로드하세요:

cy.visit('/your-page')
cy.server().route('POST', /users\.json/, {})

POST가 페이지 로드 중에 발생하는 경우, 방문하기 전에 라우트를 정의하세요:

cy.server()
cy.route('POST', /users\.json/, {})
cy.visit('/your-page')

이전 테스트에서 일반 <a> 링크를 클릭하여 수행된 탐색에 의존하지 마세요. cy.server()를 사용하기 전에 cy.visit(targetUrl)을 직접 호출하거나 Cypress를 통해 페이지를 다시 로드하세요. 크로스 오리진 페이지는 이 방법으로 스터빙할 수 없습니다.

최신 Cypress에서는 cy.server()/cy.route()를 다음과 같이 대체하세요:

cy.intercept('POST', '**/users.json', {})
cy.visit('/your-page')

원본 Issue #12
문제 해결
Cypress에서 .within() 내부에서 cy.contains()를 사용할 때 발생하는 "TypeError: Cannot read properties of undefined (reading 'selector')" 오류를 해결하는 방법

이것은 Cypress 버그입니다(15.18.1에서 재현됨): .within() 내부에서는 재시도할 때마다 subject가 다시 쿼리되는데, cy.contains()의 첫 번째 시도에서 빈 집합으로 resolve되면 getOptions.withinSubject가 undefined 상태로 남습니다. 그러면 에러 메시지 빌더 getPhrase()가 undefined의 el.selector에서 크래시하고, 이 에러가 재시도를 중단시킵니다. 따라서 테스트는 defaultCommandTimeout을 기다리는 대신 몇 밀리초 만에 실패합니다(일반적인 트리거: refetch/로딩 상태 동안 잠시 언마운트되는 목록). 우회 방법: .within() 내부의 cy.get()은 올바르게 재시도하므로, cy.contains()를 cy.get()과 텍스트 단언으로 대체하세요:

// 불안정함 — 재시도하는 대신 TypeError를 던짐
cy.get('#group').within(() => {
  cy.contains('new');
});

// 안정적 — subject가 다시 마운트되어 텍스트를 포함할 때까지 재시도함
cy.get('#group').within(() => {
  cy.get('p').should('contain.text', 'new');
});

또는, 첫 번째 시도에서 subject가 존재하도록 contains를 가드할 수도 있습니다:
cy.get('#group').within(() => {
  cy.get('p').should('exist'); // 로딩 상태가 끝날 때까지 기다림
  cy.contains('new');
});

영구적인 해결책: 패치가 적용되면 Cypress를 업그레이드하세요. 제안된 수정 사항은 withinSubject가 undefined일 때 getPhrase가 selector(또는 일반적인 문구)로 폴백하도록 만들어, cy.contains()가 cy.get()처럼 계속 재시도하게 합니다.

원본 Issue #34994