add custom headers via --headers
This commit is contained in:
@@ -411,6 +411,12 @@ async function handleNavigate(
|
||||
browser: BrowserManager
|
||||
): Promise<Response<NavigateData>> {
|
||||
const page = browser.getPage();
|
||||
|
||||
// If headers are provided, set up scoped headers for this origin
|
||||
if (command.headers && Object.keys(command.headers).length > 0) {
|
||||
await browser.setScopedHeaders(command.url, command.headers);
|
||||
}
|
||||
|
||||
await page.goto(command.url, {
|
||||
waitUntil: command.waitUntil ?? 'load',
|
||||
});
|
||||
|
||||
+74
-2
@@ -51,6 +51,7 @@ export class BrowserManager {
|
||||
private isRecordingHar: boolean = false;
|
||||
private refMap: RefMap = {};
|
||||
private lastSnapshot: string = '';
|
||||
private scopedHeaderRoutes: Map<string, (route: Route) => Promise<void>> = new Map();
|
||||
|
||||
/**
|
||||
* Check if browser is launched
|
||||
@@ -439,7 +440,7 @@ export class BrowserManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extra HTTP headers
|
||||
* Set extra HTTP headers (global - all requests)
|
||||
*/
|
||||
async setExtraHeaders(headers: Record<string, string>): Promise<void> {
|
||||
const context = this.contexts[0];
|
||||
@@ -448,6 +449,76 @@ export class BrowserManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scoped HTTP headers (only for requests matching the origin)
|
||||
* Uses route interception to add headers only to matching requests
|
||||
*/
|
||||
async setScopedHeaders(origin: string, headers: Record<string, string>): Promise<void> {
|
||||
const page = this.getPage();
|
||||
|
||||
// Build URL pattern from origin (e.g., "api.example.com" -> "**://api.example.com/**")
|
||||
// Handle both full URLs and just hostnames
|
||||
let urlPattern: string;
|
||||
try {
|
||||
const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);
|
||||
// Match any protocol, the host, and any path
|
||||
urlPattern = `**://${url.host}/**`;
|
||||
} catch {
|
||||
// If parsing fails, treat as hostname pattern
|
||||
urlPattern = `**://${origin}/**`;
|
||||
}
|
||||
|
||||
// Remove existing route for this origin if any
|
||||
const existingHandler = this.scopedHeaderRoutes.get(urlPattern);
|
||||
if (existingHandler) {
|
||||
await page.unroute(urlPattern, existingHandler);
|
||||
}
|
||||
|
||||
// Create handler that adds headers to matching requests
|
||||
const handler = async (route: Route) => {
|
||||
const requestHeaders = route.request().headers();
|
||||
await route.continue({
|
||||
headers: {
|
||||
...requestHeaders,
|
||||
...headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Store and register the route
|
||||
this.scopedHeaderRoutes.set(urlPattern, handler);
|
||||
await page.route(urlPattern, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear scoped headers for an origin (or all if no origin specified)
|
||||
*/
|
||||
async clearScopedHeaders(origin?: string): Promise<void> {
|
||||
const page = this.getPage();
|
||||
|
||||
if (origin) {
|
||||
let urlPattern: string;
|
||||
try {
|
||||
const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);
|
||||
urlPattern = `**://${url.host}/**`;
|
||||
} catch {
|
||||
urlPattern = `**://${origin}/**`;
|
||||
}
|
||||
|
||||
const handler = this.scopedHeaderRoutes.get(urlPattern);
|
||||
if (handler) {
|
||||
await page.unroute(urlPattern, handler);
|
||||
this.scopedHeaderRoutes.delete(urlPattern);
|
||||
}
|
||||
} else {
|
||||
// Clear all scoped header routes
|
||||
for (const [pattern, handler] of this.scopedHeaderRoutes) {
|
||||
await page.unroute(pattern, handler);
|
||||
}
|
||||
this.scopedHeaderRoutes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start tracing
|
||||
*/
|
||||
@@ -522,9 +593,10 @@ export class BrowserManager {
|
||||
headless: options.headless ?? true,
|
||||
});
|
||||
|
||||
// Create context with viewport
|
||||
// Create context with viewport and optional headers
|
||||
const context = await this.browser.newContext({
|
||||
viewport: options.viewport ?? { width: 1280, height: 720 },
|
||||
extraHTTPHeaders: options.headers,
|
||||
});
|
||||
|
||||
// Set default timeout to 10 seconds (Playwright default is 30s)
|
||||
|
||||
@@ -12,12 +12,14 @@ export interface LaunchCommand extends BaseCommand {
|
||||
headless?: boolean;
|
||||
viewport?: { width: number; height: number };
|
||||
browser?: 'chromium' | 'firefox' | 'webkit';
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface NavigateCommand extends BaseCommand {
|
||||
action: 'navigate';
|
||||
url: string;
|
||||
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle';
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface ClickCommand extends BaseCommand {
|
||||
|
||||
Reference in New Issue
Block a user