revert: 품질 개선 롤백 - step-executor 형식 불일치로 5개 시나리오 실패
- company-info, draft-box, item-management, popup-management, purchase-status 실패
- 원인: selector 필드 대신 target 사용 필요, evaluate IIFE 미적용, 존재하지 않는 액션 사용
- 원래 통과하던 f6779b9 상태로 복원
This commit is contained in:
@@ -1,49 +1,18 @@
|
|||||||
{
|
{
|
||||||
"id": "company-info",
|
"id": "company-info",
|
||||||
"name": "설정 - 회사정보",
|
"name": "설정 - 회사정보",
|
||||||
"description": "회사 정보 관리 기능 테스트 - 회사 정보 조회, 수정, 회사 추가 기능",
|
|
||||||
"baseUrl": "https://dev.codebridge-x.com",
|
|
||||||
|
|
||||||
"screenshotPolicy": {
|
"screenshotPolicy": {
|
||||||
"onErrorOnly": true,
|
"onErrorOnly": true,
|
||||||
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
"captureOn": ["error", "fail", "timeout", "404", "500", "blocked"]
|
||||||
},
|
},
|
||||||
|
"description": "회사 정보 관리 기능 테스트 - 회사 정보 조회, 수정, 회사 추가 기능",
|
||||||
"selectors": {
|
"baseUrl": "https://dev.codebridge-x.com",
|
||||||
"pageTitle": "h1, h2, [class*='PageHeader'] h1, [class*='page-header'] h1",
|
|
||||||
"pageLayout": "[class*='PageLayout'], main",
|
|
||||||
"addCompanyBtn": "button:has-text('회사 추가')",
|
|
||||||
"editBtn": "button:has-text('수정')",
|
|
||||||
"saveBtn": "button:has-text('저장')",
|
|
||||||
"cancelBtn": "button:has-text('취소')",
|
|
||||||
"companyNameInput": "#companyName",
|
|
||||||
"representativeNameInput": "#representativeName",
|
|
||||||
"businessTypeInput": "#businessType",
|
|
||||||
"businessCategoryInput": "#businessCategory",
|
|
||||||
"emailInput": "#email",
|
|
||||||
"taxInvoiceEmailInput": "#taxInvoiceEmail",
|
|
||||||
"businessNumberInput": "#businessNumber",
|
|
||||||
"paymentBankInput": "#paymentBank",
|
|
||||||
"paymentAccountInput": "#paymentAccount",
|
|
||||||
"paymentAccountHolderInput": "#paymentAccountHolder",
|
|
||||||
"addressSearchBtn": "button:has-text('우편번호 찾기')",
|
|
||||||
"companyInfoCard": "[class*='Card']:has(h3:has-text('회사 정보'))",
|
|
||||||
"paymentInfoCard": "[class*='Card']:has(h3:has-text('결제 계좌 정보'))",
|
|
||||||
"dialog": "[role='dialog']",
|
|
||||||
"dialogTitle": "[role='dialog'] h2",
|
|
||||||
"dialogCancelBtn": "[role='dialog'] button:has-text('취소')",
|
|
||||||
"dialogNextBtn": "[role='dialog'] button:has-text('다음')",
|
|
||||||
"dialogBusinessNumberInput": "[role='dialog'] #businessNumber",
|
|
||||||
"alertDialog": "[role='alertdialog']",
|
|
||||||
"alertConfirmBtn": "[role='alertdialog'] button:has-text('확인')"
|
|
||||||
},
|
|
||||||
|
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"targetUrl": "/company-info",
|
"targetUrl": "/company-info",
|
||||||
"urlPattern": "/company-info|/ko/company-info",
|
"urlPattern": "/company-info|/ko/company-info|/settings/company-info",
|
||||||
"menuHints": ["회사정보", "회사 정보", "설정"]
|
"menuHints": ["회사정보", "회사 정보", "설정"]
|
||||||
},
|
},
|
||||||
|
|
||||||
"menuNavigation": {
|
"menuNavigation": {
|
||||||
"level1": "설정",
|
"level1": "설정",
|
||||||
"level2": "회사정보",
|
"level2": "회사정보",
|
||||||
@@ -51,386 +20,416 @@
|
|||||||
"searchWithinParent": true,
|
"searchWithinParent": true,
|
||||||
"closeOtherMenus": true
|
"closeOtherMenus": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"username": "TestUser5",
|
"username": "TestUser5",
|
||||||
"password": "password123!"
|
"password": "password123!"
|
||||||
},
|
},
|
||||||
|
"menuNavigationEnhanced": {
|
||||||
|
"strategy": "scroll-and-search",
|
||||||
|
"description": "사이드바를 스크롤하며 메뉴를 찾고 클릭하여 404를 방지",
|
||||||
|
"level1": "설정",
|
||||||
|
"level2": "회사정보",
|
||||||
|
"alternativeLevel1Names": ["설정", "Settings", "환경설정", "시스템설정", "관리"],
|
||||||
|
"alternativeLevel2Names": ["회사정보", "회사 정보", "Company Info", "회사관리", "기업정보"],
|
||||||
|
"fallbackUrls": [
|
||||||
|
"/company-info",
|
||||||
|
"/ko/company-info",
|
||||||
|
"/settings/company-info",
|
||||||
|
"/ko/settings/company-info"
|
||||||
|
],
|
||||||
|
"scrollConfig": {
|
||||||
|
"sidebarSelector": "nav, aside, [role='navigation'], .sidebar, #sidebar",
|
||||||
|
"menuItemSelector": "a, button, [role='menuitem'], [role='treeitem']",
|
||||||
|
"scrollStep": 200,
|
||||||
|
"maxScrollAttempts": 10,
|
||||||
|
"scrollDelay": 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"expectedAPIs": [
|
"expectedAPIs": [
|
||||||
{ "method": "GET", "path": "/api/v1/company-info", "description": "회사 정보 조회" },
|
{
|
||||||
{ "method": "PUT", "path": "/api/v1/company-info/:id", "description": "회사 정보 수정" },
|
"method": "GET",
|
||||||
{ "method": "POST", "path": "/api/v1/company-info", "description": "회사 추가" }
|
"path": "/api/v1/company-info",
|
||||||
|
"description": "회사 정보 조회"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/api/v1/company-info/:id",
|
||||||
|
"description": "회사 정보 수정"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/api/v1/company-info",
|
||||||
|
"description": "회사 추가"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"name": "사이드바 메뉴 전체 펼치기",
|
"name": "사이드바 메뉴 전체 펼치기",
|
||||||
"description": "모두 펼치기 버튼 클릭 후 메뉴 탐색 준비",
|
"description": "모두 펼치기 버튼을 클릭하여 전체 메뉴를 펼친 후 메뉴 탐색 준비",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "scroll", "target": "sidebar", "direction": "top" },
|
{ "type": "scroll", "target": "sidebar", "direction": "top", "description": "사이드바 최상단으로 스크롤" },
|
||||||
{ "type": "wait", "duration": 300 },
|
{ "type": "wait", "duration": 300 },
|
||||||
{ "type": "evaluate", "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" },
|
{ "type": "evaluate", "script": "Array.from(document.querySelectorAll('button')).find(b => b.innerText?.includes('모두 펼치기'))?.click()" },
|
||||||
{ "type": "wait", "duration": 2000 }
|
{ "type": "wait", "duration": 2000 }
|
||||||
|
],
|
||||||
|
"verification": [
|
||||||
|
"사이드바가 화면에 보이는지 확인",
|
||||||
|
"모든 메뉴가 펼쳐졌는지 확인"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "1차 메뉴 클릭: 설정",
|
"name": "1차 메뉴 찾기: 설정 (스크롤 포함)",
|
||||||
"description": "사이드바에서 설정 메뉴 찾아 클릭",
|
"description": "사이드바를 스크롤하며 '설정' 메뉴를 찾아 클릭",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"type": "scrollAndFind",
|
"type": "scrollAndFind",
|
||||||
"target": "설정",
|
"target": "설정",
|
||||||
"alternativeTexts": ["설정", "Settings", "환경설정"],
|
"alternativeTexts": ["설정", "Settings", "환경설정", "시스템설정"],
|
||||||
"scrollContainer": "sidebar",
|
"scrollContainer": "sidebar",
|
||||||
"maxAttempts": 10
|
"maxAttempts": 10,
|
||||||
|
"description": "스크롤하며 설정 메뉴 찾기"
|
||||||
},
|
},
|
||||||
{ "type": "wait", "duration": 300 },
|
{ "type": "wait", "duration": 300 },
|
||||||
{ "type": "click_if_exists", "target": "설정" },
|
{ "type": "click_if_exists", "target": "설정", "description": "설정 메뉴 클릭" },
|
||||||
{ "type": "wait", "duration": 500 }
|
{ "type": "wait", "duration": 500, "description": "서브메뉴 펼쳐지기 대기" },
|
||||||
]
|
{ "type": "screenshot", "name": "settings_menu_expanded" }
|
||||||
|
],
|
||||||
|
"verification": [
|
||||||
|
"설정 메뉴가 클릭되었는지 확인",
|
||||||
|
"서브메뉴가 펼쳐졌는지 확인",
|
||||||
|
"하위 메뉴 항목들이 보이는지 확인"
|
||||||
|
],
|
||||||
|
"fallback": {
|
||||||
|
"if": "메뉴를 찾을 수 없음",
|
||||||
|
"then": "사이드바 전체를 스크롤하며 재탐색"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "2차 메뉴 클릭: 회사정보",
|
"name": "2차 메뉴 찾기: 회사정보 (스크롤 포함)",
|
||||||
"description": "서브메뉴에서 회사정보 클릭",
|
"description": "서브메뉴에서 '회사정보'를 찾아 클릭",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"type": "scrollAndFind",
|
"type": "scrollAndFind",
|
||||||
"target": "회사정보",
|
"target": "회사정보",
|
||||||
"alternativeTexts": ["회사정보", "회사 정보"],
|
"alternativeTexts": ["회사정보", "회사 정보", "Company Info", "회사관리"],
|
||||||
"scrollContainer": "submenu",
|
"scrollContainer": "submenu",
|
||||||
"maxAttempts": 5
|
"maxAttempts": 5,
|
||||||
|
"description": "서브메뉴에서 회사정보 찾기"
|
||||||
},
|
},
|
||||||
{ "type": "wait", "duration": 200 },
|
{ "type": "wait", "duration": 200 },
|
||||||
{ "type": "click_if_exists", "target": "회사정보" },
|
{ "type": "click_if_exists", "target": "회사정보", "description": "회사정보 메뉴 클릭" },
|
||||||
{ "type": "wait", "duration": 3000 }
|
{ "type": "wait", "target": "페이지 로드 완료", "timeout": 10000 },
|
||||||
|
{ "type": "screenshot", "name": "company_info_page" }
|
||||||
|
],
|
||||||
|
"verification": [
|
||||||
|
"회사정보 메뉴 클릭 성공",
|
||||||
|
"페이지 이동 또는 컨텐츠 로드"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "페이지 URL 검증",
|
"name": "404 에러 감지 및 대체 경로 시도",
|
||||||
"description": "회사정보 페이지 URL 확인",
|
"description": "페이지 로드 후 404 에러 여부 확인, 404시 대체 경로 탐색",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "verify_url", "pattern": "/company-info" }
|
{ "type": "wait", "duration": 1000 },
|
||||||
]
|
{ "type": "checkFor404", "indicators": [
|
||||||
|
"페이지를 찾을 수 없습니다",
|
||||||
|
"404",
|
||||||
|
"Not Found",
|
||||||
|
"존재하지 않거나"
|
||||||
|
]},
|
||||||
|
{ "type": "screenshot", "name": "page_load_result" }
|
||||||
|
],
|
||||||
|
"verification": [
|
||||||
|
"현재 페이지가 404인지 확인"
|
||||||
|
],
|
||||||
|
"onError404": {
|
||||||
|
"description": "404 에러 발생 시 대체 URL 시도",
|
||||||
|
"actions": [
|
||||||
|
{ "type": "log", "message": "404 감지 - 대체 경로 탐색 시작" },
|
||||||
|
{
|
||||||
|
"type": "tryAlternativeUrls",
|
||||||
|
"urls": [
|
||||||
|
"/company-info",
|
||||||
|
"/ko/company-info"
|
||||||
|
],
|
||||||
|
"stopOnSuccess": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ifStillFailed",
|
||||||
|
"action": "navigateViaMenuClick",
|
||||||
|
"description": "URL 직접 접근 실패 시 메뉴 클릭으로 재시도"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "페이지 제목 검증",
|
"name": "페이지 정상 로드 확인",
|
||||||
"description": "페이지 제목이 '회사정보'인지 확인",
|
"description": "회사정보 페이지가 정상적으로 로드되었는지 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "type": "verify", "target": "pageTitle", "contains": ["회사정보", "회사 정보", "Company"] },
|
||||||
"type": "verify_element",
|
{ "type": "verify", "target": "pageContent", "notContains": ["404", "찾을 수 없습니다", "Not Found"] }
|
||||||
"selector": "h1, h2, [class*='PageHeader'] h1",
|
],
|
||||||
"contains": "회사정보"
|
"verification": [
|
||||||
}
|
"페이지 제목 '회사정보' 또는 관련 텍스트 표시",
|
||||||
]
|
"404 에러 메시지 미표시",
|
||||||
|
"콘텐츠가 정상 렌더링됨"
|
||||||
|
],
|
||||||
|
"successCriteria": {
|
||||||
|
"urlPattern": "/company-info",
|
||||||
|
"requiredElements": ["회사", "회사명", "대표자명"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"step": 5,
|
||||||
|
"name": "페이지 제목 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "heading",
|
||||||
|
"expected": "회사정보",
|
||||||
|
"validation": "페이지 제목이 '회사정보'로 표시됨"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 6,
|
||||||
"name": "회사 추가 버튼 존재 확인",
|
"name": "회사 추가 버튼 존재 확인",
|
||||||
"description": "'회사 추가' 버튼이 화면에 존재하는지 확인",
|
"action": "verify",
|
||||||
"actions": [
|
"target": "button[text='회사 추가']",
|
||||||
{
|
"expected": "button exists",
|
||||||
"type": "verify_element",
|
"validation": "회사 추가 버튼이 표시됨"
|
||||||
"selector": "button",
|
|
||||||
"contains": "회사 추가"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"step": 7,
|
||||||
"name": "수정 버튼 존재 확인",
|
"name": "수정 버튼 존재 확인",
|
||||||
"description": "'수정' 버튼이 화면에 존재하는지 확인",
|
"action": "verify",
|
||||||
|
"target": "button[text='수정']",
|
||||||
|
"expected": "button exists",
|
||||||
|
"validation": "수정 버튼이 표시됨"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 8,
|
||||||
|
"name": "회사명 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='회사명'][disabled]",
|
||||||
|
"expected": "프론트_테스트회사",
|
||||||
|
"validation": "회사명이 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 9,
|
||||||
|
"name": "대표자명 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='대표자명'][disabled]",
|
||||||
|
"expected": "프론트",
|
||||||
|
"validation": "대표자명이 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 10,
|
||||||
|
"name": "업태 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='업태'][disabled]",
|
||||||
|
"expected": "업태명",
|
||||||
|
"validation": "업태가 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 11,
|
||||||
|
"name": "업종 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='업종'][disabled]",
|
||||||
|
"expected": "업종명",
|
||||||
|
"validation": "업종이 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 12,
|
||||||
|
"name": "주소 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='주소명'][disabled]",
|
||||||
|
"expected": "주소 표시",
|
||||||
|
"validation": "주소가 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 13,
|
||||||
|
"name": "이메일 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='이메일 (아이디)'][disabled]",
|
||||||
|
"expected": "이메일 표시",
|
||||||
|
"validation": "이메일이 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 14,
|
||||||
|
"name": "사업자등록번호 필드 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox[label='사업자등록번호'][disabled]",
|
||||||
|
"expected": "사업자등록번호 표시",
|
||||||
|
"validation": "사업자등록번호가 표시되고 비활성화 상태"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 15,
|
||||||
|
"name": "수정 버튼 클릭",
|
||||||
|
"action": "click_if_exists",
|
||||||
|
"target": "button[text='수정']",
|
||||||
|
"expected": "edit mode enabled",
|
||||||
|
"validation": "수정 모드로 전환됨"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 16,
|
||||||
|
"name": "수정 모드 - 필드 활성화 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "textbox:not([disabled])",
|
||||||
|
"expected": "fields enabled",
|
||||||
|
"validation": "텍스트 필드들이 활성화됨"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 17,
|
||||||
|
"name": "취소 버튼 클릭",
|
||||||
|
"action": "click_if_exists",
|
||||||
|
"target": "button[text='취소']",
|
||||||
|
"expected": "edit mode disabled",
|
||||||
|
"validation": "조회 모드로 복귀"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 18,
|
||||||
|
"name": "회사 추가 버튼 클릭",
|
||||||
|
"action": "click_if_exists",
|
||||||
|
"target": "button[text='회사 추가']",
|
||||||
|
"expected": "dialog opened",
|
||||||
|
"validation": "회사 추가 다이얼로그가 열림"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 19,
|
||||||
|
"name": "회사 추가 다이얼로그 확인",
|
||||||
|
"action": "verify",
|
||||||
|
"target": "dialog",
|
||||||
|
"expected": "회사 추가 다이얼로그 표시",
|
||||||
|
"validation": "다이얼로그 제목, 입력 필드, 버튼 확인"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 20,
|
||||||
|
"name": "다이얼로그 닫기",
|
||||||
|
"action": "click_if_exists",
|
||||||
|
"target": "dialog button[text='취소']",
|
||||||
|
"expected": "dialog closed",
|
||||||
|
"validation": "다이얼로그가 닫힘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 21,
|
||||||
|
"name": "수정 모드에서 데이터 변경 테스트",
|
||||||
|
"description": "실제 데이터를 수정하고 저장 기능 검증",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "type": "click_if_exists", "target": "수정", "description": "수정 모드 진입" }
|
||||||
"type": "verify_element",
|
],
|
||||||
"selector": "button",
|
"expect": {
|
||||||
"contains": "수정"
|
"fieldsEnabled": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 22,
|
||||||
|
"name": "업태 필드 수정",
|
||||||
|
"description": "업태 필드 값 변경",
|
||||||
|
"actions": [
|
||||||
|
{ "type": "clear", "target": "업태" },
|
||||||
|
{ "type": "fill", "target": "업태", "value": "테스트업태_수정" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"step": 23,
|
||||||
"name": "회사명 입력 필드 확인",
|
"name": "저장 버튼 클릭",
|
||||||
"description": "#companyName 입력 필드가 존재하고 비활성화 상태인지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#companyName"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const el = document.querySelector('#companyName'); return { exists: !!el, disabled: el?.disabled, value: el?.value };"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 8,
|
|
||||||
"name": "대표자명 입력 필드 확인",
|
|
||||||
"description": "#representativeName 입력 필드 존재 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#representativeName"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "업태 입력 필드 확인",
|
|
||||||
"description": "#businessType 입력 필드 존재 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#businessType"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 10,
|
|
||||||
"name": "업종 입력 필드 확인",
|
|
||||||
"description": "#businessCategory 입력 필드 존재 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#businessCategory"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "이메일 입력 필드 확인",
|
|
||||||
"description": "#email 입력 필드 존재 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#email"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "사업자등록번호 입력 필드 확인",
|
|
||||||
"description": "#businessNumber 입력 필드 존재 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "#businessNumber"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 13,
|
|
||||||
"name": "조회 모드 - 필드 비활성화 상태 검증",
|
|
||||||
"description": "수정 버튼 클릭 전 모든 필드가 disabled 상태인지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const fields = ['#companyName', '#representativeName', '#businessType', '#businessCategory', '#email', '#businessNumber']; const results = fields.map(sel => { const el = document.querySelector(sel); return { selector: sel, disabled: el?.disabled ?? false }; }); const allDisabled = results.every(r => r.disabled); return { allDisabled, results };"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 14,
|
|
||||||
"name": "[UPDATE] 수정 버튼 클릭",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "수정 모드 진입",
|
|
||||||
"actions": [
|
|
||||||
{ "type": "click_button", "text": "수정" },
|
|
||||||
{ "type": "wait", "duration": 500 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "[UPDATE] 수정 모드 - 필드 활성화 검증",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "수정 모드에서 입력 필드들이 활성화되었는지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const fields = ['#companyName', '#representativeName', '#businessType', '#businessCategory']; const results = fields.map(sel => { const el = document.querySelector(sel); return { selector: sel, disabled: el?.disabled ?? true }; }); const anyEnabled = results.some(r => !r.disabled); return { anyEnabled, results };"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 16,
|
|
||||||
"name": "[UPDATE] 저장/취소 버튼 표시 확인",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "수정 모드에서 저장, 취소 버튼이 표시되는지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "button",
|
|
||||||
"contains": "저장"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "button",
|
|
||||||
"contains": "취소"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "[UPDATE] 업태 필드 값 변경",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "업태 필드에 테스트 값 입력",
|
|
||||||
"actions": [
|
|
||||||
{ "type": "clear", "selector": "#businessType" },
|
|
||||||
{ "type": "fill", "selector": "#businessType", "value": "E2E_TEST_업태" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 18,
|
|
||||||
"name": "[UPDATE] 저장 버튼 클릭",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "수정된 회사 정보 저장",
|
"description": "수정된 회사 정보 저장",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "click_button", "text": "저장" },
|
{ "type": "click_if_exists", "target": "저장" }
|
||||||
{ "type": "wait", "duration": 2000 }
|
],
|
||||||
]
|
"waitFor": {
|
||||||
|
"type": "apiResponse",
|
||||||
|
"method": "PUT",
|
||||||
|
"timeout": 5000
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"toast": ["수정", "완료", "성공", "저장"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 19,
|
"step": 24,
|
||||||
"name": "[UPDATE] 저장 성공 토스트 확인",
|
"name": "⚠️ 필수 검증: 수정 데이터 반영 확인",
|
||||||
"phase": "UPDATE",
|
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 변경 확인 필수!",
|
||||||
"description": "저장 성공 메시지 토스트 확인",
|
"description": "수정된 업태 값이 반영되었는지 확인",
|
||||||
"actions": [
|
"verify": {
|
||||||
{
|
"fieldValue": {
|
||||||
"type": "verify_toast",
|
"target": "업태",
|
||||||
"contains": ["저장", "완료", "성공"]
|
"expected": "테스트업태_수정"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 20,
|
"step": 25,
|
||||||
"name": "[UPDATE] 수정 데이터 반영 확인",
|
|
||||||
"phase": "UPDATE",
|
|
||||||
"description": "변경된 업태 값이 필드에 반영되었는지 확인",
|
|
||||||
"critical": true,
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "verify_input_value",
|
|
||||||
"selector": "#businessType",
|
|
||||||
"contains": "E2E_TEST_업태"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "회사 추가 다이얼로그 열기",
|
"name": "회사 추가 다이얼로그 열기",
|
||||||
"description": "회사 추가 버튼 클릭하여 다이얼로그 표시",
|
"description": "회사 추가 버튼 클릭하여 다이얼로그 열기",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "click_button", "text": "회사 추가" },
|
{ "type": "click_if_exists", "target": "회사 추가" }
|
||||||
{ "type": "wait", "duration": 500 }
|
],
|
||||||
|
"expect": {
|
||||||
|
"dialog": true,
|
||||||
|
"visible": ["회사명", "대표자명", "사업자등록번호", "등록", "취소"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 26,
|
||||||
|
"name": "새 회사 정보 입력",
|
||||||
|
"description": "회사 추가 다이얼로그에서 필수 정보 입력",
|
||||||
|
"actions": [
|
||||||
|
{ "type": "fill", "target": "회사명", "value": "테스트회사_{timestamp}" },
|
||||||
|
{ "type": "fill", "target": "대표자명", "value": "테스트대표" },
|
||||||
|
{ "type": "fill", "target": "사업자등록번호", "value": "123-45-67890" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 22,
|
"step": 27,
|
||||||
"name": "회사 추가 다이얼로그 표시 검증",
|
"name": "회사 등록",
|
||||||
"description": "다이얼로그가 열리고 제목이 '회사 추가'인지 확인",
|
"description": "등록 버튼 클릭하여 새 회사 등록",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "type": "click_if_exists", "target": "등록" }
|
||||||
"type": "verify_element",
|
],
|
||||||
"selector": "[role='dialog']"
|
"waitFor": {
|
||||||
},
|
"type": "apiResponse",
|
||||||
{
|
"method": "POST",
|
||||||
"type": "verify_element",
|
"timeout": 5000
|
||||||
"selector": "[role='dialog'] h2",
|
},
|
||||||
"contains": "회사 추가"
|
"expect": {
|
||||||
}
|
"toast": ["등록", "완료", "성공"],
|
||||||
]
|
"dialogClosed": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 23,
|
"step": 28,
|
||||||
"name": "다이얼로그 내 사업자등록번호 입력 필드 확인",
|
"name": "⚠️ 필수 검증: 회사 등록 반영 확인",
|
||||||
"description": "다이얼로그 내 #businessNumber 입력 필드 존재 확인",
|
"note": "토스트 성공 메시지만으로 PASS 판정 불가. 실제 데이터 등록 확인 필수!",
|
||||||
"actions": [
|
"description": "등록된 회사가 목록에 표시되는지 확인",
|
||||||
{
|
"verify": {
|
||||||
"type": "verify_element",
|
"visible": "테스트회사"
|
||||||
"selector": "[role='dialog'] #businessNumber"
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 24,
|
"step": 29,
|
||||||
"name": "다이얼로그 내 취소/다음 버튼 확인",
|
"name": "원복: 업태 필드 원래 값으로 복구",
|
||||||
"description": "취소, 다음 버튼 존재 확인",
|
"description": "테스트 후 원래 값으로 복구",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "type": "click_if_exists", "target": "수정" },
|
||||||
"type": "evaluate",
|
{ "type": "clear", "target": "업태" },
|
||||||
"script": "const dialog = document.querySelector('[role=\"dialog\"]'); if (!dialog) return { error: 'Dialog not found' }; const buttons = Array.from(dialog.querySelectorAll('button')).map(b => b.innerText.trim()); return { buttons, hasCancel: buttons.includes('취소'), hasNext: buttons.includes('다음') };"
|
{ "type": "fill", "target": "업태", "value": "업태명" },
|
||||||
}
|
{ "type": "click_if_exists", "target": "저장" }
|
||||||
]
|
],
|
||||||
},
|
"expect": {
|
||||||
{
|
"toast": ["수정", "완료", "성공", "저장"]
|
||||||
"id": 25,
|
}
|
||||||
"name": "다이얼로그 사업자등록번호 입력",
|
|
||||||
"description": "10자리 사업자등록번호 입력",
|
|
||||||
"actions": [
|
|
||||||
{ "type": "fill", "selector": "[role='dialog'] #businessNumber", "value": "1234567890" },
|
|
||||||
{ "type": "wait", "duration": 300 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 26,
|
|
||||||
"name": "다이얼로그 다음 버튼 활성화 확인",
|
|
||||||
"description": "10자리 입력 후 다음 버튼이 활성화되는지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const dialog = document.querySelector('[role=\"dialog\"]'); const nextBtn = Array.from(dialog?.querySelectorAll('button') || []).find(b => b.innerText.includes('다음')); return { disabled: nextBtn?.disabled ?? true, text: nextBtn?.innerText };"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 27,
|
|
||||||
"name": "다이얼로그 취소 클릭",
|
|
||||||
"description": "취소 버튼 클릭하여 다이얼로그 닫기",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const dialog = document.querySelector('[role=\"dialog\"]'); const cancelBtn = Array.from(dialog?.querySelectorAll('button') || []).find(b => b.innerText.includes('취소')); cancelBtn?.click(); return { clicked: !!cancelBtn };"
|
|
||||||
},
|
|
||||||
{ "type": "wait", "duration": 500 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 28,
|
|
||||||
"name": "다이얼로그 닫힘 확인",
|
|
||||||
"description": "다이얼로그가 닫혔는지 확인",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const dialog = document.querySelector('[role=\"dialog\"]'); return { dialogClosed: !dialog || dialog.offsetParent === null };"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 29,
|
|
||||||
"name": "[CLEANUP] 업태 필드 원래 값 복구",
|
|
||||||
"phase": "CLEANUP",
|
|
||||||
"description": "테스트 데이터 정리 - 업태 필드 원복",
|
|
||||||
"actions": [
|
|
||||||
{ "type": "click_button", "text": "수정" },
|
|
||||||
{ "type": "wait", "duration": 500 },
|
|
||||||
{ "type": "clear", "selector": "#businessType" },
|
|
||||||
{ "type": "fill", "selector": "#businessType", "value": "업태명" },
|
|
||||||
{ "type": "click_button", "text": "저장" },
|
|
||||||
{ "type": "wait", "duration": 2000 }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"notes": [
|
"notes": [
|
||||||
"직접 URL 접근 금지: 반드시 메뉴 클릭으로 페이지 진입 (404 방지)",
|
"직접 URL 접근 금지: 반드시 메뉴 클릭으로 페이지 진입 (404 방지)",
|
||||||
"스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",
|
"스크롤 필수: 사이드바가 길 경우 메뉴가 화면 밖에 있을 수 있음",
|
||||||
"메뉴 계층: 설정 > 회사정보",
|
"대체 경로: 메뉴명이 변경되었을 수 있으므로 다양한 이름으로 탐색",
|
||||||
"주요 필드 ID: #companyName, #representativeName, #businessType, #businessCategory, #email, #businessNumber",
|
"메뉴 계층: 설정 > 회사정보"
|
||||||
"수정 모드: 수정 버튼 클릭 시 필드 활성화, 저장/취소 버튼 표시"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
1537
draft-box.json
1537
draft-box.json
File diff suppressed because it is too large
Load Diff
1508
item-management.json
1508
item-management.json
File diff suppressed because it is too large
Load Diff
@@ -170,18 +170,7 @@
|
|||||||
"name": "페이지 구조 확인",
|
"name": "페이지 구조 확인",
|
||||||
"description": "페이지 타이틀, 설명 확인",
|
"description": "페이지 타이틀, 설명 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "wait", "duration": 500 },
|
{ "type": "verify", "target": "페이지 구조" }
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "h1, h2, [class*='title'], [class*='header'] h1, [class*='header'] h2, [class*='page-title']",
|
|
||||||
"description": "페이지 타이틀 요소 존재 확인"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verify_text",
|
|
||||||
"selector": "h1, h2, [class*='title'], [class*='header']",
|
|
||||||
"contains": ["결제", "내역", "Payment"],
|
|
||||||
"description": "페이지 타이틀에 '결제' 또는 '내역' 텍스트 포함 확인"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"expected": {
|
"expected": {
|
||||||
"pageTitle": "결제내역",
|
"pageTitle": "결제내역",
|
||||||
@@ -193,22 +182,7 @@
|
|||||||
"name": "테이블 구조 확인",
|
"name": "테이블 구조 확인",
|
||||||
"description": "결제 내역 테이블의 컬럼 헤더 확인",
|
"description": "결제 내역 테이블의 컬럼 헤더 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "wait", "duration": 500 },
|
{ "type": "verify", "target": "table columns" }
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "table, [role='table'], [class*='table'], [class*='grid'], [class*='list']",
|
|
||||||
"description": "테이블 또는 그리드 요소 존재 확인"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "table thead th, table th, [role='columnheader'], [class*='header'] [class*='cell'], [class*='table-header']",
|
|
||||||
"description": "테이블 헤더 컬럼 존재 확인"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const headers = document.querySelectorAll('table thead th, table th, [role=\"columnheader\"]'); return headers.length > 0 ? `테이블 컬럼 ${headers.length}개 발견` : '컬럼 없음';",
|
|
||||||
"description": "테이블 컬럼 개수 확인"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"expected": {
|
"expected": {
|
||||||
"tableExists": true,
|
"tableExists": true,
|
||||||
@@ -220,18 +194,7 @@
|
|||||||
"name": "데이터 로드 확인",
|
"name": "데이터 로드 확인",
|
||||||
"description": "결제 내역 데이터가 테이블에 표시되는지 확인",
|
"description": "결제 내역 데이터가 테이블에 표시되는지 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "wait", "duration": 1000 },
|
{ "type": "verify", "target": "table data" }
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const rows = document.querySelectorAll('table tbody tr, [role=\"row\"]:not([role=\"columnheader\"]), [class*=\"table-row\"], [class*=\"list-item\"]'); const emptyMsg = document.body.innerText.includes('데이터가 없습니다') || document.body.innerText.includes('No data') || document.body.innerText.includes('결과가 없습니다'); return rows.length > 0 ? `데이터 ${rows.length}행 표시됨` : (emptyMsg ? '빈 데이터 메시지 표시됨 (정상)' : '데이터 확인 필요');",
|
|
||||||
"description": "테이블 데이터 행 또는 빈 데이터 메시지 확인"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verify_element",
|
|
||||||
"selector": "table tbody, [role='rowgroup'], [class*='table-body'], [class*='list-body']",
|
|
||||||
"optional": true,
|
|
||||||
"description": "테이블 본문 영역 확인"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"expected": {
|
"expected": {
|
||||||
"dataExists": "데이터 행 존재 또는 '데이터가 없습니다' 메시지"
|
"dataExists": "데이터 행 존재 또는 '데이터가 없습니다' 메시지"
|
||||||
@@ -242,33 +205,18 @@
|
|||||||
"name": "페이지네이션 확인",
|
"name": "페이지네이션 확인",
|
||||||
"description": "테이블 하단에 페이지네이션이 표시되는지 확인",
|
"description": "테이블 하단에 페이지네이션이 표시되는지 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{ "type": "wait", "duration": 500 },
|
{ "type": "verify", "target": "pagination component" }
|
||||||
{
|
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const pagination = document.querySelector('[class*=\"pagination\"], [class*=\"pager\"], [aria-label*=\"pagination\"], nav[class*=\"page\"], [class*=\"Pagination\"]'); const pageButtons = document.querySelectorAll('button[class*=\"page\"], a[class*=\"page\"], [aria-label*=\"page\"]'); return pagination ? '페이지네이션 컴포넌트 존재' : (pageButtons.length > 0 ? `페이지 버튼 ${pageButtons.length}개 발견` : '페이지네이션 없음 (데이터 적음 또는 미구현)');",
|
|
||||||
"description": "페이지네이션 컴포넌트 확인"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"expected": {
|
"expected": {
|
||||||
"paginationExists": true
|
"paginationExists": true
|
||||||
},
|
}
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "콘솔 에러 확인",
|
"name": "콘솔 에러 확인",
|
||||||
"description": "페이지 동작 중 콘솔에 에러가 발생하지 않는지 확인",
|
"description": "페이지 동작 중 콘솔에 에러가 발생하지 않는지 확인",
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "type": "verify", "target": "console errors" }
|
||||||
"type": "evaluate",
|
|
||||||
"script": "const logs = window.__API_LOGS__ || []; const errors = logs.filter(l => !l.ok || l.status >= 400); return errors.length === 0 ? 'API 에러 없음' : `API 에러 ${errors.length}개: ${errors.map(e => e.url + ' (' + e.status + ')').join(', ')}';",
|
|
||||||
"description": "API 에러 로그 확인"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verify_page",
|
|
||||||
"notContains": ["500", "Internal Server Error", "서버 오류"],
|
|
||||||
"description": "서버 에러 메시지 미표시 확인"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"expected": {
|
"expected": {
|
||||||
"noErrors": "콘솔 에러 없음"
|
"noErrors": "콘솔 에러 없음"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -43,79 +43,106 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "현황판 구조 확인 - 통계 카드",
|
"name": "현황판 구조 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": "[class*='card'], [class*='stat'], [class*='summary'], [class*='kpi'], [class*='dashboard'] [class*='item']",
|
"checks": [
|
||||||
"expected": "통계 카드 영역 존재"
|
"생산 통계 카드",
|
||||||
|
"현황 차트",
|
||||||
|
"기간 선택 필터",
|
||||||
|
"라인/공정별 필터"
|
||||||
|
],
|
||||||
|
"expected": "현황판 구조 정상 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "현황판 구조 확인 - 차트 영역",
|
"phase": "READ",
|
||||||
"action": "verify_element",
|
"name": "[READ] 생산 통계 카드 확인",
|
||||||
"selector": "canvas, svg[class*='chart'], [class*='chart'], [class*='Chart'], [class*='recharts'], [class*='graph']",
|
"action": "verify_detail",
|
||||||
"expected": "차트 또는 그래프 영역 존재"
|
"checks": [
|
||||||
|
"오늘 생산량",
|
||||||
|
"목표 대비 달성률",
|
||||||
|
"불량률"
|
||||||
|
],
|
||||||
|
"expected": "생산 통계 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"phase": "READ",
|
"phase": "READ",
|
||||||
"name": "[READ] 생산 통계 텍스트 확인",
|
"name": "[READ] 생산 추이 차트 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"text": ["생산", "목표", "달성", "실적", "수량", "현황"],
|
"checks": [
|
||||||
"matchAny": true,
|
"일별/주별/월별 생산 추이 차트",
|
||||||
"expected": "생산 관련 텍스트 표시"
|
"차트 데이터 표시"
|
||||||
|
],
|
||||||
|
"expected": "생산 추이 차트 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"phase": "READ",
|
"phase": "FILTER",
|
||||||
"name": "[READ] 숫자 데이터 존재 확인",
|
"name": "[FILTER] 기간 필터 테스트",
|
||||||
"action": "evaluate",
|
"action": "click_if_exists",
|
||||||
"script": "(() => { const nums = document.body.innerText.match(/\\d{1,3}(,\\d{3})*(\\.\\d+)?(%|개|건|EA)?/g); return { hasNumbers: nums && nums.length > 3, count: nums ? nums.length : 0 }; })()",
|
"target": "select[name*='period'], button:has-text('기간'), [class*='filter']",
|
||||||
"expected": "숫자 데이터 3개 이상 표시"
|
"expected": "기간 필터 옵션 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"phase": "FILTER",
|
"phase": "FILTER",
|
||||||
"name": "[FILTER] 기간/날짜 필터 확인",
|
"name": "[FILTER] 라인/공정별 필터",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": "input[type='date'], [class*='date'], [class*='period'], [class*='calendar'], select[name*='period'], button[class*='date']",
|
"checks": [
|
||||||
"expected": "기간/날짜 선택 요소 존재"
|
"생산라인 선택 가능",
|
||||||
|
"공정별 필터 가능"
|
||||||
|
],
|
||||||
|
"expected": "라인/공정 필터 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"phase": "FILTER",
|
"name": "실시간 현황 표시",
|
||||||
"name": "[FILTER] 드롭다운/셀렉트 필터 확인",
|
"action": "verify_elements",
|
||||||
"action": "verify_element",
|
"checks": [
|
||||||
"selector": "select, [class*='select'], [class*='dropdown'], [class*='filter'], [role='combobox'], [role='listbox']",
|
"현재 가동 라인",
|
||||||
"expected": "필터 선택 요소 존재"
|
"실시간 생산량 또는 마지막 갱신 시간"
|
||||||
|
],
|
||||||
|
"expected": "실시간 현황 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "테이블 또는 그리드 데이터 확인",
|
"name": "불량률 현황 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_detail",
|
||||||
"selector": "table, [class*='table'], [class*='grid'], [class*='list'], [role='grid'], [role='table']",
|
"checks": [
|
||||||
"expected": "데이터 테이블/그리드 존재"
|
"불량률 표시",
|
||||||
|
"불량 유형별 통계"
|
||||||
|
],
|
||||||
|
"expected": "불량률 현황 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 10,
|
"id": 10,
|
||||||
"name": "퍼센트/비율 데이터 확인",
|
"name": "생산 목표 대비 현황",
|
||||||
"action": "evaluate",
|
"action": "verify_elements",
|
||||||
"script": "(() => { const text = document.body.innerText; const hasPercent = /%/.test(text); const hasRate = /달성|비율|률/.test(text); return { hasPercent, hasRate, valid: hasPercent || hasRate }; })()",
|
"checks": [
|
||||||
"expected": "퍼센트 또는 비율 데이터 표시"
|
"목표 생산량",
|
||||||
|
"실제 생산량",
|
||||||
|
"달성률"
|
||||||
|
],
|
||||||
|
"expected": "목표 대비 현황 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "새로고침/갱신 버튼 확인",
|
"name": "자동 새로고침 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": "button[class*='refresh'], button[class*='reload'], [class*='sync'], button:has(svg[class*='refresh']), button:has([class*='icon-refresh'])",
|
"checks": [
|
||||||
"fallbackSelector": "button",
|
"자동 새로고침 설정 또는 수동 새로고침 버튼"
|
||||||
"expected": "새로고침 또는 버튼 존재"
|
],
|
||||||
|
"expected": "새로고침 기능 존재"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"name": "페이지 인터랙티브 요소 확인",
|
"name": "전체화면 모드 확인",
|
||||||
"action": "evaluate",
|
"action": "verify_elements",
|
||||||
"script": "(() => { const btns = document.querySelectorAll('button:not([disabled])').length; const inputs = document.querySelectorAll('input, select, textarea').length; const links = document.querySelectorAll('a[href]').length; return { buttons: btns, inputs, links, totalInteractive: btns + inputs + links, isInteractive: (btns + inputs + links) >= 2 }; })()",
|
"checks": [
|
||||||
"expected": "인터랙티브 요소 2개 이상 존재"
|
"전체화면 버튼 존재 여부"
|
||||||
|
],
|
||||||
|
"expected": "전체화면 기능 확인"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"expectedAPIs": [
|
"expectedAPIs": [
|
||||||
|
|||||||
@@ -25,16 +25,6 @@
|
|||||||
"username": "TestUser5",
|
"username": "TestUser5",
|
||||||
"password": "password123!"
|
"password": "password123!"
|
||||||
},
|
},
|
||||||
"selectors": {
|
|
||||||
"statisticsCard": ".card, [class*='stat'], [class*='summary'], [class*='card']",
|
|
||||||
"dateFilter": "input[type='date'], input[type='text'][placeholder*='날짜'], [class*='datepicker'] input",
|
|
||||||
"searchButton": "button:has-text('조회'), button:has-text('검색'), button[type='submit']",
|
|
||||||
"dataTable": "table, [class*='table'], [role='grid']",
|
|
||||||
"statusFilter": "select, [class*='select'], [class*='dropdown'], [role='combobox']",
|
|
||||||
"excelButton": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드'), button[class*='excel']",
|
|
||||||
"printButton": "button:has-text('인쇄'), button:has-text('Print'), button[class*='print']",
|
|
||||||
"chartArea": "canvas, svg, [class*='chart'], [class*='Chart']"
|
|
||||||
},
|
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@@ -55,108 +45,137 @@
|
|||||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||||
"action": "verify_not_mockup",
|
"action": "verify_not_mockup",
|
||||||
"checks": [
|
"checks": [
|
||||||
"input, select, button[type='submit']",
|
"구매 현황 표시",
|
||||||
"table, [class*='table'], [role='grid']"
|
"기간 필터 존재",
|
||||||
|
"통계 또는 차트 존재"
|
||||||
],
|
],
|
||||||
"expected": "정상 페이지 (목업 아님)"
|
"expected": "정상 페이지 (목업 아님)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "구매현황 페이지 구조 확인",
|
"name": "구매현황 페이지 구조 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": ".card, [class*='stat'], [class*='summary'], table, [class*='table']",
|
"checks": [
|
||||||
|
"구매 통계 카드",
|
||||||
|
"기간 선택 필터",
|
||||||
|
"구매 목록 테이블 또는 차트"
|
||||||
|
],
|
||||||
"expected": "구매현황 페이지 정상 표시"
|
"expected": "구매현황 페이지 정상 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"phase": "READ",
|
"phase": "READ",
|
||||||
"name": "[READ] 구매 통계 카드 확인",
|
"name": "[READ] 구매 통계 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_detail",
|
||||||
"target": ".card, [class*='stat'], [class*='summary'], [class*='total'], [class*='count']",
|
"checks": [
|
||||||
"expected": "구매 통계 카드 표시"
|
"총 구매금액",
|
||||||
|
"구매 건수",
|
||||||
|
"평균 구매금액"
|
||||||
|
],
|
||||||
|
"expected": "구매 통계 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"phase": "FILTER",
|
"phase": "FILTER",
|
||||||
"name": "[FILTER] 날짜 필터 필드 확인",
|
"name": "[FILTER] 기간 필터 - 시작일",
|
||||||
"action": "verify_element",
|
"action": "click_if_exists",
|
||||||
"target": "input[type='date'], input[type='text'][placeholder*='날짜'], [class*='datepicker']",
|
"target": "input[type='date']:first-of-type, input[name*='start']"
|
||||||
"expected": "날짜 필터 필드 존재"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"phase": "FILTER",
|
"phase": "FILTER",
|
||||||
"name": "[FILTER] 조회 버튼 클릭",
|
"name": "[FILTER] 기간 필터 - 종료일",
|
||||||
"action": "click_if_exists",
|
"action": "click_if_exists",
|
||||||
"target": "button:has-text('조회'), button:has-text('검색'), button[type='submit']",
|
"target": "input[type='date']:last-of-type, input[name*='end']"
|
||||||
"timeout": 3000
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"phase": "FILTER",
|
"phase": "FILTER",
|
||||||
"name": "[FILTER] 조회 결과 테이블 확인",
|
"name": "[FILTER] 조회 실행",
|
||||||
"action": "wait_for_element",
|
"action": "click_if_exists",
|
||||||
"target": "table tbody tr, [class*='table'] [class*='row'], [role='row']",
|
"target": "button:has-text('조회'), button:has-text('검색')",
|
||||||
"timeout": 5000,
|
"expected": {
|
||||||
"expected": "조회 결과 데이터 로드"
|
"data_loaded": true,
|
||||||
|
"api_call": "GET /api/v1/purchase/status"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"name": "구매 현황 테이블 구조 확인",
|
"name": "구매 현황 테이블 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_table",
|
||||||
"target": "table thead th, table th, [role='columnheader']",
|
"checks": [
|
||||||
"expected": "테이블 헤더 컬럼 표시"
|
"발주일 컬럼",
|
||||||
|
"거래처 컬럼",
|
||||||
|
"품목 컬럼",
|
||||||
|
"금액 컬럼",
|
||||||
|
"상태 컬럼"
|
||||||
|
],
|
||||||
|
"expected": "구매 현황 테이블 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "테이블 데이터 행 존재 확인",
|
"name": "상태별 필터 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": "table tbody tr, [class*='table'] [class*='row']:not(:first-child), [role='row']",
|
"checks": [
|
||||||
"expected": "테이블 데이터 행 표시"
|
"진행중/완료/취소 상태 필터"
|
||||||
|
],
|
||||||
|
"expected": "상태 필터 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 10,
|
"id": 10,
|
||||||
"name": "상태 필터/선택 요소 확인",
|
"name": "거래처별 통계 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": "select, [class*='select'], [class*='dropdown'], [role='combobox'], [class*='filter']",
|
"checks": [
|
||||||
"expected": "상태/필터 선택 요소 표시"
|
"거래처별 구매금액 표시"
|
||||||
|
],
|
||||||
|
"expected": "거래처별 통계 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "통계 영역 확인",
|
"name": "품목별 통계 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": ".card, [class*='stat'], [class*='summary'], [class*='total']",
|
"checks": [
|
||||||
"expected": "통계 정보 영역 표시"
|
"품목별 구매금액 표시"
|
||||||
|
],
|
||||||
|
"expected": "품목별 통계 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"name": "차트 또는 시각화 영역 확인",
|
"name": "월별 추이 차트 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": "canvas, svg, [class*='chart'], [class*='Chart'], [class*='graph']",
|
"checks": [
|
||||||
"optional": true,
|
"월별 구매 추이 차트"
|
||||||
"expected": "차트/그래프 영역 표시 (선택적)"
|
],
|
||||||
|
"expected": "추이 차트 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 13,
|
"id": 13,
|
||||||
"name": "필수 검증 #1: 엑셀 다운로드 버튼 확인",
|
"name": "필수 검증 #1: 엑셀 다운로드",
|
||||||
"action": "verify_element",
|
"action": "click_if_exists",
|
||||||
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드'), button[class*='excel'], a[href*='export'], a[href*='download']",
|
"target": "button:has-text('엑셀'), button:has-text('Excel'), button:has-text('다운로드')",
|
||||||
"expected": "엑셀 다운로드 버튼 존재"
|
"verify": {
|
||||||
|
"api_call": "GET /api/v1/purchase/status/export",
|
||||||
|
"file_download": true
|
||||||
|
},
|
||||||
|
"expected": "엑셀 파일 다운로드"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 14,
|
"id": 14,
|
||||||
"name": "인쇄 버튼 확인",
|
"name": "인쇄 기능 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"target": "button:has-text('인쇄'), button:has-text('Print'), button[class*='print'], [class*='print']",
|
"checks": [
|
||||||
"optional": true,
|
"인쇄 버튼 존재"
|
||||||
"expected": "인쇄 버튼 표시 (선택적)"
|
],
|
||||||
|
"expected": "인쇄 기능 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 15,
|
"id": 15,
|
||||||
"name": "페이지 정상 동작 최종 확인",
|
"name": "전년 대비 비교 확인",
|
||||||
"action": "verify_url_stability",
|
"action": "verify_elements",
|
||||||
"timeout": 2000,
|
"checks": [
|
||||||
"expected": "페이지 정상 유지 (에러 없음)"
|
"전년 동기 대비 증감 표시"
|
||||||
|
],
|
||||||
|
"expected": "비교 분석 표시"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"expectedAPIs": [
|
"expectedAPIs": [
|
||||||
@@ -169,16 +188,21 @@
|
|||||||
"method": "GET",
|
"method": "GET",
|
||||||
"endpoint": "/api/v1/purchase/statistics",
|
"endpoint": "/api/v1/purchase/statistics",
|
||||||
"description": "구매 통계 조회"
|
"description": "구매 통계 조회"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"endpoint": "/api/v1/purchase/status/export",
|
||||||
|
"description": "구매현황 엑셀 다운로드"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requiredVerifications": [
|
"requiredVerifications": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "엑셀 다운로드 버튼",
|
"name": "엑셀 다운로드",
|
||||||
"steps": [
|
"steps": [
|
||||||
13
|
13
|
||||||
],
|
],
|
||||||
"criteria": "엑셀 다운로드 버튼 존재 확인"
|
"criteria": "API 호출 + 파일 다운로드"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
@@ -186,10 +210,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
"criteria": "입력 필드, 테이블 등 실제 UI 요소 존재"
|
"criteria": "구매 현황, 기간 필터, 통계/차트 존재"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rollbackPlan": {
|
"rollbackPlan": {
|
||||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
"note": "조회 전용 페이지로 데이터 변경 없음"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,14 +18,6 @@
|
|||||||
"username": "TestUser5",
|
"username": "TestUser5",
|
||||||
"password": "password123!"
|
"password": "password123!"
|
||||||
},
|
},
|
||||||
"selectors": {
|
|
||||||
"pageTitle": "h1.text-xl.md\\:text-2xl",
|
|
||||||
"planCard": "main .bg-card",
|
|
||||||
"planName": "h3.text-xl",
|
|
||||||
"paymentGrid": ".grid.grid-cols-1.md\\:grid-cols-3",
|
|
||||||
"exportButton": "button:has-text('자료 내보내기')",
|
|
||||||
"cancelButton": "button:has-text('서비스 해지')"
|
|
||||||
},
|
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@@ -35,107 +27,117 @@
|
|||||||
"level2": "구독관리",
|
"level2": "구독관리",
|
||||||
"expected": {
|
"expected": {
|
||||||
"url_contains": "/subscription",
|
"url_contains": "/subscription",
|
||||||
"visible": ["구독관리"]
|
"visible": ["구독관리", "구독"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "페이지 타이틀 확인",
|
|
||||||
"action": "verify_element",
|
|
||||||
"selector": "h1",
|
|
||||||
"contains": "구독관리",
|
|
||||||
"expected": "구독관리 페이지 타이틀 표시"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "필수 검증 #5: 목업 페이지 감지",
|
"name": "필수 검증 #5: 목업 페이지 감지",
|
||||||
"action": "verify_not_mockup",
|
"action": "verify_not_mockup",
|
||||||
"checks": [
|
"checks": [
|
||||||
"구독 정보 카드 존재",
|
"구독 정보 표시",
|
||||||
"플랜 정보 표시",
|
"플랜 정보 표시",
|
||||||
"사용량 현황 표시"
|
"결제 정보 표시"
|
||||||
],
|
],
|
||||||
"expected": "정상 페이지 (목업 아님)"
|
"expected": "정상 페이지 (목업 아님)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "현재 플랜 정보 확인",
|
||||||
|
"action": "verify_elements",
|
||||||
|
"checks": [
|
||||||
|
"현재 플랜명 표시",
|
||||||
|
"플랜 가격 표시",
|
||||||
|
"포함 기능 표시"
|
||||||
|
],
|
||||||
|
"expected": "현재 플랜 정보 표시"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "현재 플랜명 확인",
|
"name": "구독 기간 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": "h3.text-xl",
|
"checks": [
|
||||||
"expected": "현재 플랜명 (무료/유료) 표시"
|
"구독 시작일 표시",
|
||||||
|
"구독 종료일 표시",
|
||||||
|
"남은 기간 표시"
|
||||||
|
],
|
||||||
|
"expected": "구독 기간 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"name": "결제 정보 카드 그리드 확인",
|
"name": "결제 정보 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": ".grid.grid-cols-1",
|
"checks": [
|
||||||
"expected": "결제 정보 카드 그리드 표시"
|
"결제 방법 표시",
|
||||||
|
"다음 결제일 표시",
|
||||||
|
"결제 금액 표시"
|
||||||
|
],
|
||||||
|
"expected": "결제 정보 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"name": "최근 결제일시 카드 확인",
|
"name": "플랜 비교 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "최근 결제일시",
|
"checks": [
|
||||||
"expected": "최근 결제일시 정보 표시"
|
"플랜 비교 테이블 또는 카드"
|
||||||
|
],
|
||||||
|
"expected": "플랜 비교 가능"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"name": "다음 결제일시 카드 확인",
|
"name": "플랜 변경 버튼 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "다음 결제일시",
|
"checks": [
|
||||||
"expected": "다음 결제일시 정보 표시"
|
"플랜 변경 또는 업그레이드 버튼"
|
||||||
|
],
|
||||||
|
"expected": "플랜 변경 버튼 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"name": "구독금액 카드 확인",
|
"name": "사용량 현황 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "구독금액",
|
"checks": [
|
||||||
"expected": "구독금액 정보 표시"
|
"사용자 수 현황",
|
||||||
|
"저장 용량 현황",
|
||||||
|
"기능 사용 현황"
|
||||||
|
],
|
||||||
|
"expected": "사용량 현황 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "구독 정보 카드 확인",
|
"name": "결제 내역 확인",
|
||||||
"action": "verify_element",
|
"action": "verify_elements",
|
||||||
"selector": ".bg-card",
|
"checks": [
|
||||||
"contains": "구독 정보",
|
"결제 내역 테이블 또는 리스트"
|
||||||
"expected": "구독 정보 카드 표시"
|
],
|
||||||
|
"expected": "결제 내역 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 10,
|
"id": 10,
|
||||||
"name": "사용자 수 현황 확인",
|
"name": "영수증 다운로드 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "사용자 수",
|
"checks": [
|
||||||
"expected": "사용자 수 현황 표시"
|
"영수증 다운로드 버튼 존재"
|
||||||
|
],
|
||||||
|
"expected": "영수증 다운로드 기능 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "저장 공간 현황 확인",
|
"name": "결제 수단 변경 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "저장 공간",
|
"checks": [
|
||||||
"expected": "저장 공간 현황 표시"
|
"결제 수단 변경 버튼 존재"
|
||||||
|
],
|
||||||
|
"expected": "결제 수단 변경 기능 표시"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"name": "AI API 호출 현황 확인",
|
"name": "구독 취소 버튼 확인",
|
||||||
"action": "verify_text",
|
"action": "verify_elements",
|
||||||
"contains": "AI API 호출",
|
"checks": [
|
||||||
"expected": "AI API 호출 현황 표시"
|
"구독 취소 또는 해지 버튼 존재"
|
||||||
},
|
],
|
||||||
{
|
"expected": "구독 취소 기능 표시"
|
||||||
"id": 13,
|
|
||||||
"name": "자료 내보내기 버튼 확인",
|
|
||||||
"action": "verify_element",
|
|
||||||
"selector": "main button",
|
|
||||||
"contains": "자료 내보내기",
|
|
||||||
"expected": "자료 내보내기 버튼 표시"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 14,
|
|
||||||
"name": "서비스 해지 버튼 확인",
|
|
||||||
"action": "verify_element",
|
|
||||||
"selector": "main button",
|
|
||||||
"contains": "서비스 해지",
|
|
||||||
"expected": "서비스 해지 버튼 표시"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"expectedAPIs": [
|
"expectedAPIs": [
|
||||||
@@ -144,6 +146,16 @@
|
|||||||
"endpoint": "/api/v1/subscription",
|
"endpoint": "/api/v1/subscription",
|
||||||
"description": "구독 정보 조회"
|
"description": "구독 정보 조회"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"endpoint": "/api/v1/subscription/plans",
|
||||||
|
"description": "플랜 목록 조회"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"endpoint": "/api/v1/subscription/payments",
|
||||||
|
"description": "결제 내역 조회"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"endpoint": "/api/v1/subscription/usage",
|
"endpoint": "/api/v1/subscription/usage",
|
||||||
@@ -154,11 +166,11 @@
|
|||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"name": "목업 페이지 감지",
|
"name": "목업 페이지 감지",
|
||||||
"steps": [3],
|
"steps": [2],
|
||||||
"criteria": "구독 정보 카드, 플랜 정보, 사용량 현황 존재"
|
"criteria": "구독 정보, 플랜 정보, 결제 정보 존재"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rollbackPlan": {
|
"rollbackPlan": {
|
||||||
"note": "조회 전용 페이지로 데이터 변경 없음"
|
"note": "조회 전용 페이지로 데이터 변경 없음 (결제/플랜 변경은 별도 테스트)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user