[240106] TIL
playwright ๊ธฐ๋ณธ ์ฌ์ฉ ๋ฐฉ๋ฒ
์ฝ๋ ์คํ
yarn playwright test stock.spec.ts
[Installation | Playwright](https://playwright.dev/docs/intro) |
Action
Navigation
await page.goto("http://playwright.dev/");
[Page | Playwright](https://playwright.dev/docs/api/class-page#page-goto) |
- ๊ธฐ๋ณธ ๋ฆฌ์์ค ์๋ต์ ๋ฐํ
Interactions
// Create a locator
const getStarted = page.getByRole("link", { name: "Get started" });
// Click it
await getStarted.click();
Action | Description |
---|---|
locator.check() | Check the input checkbox |
locator.click() | Click the element |
locator.uncheck() | Uncheck the input checkbox |
locator.hover() | Hover mouse over the element |
locator.fill() | Fill the form field, input text |
locator.focus() | Focus the element |
locator.press() | Press single key |
locator.setInputFiles() | Pick files to upload |
locator.selectOption() | Select option in the drop down |
locator
// 1. ๊ธฐ๋ณธ์ ์ธ locator ์ฌ์ฉ๋ฒ
test("locator ์์ ", async ({ page }) => {
// text๋ก ์ฐพ๊ธฐ
page.locator("text=๋ก๊ทธ์ธ");
// CSS ์ ํ์๋ก ์ฐพ๊ธฐ
page.locator(".login-button");
page.locator("#username");
// role๋ก ์ฐพ๊ธฐ (์ ๊ทผ์ฑ ๊ด๋ จ)
page.locator("role=button");
// XPath๋ก ์ฐพ๊ธฐ
page.locator("xpath=//button");
});
- ์ฒด์ด๋ ๊ฐ๋ฅ
- ๋ค์ํ ๋ฐฉ์์ผ๋ก ์์ ์ฐพ๊ธฐ ๊ฐ๋ฅ
Assertions
// Playwright ํ
์คํธ ์์
test("๋ก๊ทธ์ธ ํ์ด์ง ํ
์คํธ", async ({ page }) => {
await page.goto("https://example.com/login");
// assertions ์์๋ค:
// 1. ์ ๋ชฉ์ด "๋ก๊ทธ์ธ"์ด์ด์ผ ํ๋ค
await expect(page.locator("h1")).toHaveText("๋ก๊ทธ์ธ");
// 2. ๋ก๊ทธ์ธ ๋ฒํผ์ด ํ์ด์ง์ ์กด์ฌํด์ผ ํ๋ค
await expect(page.locator('button[type="submit"]')).toBeVisible();
// 3. ์ด๋ฉ์ผ ์
๋ ฅ๋์ด ๋น์ด์์ด์ผ ํ๋ค
await expect(page.locator('input[type="email"]')).toBeEmpty();
});
Assertion | Description |
---|---|
expect(locator).toBeChecked() | Checkbox is checked |
expect(locator).toBeEnabled() | Control is enabled |
expect(locator).toBeVisible() | Element is visible |
expect(locator).toContainText() | Element contains text |
expect(locator).toHaveAttribute() | Element has attribute |
expect(locator).toHaveCount() | List of elements has given length |
expect(locator).toHaveText() | Element matches text |
expect(locator).toHaveValue() | Input element has value |
expect(page).toHaveTitle() | Page has title |
expect(page).toHaveURL() | Page has URL |
Test lsolation
๊ฐ ํ ์คํธ๊ฐ ์๋ก ์ํฅ์ ์ฃผ์ง ์๊ณ ์์ ํ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋๋ ๊ฒ์ ์๋ฏธ
test.describe("๋ก๊ทธ์ธ ์ํ ํ
์คํธ", () => {
test("๋ก๊ทธ์ธ ํ
์คํธ", async ({ page }) => {
await page.goto("/login");
await page.fill('input[name="email"]', "test@example.com");
await page.fill('input[name="password"]', "password");
await page.click('button[type="submit"]');
});
test("๋น๋ก๊ทธ์ธ ์ํ ํ
์คํธ", async ({ page }) => {
await page.goto("/profile");
// ์ด์ ํ
์คํธ์์ ๋ก๊ทธ์ธํ์ง๋ง
// ์ด ํ
์คํธ๋ ์๋ก์ด ์ปจํ
์คํธ์์ ์์๋๋ฏ๋ก
// ๋ก๊ทธ์ธ๋์ง ์์ ์ํ์
๋๋ค
await expect(page.locator(".login-required")).toBeVisible();
});
});
โ ๊ฐ ๊ฒฉ๋ฆฌ๋ ํ๊ฒฝ์์ ํ ์คํธ
test.describe
// ๐
โโ๏ธ describe ์์ด ์์ฑ
test("๋ก๊ทธ์ธ ์ฑ๊ณต", async ({ page }) => {
/* ... */
});
test("๋ก๊ทธ์ธ ์คํจ", async ({ page }) => {
/* ... */
});
test("ํ์๊ฐ์
์ฑ๊ณต", async ({ page }) => {
/* ... */
});
test("ํ์๊ฐ์
์คํจ", async ({ page }) => {
/* ... */
});
// ๐ describe๋ก ๊ตฌ์กฐํ
test.describe("๋ก๊ทธ์ธ", () => {
test("์ฑ๊ณต", async ({ page }) => {
/* ... */
});
test("์คํจ", async ({ page }) => {
/* ... */
});
});
test.describe("ํ์๊ฐ์
", () => {
test("์ฑ๊ณต", async ({ page }) => {
/* ... */
});
test("์คํจ", async ({ page }) => {
/* ... */
});
});
โ ํน๋ณํ ๊ธฐ๋ฅ๋ณด๋ค๋ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์๋ฅผ ์ํ ๊ตฌ์กฐํ ๋๊ตฌ
Using Test Hooks
ํ ์คํธ ์ /ํ์ ํน์ ์ฝ๋๋ฅผ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ
ํ ์คํธ ์ค์ ์ด๋ ์ ๋ฆฌ ์์ ์ ์ฌ์ฉ
import { test, expect } from "@playwright/test";
test.describe("์ผํ๋ชฐ ํ
์คํธ", () => {
// 1. beforeAll: ๋ชจ๋ ํ
์คํธ ์์ ์ ํ ๋ฒ๋ง ์คํ
test.beforeAll(async () => {
// ์: ํ
์คํธ ๋ฐ์ดํฐ ์ธํ
await setupTestDatabase();
});
// 2. beforeEach: ๊ฐ ํ
์คํธ ์์ ์ ๋ง๋ค ์คํ
test.beforeEach(async ({ page }) => {
// ์: ๋ก๊ทธ์ธ ์ํ๋ก ์์
await page.goto("/login");
await page.fill("#email", "test@example.com");
await page.fill("#password", "password");
await page.click('button[type="submit"]');
});
// ํ
์คํธ ์ผ์ด์ค๋ค
test("์ฅ๋ฐ๊ตฌ๋ ์ถ๊ฐ", async ({ page }) => {
// ์ด๋ฏธ ๋ก๊ทธ์ธ๋ ์ํ์์ ์์
await page.goto("/products");
await page.click(".add-to-cart");
});
// 3. afterEach: ๊ฐ ํ
์คํธ ์ข
๋ฃ ํ๋ง๋ค ์คํ
test.afterEach(async ({ page }) => {
// ์: ์ฅ๋ฐ๊ตฌ๋ ๋น์ฐ๊ธฐ
await page.goto("/cart");
await page.click(".clear-cart");
});
// 4. afterAll: ๋ชจ๋ ํ
์คํธ ์ข
๋ฃ ํ ํ ๋ฒ๋ง ์คํ
test.afterAll(async () => {
// ์: ํ
์คํธ ๋ฐ์ดํฐ ์ ๋ฆฌ
await cleanupTestDatabase();
});
});
์๋ฐํด ํ๋ก์ ํธ
๊ธฐํ
- ์๊ฐ
- ๋งํด๋ณด์นด
Leave a comment