[인프런] Playwright 기초 - 기초적인 활용법과 핵심 원리
Section4 핵심개념
8강 웹 친화적인 작동방식
Resilient no Freaky 테스트
=> 번역하자면 탄력적이고 불안정한 테스트
예상치 못한 엣지 케이스나 이상한 입력을 시스템에 넣어 비정상적인 상황을 테스트하는 걸 의미
로케이터 유형 설명 예제
page.locator("css=selector") | CSS 선택자로 찾기 | page.locator("css=.button") |
page.locator("xpath=//div[@class='button']") | XPath로 찾기 | page.locator("xpath=//button[@id='submit']") |
page.locator("text=로그인") | 텍스트로 찾기 | page.locator("text=로그인") |
page.locator("id=login") | ID로 찾기 | page.locator("id=login") |
page.locator("role=button[name='확인']") | 접근성 역할(Role) 기반 찾기 | page.locator("role=button[name='확인']") |
로케이터 사용법
Playwright에서는 로케이터를 활용해 요소를 찾고 다양한 액션을 수행
#클릭하기
button = page.locator("text=Submit")
button.click()
#텍스트 입력하기
button = page.locator("text=Submit") button.click()
#요소가 나타날 때까지 기다리기
page.locator("text=Loading...").wait_for(state="hidden")
#여러 개의 요소 찾기
items = page.locator(".list-item")
print(items.count()) # 리스트 개수 출력
로케이터 vs 기존 요소 선택 방식
기존에는 page.query_selector() 같은 방식으로 요소를 찾았지만, 로케이터는 더 강력하고 효율적인 방식
page.locator()는 지연 평가(lazy evaluation)를 하므로, DOM이 동적으로 변경되어도 최신 요소를 찾을 수 있음
page.query_selector()는 즉시 평가되므로 요소가 동적으로 바뀌면 업데이트되지 않을 수 있음
DOM(Document Object Model)
웹 페이지의 HTML 문서를 브라우저가 해석하여 만든 구조화된 트리(Tree) 형태의 모델
HTML 문서를 JavaScript나 Playwright 같은 도구로 조작할 수 있도록 변환한 객체 모델
웹 페이지를 로드하면 브라우저는 HTML 코드를 읽고 이를 DOM 트리로 변환해.
Ex. 아래와 같은 HTML이 있다..!
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is a paragraph.</p>
</body>
</html>
이 HTML 문서는 브라우저에서 DOM 트리로 변환
DOM 트리 구조
document
├── html
│ ├── head
│ │ ├── title (My Page)
│ ├── body
│ ├── h1 (Hello, World!)
│ ├── p (This is a paragraph.)
각 HTML 태그가 노드(Node) 가 되고, 이 노드들을 통해 JavaScript나 Playwright에서 요소를 조작할 수 있음..!
DOM을 조작하는 방법
1. JavaScript로 DOM 변경하기
document.querySelector("h1").textContent = "Changed Title!";
#querySelector("h1") → <h1> 요소를 선택하고 textContent를 변경
2. Playwright에서 DOM 요소 찾기
page.locator("h1").text_content()
DOM의 개념
DOM은 트리(Tree) 구조
document가 최상위 노드(루트)이며, 그 아래에 html, head, body 등이 있음.
노드(Node) 타입
DOM에서는 요소가 여러 유형의 노드(Node)로 표현
노드 타입 설명 예시
요소 노드(Element Node) | HTML 태그 자체 | <h1>, <p> |
텍스트 노드(Text Node) | 태그 내부의 텍스트 | "Hello, World!" |
속성 노드(Attribute Node) | 요소의 속성값 | id="main" |
DOM 조작
읽기: document.querySelector("h1").textContent
수정: document.querySelector("h1").textContent = "New Title"
추가: document.createElement("div")
삭제: element.remove()
결론 : Playwright에서 DOM을 다루는 방법을 잘 알아야 웹 자동화를 쉽게 할 수 있음~!~!
#Playwright에서 요소 찾기
page.locator("h1").text_content()
#Playwright에서 DOM 요소 클릭하기
page.locator("button").click()
#Playwright에서 입력하기
page.locator("#username").fill("test_user")
정리
DOM | HTML 문서를 브라우저가 해석하여 만든 트리 구조 |
노드(Node) | HTML 태그, 텍스트, 속성 등을 객체로 표현한 것 |
요소 선택 | document.querySelector("h1"), page.locator("h1") |
요소 조작 | textContent, innerHTML, click(), fill() 등 |
네비게이션 완료와 검증이 서로 레이스 상태
결론
e2e 테스트에서 테스트 대상인 웹 앱과 테스트가 서로 다른 프로세스에서 동작함
비동기(Asynchronous)
어떤 작업을 실행할 때 다른 작업이 끝날 때까지 기다리지 않고 즉시 다음 작업을 수행하는 방식
비동기가 필요한 이유
어떤 작업이 오래 걸리는 경우(예: 서버에서 데이터 가져오기, 파일 읽기 등) 기다리면 프로그램이 멈춘 것처럼 보일 수 있으나
비동기를 사용하면 메인 프로그램이 멈추지 않고 다른 작업을 계속할 수 있음
특히 JavaScript는 기본적으로 싱글 스레드(single-thread) 기반이라 비동기 처리가 매우 중요
=> 다른 프로세스에서 작동하기 때문에 생기는 문제 해결위해 playwright의 많은 api 웹 친화적으로 작동
일정 시간동안에 계속 try, 성공 시 다음 단계로 진행, 만약 시간 안에 성공 못하면 에러나는 발생
결론
playwright은 별도의 프로세스로 전개, fill 이벤트에 대해서 상태 전파가 완료되었다는 것을 100% 보장할 수 x
따라서 대부분 기능들이 테스트의 안정성 높이기 위해 웹 친화적으로 설계
해당 단계 일정 시간동안 retry 방식으로 작동, 시간 안에 성공하면 다음 단계 진행, 실패 시 해당 테스트 전체 실패