CI/CD에서 Playwright 브라우저 캐싱
이 스킬을 사용하는 경우
다음 상황에서 이 스킬을 사용하세요:
- Playwright E2E 테스트가 포함된 프로젝트의 CI/CD 설정 시
- 브라우저 다운로드(~400MB, 1-2분)로 빌드 시간이 느린 경우
- Playwright 버전 변경 시 자동으로 캐시를 무효화하려는 경우
- GitHub Actions 또는 Azure DevOps 파이프라인을 사용하는 경우
문제
Playwright 브라우저(~400MB)는 기본적으로 모든 CI 실행 시 다운로드되어야 합니다. 이로 인해:
- 모든 빌드에 1-2분이 추가됨
- 대역폭 낭비
- 일시적인 네트워크 문제로 실패 가능
- PR 피드백 루프 지연
핵심 패턴
- Playwright 버전 추출 -
Directory.Packages.props(CPM)에서 캐시 키로 사용할 버전 추출 - 브라우저 바이너리 캐싱 - 플랫폼에 적합한 경로 사용
- 조건부 설치 - 캐시 미스 시에만 다운로드
- 자동 캐시 무효화 - 키에 버전이 포함되어 패키지 업그레이드 시 캐시가 무효화됨
OS별 캐시 경로
| OS | 경로 |
|---|---|
| Linux | ~/.cache/ms-playwright |
| macOS | ~/Library/Caches/ms-playwright |
| Windows | %USERPROFILE%\AppData\Local\ms-playwright |
GitHub Actions
- name: Get Playwright Version
shell: pwsh
run: |
$propsPath = "Directory.Packages.props"
[xml]$props = Get-Content $propsPath
$version = $props.Project.ItemGroup.PackageVersion |
Where-Object { $_.Include -eq "Microsoft.Playwright" } |
Select-Object -ExpandProperty Version
echo "PlaywrightVersion=$version" >> $env:GITHUB_ENV
- name: Cache Playwright Browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PlaywrightVersion }}
- name: Install Playwright Browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
shell: pwsh
run: ./build/playwright.ps1 install --with-deps
멀티 OS GitHub Actions
여러 운영 체제에서 실행되는 워크플로의 경우:
- name: Cache Playwright Browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
~/AppData/Local/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PlaywrightVersion }}
Azure DevOps
- task: PowerShell@2
displayName: 'Playwright 버전 가져오기'
inputs:
targetType: 'inline'
script: |
[xml]$props = Get-Content "Directory.Packages.props"
$version = $props.Project.ItemGroup.PackageVersion |
Where-Object { $_.Include -eq "Microsoft.Playwright" } |
Select-Object -ExpandProperty Version
Write-Host "##vso[task.setvariable variable=PlaywrightVersion]$version"
- task: Cache@2
displayName: 'Playwright 브라우저 캐싱'
inputs:
key: 'playwright | "$(Agent.OS)" | $(PlaywrightVersion)'
path: '$(HOME)/.cache/ms-playwright'
cacheHitVar: 'PlaywrightCacheHit'
- task: PowerShell@2
displayName: 'Playwright 브라우저 설치'
condition: ne(variables['PlaywrightCacheHit'], 'true')
inputs:
filePath: 'build/playwright.ps1'
arguments: 'install --with-deps'
도우미 스크립트: playwright.ps1
Playwright CLI를 찾아 실행하는 build/playwright.ps1 스크립트를 만듭니다. 이는 프로젝트 구조에 따라 달라지는 Playwright CLI 위치를 추상화합니다.
# build/playwright.ps1
# Microsoft.Playwright.dll을 찾아 번들된 Playwright CLI를 실행합니다
param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
# Playwright DLL 찾기 (dotnet build/restore 후)
$playwrightDll = Get-ChildItem -Path . -Recurse -Filter "Microsoft.Playwright.dll" -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $playwrightDll) {
Write-Error "Microsoft.Playwright.dll을 찾을 수 없습니다. 먼저 'dotnet build'를 실행하세요."
exit 1
}
$playwrightDir = $playwrightDll.DirectoryName
# Playwright CLI 찾기 (경로는 OS와 node 버전에 따라 다름)
$playwrightCmd = Get-ChildItem -Path "$playwrightDir/.playwright/node" -Recurse -Filter "playwright.cmd" -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $playwrightCmd) {
# Unix 실행 파일 시도
$playwrightCmd = Get-ChildItem -Path "$playwrightDir/.playwright/node" -Recurse -Filter "playwright" -ErrorAction SilentlyContinue |
Where-Object { $_.Name -eq "playwright" } |
Select-Object -First 1
}
if (-not $playwrightCmd) {
Write-Error "$playwrightDir/.playwright/node에서 Playwright CLI를 찾을 수 없습니다."
exit 1
}
Write-Host "사용 중인 Playwright CLI: $($playwrightCmd.FullName)"
& $playwrightCmd.FullName @Arguments
사용법:
# 브라우저 설치
./build/playwright.ps1 install --with-deps
# 특정 브라우저 설치
./build/playwright.ps1 install chromium
# 설치된 브라우저 확인
./build/playwright.ps1 install --dry-run
전제 조건
이 패턴은 다음을 가정합니다:
-
**중앙 패키지 관리(CPM)**와
Directory.Packages.props:<Project> <ItemGroup> <PackageVersion Include="Microsoft.Playwright" Version="1.40.0" /> </ItemGroup> </Project> -
playwright.ps1실행 전에 프로젝트가 빌드되어 있어야 함 (DLL이 존재해야 함) -
CI 에이전트에 PowerShell 사용 가능 (GitHub Actions 및 Azure DevOps에 사전 설치됨)
버전 기반 캐시 키가 중요한 이유
캐시 키에 Playwright 버전을 사용하면 다음이 보장됩니다:
- Playwright 업그레이드 시 자동 무효화
- SDK 버전과 일치하지 않는 오래된 브라우저 바이너리 없음
- 버전 업데이트 후 수동 캐시 삭제 불필요
캐시 키를 하드코딩하면(예: playwright-browsers-v1) Playwright 업그레이드 시마다 수동으로 키를 변경해야 하거나, 버전 불일치로 인한 오류 메시지가 발생할 수 있습니다.
문제 해결
캐시가 사용되지 않는 경우
- 버전 추출 단계가 올바른 버전을 출력하는지 확인
- 캐시 경로가 OS와 일치하는지 확인
Directory.Packages.props가 존재하고 Playwright 패키지가 포함되어 있는지 확인
캐시 히트 후 "브라우저를 찾을 수 없음" 오류
캐시된 브라우저가 Playwright SDK 버전과 일치하지 않는 경우입니다. 다음과 같은 상황에서 발생합니다:
- 캐시 키에 버전이 포함되지 않은 경우
- 버전 추출이 무시되었을 경우
해결 방법: 캐시 키에 Playwright 버전이 포함되도록 합니다.
playwright.ps1이 DLL을 찾을 수 없는 경우
스크립트를 실행하기 전에 dotnet build 또는 dotnet restore를 실행하세요. Playwright DLL은 NuGet 복원 후에만 존재합니다.
참고 자료
이 패턴은 실제 프로젝트에서 검증되었습니다:
관련 스킬
dotnet-skills:playwright-blazor- Blazor 애플리케이션용 Playwright 테스트 작성dotnet-skills:project-structure- 중앙 패키지 관리 설정