feat: add comprehensive device emulation with geolocation, locale, timezone, permissions, and colorScheme

- Added browser_list_devices tool to show 143+ available device profiles organized by category (iPhone, iPad, Pixel, Galaxy, Desktop, Other)
- Enhanced browser_configure tool with device emulation using Playwright's device descriptors database
- Added support for geolocation coordinates with accuracy settings
- Implemented locale and timezone configuration for internationalization testing
- Added colorScheme preference (light/dark/no-preference) for accessibility testing
- Included permissions management for various browser APIs (geolocation, notifications, camera, microphone)
- Device emulation properly overrides individual viewport/userAgent settings when specified
- All context options are properly applied and browser context is recreated with new settings

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ryan Malloy 2025-08-11 06:06:43 -06:00
parent 4d13e72213
commit b2462593bc
2 changed files with 151 additions and 5 deletions

View file

@ -16,6 +16,7 @@
import debug from 'debug';
import * as playwright from 'playwright';
import { devices } from 'playwright';
import { logUnhandledError } from './log.js';
import { Tab } from './tab.js';
@ -341,6 +342,12 @@ export class Context {
headless?: boolean;
viewport?: { width: number; height: number };
userAgent?: string;
device?: string;
geolocation?: { latitude: number; longitude: number; accuracy?: number };
locale?: string;
timezone?: string;
colorScheme?: 'light' | 'dark' | 'no-preference';
permissions?: string[];
}): Promise<void> {
const currentConfig = { ...this.config };
@ -348,11 +355,52 @@ export class Context {
if (changes.headless !== undefined) {
currentConfig.browser.launchOptions.headless = changes.headless;
}
if (changes.viewport) {
currentConfig.browser.contextOptions.viewport = changes.viewport;
// Handle device emulation - this overrides individual viewport/userAgent settings
if (changes.device) {
if (!devices[changes.device]) {
throw new Error(`Unknown device: ${changes.device}`);
}
const deviceConfig = devices[changes.device];
// Apply all device properties to context options
currentConfig.browser.contextOptions = {
...currentConfig.browser.contextOptions,
...deviceConfig,
};
} else {
// Apply individual settings only if no device is specified
if (changes.viewport) {
currentConfig.browser.contextOptions.viewport = changes.viewport;
}
if (changes.userAgent) {
currentConfig.browser.contextOptions.userAgent = changes.userAgent;
}
}
if (changes.userAgent) {
currentConfig.browser.contextOptions.userAgent = changes.userAgent;
// Apply additional context options
if (changes.geolocation) {
currentConfig.browser.contextOptions.geolocation = {
latitude: changes.geolocation.latitude,
longitude: changes.geolocation.longitude,
accuracy: changes.geolocation.accuracy || 100
};
}
if (changes.locale) {
currentConfig.browser.contextOptions.locale = changes.locale;
}
if (changes.timezone) {
currentConfig.browser.contextOptions.timezoneId = changes.timezone;
}
if (changes.colorScheme) {
currentConfig.browser.contextOptions.colorScheme = changes.colorScheme;
}
if (changes.permissions) {
currentConfig.browser.contextOptions.permissions = changes.permissions;
}
// Store the modified config