Socket
Socket
Sign inDemoInstall

chromium-bidi

Package Overview
Dependencies
Maintainers
2
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chromium-bidi - npm Package Compare versions

Comparing version 0.5.19 to 0.5.20

lib/cjs/utils/DistinctValues.d.ts

2

lib/cjs/bidiMapper/CommandProcessor.js

@@ -54,3 +54,3 @@ "use strict";

this.#browserProcessor = new BrowserProcessor_js_1.BrowserProcessor(browserCdpClient);
this.#browsingContextProcessor = new BrowsingContextProcessor_js_1.BrowsingContextProcessor(browserCdpClient, browsingContextStorage);
this.#browsingContextProcessor = new BrowsingContextProcessor_js_1.BrowsingContextProcessor(browserCdpClient, browsingContextStorage, eventManager);
this.#cdpProcessor = new CdpProcessor_js_1.CdpProcessor(browsingContextStorage, realmStorage, cdpConnection, browserCdpClient);

@@ -57,0 +57,0 @@ this.#inputProcessor = new InputProcessor_js_1.InputProcessor(browsingContextStorage, realmStorage);

@@ -380,4 +380,5 @@ "use strict";

message: params.message,
// Don't set the value if empty string
defaultValue: params.defaultPrompt || undefined,
...(params.type === 'prompt'
? { defaultValue: params.defaultPrompt }
: {}),
},

@@ -591,5 +592,14 @@ }, this.id);

(0, assert_js_1.assert)(origin);
const rect = params.clip
? getIntersectionRect(await this.#parseRect(params.clip), origin)
: origin;
let rect = origin;
if (params.clip) {
const clip = params.clip;
if (params.origin === 'viewport' && clip.type === 'box') {
// For viewport origin, the clip is relative to the viewport, while the CDP
// screenshot is relative to the document. So correction for the viewport position
// is required.
clip.x += origin.x;
clip.y += origin.y;
}
rect = getIntersectionRect(await this.#parseRect(clip), origin);
}
if (rect.width === 0 || rect.height === 0) {

@@ -755,4 +765,6 @@ throw new protocol_js_1.UnableToCaptureScreenException(`Unable to capture screenshot with zero dimensions: width=${rect.width}, height=${rect.height}`);

const locateNodesUsingCss = (element) => {
if (!(element instanceof HTMLElement)) {
throw new Error('startNodes in css selector should be HTMLElement');
if (!(element instanceof HTMLElement ||
element instanceof Document ||
element instanceof DocumentFragment)) {
throw new Error('startNodes in css selector should be HTMLElement, Document or DocumentFragment');
}

@@ -823,4 +835,17 @@ return [...element.querySelectorAll(cssSelector)];

: innerTextSelector;
const locateNodesUsingInnerText = (element, currentMaxDepth) => {
const locateNodesUsingInnerText = (node, currentMaxDepth) => {
const returnedNodes = [];
if (node instanceof DocumentFragment ||
node instanceof Document) {
const children = [...node.children];
children.forEach((child) =>
// `currentMaxDepth` is not decremented intentionally according to
// https://github.com/w3c/webdriver-bidi/pull/713.
returnedNodes.push(...locateNodesUsingInnerText(child, currentMaxDepth)));
return returnedNodes;
}
if (!(node instanceof HTMLElement)) {
return [];
}
const element = node;
const nodeInnerText = ignoreCase

@@ -852,3 +877,3 @@ ? element.innerText?.toUpperCase()

// Don't search deeper if `maxDepth` is reached.
currentMaxDepth === 0
currentMaxDepth <= 0
? []

@@ -871,5 +896,4 @@ : childNodes

};
// TODO: add maxDepth.
// TODO: stop search early if `maxNodeCount` is reached.
startNodes = startNodes.length > 0 ? startNodes : [document.body];
startNodes = startNodes.length > 0 ? startNodes : [document];
const returnedNodes = startNodes

@@ -1006,4 +1030,4 @@ .map((startNode) =>

if (locatorResult.exceptionDetails.text ===
'Error: startNodes in css selector should be HTMLElement') {
throw new protocol_js_1.InvalidArgumentException(`startNodes in css selector should be HTMLElement`);
'Error: startNodes in css selector should be HTMLElement, Document or DocumentFragment') {
throw new protocol_js_1.InvalidArgumentException('startNodes in css selector should be HTMLElement, Document or DocumentFragment');
}

@@ -1010,0 +1034,0 @@ throw new protocol_js_1.UnknownErrorException(`Unexpected error in selector script: ${locatorResult.exceptionDetails.text}`);

import type { CdpClient } from '../../../cdp/CdpClient.js';
import { BrowsingContext, type EmptyResult } from '../../../protocol/protocol.js';
import type { EventManager } from '../session/EventManager.js';
import type { BrowsingContextStorage } from './BrowsingContextStorage.js';
export declare class BrowsingContextProcessor {
#private;
constructor(browserCdpClient: CdpClient, browsingContextStorage: BrowsingContextStorage);
constructor(browserCdpClient: CdpClient, browsingContextStorage: BrowsingContextStorage, eventManager: EventManager);
getTree(params: BrowsingContext.GetTreeParameters): BrowsingContext.GetTreeResult;

@@ -8,0 +9,0 @@ create(params: BrowsingContext.CreateParameters): Promise<BrowsingContext.CreateResult>;

@@ -8,5 +8,8 @@ "use strict";

#browsingContextStorage;
constructor(browserCdpClient, browsingContextStorage) {
#eventManager;
constructor(browserCdpClient, browsingContextStorage, eventManager) {
this.#browserCdpClient = browserCdpClient;
this.#browsingContextStorage = browsingContextStorage;
this.#eventManager = eventManager;
this.#eventManager.addSubscribeHook(protocol_js_1.ChromiumBidi.BrowsingContext.EventNames.ContextCreated, this.#onContextCreatedSubscribeHook.bind(this));
}

@@ -176,4 +179,19 @@ getTree(params) {

}
#onContextCreatedSubscribeHook(contextId) {
const context = this.#browsingContextStorage.getContext(contextId);
const contextsToReport = [
context,
...this.#browsingContextStorage.getContext(contextId).allChildren,
];
contextsToReport.forEach((context) => {
this.#eventManager.registerEvent({
type: 'event',
method: protocol_js_1.ChromiumBidi.BrowsingContext.EventNames.ContextCreated,
params: context.serializeToBidiValue(),
}, context.id);
});
return Promise.resolve();
}
}
exports.BrowsingContextProcessor = BrowsingContextProcessor;
//# sourceMappingURL=BrowsingContextProcessor.js.map

@@ -22,2 +22,3 @@ "use strict";

const assert_js_1 = require("../../../utils/assert.js");
const GraphemeTools_1 = require("../../../utils/GraphemeTools");
const InputSource_js_1 = require("./InputSource.js");

@@ -389,6 +390,9 @@ const keyUtils_js_1 = require("./keyUtils.js");

async #dispatchKeyDownAction(source, action) {
if ([...action.value].length > 1) {
throw new protocol_js_1.InvalidArgumentException(`Invalid key value: ${action.value}`);
const rawKey = action.value;
if (!(0, GraphemeTools_1.isSingleGrapheme)(rawKey)) {
// https://w3c.github.io/webdriver/#dfn-process-a-key-action
// WebDriver spec allows a grapheme to be used.
throw new protocol_js_1.InvalidArgumentException(`Invalid key value: ${rawKey}`);
}
const rawKey = action.value;
const isGrapheme = (0, GraphemeTools_1.isSingleComplexGrapheme)(rawKey);
const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);

@@ -417,3 +421,3 @@ const repeat = source.pressed.has(key);

// to measure.
const unmodifiedText = getKeyEventUnmodifiedText(key, source);
const unmodifiedText = getKeyEventUnmodifiedText(key, source, isGrapheme);
const text = getKeyEventText(code ?? '', source) ?? unmodifiedText;

@@ -472,6 +476,9 @@ let command;

#dispatchKeyUpAction(source, action) {
if ([...action.value].length > 1) {
throw new protocol_js_1.InvalidArgumentException(`Invalid key value: ${action.value}`);
const rawKey = action.value;
if (!(0, GraphemeTools_1.isSingleGrapheme)(rawKey)) {
// https://w3c.github.io/webdriver/#dfn-process-a-key-action
// WebDriver spec allows a grapheme to be used.
throw new protocol_js_1.InvalidArgumentException(`Invalid key value: ${rawKey}`);
}
const rawKey = action.value;
const isGrapheme = (0, GraphemeTools_1.isSingleComplexGrapheme)(rawKey);
const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);

@@ -502,3 +509,3 @@ if (!source.pressed.has(key)) {

// to measure.
const unmodifiedText = getKeyEventUnmodifiedText(key, source);
const unmodifiedText = getKeyEventUnmodifiedText(key, source, isGrapheme);
const text = getKeyEventText(code ?? '', source) ?? unmodifiedText;

@@ -521,6 +528,16 @@ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {

exports.ActionDispatcher = ActionDispatcher;
const getKeyEventUnmodifiedText = (key, source) => {
/**
* Translates a non-grapheme key to either an `undefined` for a special keys, or a single
* character modified by shift if needed.
*/
const getKeyEventUnmodifiedText = (key, source, isGrapheme) => {
if (isGrapheme) {
// Graphemes should be presented as text in the CDP command.
return key;
}
if (key === 'Enter') {
return '\r';
}
// If key is not a single character, it is a normalized key value, and should be
// presented as key, not text in the CDP command.
return [...key].length === 1

@@ -527,0 +544,0 @@ ? source.shift

@@ -56,12 +56,15 @@ "use strict";

if (!(this instanceof HTMLInputElement)) {
return 0 /* ErrorCode.Object */;
if (this instanceof Element) {
return 1 /* ErrorCode.Element */;
}
return 0 /* ErrorCode.Node */;
}
if (this.type !== 'file') {
return 1 /* ErrorCode.Type */;
return 2 /* ErrorCode.Type */;
}
if (this.disabled) {
return 2 /* ErrorCode.Disabled */;
return 3 /* ErrorCode.Disabled */;
}
if (fileListLength > 1 && !this.multiple) {
return 3 /* ErrorCode.Multiple */;
return 4 /* ErrorCode.Multiple */;
}

@@ -72,3 +75,3 @@ return;

catch {
throw new protocol_js_1.NoSuchElementException(`Could not find element ${params.element.sharedId}`);
throw new protocol_js_1.NoSuchNodeException(`Could not find element ${params.element.sharedId}`);
}

@@ -78,12 +81,15 @@ (0, assert_js_1.assert)(result.type === 'success');

switch (result.result.value) {
case 0 /* ErrorCode.Object */: {
case 0 /* ErrorCode.Node */: {
throw new protocol_js_1.NoSuchElementException(`Could not find element ${params.element.sharedId}`);
}
case 1 /* ErrorCode.Type */: {
throw new protocol_js_1.UnableToSetFileInputException(`Element ${params.element.sharedId} is not a file input`);
case 1 /* ErrorCode.Element */: {
throw new protocol_js_1.UnableToSetFileInputException(`Element ${params.element.sharedId} is not a input`);
}
case 2 /* ErrorCode.Disabled */: {
case 2 /* ErrorCode.Type */: {
throw new protocol_js_1.UnableToSetFileInputException(`Input element ${params.element.sharedId} is not a file type`);
}
case 3 /* ErrorCode.Disabled */: {
throw new protocol_js_1.UnableToSetFileInputException(`Input element ${params.element.sharedId} is disabled`);
}
case 3 /* ErrorCode.Multiple */: {
case 4 /* ErrorCode.Multiple */: {
throw new protocol_js_1.UnableToSetFileInputException(`Cannot set multiple files on a non-multiple input element`);

@@ -90,0 +96,0 @@ }

@@ -54,9 +54,9 @@ /**

count: number;
"__#89377@#x": number;
"__#89377@#y": number;
"__#89377@#time": number;
"__#90659@#x": number;
"__#90659@#y": number;
"__#90659@#time": number;
compare(context: any): boolean;
};
"__#89377@#DOUBLE_CLICK_TIME_MS": number;
"__#89377@#MAX_DOUBLE_CLICK_RADIUS": number;
"__#90659@#DOUBLE_CLICK_TIME_MS": number;
"__#90659@#MAX_DOUBLE_CLICK_RADIUS": number;
};

@@ -63,0 +63,0 @@ setClickCount(button: number, context: InstanceType<typeof PointerSource.ClickContext>): number;

@@ -17,4 +17,16 @@ /**

*/
/**
* Returns the normalized key value for a given key according to the table:
* https://w3c.github.io/webdriver/#dfn-normalized-key-value
*/
export declare function getNormalizedKey(value: string): string;
/**
* Returns the key code for a given key according to the table:
* https://w3c.github.io/webdriver/#dfn-shifted-character
*/
export declare function getKeyCode(key: string): string | undefined;
/**
* Returns the location of the key according to the table:
* https://w3c.github.io/webdriver/#dfn-key-location
*/
export declare function getKeyLocation(key: string): 0 | 1 | 2 | 3;

@@ -20,2 +20,6 @@ "use strict";

exports.getKeyLocation = exports.getKeyCode = exports.getNormalizedKey = void 0;
/**
* Returns the normalized key value for a given key according to the table:
* https://w3c.github.io/webdriver/#dfn-normalized-key-value
*/
function getNormalizedKey(value) {

@@ -35,4 +39,5 @@ switch (value) {

return 'Clear';
// Specification declares the '\uE006' to be `Return`, but it is not supported by
// Chrome, so fall back to `Enter`, which aligns with WPT.
case '\uE006':
return 'Return';
case '\uE007':

@@ -169,2 +174,6 @@ return 'Enter';

exports.getNormalizedKey = getNormalizedKey;
/**
* Returns the key code for a given key according to the table:
* https://w3c.github.io/webdriver/#dfn-shifted-character
*/
function getKeyCode(key) {

@@ -222,2 +231,6 @@ switch (key) {

return 'Equal';
// The spec declares the '<' to be `IntlBackslash` as well, but it is already covered
// in the `Comma` above.
case '>':
return 'IntlBackslash';
case 'a':

@@ -325,2 +338,4 @@ case 'A':

return 'Enter';
case '\uE00B':
return 'Pause';
case '\uE03D':

@@ -387,2 +402,4 @@ return 'MetaLeft';

return 'F12';
case '\uE019':
return 'NumpadEqual';
case '\uE01A':

@@ -437,2 +454,6 @@ case '\uE05C':

exports.getKeyCode = getKeyCode;
/**
* Returns the location of the key according to the table:
* https://w3c.github.io/webdriver/#dfn-key-location
*/
function getKeyLocation(key) {

@@ -446,2 +467,3 @@ switch (key) {

return 1;
case '\uE019':
case '\uE01A':

@@ -448,0 +470,0 @@ case '\uE01B':

@@ -16,2 +16,6 @@ import { Network, type EmptyResult } from '../../../protocol/protocol.js';

/**
* Validate https://fetch.spec.whatwg.org/#header-value
*/
static validateHeaders(headers: Network.Header[]): void;
/**
* Attempts to parse the given url.

@@ -22,2 +26,3 @@ * Throws an InvalidArgumentException if the url is invalid.

static parseUrlPatterns(urlPatterns: Network.UrlPattern[]): Network.UrlPattern[];
static wrapInterceptionError(error: any): any;
}

@@ -35,2 +35,5 @@ "use strict";

}
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
const request = this.#getBlockedRequestOrFail(networkId, [

@@ -42,8 +45,13 @@ "beforeRequestSent" /* Network.InterceptPhase.BeforeRequestSent */,

// ; Step 9. cookies
await request.continueRequest({
url,
method,
headers,
postData: getCdpBodyFromBiDiBytesValue(body),
});
try {
await request.continueRequest({
url,
method,
headers,
postData: getCdpBodyFromBiDiBytesValue(body),
});
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
return {};

@@ -53,2 +61,5 @@ }

const { request: networkId, statusCode, reasonPhrase, headers } = params;
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
const responseHeaders = (0, NetworkUtils_js_1.cdpFetchHeadersFromBidiNetworkHeaders)(headers);

@@ -82,7 +93,12 @@ const request = this.#getBlockedRequestOrFail(networkId, [

// ; Step 10. cookies
await request.continueResponse({
responseCode: statusCode,
responsePhrase: reasonPhrase,
responseHeaders,
});
try {
await request.continueResponse({
responseCode: statusCode,
responsePhrase: reasonPhrase,
responseHeaders,
});
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
}

@@ -124,2 +140,5 @@ return {};

const { statusCode, reasonPhrase: responsePhrase, headers, body, request: networkId, } = params;
if (params.headers) {
NetworkProcessor.validateHeaders(params.headers);
}
// TODO: Step 6

@@ -130,3 +149,2 @@ // https://w3c.github.io/webdriver-bidi/#command-network-continueResponse

// ; Step 10. cookies
// ; Step 11. credentials
const request = this.#getBlockedRequestOrFail(networkId, [

@@ -147,4 +165,4 @@ "beforeRequestSent" /* Network.InterceptPhase.BeforeRequestSent */,

}
// If we con't modify the response
// Just continue the request
// If we don't modify the response
// just continue the request
if (!body && !headers) {

@@ -155,8 +173,13 @@ await request.continueRequest();

const responseCode = statusCode ?? request.statusCode ?? 200;
await request.provideResponse({
responseCode,
responsePhrase,
responseHeaders,
body: getCdpBodyFromBiDiBytesValue(body),
});
try {
await request.provideResponse({
responseCode,
responsePhrase,
responseHeaders,
body: getCdpBodyFromBiDiBytesValue(body),
});
}
catch (error) {
throw NetworkProcessor.wrapInterceptionError(error);
}
return {};

@@ -189,2 +212,21 @@ }

/**
* Validate https://fetch.spec.whatwg.org/#header-value
*/
static validateHeaders(headers) {
for (const header of headers) {
let headerValue;
if (header.value.type === 'string') {
headerValue = header.value.value;
}
else {
headerValue = atob(header.value.value);
}
if (headerValue !== headerValue.trim() ||
headerValue.includes('\n') ||
headerValue.includes('\0')) {
throw new protocol_js_1.InvalidArgumentException(`Header value '${headerValue}' is not acceptable value`);
}
}
}
/**
* Attempts to parse the given url.

@@ -278,2 +320,9 @@ * Throws an InvalidArgumentException if the url is invalid.

}
static wrapInterceptionError(error) {
// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/protocol/fetch_handler.cc;l=169
if (error?.message.includes('Invalid header')) {
return new protocol_js_1.InvalidArgumentException('Invalid header');
}
return error;
}
}

@@ -280,0 +329,0 @@ exports.NetworkProcessor = NetworkProcessor;

@@ -43,3 +43,3 @@ /**

/** @see https://chromedevtools.github.io/devtools-protocol/tot/Fetch/#method-continueRequest */
continueRequest({ url, method, headers, postData, }?: Omit<Protocol.Fetch.ContinueRequestRequest, 'requestId'>): Promise<void>;
continueRequest(overrides?: Omit<Protocol.Fetch.ContinueRequestRequest, 'requestId'>): Promise<void>;
/** @see https://chromedevtools.github.io/devtools-protocol/tot/Fetch/#method-continueResponse */

@@ -46,0 +46,0 @@ continueResponse({ responseCode, responsePhrase, responseHeaders, }?: Omit<Protocol.Fetch.ContinueResponseRequest, 'requestId'>): Promise<void>;

@@ -86,2 +86,3 @@ "use strict";

this.#response.paused?.request.url ??
this.#request.overrides?.url ??
this.#request.auth?.request.url ??

@@ -94,3 +95,4 @@ this.#request.info?.request.url ??

get method() {
return (this.#request.info?.request.method ??
return (this.#request.overrides?.method ??
this.#request.info?.request.method ??
this.#request.paused?.request.method ??

@@ -290,11 +292,17 @@ this.#request.auth?.request.method ??

/** @see https://chromedevtools.github.io/devtools-protocol/tot/Fetch/#method-continueRequest */
async continueRequest({ url, method, headers, postData, } = {}) {
async continueRequest(overrides = {}) {
(0, assert_js_1.assert)(this.#fetchId, 'Network Interception not set-up.');
await this.cdpClient.sendCommand('Fetch.continueRequest', {
requestId: this.#fetchId,
url,
method,
headers,
postData,
url: overrides.url,
method: overrides.method,
headers: overrides.headers,
postData: overrides.postData,
});
// TODO: Store postData's size only
this.#request.overrides = {
url: overrides.url,
method: overrides.method,
headers: overrides.headers,
};
this.#interceptPhase = undefined;

@@ -399,5 +407,11 @@ }

}
const headers = [
...(0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#response.info?.headers),
...(0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#response.extraInfo?.headers),
// TODO: Verify how to dedupe these
// ...bidiNetworkHeadersFromCdpNetworkHeadersEntries(
// this.#response.paused?.responseHeaders
// ),
];
// TODO: get headers from Fetch.requestPaused
const headers = (0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#response.info?.headers);
// TODO: get headers from Fetch.requestPaused
const authChallenges = this.#authChallenges(this.#response.info?.headers ?? {});

@@ -442,3 +456,14 @@ return {

: [];
const headers = (0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#request.info?.request.headers);
let headers = [];
if (this.#request.overrides?.headers) {
headers = [
...(0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeadersEntries)(this.#request.overrides?.headers),
];
}
else {
headers = [
...(0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#request.info?.request.headers),
...(0, NetworkUtils_js_1.bidiNetworkHeadersFromCdpNetworkHeaders)(this.#request.extraInfo?.headers),
];
}
return {

@@ -445,0 +470,0 @@ request: this.#id,

@@ -7,4 +7,6 @@ /**

export declare function computeHeadersSize(headers: Network.Header[]): number;
/** Converts from CDP Network domain headers to Bidi network headers. */
/** Converts from CDP Network domain headers to BiDi network headers. */
export declare function bidiNetworkHeadersFromCdpNetworkHeaders(headers?: Protocol.Network.Headers): Network.Header[];
/** Converts from CDP Fetch domain headers to BiDi network headers. */
export declare function bidiNetworkHeadersFromCdpNetworkHeadersEntries(headers?: Protocol.Fetch.HeaderEntry[]): Network.Header[];
/** Converts from Bidi network headers to CDP Network domain headers. */

@@ -11,0 +13,0 @@ export declare function cdpNetworkHeadersFromBidiNetworkHeaders(headers?: Network.Header[]): Protocol.Network.Headers | undefined;

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.matchUrlPattern = exports.isSpecialScheme = exports.sameSiteBiDiToCdp = exports.bidiToCdpCookie = exports.deserializeByteValue = exports.cdpToBiDiCookie = exports.cdpAuthChallengeResponseFromBidiAuthContinueWithAuthAction = exports.cdpFetchHeadersFromBidiNetworkHeaders = exports.bidiNetworkHeadersFromCdpFetchHeaders = exports.cdpNetworkHeadersFromBidiNetworkHeaders = exports.bidiNetworkHeadersFromCdpNetworkHeaders = exports.computeHeadersSize = void 0;
exports.matchUrlPattern = exports.isSpecialScheme = exports.sameSiteBiDiToCdp = exports.bidiToCdpCookie = exports.deserializeByteValue = exports.cdpToBiDiCookie = exports.cdpAuthChallengeResponseFromBidiAuthContinueWithAuthAction = exports.cdpFetchHeadersFromBidiNetworkHeaders = exports.bidiNetworkHeadersFromCdpFetchHeaders = exports.cdpNetworkHeadersFromBidiNetworkHeaders = exports.bidiNetworkHeadersFromCdpNetworkHeadersEntries = exports.bidiNetworkHeadersFromCdpNetworkHeaders = exports.computeHeadersSize = void 0;
const ErrorResponse_js_1 = require("../../../protocol/ErrorResponse.js");

@@ -32,3 +32,3 @@ const Base64_js_1 = require("../../../utils/Base64.js");

exports.computeHeadersSize = computeHeadersSize;
/** Converts from CDP Network domain headers to Bidi network headers. */
/** Converts from CDP Network domain headers to BiDi network headers. */
function bidiNetworkHeadersFromCdpNetworkHeaders(headers) {

@@ -47,2 +47,16 @@ if (!headers) {

exports.bidiNetworkHeadersFromCdpNetworkHeaders = bidiNetworkHeadersFromCdpNetworkHeaders;
/** Converts from CDP Fetch domain headers to BiDi network headers. */
function bidiNetworkHeadersFromCdpNetworkHeadersEntries(headers) {
if (!headers) {
return [];
}
return headers.map(({ name, value }) => ({
name,
value: {
type: 'string',
value,
},
}));
}
exports.bidiNetworkHeadersFromCdpNetworkHeadersEntries = bidiNetworkHeadersFromCdpNetworkHeadersEntries;
/** Converts from Bidi network headers to CDP Network domain headers. */

@@ -49,0 +63,0 @@ function cdpNetworkHeadersFromBidiNetworkHeaders(headers) {

@@ -33,2 +33,9 @@ /**

};
/**
* Subscription item is a pair of event name and context id.
*/
export type SubscriptionItem = {
contextId: BrowsingContext.BrowsingContext;
event: ChromiumBidi.EventNames;
};
export declare class EventManager extends EventEmitter<EventManagerEventsMap> {

@@ -38,2 +45,3 @@ #private;

get subscriptionManager(): SubscriptionManager;
addSubscribeHook(event: ChromiumBidi.EventNames, hook: (contextId: BrowsingContext.BrowsingContext) => Promise<void>): void;
registerEvent(event: ChromiumBidi.Event, contextId: BrowsingContext.BrowsingContext | null): void;

@@ -40,0 +48,0 @@ registerPromiseEvent(event: Promise<Result<ChromiumBidi.Event>>, contextId: BrowsingContext.BrowsingContext | null, eventName: ChromiumBidi.EventNames): void;

@@ -23,2 +23,3 @@ "use strict";

const DefaultMap_js_1 = require("../../../utils/DefaultMap.js");
const DistinctValues_js_1 = require("../../../utils/DistinctValues.js");
const EventEmitter_js_1 = require("../../../utils/EventEmitter.js");

@@ -71,2 +72,6 @@ const IdWrapper_js_1 = require("../../../utils/IdWrapper.js");

#browsingContextStorage;
/**
* Map of event name to hooks to be called when client is subscribed to the event.
*/
#subscribeHooks;
constructor(browsingContextStorage) {

@@ -76,2 +81,3 @@ super();

this.#subscriptionManager = new SubscriptionManager_js_1.SubscriptionManager(browsingContextStorage);
this.#subscribeHooks = new DefaultMap_js_1.DefaultMap(() => []);
}

@@ -87,2 +93,5 @@ get subscriptionManager() {

}
addSubscribeHook(event, hook) {
this.#subscribeHooks.get(event).push(hook);
}
registerEvent(event, contextId) {

@@ -118,5 +127,9 @@ this.registerPromiseEvent(Promise.resolve({

}
// List of the subscription items that were actually added. Each contains a specific
// event and context. No domain event (like "network") or global context subscription
// (like null) are included.
const addedSubscriptionItems = [];
for (const eventName of eventNames) {
for (const contextId of contextIds) {
this.#subscriptionManager.subscribe(eventName, contextId, channel);
addedSubscriptionItems.push(...this.#subscriptionManager.subscribe(eventName, contextId, channel));
for (const eventWrapper of this.#getBufferedEvents(eventName, contextId, channel)) {

@@ -132,2 +145,9 @@ // The order of the events is important.

}
// Iterate over all new subscription items and call hooks if any. There can be
// duplicates, e.g. when subscribing to the whole domain and some specific event in
// the same time ("network", "network.responseCompleted"). `distinctValues` guarantees
// that hooks are called only once per pair event + context.
(0, DistinctValues_js_1.distinctValues)(addedSubscriptionItems).forEach(({ contextId, event }) => {
this.#subscribeHooks.get(event).forEach((hook) => hook(contextId));
});
await this.toggleModulesIfNeeded();

@@ -134,0 +154,0 @@ }

@@ -18,4 +18,5 @@ /**

import type { BidiPlusChannel } from '../../../protocol/chromium-bidi.js';
import { ChromiumBidi, type BrowsingContext } from '../../../protocol/protocol.js';
import { type BrowsingContext, ChromiumBidi } from '../../../protocol/protocol.js';
import type { BrowsingContextStorage } from '../context/BrowsingContextStorage.js';
import type { SubscriptionItem } from './EventManager.js';
/**

@@ -41,4 +42,14 @@ * Returns the cartesian product of the given arrays.

isSubscribedTo(moduleOrEvent: ChromiumBidi.EventNames, contextId?: BrowsingContext.BrowsingContext | null): boolean;
subscribe(event: ChromiumBidi.EventNames, contextId: BrowsingContext.BrowsingContext | null, channel: BidiPlusChannel): void;
/**
* Subscribes to event in the given context and channel.
* @param {EventNames} event
* @param {BrowsingContext.BrowsingContext | null} contextId
* @param {BidiPlusChannel} channel
* @return {SubscriptionItem[]} List of
* subscriptions. If the event is a whole module, it will return all the specific
* events. If the contextId is null, it will return all the top-level contexts which were
* not subscribed before the command.
*/
subscribe(event: ChromiumBidi.EventNames, contextId: BrowsingContext.BrowsingContext | null, channel: BidiPlusChannel): SubscriptionItem[];
/**
* Unsubscribes atomically from all events in the given contexts and channel.

@@ -45,0 +56,0 @@ */

@@ -152,2 +152,12 @@ "use strict";

}
/**
* Subscribes to event in the given context and channel.
* @param {EventNames} event
* @param {BrowsingContext.BrowsingContext | null} contextId
* @param {BidiPlusChannel} channel
* @return {SubscriptionItem[]} List of
* subscriptions. If the event is a whole module, it will return all the specific
* events. If the contextId is null, it will return all the top-level contexts which were
* not subscribed before the command.
*/
subscribe(event, contextId, channel) {

@@ -159,13 +169,17 @@ // All the subscriptions are handled on the top-level contexts.

case protocol_js_1.ChromiumBidi.BiDiModule.BrowsingContext:
Object.values(protocol_js_1.ChromiumBidi.BrowsingContext.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
return;
return Object.values(protocol_js_1.ChromiumBidi.BrowsingContext.EventNames)
.map((specificEvent) => this.subscribe(specificEvent, contextId, channel))
.flat();
case protocol_js_1.ChromiumBidi.BiDiModule.Log:
Object.values(protocol_js_1.ChromiumBidi.Log.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
return;
return Object.values(protocol_js_1.ChromiumBidi.Log.EventNames)
.map((specificEvent) => this.subscribe(specificEvent, contextId, channel))
.flat();
case protocol_js_1.ChromiumBidi.BiDiModule.Network:
Object.values(protocol_js_1.ChromiumBidi.Network.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
return;
return Object.values(protocol_js_1.ChromiumBidi.Network.EventNames)
.map((specificEvent) => this.subscribe(specificEvent, contextId, channel))
.flat();
case protocol_js_1.ChromiumBidi.BiDiModule.Script:
Object.values(protocol_js_1.ChromiumBidi.Script.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
return;
return Object.values(protocol_js_1.ChromiumBidi.Script.EventNames)
.map((specificEvent) => this.subscribe(specificEvent, contextId, channel))
.flat();
default:

@@ -182,7 +196,16 @@ // Intentionally left empty.

const eventMap = contextToEventMap.get(contextId);
// Do not re-subscribe to events to keep the priority.
if (eventMap.has(event)) {
return;
const affectedContextIds = (contextId === null
? this.#browsingContextStorage.getTopLevelContexts().map((c) => c.id)
: [contextId])
// There can be contexts that are already subscribed to the event. Do not include
// them to the output.
.filter((contextId) => !this.isSubscribedTo(event, contextId));
if (!eventMap.has(event)) {
// Add subscription only if it's not already subscribed.
eventMap.set(event, this.#subscriptionPriority++);
}
eventMap.set(event, this.#subscriptionPriority++);
return affectedContextIds.map((contextId) => ({
event,
contextId,
}));
}

@@ -189,0 +212,0 @@ /**

@@ -102,7 +102,17 @@ "use strict";

const browserClient = await cdpConnection.createBrowserSession();
const { targetId: mapperTabTargetId } = await browserClient.sendCommand('Target.createTarget', {
// Run mapper in the first open tab.
const targets = (await cdpConnection.sendCommand('Target.getTargets', {}));
const mapperTabTargetId = targets.targetInfos.filter((target) => target.type === 'page')[0].targetId;
const { sessionId: mapperSessionId } = await browserClient.sendCommand('Target.attachToTarget', { targetId: mapperTabTargetId, flatten: true });
const mapperCdpClient = cdpConnection.getCdpClient(mapperSessionId);
// Click on the body to interact with the page in order to "beforeunload" being
// triggered when the tab is closed.
await mapperCdpClient.sendCommand('Runtime.evaluate', {
expression: 'document.body.click()',
userGesture: true,
});
// Create and activate new tab with a blank page.
await browserClient.sendCommand('Target.createTarget', {
url: 'about:blank',
});
const { sessionId: mapperSessionId } = await browserClient.sendCommand('Target.attachToTarget', { targetId: mapperTabTargetId, flatten: true });
const mapperCdpClient = cdpConnection.getCdpClient(mapperSessionId);
const bidiSession = new SimpleTransport_js_1.SimpleTransport(async (message) => await this.#sendMessage(mapperCdpClient, message));

@@ -109,0 +119,0 @@ // Process responses from the mapper tab.

@@ -29,4 +29,5 @@ /**

sendDebugMessage?: ((message: string) => void) | null;
onbeforeunload: ((this: WindowEventHandlers, ev: BeforeUnloadEvent) => any) | null;
}
}
export {};

@@ -29,2 +29,4 @@ "use strict";

globalThis.document.documentElement.innerHTML = mapperPageSource;
// Show a confirmation dialog when the user tries to leave the Mapper tab.
globalThis.window.onbeforeunload = () => 'Closing or reloading this tab will stop the BiDi process. Are you sure you want to leave?';
}

@@ -31,0 +33,0 @@ exports.generatePage = generatePage;

@@ -33,9 +33,3 @@ /**

request: string;
body?: {
type: "string";
value: string;
} | {
type: "base64";
value: string;
} | undefined;
url?: string | undefined;
cookies?: {

@@ -51,2 +45,10 @@ value: {

}[] | undefined;
method?: string | undefined;
body?: {
type: "string";
value: string;
} | {
type: "base64";
value: string;
} | undefined;
headers?: {

@@ -62,4 +64,2 @@ value: {

}[] | undefined;
method?: string | undefined;
url?: string | undefined;
};

@@ -66,0 +66,0 @@ function parseContinueResponseParameters(params: unknown): Protocol.Network.ContinueResponseParameters;

{
"name": "chromium-bidi",
"version": "0.5.19",
"version": "0.5.20",
"description": "An implementation of the WebDriver BiDi protocol for Chromium implemented as a JavaScript layer translating between BiDi and CDP, running inside a Chrome tab.",

@@ -150,6 +150,6 @@ "scripts": {

"@actions/core": "1.10.1",
"@puppeteer/browsers": "2.2.0",
"@puppeteer/browsers": "2.2.3",
"@rollup/plugin-commonjs": "25.0.7",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/wasm-node": "4.13.2",
"@rollup/wasm-node": "4.17.2",
"@types/chai": "4.3.11",

@@ -159,3 +159,3 @@ "@types/chai-as-promised": "7.1.8",

"@types/mocha": "10.0.6",
"@types/node": "20.12.2",
"@types/node": "20.12.8",
"@types/sinon": "17.0.3",

@@ -165,8 +165,8 @@ "@types/websocket": "1.0.10",

"@types/yargs": "17.0.32",
"@typescript-eslint/eslint-plugin": "7.4.0",
"@typescript-eslint/parser": "7.4.0",
"@typescript-eslint/eslint-plugin": "7.8.0",
"@typescript-eslint/parser": "7.8.0",
"chai": "4.4.1",
"chai-as-promised": "7.1.1",
"debug": "4.3.4",
"devtools-protocol": "0.0.1286932",
"devtools-protocol": "0.0.1306150",
"eslint": "8.57.0",

@@ -176,3 +176,3 @@ "eslint-config-prettier": "9.1.0",

"eslint-plugin-import": "2.29.1",
"eslint-plugin-mocha": "10.4.1",
"eslint-plugin-mocha": "10.4.3",
"eslint-plugin-prettier": "5.1.3",

@@ -186,13 +186,13 @@ "eslint-plugin-promise": "6.1.1",

"rimraf": "5.0.5",
"rollup": "4.13.2",
"rollup": "4.17.2",
"rollup-plugin-license": "3.3.1",
"selenium-webdriver": "4.19.0",
"selenium-webdriver": "4.20.0",
"sinon": "17.0.1",
"source-map-support": "0.5.21",
"tslib": "2.6.2",
"typescript": "5.4.3",
"webdriverio": "8.35.1",
"typescript": "5.4.5",
"webdriverio": "8.36.1",
"websocket": "1.0.34",
"wireit": "0.14.4",
"ws": "8.16.0",
"ws": "8.17.0",
"yargs": "17.7.2"

@@ -203,4 +203,4 @@ },

"urlpattern-polyfill": "10.0.0",
"zod": "3.22.4"
"zod": "3.23.5"
}
}

@@ -31,3 +31,3 @@ # WebDriver BiDi for Chromium [![chromium-bidi on npm](https://img.shields.io/npm/v/chromium-bidi)](https://www.npmjs.com/package/chromium-bidi)

method: "cdp.sendCommand",
params: ScriptEvaluateParameters,
params: CdpSendCommandParameters,
}

@@ -56,3 +56,3 @@

method: "cdp.getSession",
params: ScriptEvaluateParameters,
params: CdpGetSessionParameters,
}

@@ -76,3 +76,3 @@

method: "cdp.resolveRealm",
params: ScriptEvaluateParameters,
params: CdpResolveRealmParameters,
}

@@ -79,0 +79,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc