Playwright issues

#0 - selecting <Select/> from Ant.design

Situation

원래는 Locator | Playwright 을 이용해 select의 자식들을 선택할 수 있어야하지만, ant design의 select는 클릭 후 비동기적으로 option들을 dom tree에 추가시키는 형태여서 마땅한 dom selector가 없는 상황

id로 선택하려고 해도 rc_select_<number> 형태로 임의의 숫자가 붙이기에 id selector는 안됨

Attempt #1

playwright의 network response를 intercept하는 기능을 사용하여 해당 테스트를 진행하는 동안에만 item 개수를 제한해서 테스트하기

const MOCK_DATA = {
  data: {
    waitlistConnection: {
      edges: [
        {
          id: 'test-id',
          firstName: 'test',
          lastName: 'test',
          companyName: 'test',
          emailAddress: 'test',
          status: 'INVITED',
          registerDate: new Date(),
        },
      ],
    },
  },
}

test.beforeEach(async ({ page, baseURL }) => {
  await page.goto(`${baseURL}waitlist`)

  await page.route('https://apiToFetch.com', async (route) => {
    route.fulfill({ json: MOCK_DATA })
  })
  await page.waitForResponse('https://apiToFetch.com')
})

item 개수를 한개로 만들면 새로 생성된 option은 무조건 해당 item의 것임으로 테스트 가능

Attempt #2

화면을 기준으로 해당 select의 위치와 크기를 이용해서 클릭하기

const select = page
  .locator('.ant-select-selector')
  .filter({ hasText: /registered/i })
  .nth(0)

await select.click()

const selectBox = await select.boundingBox()

await page.mouse.click(selectBox.x + selectBox.width / 2, selectBox.y + selectBox.height * 3 + 10)

Attempt #3

test 1회당 1회 클릭 하는 것을 전제로 waitFor 사용하기

const differentOption = page.locator('.ant-select-item-option').nth(0)

await differentOption.waitFor()
await differentOption.click()

제일 깔끔하지만 click 2회 이상은 안됨, page.close 나 page.reload 필요해짐


#1 - playwright VS cypress

Situation

  1. 데모 시연을 위한 —trace(Trace viewer | Playwright)가 nx을 위한 playwright plugin 에서 작동하지 않음

Pros & Cons - playwright

TL;DR - 많은 테스트들을 빠르게 돌리기 좋다, 데모 및 디버깅용으로는 아쉽다

Pros

  1. Parallelism and sharding | Playwright 테스트들을 병렬로 돌려서 많은 테스트를 빨리 끝낼 수 있다
  2. Test generator | Playwright 직접 로컬에서 화면을 띄워서 인터랙션하고 그 결과를 codegen 시킬 수 있다
  3. Browsers | Playwright 한번에 여러 브라우저들을 테스트할 수 있다
  4. Emulation | Playwright 모바일 환경에서 테스트 할 수도 있다

Cons

  1. playwright 자체적으로는 문제가 없을 수 있지만, nx와 호환이 잘 안되는 부분들이 있다(공식 플러그인 또한 없다)
  2. 데모 시연을 하기 위해서는 부족한 설정들, 예컨대 slowmo를 이용해서 천천히 볼 수 있지만 모든 스텝을 느리게 만들기에 req, res마저 기다려야 한다. 또한 debugger에서 한단계씩 볼순 있지만 뒤돌아가기는 안된다
  3. 2번 장점이었던 test generator는 애초에 TDD로 작성한 화면이 아니라면 크게 도움이 되지 않는다. 아래 사진을 보면 dom selector가 난장판이다

Pros & Cons - cypress

TL;DR - 데모 및 디버깅이 괜찮고 코드도 직관적이다. 다만 기능상 아쉬운 점들이 있다

Pros

  1. 데모 시연을 위해 더 나은 GUI와 설정들이 있다.
    • 단계별 보기
    • req, res을 따로 설정하지 않아도 보여주고 거기에 별명을 붙일 수도 있다
cy.session(
  username,
  () => {
    cy.request('POST', Cypress.env('API_LOGIN'), {
      username,
      password,
    }).as('currentUser')

    cy.request('POST', Cypress.env('API_AUTH_REFRESH')).as('authRefresh')
  },
  {
    validate: () => {
      cy.getAllCookies()
        .should('have.length.above', 0)
        .then((cookies) => {
          expect(cookies[0]).to.have.property('name', 'sRefreshToken')
          expect(cookies[1]).to.have.property('name', 'sAccessToken')
        })
    },
  }
)
  1. within | Cypress 등을 이용하면 debugger에서 실행단계를 더 직관적으로 볼 수 있다
cy.get('form').within(() => {
  getInputByPlaceholer('email').type(Cypress.env('BACKOFFICE_ID'))
  getInputByPlaceholer('password').type(Cypress.env('BACKOFFICE_PW'))
  getButtonByName('log in').click()
})
  1. cypress cloud를 사용해서 테스트 결과를 영상으로 남길 수도 있다, cloud를 사용하지 않아도 다른 테스트를 돌리기 전까진 영상을 볼 수 있다

  2. session | Cypress 세션을 생성해서 로그인이 필요한 화면의 경우 playwright와 다르게 매번 로그인 request를 보낼 필요가 없다

Cons

  1. Parallelization | Cypress 테스트를 병렬로 돌리기 위해서는 cypress cloud을 사용해야 하고 월 500회 이상부터는 유료다
  2. Cross Browser Testing | Cypress 한번에 여러 브라우저들을 headed로 돌릴 순 없다. headless또한 Circle CI orb을 통해서 세팅 이후에 돌릴 수 있다
  3. General Questions | Cypress 모바일 환경에서 테스트할 수 없다. 다만 비슷하게 viewport를 줄인 채로는 가능하다