Logo
Hyunsu Blog
playwright-config

๐Ÿ“†Published :Aug 26, 2021 โ€ข

๐Ÿ“†Updated :Aug 26, 2021 โ€ข

โ˜•๏ธ2min

Typescript + Playwright + Jest ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์ถ•

Jest๋ฅผ ์„ ํƒํ•˜๊ธฐ ๊นŒ์ง€

๊ฐ€์žฅ ์•ˆ์ •์ ์ด๊ณ  ๋„๋ฆฌ ์•Œ๋ ค์ง„ Mocha์™€์˜ ์„ฑ๋Šฅ์ฐจ์ด๋ฅผ ๋น„๊ตํ•œ ๊ฐ€์šด๋ฐ, ํ…Œ์ŠคํŒ… ์†๋„ ๋˜ํ•œ ์˜๊ฒฌ์ด ๋ถ„๋ถ„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ €ํฌ ํ”„๋กœ์ ํŠธ์— ๋งž๋Š” ๊ฒฐ์ •์  ์š”์ธ์ด ๋‚ด๋ ค์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ ์œ ์œจ์„ ํ™•์ธ ํ›„, JEST๊ฐ€ ๋†’์€ ๊ฐ€์šด๋ฐ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฐœ๋ฐœ์ž ๋ฐ ํ”„๋กœ์ ํŠธ์˜ ํŠน์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ด์ ์œผ๋กœ ์„ ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. (ํ˜น์‹œ ๊ฒฝํ—˜์ด ์žˆ์œผ์‹œ๊ฑฐ๋‚˜ ๊ณ ๋ คํ•  ์‚ฌํ•ญ๋“ค์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!)

  1. ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ cli์—์„œ ๋‚ด์žฅ๋œ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ .
  2. Playwright ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ jest์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ง€์›
  3. Jest ๋˜ํ•œ Typescript ๋ฅผ ์ง€์›
  4. ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํŒŒ์ผ/๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ ์ง€์ •์ด ์œ ๋™์  (์‹คํ–‰ํ•˜๋ ค๋Š” ํŒŒ์ผ์„ regex๋กœ ๊ตฌ๋ถ„ํ•˜๋ฏ€๋กœ ํ†ตํ•ฉํ…Œ์ŠคํŠธ๋‚˜, ์›น ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ ์‹œ ๊ตฌ๋ณ„ํ•˜์—ฌ ๋”ฐ๋กœ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๊ฐ€๋Šฅ)
  5. ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ (๊ฐ€์žฅ ๋Š๋ฆฐ ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ์‹คํ–‰) -> ํšจ์œจ์ .
stackshare

์ด๋ฏธ์ง€ ๋ฐœ์ทŒ : npmtrends

ํ˜„์žฌ ๋ฒ„์ „ jest 27.0

1. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์„ค์น˜

npm install -D typescript

2. Jest Playwright ์„ค์น˜ (Jest ๋ฐ Playwright ๊ด€๋ จ ํŒจํ‚ค์ง€)

npm install -D jest jest-playwright-preset playwright ts-jest @types/jest
  • jest-playwright-preset : Playwright๋กœ ์ œ์–ด๋˜๋Š” ๋ธŒ๋ผ์šฐ์ €(headless browser)์—์„œ Jest๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š” preset์ž…๋‹ˆ๋‹ค.

  • ts-jest : Jest๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰ ๋  ๋•Œ type-check์„ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, type-check์„ ํ•˜๊ธฐ ์œ„ํ•ด์„  ts-jest๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ tsc๋ฅผ ๋ณ„๋„๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ๊ธˆ ๋” ์ˆ˜์›”ํ•˜๊ฒŒ ํ•˜๋„๋ก ts-jest๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/kulshekhar/ts-jest

  • @types/jest: jest๋ฅผ ์œ„ํ•œ ํƒ€์ž…์ด ์ •์˜ ๋˜์–ด ์žˆ๋Š” ํŒจํ‚ค์ง€ ์ž…๋‹ˆ๋‹ค. types์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…

NOTE : @types/ ๋ชจ๋“ˆ๋“ค์€ ๊ด€๋ จ์žˆ๋Š” ๋ชจ๋“ˆ๊ณผ ๋ฒ„์ „์„ ์ผ์น˜ ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ถŒ๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 26.4.0 ๋ฒ„์ „์˜ jest๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, 26.4.์˜ @types /jest๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ฆ‰ ๋ฉ”์ด์ € ๋ฒ„์ „๊ณผ ๋งˆ์ด๋„ˆ ๋ฒ„์ „์„ ๊ฐ€๋Šฅํ•œ ๋งค์น˜ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.) ์ถœ์ฒ˜: JEST ๊ณต์‹๋ฌธ์„œ

3. JEST configuration

Jest ์˜ ํ™˜๊ฒฝ์„ค์ •์€ package.json ๋˜๋Š” jest.config.ts ์ฒ˜๋Ÿผ ํŒŒ์ผ์„ root ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์— ์ƒ์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. configuration ๊ณต์‹๋ฌธ์„œ ์ฐธ์กฐ

์ €๋Š” ์ข€ ๋” ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์„ค์ •์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์•„ ํŒŒ์ผ์„ ๋”ฐ๋กœ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

module.exports = { preset: 'jest-playwright-preset', testTimeout: 20000, transform: { '^.+\\.ts$': 'ts-jest', }, testEnvironmentOptions: { 'jest-playwright': { // Options... browsers: ['chromium'], //์‚ฌ์šฉํ•  ๋ธŒ๋ผ์šฐ์ € ์ง€์ •, ["chromium","firefox","safari"] ๋ชจ๋‘ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ launchOptions: { headless: false, //๋ธŒ๋ผ์šฐ์ €๋ฅผ ์Šคํฌ๋ฆฐ์ƒ์— ๋ณด์—ฌ์ค„ ๊ฒƒ์ธ์ง€ false- ๋ณด์—ฌ์คŒ slowMo: 100, // ๋ธŒ๋ผ์šฐ์ €์˜ ์ง„ํ–‰์†๋„ }, }, }, }
  • transform : Jest๋Š” ํ”„๋กœ์ ํŠธ ์ฝ”๋“œ๋ฅผ JavaScript๋กœ ์‹คํ–‰ํ•˜์ง€๋งŒ Node.js์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์œ ํ˜•๋“ค (Typescript, Vue)์˜ ๊ฒฝ์šฐ transform์˜ ๊ตฌ์„ฑ ์˜ต์…˜์„ ํ†ตํ•ด JavaScirpt๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • testTimeout: playwright-jest ์—์„  playwright ์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—, 5์ดˆ์—์„œ 15์ดˆ ์ •๋„๋ฅผ ๊ธฐ์กด์˜ jest์„ค์ •์„ ์žฌ์ •์˜ ํ•˜๋Š”๋ฐ testTimeout ์œผ๋กœ ๋‹ค์‹œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. jest-playwright ์ฐธ์กฐ

    • ์ œ๊ฐ€ ์‹ค์ œ ๊ฒช์€ BeforeAll์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ running ํ•˜์ง€ ๋ชปํ•˜๊ณ  timeout์ด ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. thrown: "Exceeded timeout of 15000 ms for a hook. Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
  • launchOptions

    • healess : false ์ผ ๊ฒฝ์šฐ, browser๋ฅผ ์˜คํ”ˆํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. true ์ผ ๋•Œ๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋„์šฐ๋Š” ๋น„์šฉ์ด ๋“ค์ง€ ์•Š๋Š” ๋งŒํผ ๋น ๋ฅธ ํ…Œ์ŠคํŒ… ์†๋„๋ฅผ ๋ƒ…๋‹ˆ๋‹ค.

    • slowMo : headless ๊ฐ€ false์ผ ๋•Œ, ms ๋‹จ์œ„๋กœ ๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ๋“ค์ด ์ฒœ์ฒœํžˆ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ๋””๋ฒ„๊น…์‹œ ๊ฐ ์ด๋ฒคํŠธ๋งˆ๋‹ค ์–ด๋–ป๊ฒŒ ์ผ์–ด๋‚˜๋Š”์ง€ ๋ณผ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    slowMo:0 (default) vs slowMo:250 headful ๋ธŒ๋ผ์šฐ์ €๊ฐ€ wikipedia์—์„œ javascript ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” headless:false ์™€ slowMo๋ฅผ ์‚ฌ์šฉํ•˜๋˜, ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ์—์„œ๋Š” headless:true ์„ค์ •์œผ๋กœ ๋น ๋ฅธ ์‹คํ–‰ ์†๋„๋ฅผ ๊ฐ€์ง€๋Š”๊ฒŒ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

4. TypeScript Configuration

์ตœ์†Œํ•œ์˜ ์„ค์ •์„ ๋‹ด์€ tsconfig.json ์ž…๋‹ˆ๋‹ค.

{ "compilerOptions": { "target": "ESNext", "module": "commonjs", "strict": true, "forceConsistentCasingInFileNames": true, "types": [ "@types/jest", "jest-playwright-preset", // "expect-playwright", ] "rootDir": "src", "outDir": "lib", "lib": [ "es2017", "DOM","DOM.iterable" ] }, "files": [] }

strict์— ๋Œ€ํ•œ ์ดํŽ™ํ‹ฐ๋ธŒ ํƒ€์ž…์Šค๋ฆฝํŠธ ์ •๋ฆฌ ๊ธ€

5. package.json

{ ..., "scripts": { "test": "jest", }, ... }

๋””๋ฒ„๊น… ๋ฐฉ๋ฒ•

1. Run in headed mode

await chromium.launch({ headless: false, slowMo: 100 }) // or firefox, webkit

2. Playwright Inspector

์ €๊ฐ™์€ ๊ฒฝ์šฐ๋Š” selector์— ๋งŽ์ด ํ• ์•  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— inspector๋ฅผ ํ†ตํ•ด ์ฐพ๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ์œผ๋กœ ์ด์šฉ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

2-1. ์Šคํฌ๋ฆฝํŠธ์—์„œ breakpoint๋ฅผ ์‚ฌ์šฉํ•˜๋“ฏ์ด await page.pause(); ์›ํ•˜๋Š” ๋ผ์ธ์— ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

describe('GitHub', () => { it('should show the microsoft/Playwright project in the search if you search for Playwright', async () => { await page.goto('https://github.com') await page.pause() await page.type('input[name="q"]', 'Playwright') await page.press('input[name="q"]', 'Enter') await expect(page).toMatchText('.repo-list-item', 'microsoft/playwright') }) })

2-2. PWDEBUG=1 ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์‚ฌ์šฉ

PWDEBUG=1 ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, await page.pause() ์˜ ์œ„์น˜์™€ ์ƒ๊ด€์—†์ด ์ค‘๋‹จ์ ์ด ์Šคํฌ๋ฆฝํŠธ์˜ ๋งจ ์ฒซ์ค„์—์„œ ํŠธ๋ฆฌ๊ฑฐ ๋ฉ๋‹ˆ๋‹ค.

# Linux/macOS PWDEBUG=1 npm run test # Windows with cmd.exe set PWDEBUG=1 npm run test # Windows with PowerShell $env:PWDEBUG=1 npm run test

๋˜ํ•œ inspector์—์„œ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‚ด์—์„œ ์ผ์–ด๋‚˜๋Š” ๋ชจ๋“  ์ด๋ฒคํŠธ์˜ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑ ํ•ด์ค๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด,

jest.setTimeout(1000000) describe('GitHub', () => { it('should show the microsoft/Playwright project in the search if you search for Playwright', async () => { await page.goto('https://wikipedia.org') await page.pause() }) })

์œ„์˜ ์Šคํฌ๋ฆฝํŠธ์™€ ํ•จ๊ป˜ PWDEBUG=1 npm run test์„ ์‹คํ–‰์‹œํ‚จ ํ›„, Record ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด, ๋…นํ™”๋ชจ๋“œ๋กœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

recording1

์˜ค๋ฅธ์ชฝ์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์›ํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

recording2

์ด ๋ถ€๋ถ„์ด ์œ ์šฉํ•˜๋‹ค๊ณ  ๋Š๋‚€์ ์€, ์ œ๊ฐ€ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „๊นŒ์ง„ promise race condition ๋ถ€๋ถ„์„ ์ฒ˜๋ฆฌํ•˜๋Š๋ผ ์ฝ”๋“œ๋ฅผ vscode ๋””๋ฒ„๊น…์„ ๋Œ๋ฆฌ๊ณ , promise return ๊ฐ’์„ ํ™•์ธํ•˜๊ณ  ๋‹ค์‹œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑ ํ•ด์•ผ ํ–ˆ์—ˆ๋Š”๋ฐ, Promise.all๋กœ ์ž๋™ ์ƒ์„ฑํ•˜์—ฌ race condition์ด ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ค„์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

recording3

์ด์ƒ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • ๋ฐ ๋””๋ฒ„๊น… ํŽธ์ด์—ˆ์Šต๋‹ˆ๋‹ค.


์ฐธ๊ณ ์ž๋ฃŒ

Hi, I'm Hyunsu ๐Ÿ‘‹

Profile Image

์•ˆ๋…•ํ•˜์„ธ์š”. ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ฃผํ˜„์ˆ˜์ž…๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ํ’๋ถ€ํ•˜๊ณ  ๊ฐ€์น˜ ์žˆ๋Š” ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ์ผ์— ๋ฟŒ๋“ฏํ•จ์„ ๋Š๋‚๋‹ˆ๋‹ค.

์˜ต์‹œ๋””์–ธ(Obsidian)์—์„œ ํ˜„์žฌ ๋ธ”๋กœ๊ทธ๋กœ ํ•˜๋‚˜์”ฉ ๊ธ€์„ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์— ์žˆ์–ด์š”. โ˜•๏ธ ๐Ÿ‘ฉโ€๐Ÿ’ป โ›ท

Github on ViewReach Me Out