실제 브라우저로 '다 조립된 앱'(프론트+백엔드+DB)을 태우는 통합 테스트 6개: - 인증 가드(비로그인→로그인), 로그인 실패 안내, 학생 로그인→대시보드 - 학습 센터→강좌 열기, 퀴즈 풀기→제출→서버 채점 결과 - 멘토 로그인→멘토 화면+개인정보 접근 기록(SEC-02 감사로그까지 검증) 운영 무오염 설계: - deploy/docker-compose.e2e.yml — 별도 프로젝트(mirime2e)·네트워크·휘발성 DB(tmpfs) - deploy/Caddyfile.e2e — 평문 HTTP로 SPA+/api 프록시(운영과 동일 구조) - deploy/e2e.sh — 스택 기동→테스트 학생 API 생성→퀴즈 slug 자동조회→ Playwright(브라우저 내장 이미지) 실행→down -v(정리) - 백엔드 힙 256MB 제한(작은 인스턴스에서 운영과 공존) EC2에서 6/6 통과 확인. 러너가 운영과 같은 인스턴스라 push마다가 아닌 온디맨드(릴리스 전)로 운영 — 전용 러너 확보 시 CI 게이트로 승격. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
2.2 KiB
JavaScript
47 lines
2.2 KiB
JavaScript
// 이 파일이 하는 일: 프론트 코드의 "문법·버그 냄새"를 기계가 자동으로 잡는 규칙(ESLint) 설정이다.
|
|
//
|
|
// 학습 포인트 — 린트(lint)는 "사람이 못 보고 넘긴 실수를 컴파일 전에 잡는 자동 검사"다.
|
|
// 예: 안 쓰는 변수, 존재하지 않는 전역 참조, React 훅을 조건문 안에서 잘못 쓰는 것 등.
|
|
// npm run lint 로 로컬에서 돌리고, CI에서도 자동으로 돌아 "에러가 있으면 빨간불"이 된다.
|
|
// ESLint 9의 "flat config"(배열로 규칙을 겹쳐 쌓는 방식)를 쓴다.
|
|
import js from '@eslint/js'
|
|
import globals from 'globals'
|
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
|
|
export default [
|
|
// 검사에서 제외할 폴더 (빌드 산출물·커버리지·의존성·E2E 리포트)
|
|
{ ignores: ['dist', 'coverage', 'node_modules', 'playwright-report', 'test-results'] },
|
|
|
|
{
|
|
files: ['**/*.{js,jsx}'],
|
|
languageOptions: {
|
|
ecmaVersion: 2022,
|
|
sourceType: 'module',
|
|
// 브라우저 전역(window, self, document…) + Node 전역(process 등)을 "정의됨"으로 인정.
|
|
globals: { ...globals.browser, ...globals.node },
|
|
parserOptions: { ecmaFeatures: { jsx: true } },
|
|
},
|
|
plugins: { 'react-hooks': reactHooks },
|
|
rules: {
|
|
...js.configs.recommended.rules, // 존재하지 않는 변수, 중복 선언 등 기본 버그류 = 에러
|
|
// React 훅 규칙: 훅을 조건/반복문 안에서 부르는 진짜 버그는 에러, 의존성 배열은 경고.
|
|
'react-hooks/rules-of-hooks': 'error',
|
|
'react-hooks/exhaustive-deps': 'warn',
|
|
// 안 쓰는 변수는 경고(빌드는 막지 않음). 대문자 시작(컴포넌트/상수)·_prefix 인자는 예외.
|
|
'no-unused-vars': ['warn', { varsIgnorePattern: '^[A-Z_]', argsIgnorePattern: '^_' }],
|
|
},
|
|
},
|
|
|
|
// 테스트 파일: vitest 전역(describe/it/expect…)을 "정의됨"으로 인정.
|
|
{
|
|
files: ['**/*.test.{js,jsx}'],
|
|
languageOptions: {
|
|
globals: {
|
|
describe: 'readonly', it: 'readonly', test: 'readonly', expect: 'readonly',
|
|
vi: 'readonly', beforeEach: 'readonly', afterEach: 'readonly',
|
|
beforeAll: 'readonly', afterAll: 'readonly',
|
|
},
|
|
},
|
|
},
|
|
]
|