fix: HR/설정 시나리오 셀렉터 수정 (8개 파일)
- settings-attendance: verify_elements→evaluate, :has-text→텍스트 target - settings-vacation-policy: :nth-of-type/:has-text 제거, evaluate로 변경 - employee-register: menuNavigation 사원관리→직원관리, fill_form→evaluate - department-add: verify_elements→evaluate, click_first_row 사용 - settings-rank: :has-text→텍스트 target, 직급명 입력 필드 확인 추가 - settings-position: verify_not_mockup→wait+evaluate, 직책명 입력 확인 - hr-vacation: 날짜 입력 evaluate 추가, :has-text→텍스트 target - hr-salary: 날짜 필터 확인 스텝 추가, :has-text→텍스트 target Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,14 +19,14 @@
|
||||
"targetUrl": "/hr/employee-management",
|
||||
"urlPattern": "/hr/employee-management|/ko/hr/employee-management",
|
||||
"menuHints": [
|
||||
"사원관리",
|
||||
"사원 관리",
|
||||
"직원관리",
|
||||
"직원 관리",
|
||||
"인사관리"
|
||||
]
|
||||
},
|
||||
"menuNavigation": {
|
||||
"level1": "인사관리",
|
||||
"level2": "사원관리",
|
||||
"level2": "직원관리",
|
||||
"expectedUrl": "/ko/hr/employee-management",
|
||||
"searchWithinParent": true,
|
||||
"closeOtherMenus": true
|
||||
@@ -40,7 +40,7 @@
|
||||
"scrollStep": 200
|
||||
},
|
||||
"level2": {
|
||||
"text": "사원관리",
|
||||
"text": "직원관리",
|
||||
"waitAfterLevel1": 500
|
||||
},
|
||||
"fallbackUrl": "/ko/hr/employee-management",
|
||||
@@ -136,52 +136,20 @@
|
||||
{
|
||||
"id": 6,
|
||||
"name": "사원 상세 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{
|
||||
"name": "사원코드",
|
||||
"type": "text",
|
||||
"value": "E2E_TEST_EMP001"
|
||||
},
|
||||
{
|
||||
"name": "남성",
|
||||
"type": "radio",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "상세주소를 입력해주세요",
|
||||
"type": "text",
|
||||
"value": "123번지 4층"
|
||||
}
|
||||
]
|
||||
"action": "evaluate",
|
||||
"script": "(async () => { const w = ms => new Promise(r => setTimeout(r, ms)); const fillByLabel = (label, value) => { const labels = Array.from(document.querySelectorAll('label, span, div, p')); const found = labels.find(l => l.innerText?.trim().includes(label)); if (!found) return false; const container = found.closest('[class*=\"field\"], [class*=\"form-group\"], [class*=\"Form\"], .grid, tr, [class*=\"row\"]') || found.parentElement; if (!container) return false; const input = container.querySelector('input:not([type=\"hidden\"]):not([type=\"radio\"]):not([type=\"checkbox\"]), textarea'); if (input) { const ns = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; if (ns) ns.call(input, value); else input.value = value; input.dispatchEvent(new Event('input', {bubbles:true})); input.dispatchEvent(new Event('change', {bubbles:true})); return true; } return false; }; const r1 = fillByLabel('사원코드', 'E2E_TEST_EMP001'); await w(200); const radioM = document.querySelector('input[type=\"radio\"][value=\"male\"], input[type=\"radio\"][value=\"M\"]') || Array.from(document.querySelectorAll('label')).find(l => l.innerText?.includes('남성'))?.querySelector('input[type=\"radio\"]') || Array.from(document.querySelectorAll('label')).find(l => l.innerText?.includes('남성')); if (radioM) radioM.click(); await w(200); const r3 = fillByLabel('상세주소', '123번지 4층'); return JSON.stringify({code: r1, gender: !!radioM, address: r3}); })()"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "인사 정보 입력",
|
||||
"action": "evaluate",
|
||||
"script": "(async () => { const fillField = (label, value) => { const labels = Array.from(document.querySelectorAll('label, span, div')); const found = labels.find(l => l.innerText?.includes(label)); if (found) { const input = found.closest('.form-group, .field, [class*=field], [class*=form]')?.querySelector('input, textarea, select') || found.parentElement?.querySelector('input, textarea, select'); if (input) { input.focus(); input.value = value; input.dispatchEvent(new Event('input', {bubbles:true})); input.dispatchEvent(new Event('change', {bubbles:true})); return true; } } return false; }; fillField('입사일', '2026-01-14'); await new Promise(r => setTimeout(r, 300)); const clickText = (text) => { const el = Array.from(document.querySelectorAll('button, [role=button], [role=option], li, div[class*=option], span')).find(e => e.innerText?.trim() === text || e.innerText?.includes(text)); if (el) { el.click(); return true; } return false; }; clickText('고용형태 선택'); await new Promise(r => setTimeout(r, 300)); clickText('정규직'); await new Promise(r => setTimeout(r, 300)); clickText('직급 선택'); await new Promise(r => setTimeout(r, 300)); clickText('사원'); await new Promise(r => setTimeout(r, 300)); return 'HR info filled'; })()"
|
||||
"script": "(async () => { const w = ms => new Promise(r => setTimeout(r, ms)); const fillByLabel = (label, value) => { const labels = Array.from(document.querySelectorAll('label, span, div, p')); const found = labels.find(l => l.innerText?.trim().includes(label)); if (!found) return false; const container = found.closest('[class*=\"field\"], [class*=\"form-group\"], [class*=\"Form\"], .grid, tr, [class*=\"row\"]') || found.parentElement; if (!container) return false; const input = container.querySelector('input:not([type=\"hidden\"]):not([type=\"radio\"]):not([type=\"checkbox\"]), textarea'); if (input) { const ns = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; if (ns) ns.call(input, value); else input.value = value; input.dispatchEvent(new Event('input', {bubbles:true})); input.dispatchEvent(new Event('change', {bubbles:true})); return true; } return false; }; fillByLabel('입사일', '2026-01-14'); await w(300); const clickCombobox = async (placeholder) => { const triggers = Array.from(document.querySelectorAll('button[role=\"combobox\"], [class*=\"select-trigger\"], [class*=\"SelectTrigger\"], select, [role=\"combobox\"]')); const trigger = triggers.find(t => t.innerText?.includes(placeholder) || t.getAttribute('placeholder')?.includes(placeholder)); if (trigger) { trigger.click(); await w(500); return true; } return false; }; const clickOption = async (text) => { const options = Array.from(document.querySelectorAll('[role=\"option\"], [role=\"menuitem\"], li[class*=\"option\"], div[class*=\"option\"]')); const opt = options.find(o => o.innerText?.trim() === text || o.innerText?.includes(text)); if (opt) { opt.click(); await w(300); return true; } return false; }; let r1 = await clickCombobox('고용형태'); if (!r1) r1 = await clickCombobox('고용'); await clickOption('정규직'); await w(300); let r2 = await clickCombobox('직급'); await clickOption('사원'); return JSON.stringify({employType: r1, rank: r2}); })()"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "사용자 정보 입력",
|
||||
"action": "fill_form",
|
||||
"fields": [
|
||||
{
|
||||
"name": "아이디 *",
|
||||
"type": "text",
|
||||
"value": "e2e_test_user001"
|
||||
},
|
||||
{
|
||||
"name": "비밀번호 *",
|
||||
"type": "text",
|
||||
"value": "password123!"
|
||||
},
|
||||
{
|
||||
"name": "비밀번호 확인 *",
|
||||
"type": "text",
|
||||
"value": "password123!"
|
||||
}
|
||||
]
|
||||
"action": "evaluate",
|
||||
"script": "(async () => { const w = ms => new Promise(r => setTimeout(r, ms)); const fillByLabel = (label, value) => { const labels = Array.from(document.querySelectorAll('label, span, div, p')); const found = labels.find(l => l.innerText?.trim().includes(label)); if (!found) return false; const container = found.closest('[class*=\"field\"], [class*=\"form-group\"], [class*=\"Form\"], .grid, tr, [class*=\"row\"]') || found.parentElement; if (!container) return false; const input = container.querySelector('input:not([type=\"hidden\"]):not([type=\"radio\"]):not([type=\"checkbox\"]), textarea'); if (input) { const ns = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; if (ns) ns.call(input, value); else input.value = value; input.dispatchEvent(new Event('input', {bubbles:true})); input.dispatchEvent(new Event('change', {bubbles:true})); return true; } return false; }; const r1 = fillByLabel('아이디', 'e2e_test_user001'); await w(200); const r2 = fillByLabel('비밀번호', 'password123!'); await w(200); const pwInputs = Array.from(document.querySelectorAll('input[type=\"password\"]')); if (pwInputs.length >= 2) { const ns = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; if (ns) ns.call(pwInputs[1], 'password123!'); else pwInputs[1].value = 'password123!'; pwInputs[1].dispatchEvent(new Event('input', {bubbles:true})); pwInputs[1].dispatchEvent(new Event('change', {bubbles:true})); } return JSON.stringify({id: r1, pw: r2, pwConfirm: pwInputs.length >= 2}); })()"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
|
||||
Reference in New Issue
Block a user