9.4 Browser API, Permission, Geolocation
Browser API test는 OS dialog를 자동화하는 대신 context의 permission과 emulation 입력을 통제합니다. 제품이 geolocation, clipboard, notification, locale, media feature에 반응하는지 검증할 수 있습니다.
Geolocation
test.use({
geolocation: { longitude: 126.978, latitude: 37.5665 },
permissions: ['geolocation'],
});
test('서울 지점을 추천한다', async ({ page }) => {
await page.goto('/stores');
await expect(page.getByText('서울')).toBeVisible();
});
Permission과 좌표는 별개입니다. 좌표만 설정하고 permission을 허용하지 않으면 application은 denied flow로 갈 수 있습니다.
Context 중간에 permission 변경
await context.grantPermissions(['geolocation'], { origin: baseURL });
await context.setGeolocation({ longitude: 129.0756, latitude: 35.1796 });
await page.getByRole('button', { name: '현재 위치 다시 찾기' }).click();
await expect(page.getByText('부산')).toBeVisible();
await context.clearPermissions();
Locale, timezone, color scheme
const projects = [
{
name: 'ko-light',
use: { locale: 'ko-KR', timezoneId: 'Asia/Seoul', colorScheme: 'light' },
},
{
name: 'en-dark',
use: { locale: 'en-US', timezoneId: 'UTC', colorScheme: 'dark' },
},
];
모든 조합을 full E2E로 실행하면 matrix가 폭발합니다. Business-critical 조합은 E2E, component rendering 조합은 더 낮은 test level로 나눕니다.
Browser API mocking
Application script가 실행되기 전에 addInitScript()로 API를 대체할 수 있습니다.
await page.addInitScript(() => {
Object.defineProperty(navigator, 'hardwareConcurrency', { value: 4 });
});
await page.goto('/diagnostics');
await expect(page.getByText('CPU: 4')).toBeVisible();
Mock이 실제 browser behavior와 멀어지지 않도록 최소 surface만 구현하고 contract를 문서화합니다.
실패, 거부 path도 제품 기능이다
- Permission denied
- API unavailable
- Timeout
- Invalid coordinate
- Clipboard가 secure context에서만 가능한 경우
- Mobile viewport에서 orientation change
Happy path project만 두면 실제 사용자 환경의 중요한 오류 처리를 놓칩니다.
실습
- Permission granted/denied project를 분리합니다.
- Locale에 따라 button label locator가 깨지지 않도록 role과 locale별 expected name을 설계합니다.
- Dark mode visual snapshot은 light baseline과 분리합니다.
- Mocked API가 호출되지 않은 fallback path를 검증합니다.