개요
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에서 영구적인 수정 사항이 추적되고 있습니다.
문제 해결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 요청에 국한됩니다.
문제 해결`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이 포함된 릴리스로 업그레이드하는 것입니다.
문제 해결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')문제 해결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()처럼 계속 재시도하게 합니다.