맨날개발 2025. 1. 7. 20:37

Playwright에서는 사용자가 HTML로 상호작용하는 많은 부분에 대한 기능을 제공한다. 예로 input을 통해 입력하거나, 마우스 클릭, 파일 업로드 기능까지 지원한다.

 

🎈 Text input

input에 텍스트를 입력하는 가장 쉬운 방법은 locator.fill() 을 사용하는 것이다. input 요소에 포커스하고 입력된 텍스트로 input 이벤트를 트리거한다.

 

아래의 3 종류의 엘리먼트에서 사용 가능하다.

  • input
  • textarea
  • [contenteditable]
await page.getByRole('textbox').fill('안녕하세요.');
await page.getByLabel('Local time').fill('2020-03-02T05:15');

 

✨ fill 함수의 경우 기존의 컨텐츠를 모두 제거후 해당 텍스트로만 채우는 기능이다.

 

input 등에 입력 된 텍스트를 확인할 때는 toHaveValue 매처를 사용한다.

await expect(page.getByRole('textbox')).toHaveValue('안녕하세요');

 

 

🛒 체크박스와 라디오 버튼

체크박스와 라디오 박스에 값을 설정하는 가장 쉬운 방법은 locator.setChecked(값)을 사용하는 것이다. 값을 전달해서 원하는 상태를 설정할 수 있다. 보통은 테스트 전 미리 상태를 셋팅할 때 사용하게 된다.

 

해당 함수는 아래의 3 종류의 엘리먼트에서 사용 가능하다.

  • input[type=checkbox]
  • input[type=radio]
  • [role=checkbox]
await page.getByRole('checkbox').setChecked(true);
await page.getByRole('checkbox').setChecked(false);

 

 

다른 방법으로 locator.check()locator.uncheck()가 존재한다. 함수이름으로 행동을 명확히 전달하고 싶다면 해당 함수를 사용하면 좋다.

  locator.check()는 체크하는 행위를 정의한게 아닌 checked 상태를 true로 만들어주는 것이다.
그래서 반대 행위인 locator.uncheck()가 존재한다.

 

체크 상태를 검증할 때는 toBeChcked를 사용한다.

expect(page.getByRole('checkbox')).toBeChecked();
expect(page.getByRole('checkbox')).not.toBeChecked();

 

 

📯 셀렉트 옵션

셀렉트박스에서 셀렉트할때는 locator.selectOption() 함수를 사용한다. 하나 또는 다중선택 모두 가능하다. 셀렉트 옵션에 설정 된 label 또는 value를 활용해서 모두 선택이 가능하다.

 

파라미터로 label 속성을 지정하면 label로 선택가능하고 나머지는 값으로 인식한다. 배열을 전달하면 배열의 값과 value를 비교해서 다중 선택할 수 있다.

await page.getByLabel('Select').selectOption('hello');
await page.getByLabel('Select').selectOption(['hello', 'hi']);
await page.getByLabel('Select').selectOption({ label: 'Hello' });

 

선택 한 대상을 검증할 때는 toHaveValue 매처를 사용한다.

await expect(page.getByLabel('Select')).toHaveValue('hello');

 

다중선택된 대상을 모두 확인 하고 싶은 경우 toHaveValues 를 사용한다.

await expect(page.getByLabel('Select')).toHaveValues(['hello', 'hi']);

 

 

👓 마우스 클릭

사람이 마우스 클릭하는 것처럼 클릭을 수행한다.

await page.getByRole('button').click();
await page.getByRole('button').dblclick();
await page.getByRole('button').click({ button: 'right' });
await page.getByRole('button').click({ modifiers: ['Shift'] });
await page.getByRole('button').click({ modifiers: ['ControlOrMeta'] });
await page.getByRole('button').click({ position: { x: 0, y: 0 } });
await page.getByRole('button').click({ force: true });

await page.getByRole('button').hover();
  • click() : 일반적인 클릭
  • dblclick() : 더블 클릭
  • click({ button: ‘right’ }) : 우측 클릭
  • click({ modifiers: ['Shift'] }) : Shift + 클릭
  • click({ modifiers: ['ControlOrMeta'] }) : Ctrl + 클릭(윈도우 또는 리눅스) 또는 Meta + 클릭(맥)
  • click({ position: { x: 0, y: 0 } }) : 대상의 좌측 상단 코너를 기준으로 해당 좌표를 클릭
  • click({ force : true }) : 강제 클릭. 일반적인 사용방법은 아니지만 강제 클릭을 사용해야하는 경우가 존재.
  • hover

 

👔 키입력과 숏컷

사용자가 타이핑하는 것처럼 키를 입력할 수 있다. press는 사용자가 키보드에서 하나의 키입력과 관련된 모든 이벤트(keydown, keyup, kekypress)를 발생시킨다.

 

press의 파라미터로는 숏컷이 아니라면 문자열을 전달할 수 없다. locator.fill()와 같이 문자열을 사용하고 싶다면 반복문을 이용하거나 여러번의 press 코드를 사용해야 한다.

await page.getByText('Submit').press('Enter');
await page.getByRole('textbox').press('Control+ArrowRight');
await page.getByRole('textbox').press('a');

// ❎ 아래처럼 사용불가
await page.getByRole('textbox').press('안녕하세요');

 

파라미터로 논리적 키 이름을 사용할 수 도 있다. 아래와 같은 논리적 키 이름을 사용가능하다.

Backquote, Minus, Equal, Backslash, Backspace, Tab, Delete, Escape,
ArrowDown, End, Enter, Home, Insert, PageDown, PageUp, ArrowRight,
ArrowUp, F1 - F12, Digit0 - Digit9, KeyA - KeyZ, etc.

 

Shift, Control, Alt, Meta와 같은 수정자를 사용하는 건 허용한다.

await page.locator('#name').press('Shift+A');
await page.locator('#name').press('Shift+ArrowLeft');
await page.locator('#name').press('Control+Shift+T');

 

✨ 이때 대문자를 지정하려면 Shift + A와 같이 뒤에 오는 문자가 대문자여야 한다. Shift + a는 소문자로 입렵된다. 이건 Caps Lock 상태일때를 위한 테스트를 위해 제공한다.

 

 

🩳 파일 업로드

playwright에서는 locator.setInputFiles()를 사용해서 input[type=file]에 파일을 설정 가능하다. 이때 파일을 저장 하는 건 실제 파일 경로에서 저장하는 것이다. 상대경로로 설정하는 경우 현재 테스트 파일이 위치한 곳으로부터 경로를 지정하면 된다.

// 단일 파일
await page.getByLabel('Upload').setInputFiles(path.join(__dirname, 'test.txt'));

// 다중 파일
await page.getByLabel('Upload').setInputFiles([
  path.join(__dirname, 'test1.txt'),
  path.join(__dirname, 'test2.txt')
]);

// 선택된 파일 모두 제거
await page.getByLabel('Upload').setInputFiles([]);

 

✨ 이를 통해서 파일 업로드 시 이미지 미리보기 등을 테스트해볼 수 있을 것 같다.

 

 

🧣 포커싱

포커싱하는 건 locator.fucus()를 통해서 간단하게 처리할 수 있다.

await page.getByLabel('Password').focus();

 

 

👜 드래그 앤 드롭

드래그앤드롭은 locator.dragTo()를 통해서 수행할 수 있다. 해당 함수 실행 시 아래와 같은 절차를 따른다.

  1. 드래그 할 요소에 마우스를 올린다
  2. 왼쪽 마우스 버튼을 클릭 후 유지
  3. 드롭할 위치로 마우스를 이동
  4. 왼쪽 버튼 클릭 해제
await page.locator('.item').dragTo(page.locator('.area'));

 

✨ 드롭할 위치도 locator를 전달하면 된다.
✨ 만약 좀 더 정확한 드래그 앤 드롭을 구현하고 싶다면 위의 4가지 과정을 실제로 구현하면 된다.

 

 

🎨 스크롤링

대부분의 playwright로 작업을 수행하는 경우 따로 스크롤링을 지정하지 않더라도 playwright에서 자동으로 스크롤링 후 개발자가 지정한 작업을 수행하게 된다. 그래서 따로 스크롤링을 할 필요는 없다.

 

예를 들어 아래와 같이 버튼을 클릭한다고 하면 버튼이 화면상에서 보이는 위치로 스크롤링을 한 후에 아래의 버튼 클릭 작업을 수행하게 된다.

await page.getByRole('button').click();

 

테스트 코드를 작성하다보면 명시적으로 스크롤을 해야하는 경우가 존재한다.

  1. 무한 스크롤 구현을 테스트
  2. 스크린샷을 원하는 위치로 이동

 

스크롤하는 가장 안정적인 방법은 locator.scrollIntoViewIfNeeded()를 사용하는 것이다. 해당 함수는 대상이 화면에 보이는 위치를 자동으로 계산해서 이동하게 해준다. 따로 좌표를 지정할 필요가 없기 때문에 레이아웃이 변경되거나 하는 경우에도 테스트 코드를 수정할 필요가 없게 해준다.

await page.getByText('Footer text').scrollIntoViewIfNeeded();

 

대부분은 scrollIntoViewIfNeeded를 사용하면 되지만 좀 더 정확하게 스크롤을 이동해야하는 하는 경우에는 다음과 같은 방법을 사용해볼 수 있따.

  • page.mouse.wheel(x, y);
  • locator.evalute(e ⇒ e.scrollTop += 100);
✨ page.mouse.wheel을 사용하고, 만약 이를 활용할 수 없을 경우에만 evalute에서 처리하자.