Skip to content

Commit

Permalink
Feat: user defined user agent (#115)
Browse files Browse the repository at this point in the history
* Feat: manually define user agent

* WIP: Add options at page level

* Page.setUserAgent

* fmt

* Example

* Fix failing tests

* fmt (again)

* Lint

* Small review tweaks
  • Loading branch information
chaosharmonic authored Dec 13, 2024
1 parent 142baec commit 0d225de
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
33 changes: 33 additions & 0 deletions examples/user_agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { launch } from "../mod.ts";

const browser = await launch();

const page = await browser.newPage("https://whatsmybrowser.org");

const getUserAgent = async () => {
const uaElement = await page.$(".user-agent");

const ua = await uaElement?.innerText() || "";

console.log(ua);

return ua;
};

const userAgent = await getUserAgent();

// get current version of Chrome
const version = userAgent?.split("Chrome/")?.at(1)?.split(".").at(0) || "";

// NOTE: this is *just* the major version, and may produce version
// numbers that don't actually exist... but this is just for
// demonstration, so that's fine
const nextVersion = String(Number(version) - 1);

await page.setUserAgent(userAgent?.replace(version, nextVersion));

await page.reload();

await getUserAgent();

await browser.close();
21 changes: 15 additions & 6 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { deadline } from "@std/async/deadline";

import { Celestial, PROTOCOL_VERSION } from "../bindings/celestial.ts";
import { getBinary } from "./cache.ts";
import { Page, type SandboxOptions, type WaitForOptions } from "./page.ts";
import {
Page,
type SandboxOptions,
type UserAgentOptions,
type WaitForOptions,
} from "./page.ts";
import { WEBSOCKET_ENDPOINT_REGEX, websocketReady } from "./util.ts";
import { DEBUG } from "./debug.ts";

Expand Down Expand Up @@ -74,6 +79,7 @@ async function runCommand(
export interface BrowserOptions {
headless?: boolean;
product?: "chrome" | "firefox";
userAgent?: string;
}

/**
Expand Down Expand Up @@ -156,7 +162,7 @@ export class Browser {
*/
async newPage(
url?: string,
options?: WaitForOptions & SandboxOptions,
options?: WaitForOptions & SandboxOptions & UserAgentOptions,
): Promise<Page> {
const { targetId } = await this.#celestial.Target.createTarget({
url: "",
Expand All @@ -172,12 +178,15 @@ export class Browser {
this.pages.push(page);

const celestial = page.unsafelyGetCelestialBindings();
const { userAgent } = await celestial.Browser.getVersion();
const { userAgent: defaultUserAgent } = await celestial.Browser
.getVersion();

const userAgent = options?.userAgent ||
this.#options.userAgent ||
defaultUserAgent.replaceAll("Headless", "");

await Promise.all([
celestial.Emulation.setUserAgentOverride({
userAgent: userAgent.replaceAll("Headless", ""),
}),
celestial.Emulation.setUserAgentOverride({ userAgent }),
celestial.Page.enable(),
celestial.Runtime.enable(),
celestial.Network.enable({}),
Expand Down
9 changes: 9 additions & 0 deletions src/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export type SandboxOptions = {
sandbox?: boolean;
};

/** The options for user agents */
export type UserAgentOptions = {
userAgent?: string;
};

/** The options for valid media features */
export type MediaFeature = Exclude<
Parameters<Celestial["Emulation"]["setEmulatedMedia"]>[0]["features"],
Expand Down Expand Up @@ -260,6 +265,10 @@ export class Page extends EventTarget {
return new ElementHandle(doc.root.nodeId, this.#celestial, this);
}

async setUserAgent(userAgent: string) {
await this.#celestial.Emulation.setUserAgentOverride({ userAgent });
}

// @ts-ignore see below
addEventListener<K extends keyof PageEventMap>(
type: K,
Expand Down

0 comments on commit 0d225de

Please sign in to comment.