← 홈

🎭

⌘K
🤖
Claude Code AI 도구
🤗
Hugging Face AI 도구
🦜
LangChain AI 도구
🧠
Keras AI 도구
🦙
Ollama AI 도구
🐍
Python 프로그래밍 언어
🟨
JavaScript 프로그래밍 언어
🔷
TypeScript 프로그래밍 언어
⚛️
React 프로그래밍 언어
🐹
Go 프로그래밍 언어
🦀
Rust 프로그래밍 언어
📊
MATLAB 프로그래밍 언어
🗄️
SQL 프로그래밍 언어
⚙️
C/C++ 프로그래밍 언어
Java 프로그래밍 언어
🟣
C# 프로그래밍 언어
🍎
Swift 프로그래밍 언어
🟠
Kotlin 프로그래밍 언어
Next.js 프로그래밍 언어
💚
Vue.js 프로그래밍 언어
🔥
Svelte 프로그래밍 언어
🎨
Tailwind CSS 프로그래밍 언어
💚
Node.js 프로그래밍 언어
🌐
HTML 프로그래밍 언어
🎨
CSS/SCSS 프로그래밍 언어
🐘
PHP 프로그래밍 언어
💎
Ruby 프로그래밍 언어
🔴
Scala 프로그래밍 언어
📊
R 프로그래밍 언어
🎯
Dart 프로그래밍 언어
💧
Elixir 프로그래밍 언어
🌙
Lua 프로그래밍 언어
🐪
Perl 프로그래밍 언어
🅰️
Angular 프로그래밍 언어
🚂
Express.js 프로그래밍 언어
🐱
NestJS 프로그래밍 언어
🛤️
Ruby on Rails 프로그래밍 언어
◼️
GraphQL 프로그래밍 언어
🟪
Haskell 프로그래밍 언어
💚
Nuxt.js 프로그래밍 언어
🔷
SolidJS 프로그래밍 언어
htmx 프로그래밍 언어
💻
VS Code 개발 도구
🧠
PyCharm 개발 도구
📓
Jupyter 개발 도구
🧠
IntelliJ IDEA 개발 도구
💚
Neovim 개발 도구
🔮
Emacs 개발 도구
🔀
Git DevOps & CLI
🐳
Docker DevOps & CLI
☸️
Kubernetes DevOps & CLI
☁️
AWS CLI DevOps & CLI
🔄
GitHub Actions DevOps & CLI
🐧
Linux 명령어 DevOps & CLI
💻
Bash 스크립팅 DevOps & CLI
🌐
Nginx DevOps & CLI
📝
Vim DevOps & CLI
🔨
Makefile DevOps & CLI
🧪
Pytest DevOps & CLI
🪟
Windows DevOps & CLI
📦
패키지 매니저 DevOps & CLI
🍎
macOS DevOps & CLI
🏗️
Terraform DevOps & CLI
🔧
Ansible DevOps & CLI
Helm DevOps & CLI
🔨
Jenkins DevOps & CLI
🔥
Prometheus DevOps & CLI
📊
Grafana DevOps & CLI
💻
Zsh DevOps & CLI
🐟
Fish Shell DevOps & CLI
💙
PowerShell DevOps & CLI
🔄
Argo CD DevOps & CLI
🔀
Traefik DevOps & CLI
☁️
Azure CLI DevOps & CLI
☁️
Google Cloud CLI DevOps & CLI
📟
tmux DevOps & CLI
🔧
jq DevOps & CLI
✂️
sed DevOps & CLI
📊
awk DevOps & CLI
🌊
Apache Airflow DevOps & CLI
🔢
NumPy 데이터베이스 & 데이터
🐼
Pandas 데이터베이스 & 데이터
🔥
PyTorch 데이터베이스 & 데이터
🧠
TensorFlow 데이터베이스 & 데이터
📈
Matplotlib 데이터베이스 & 데이터
🐘
PostgreSQL 데이터베이스 & 데이터
🐬
MySQL 데이터베이스 & 데이터
🍃
MongoDB 데이터베이스 & 데이터
🔴
Redis 데이터베이스 & 데이터
🔍
Elasticsearch 데이터베이스 & 데이터
🤖
Scikit-learn 데이터베이스 & 데이터
👁️
OpenCV 데이터베이스 & 데이터
Apache Spark 데이터베이스 & 데이터
🪶
SQLite 데이터베이스 & 데이터
Supabase 데이터베이스 & 데이터
🔵
Neo4j 데이터베이스 & 데이터
📨
Apache Kafka 데이터베이스 & 데이터
🐰
RabbitMQ 데이터베이스 & 데이터
🔤
Regex 유틸리티
📝
Markdown 유틸리티
📄
LaTeX 유틸리티
🔐
SSH & GPG 유틸리티
🌐
curl & HTTP 유틸리티
📜
reStructuredText 유틸리티
🚀
Postman 유틸리티
🎬
FFmpeg 유틸리티
🖼️
ImageMagick 유틸리티
🔍
ripgrep 유틸리티
🔍
fzf 유틸리티
📗
Microsoft Excel 오피스 애플리케이션
📘
Microsoft Word 오피스 애플리케이션
📙
Microsoft PowerPoint 오피스 애플리케이션
📝
한컴 한글 한컴오피스
📽️
한컴 한쇼 한컴오피스
📊
한컴 한셀 한컴오피스
📄
Google 문서 Google Workspace
📊
Google 스프레드시트 Google Workspace
📽️
Google 프레젠테이션 Google Workspace
🔌
Cadence Virtuoso EDA & 하드웨어
⚙️
Synopsys EDA EDA & 하드웨어
💎
Verilog & VHDL EDA & 하드웨어
LTSpice EDA & 하드웨어
🔧
KiCad EDA & 하드웨어
📝
Notion 생산성 도구
💎
Obsidian 생산성 도구
💬
Slack 생산성 도구
🎮
Discord 생산성 도구
🎨
Figma 디자인 도구
📘
Confluence Atlassian
📋
Jira Atlassian
🃏
Jest 테스팅
Vitest 테스팅
🎭
Playwright 테스팅
🌲
Cypress 테스팅
🌐
Selenium 테스팅
💙
Flutter 모바일 개발
📱
React Native 모바일 개발
🍎
SwiftUI 모바일 개발
📱
Expo 모바일 개발
🐍
Django 웹 프레임워크
FastAPI 웹 프레임워크
🌶️
Flask 웹 프레임워크
🍃
Spring Boot 웹 프레임워크
🍸
Gin 웹 프레임워크
Vite 빌드 도구
📦
Webpack 빌드 도구
esbuild 빌드 도구
🐘
Gradle 빌드 도구
🪶
Maven 빌드 도구
🔧
CMake 빌드 도구
🎮
Unity 게임 개발
🤖
Godot 게임 개발
🔌
Arduino 임베디드 & IoT
🔍
Nmap 보안
🐕
Datadog 모니터링
📖
Swagger/OpenAPI 문서화
검색 결과가 없습니다
EN KO

기초

CLI 명령어

npm init playwright@latest 프로젝트 초기화
npx playwright test 모든 테스트 실행
npx playwright test --headed 브라우저 표시하며 실행
npx playwright test --debug 디버그 모드
npx playwright test --ui UI 모드
npx playwright test tests/login.spec.ts 특정 파일 실행
npx playwright test -g "login" 제목으로 실행
npx playwright test --project=chromium 특정 브라우저 실행
npx playwright codegen 코드 생성
npx playwright codegen https://example.com 액션 녹화
npx playwright show-report 리포트 표시
npx playwright install 브라우저 설치

테스트 구조

기본 테스트
import { test, expect } from '@playwright/test';

test('has title', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example/);
});
Describe 블록
test.describe('login', () => {
  test('valid login', async ({ page }) => {
    // test code
  });

  test('invalid login', async ({ page }) => {
    // test code
  });
});
건너뛰기/해당만
test.skip('skipped test', async ({ page }) => {});
test.only('only this runs', async ({ page }) => {});
test.fixme('needs fixing', async ({ page }) => {});

셀렉터

로케이터

getByRole
page.getByRole('button', { name: 'Submit' })
page.getByRole('link', { name: /learn more/i })
page.getByRole('textbox', { name: 'Email' })
page.getByRole('checkbox', { name: 'Agree' })
getByText
page.getByText('Hello World')
page.getByText(/hello/i)  // regex
getByLabel
page.getByLabel('Email')
page.getByLabel('Password')
getByPlaceholder
page.getByPlaceholder('Enter email')
getByTestId
page.getByTestId('submit-button')
CSS 셀렉터
page.locator('.btn-primary')
page.locator('#login-form')
page.locator('[data-id="123"]')
XPath
page.locator('xpath=//button[text()="Submit"]')
체이닝
page.locator('.list').locator('li').first()
page.locator('.card').filter({ hasText: 'Title' })
n번째 요소
page.locator('li').first()
page.locator('li').last()
page.locator('li').nth(2)  // 0-indexed

액션

사용자 액션

클릭
await page.click('button');
await page.getByRole('button').click();
await page.click('button', { button: 'right' });
await page.dblclick('button');
입력 채우기
await page.fill('input[name="email"]', 'test@example.com');
await page.getByLabel('Email').fill('test@example.com');
타이핑
await page.type('input', 'Hello', { delay: 100 });
지우기
await page.getByLabel('Email').clear();
옵션 선택
await page.selectOption('select', 'value');
await page.selectOption('select', { label: 'Option 1' });
체크박스
await page.check('input[type="checkbox"]');
await page.uncheck('input[type="checkbox"]');
await page.setChecked('input', true);
호버
await page.hover('.menu-item');
드래그 앤 드롭
await page.dragAndDrop('#source', '#target');
파일 업로드
await page.setInputFiles('input[type="file"]', 'path/to/file.pdf');
await page.setInputFiles('input', ['file1.pdf', 'file2.pdf']);
키보드
await page.keyboard.press('Enter');
await page.keyboard.press('Control+A');
await page.keyboard.type('Hello');

어설션

Expect 어설션

페이지 어설션
await expect(page).toHaveTitle(/Example/);
await expect(page).toHaveURL(/dashboard/);
await expect(page).toHaveURL('https://example.com');
요소 가시성
await expect(locator).toBeVisible();
await expect(locator).toBeHidden();
await expect(locator).not.toBeVisible();
텍스트 내용
await expect(locator).toHaveText('Hello');
await expect(locator).toContainText('World');
await expect(locator).toHaveText(/hello/i);
속성
await expect(locator).toHaveAttribute('href', '/home');
await expect(locator).toHaveClass(/active/);
await expect(locator).toHaveId('my-id');
await expect(locator).toHaveValue('test@example.com');
await expect(locator).toBeEmpty();
상태
await expect(locator).toBeEnabled();
await expect(locator).toBeDisabled();
await expect(locator).toBeChecked();
await expect(locator).toBeFocused();
개수
await expect(locator).toHaveCount(5);
스크린샷
await expect(page).toHaveScreenshot();
await expect(locator).toHaveScreenshot('button.png');

대기

대기 전략

셀렉터 대기
await page.waitForSelector('.loaded');
await page.waitForSelector('.loaded', { state: 'visible' });
로드 상태 대기
await page.waitForLoadState('networkidle');
await page.waitForLoadState('domcontentloaded');
응답 대기
const response = await page.waitForResponse(
  resp => resp.url().includes('/api/data')
);
요청 대기
const request = await page.waitForRequest('**/api/data');
함수 대기
await page.waitForFunction(() => {
  return document.querySelector('.loaded') !== null;
});
고정 타임아웃
await page.waitForTimeout(1000);  // Avoid if possible

픽스처와 훅

테스트 훅

Before/After 훅
test.beforeEach(async ({ page }) => {
  await page.goto('https://example.com');
});

test.afterEach(async ({ page }) => {
  // Cleanup
});

test.beforeAll(async () => {
  // Setup once
});

test.afterAll(async () => {
  // Teardown
});
커스텀 픽스처
import { test as base } from '@playwright/test';

const test = base.extend({
  loggedInPage: async ({ page }, use) => {
    await page.goto('/login');
    await page.fill('#email', 'user@example.com');
    await page.fill('#password', 'password');
    await page.click('button[type="submit"]');
    await use(page);
  },
});

test('logged in test', async ({ loggedInPage }) => {
  // Already logged in
});

네트워크

네트워크 인터셉션

API 응답 모킹
await page.route('**/api/users', route => {
  route.fulfill({
    status: 200,
    body: JSON.stringify([{ id: 1, name: 'John' }]),
  });
});
응답 수정
await page.route('**/api/data', async route => {
  const response = await route.fetch();
  const json = await response.json();
  json.modified = true;
  route.fulfill({ body: JSON.stringify(json) });
});
요청 취소
await page.route('**/*.png', route => route.abort());
수정 후 계속
await page.route('**/api/*', route => {
  route.continue({
    headers: {
      ...route.request().headers(),
      'Authorization': 'Bearer token',
    },
  });
});

설정

playwright.config.ts

기본 설정
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'Mobile Safari',
      use: { ...devices['iPhone 13'] },
    },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});