Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
[FE] test: cypress를 이용한 e2e 테스트, CI 추가 (#261)
Browse files Browse the repository at this point in the history
* chore: `cypress` 설치 및 설정파일 추가

* fix: cypress sourceMap 에러로 인해 `tsconfig` 설정에서 sourceMap 제거

* chore: `eslint-plugin-cypress` 설치

* test: `cypress` config `baseUrl` 옵션 추가

* test: `@testing-library/cypress` 설치 및 환경설정

* test: 글 가져오기 모달 창 열기 테스트 추가

* feat: 카테고리 추가 input에 `aria-label` 추가

* test: 카테고리 추가 테스트 추가

* chore: `cypress-real-events` 설치

실제 마우스 호버링 동작 재현을 위해 설치
호버링 말고도 많은 동작을 재현할 수 있음

* feat: 카테고리 이름 수정 입력 input `aria-label` 추가

* test: 카테고리 이름 수정 테스트 추가

* test: 카테고리 삭제 테스트 추가

* chore: 파일 업로드 테스트를 위한 `cypress-file-upload` 라이브러리 설치

* feat: 파일업로드 모달에 있는 파일 업로드 존 `aria-label` 추가

* test: 드래그 앤 드롭으로 마크다운 파일을 업로드하는 기능 테스트 추가

* test: 기본 카테고리에서 업로드한 글을 확인하는 테스트 추가

* refactor: test 성격에 맞게 describle 나누기

* test: cypress test CI 스크립트 추가

* refactor: conflict 해결

* chore: cypress test CI 스크립트 문법 수정

* chore: default run working-directory 수정

${{ vars.FE_DIRECTORY }} 인식 안되는 문제..

* chore: actions 개행 수정

* chore: e2e test CI `paths` 추가

* Update fe-test-e2e.yml

if: contains(github.event.pull_request.labels.*.name, 'frontend') 제거

* Update fe-test-e2e.yml

* chore: 서버 시작 후 테스트 하는 스크립트 추가

* chore: cypress 테스트 비디오 gitignore에 추가

* refactor: aria-label `파일 업로드 존` -> `파일 업로드`
  • Loading branch information
yogjin authored and HubCreator committed Aug 14, 2023
1 parent d6b45f4 commit 9fe901d
Show file tree
Hide file tree
Showing 15 changed files with 944 additions and 30 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/fe-test-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Cypress Tests

on:
pull_request:
branches:
- develop
paths:
- frontend/**
- .github/**

defaults:
run:
working-directory: ./frontend

jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Create .env.development file
run: |
touch .env.development
echo "BASE_URL=${{secrets.BASE_URL_DEVELOPMENT}}" >> .env.development
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: yarn start
wait-on: 'http://localhost:3000'
browser: chrome
working-directory: ./frontend
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions frontend/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"plugin:import/typescript",
"plugin:storybook/recommended",
"plugin:@typescript-eslint/parser",
"plugin:cypress/recommended",
"prettier"
],
"rules": {
Expand Down
4 changes: 3 additions & 1 deletion frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules/
dist/
yarn-error.log
.env.*
.env.*

cypress/videos
10 changes: 10 additions & 0 deletions frontend/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'cypress';

export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
54 changes: 54 additions & 0 deletions frontend/cypress/e2e/main-page.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
describe('동글 메인 페이지', () => {
beforeEach(() => {
cy.viewport(1440, 810);
cy.visit(`/`);
});

describe('글 업로드 테스트', () => {
it('Add Post 버튼을 누르면 글 가져오기 모달 창이 열린다.', () => {
cy.findByText('Add Post').click();

cy.findByText('글 가져오기').should('exist');
});

it('드래그 앤 드롭으로 마크다운 파일을 업로드할 수 있다.', () => {
cy.findByText('Add Post').click();
cy.findByLabelText('파일 업로드').attachFile('markdown-test.md', {
subjectType: 'drag-n-drop',
});

cy.findByText('markdown-test').should('exist');
cy.findByText('e2e 테스트를 위한 마크다운 파일입니다.').should('exist');
cy.findByText('글 정보').should('exist');
cy.findByLabelText('오른쪽 사이드바 토글').should('exist');
});

it('기본 카테고리에서 업로드한 글을 확인할 수 있다.', () => {
cy.findByText('기본').click();

cy.findAllByText('markdown-test').should('exist');
});
});

describe('카테고리 테스트', () => {
it('카테고리 추가 버튼을 클릭하여 입력 창에 이름을 입력하고 엔터를 쳐서 카테고리를 추가할 수 있다.', () => {
cy.findByLabelText('카테고리 추가 입력 창 열기').click();
cy.findByLabelText('카테고리 추가 입력 창').focus().type('동글이{enter}');
cy.findByText('동글이').should('exist');
});

it('카테고리 이름 수정 버튼을 클릭하여 입력 창에 이름을 입력하고 엔터를 쳐서 카테고리 이름을 수정할 수 있다.', () => {
cy.findByText('동글이').realHover();
cy.findByLabelText('동글이 카테고리 이름 수정').click();
cy.findByLabelText('동글이 카테고리 이름 수정 입력 창').focus().type('동글동글이{enter}');
cy.findByText('동글이').should('not.exist');
cy.findByText('동글동글이').should('exist');
});

it('카테고리 삭제 버튼을 클릭하여 카테고리를 삭제할 수 있다.', () => {
cy.findByText('동글동글이').realHover();
cy.findByLabelText('동글동글이 카테고리 삭제').click();
cy.findByText('동글동글이').should('not.exist');
});
});
});
5 changes: 5 additions & 0 deletions frontend/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
8 changes: 8 additions & 0 deletions frontend/cypress/fixtures/markdown-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## e2e 테스트를 위한 마크다운 파일입니다.

- 쿠마쿠마쿠마
- Kuma

```javascript
const name = 'kuma';
```
41 changes: 41 additions & 0 deletions frontend/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// <reference types="cypress" />
/// <reference types="@testing-library/cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
import '@testing-library/cypress/add-commands';
import 'cypress-real-events';
import 'cypress-file-upload';
20 changes: 20 additions & 0 deletions frontend/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';

// Alternatively you can use CommonJS syntax:
// require('./commands')
10 changes: 9 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"start:prod": "cross-env NODE_ENV=production webpack serve --config webpack.prod.js",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test": "jest --maxWorkers=50%"
"cy:open": "cypress open",
"cy:run": "cypress run",
"test:e2e": "start-server-and-test start http://localhost:3000 cy:run"
},
"dependencies": {
"@tanstack/react-query": "^4.32.6",
Expand All @@ -36,6 +38,7 @@
"@storybook/react-webpack5": "^7.0.26",
"@storybook/testing-library": "^0.0.14-next.2",
"@svgr/webpack": "^8.0.1",
"@testing-library/cypress": "^9.0.0",
"@testing-library/react": "^14.0.0",
"@types/dompurify": "^3.0.2",
"@types/jest": "^29.5.3",
Expand All @@ -45,10 +48,14 @@
"@typescript-eslint/eslint-plugin": "5.61.0",
"@typescript-eslint/parser": "5.61.0",
"cross-env": "^7.0.3",
"cypress": "^12.17.3",
"cypress-file-upload": "^5.0.8",
"cypress-real-events": "^1.10.0",
"dotenv-webpack": "^8.0.1",
"eslint": "8.44.0",
"eslint-config-prettier": "8.8.0",
"eslint-import-resolver-typescript": "3.5.5",
"eslint-plugin-cypress": "^2.14.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-react": "7.32.2",
Expand All @@ -60,6 +67,7 @@
"msw": "^1.2.3",
"msw-storybook-addon": "^1.8.0",
"prettier": "3.0.0",
"start-server-and-test": "^2.0.0",
"storybook": "^7.0.26",
"storybook-addon-react-router-v6": "^1.0.2",
"ts-jest": "^29.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ const FileUploader = ({ accept = '*', width = '30rem', height = '10rem', onFileS

return (
<button ref={dragRef} onClick={openFinder}>
<S.Description $isDragging={isDragging} $width={width} $height={height}>
<S.Description
$isDragging={isDragging}
$width={width}
$height={height}
aria-label='파일 업로드'
>
<ImportIcon />
드래그하거나 클릭해서 업로드
</S.Description>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/Category/Category/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const Category = ({ categoryId, categoryName, isDefaultCategory }: Props) => {
onBlur={resetInput}
onKeyDown={escapeRename}
onKeyUp={requestChangedName}
aria-label={`${categoryName} 카테고리 이름 수정 입력 창`}
/>
) : (
<>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/Category/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const Header = () => {
onBlur={resetInput}
onKeyDown={escapeAddCategory}
onKeyUp={requestAddCategory}
aria-label='카테고리 추가 입력 창'
/>
) : (
<S.Button onClick={openInput} aria-label='카테고리 추가 입력 창 열기'>
Expand Down
5 changes: 3 additions & 2 deletions frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Node",
"sourceMap": true,
"sourceMap": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"skipLibCheck": true
"skipLibCheck": true,
"types": ["cypress", "@testing-library/cypress", "cypress-real-events", "cypress-file-upload"]
},
"include": ["src", "__tests__"],
"exclude": ["node_modules"]
Expand Down
Loading

0 comments on commit 9fe901d

Please sign in to comment.