Skip to content

Commit

Permalink
chore: add goog: prefix for cdp commands
Browse files Browse the repository at this point in the history
  • Loading branch information
sadym-chromium committed Dec 2, 2024
1 parent 921f637 commit cbc4acc
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 50 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ at [WPT WebDriver BiDi status](https://wpt.fyi/results/webdriver/tests/bidi).

**"BiDi+"** is an extension of the WebDriver BiDi protocol. In addition to [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) it has:

### Command `cdp.sendCommand`
### Command `goog:cdp.sendCommand`

```cddl
CdpSendCommandCommand = {
method: "cdp.sendCommand",
method: "goog:cdp.sendCommand",
params: CdpSendCommandParameters,
}
Expand All @@ -45,11 +45,11 @@ The command runs the
described [CDP command](https://chromedevtools.github.io/devtools-protocol)
and returns the result.

### Command `cdp.getSession`
### Command `goog:cdp.getSession`

```cddl
CdpGetSessionCommand = {
method: "cdp.getSession",
method: "goog:cdp.getSession",
params: CdpGetSessionParameters,
}
Expand All @@ -64,11 +64,11 @@ CdpGetSessionResult = {

The command returns the default CDP session for the selected browsing context.

### Command `cdp.resolveRealm`
### Command `goog:cdp.resolveRealm`

```cddl
CdpResolveRealmCommand = {
method: "cdp.resolveRealm",
method: "goog:cdp.resolveRealm",
params: CdpResolveRealmParameters,
}
Expand All @@ -83,11 +83,11 @@ CdpResolveRealmResult = {

The command returns resolves a BiDi realm to its CDP execution context ID.

### Events `cdp`
### Events `goog:cdp`

```cddl
CdpEventReceivedEvent = {
method: "cdp.<CDP Event Name>",
method: "goog:cdp.<CDP Event Name>",
params: CdpEventReceivedParameters,
}
Expand Down
16 changes: 16 additions & 0 deletions src/bidiMapper/CommandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,22 @@ export class CommandProcessor extends EventEmitter<CommandProcessorEventsMap> {

// CDP module
// keep-sorted start block=yes
case 'goog:cdp.getSession':
return this.#cdpProcessor.getSession(
this.#parser.parseGetSessionParams(command.params),
);
case 'goog:cdp.resolveRealm':
return this.#cdpProcessor.resolveRealm(
this.#parser.parseResolveRealmParams(command.params),
);
case 'goog:cdp.sendCommand':
return await this.#cdpProcessor.sendCommand(
this.#parser.parseSendCommandParams(command.params),
);
// keep-sorted end
// CDP deprecated domain.
// https://github.com/GoogleChromeLabs/chromium-bidi/issues/2844
// keep-sorted start block=yes
case 'cdp.getSession':
return this.#cdpProcessor.getSession(
this.#parser.parseGetSessionParams(command.params),
Expand Down
14 changes: 14 additions & 0 deletions src/bidiMapper/modules/cdp/CdpTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,20 @@ export class CdpTarget {
if (typeof event !== 'string') {
return;
}
this.#eventManager.registerEvent(
{
type: 'event',
method: `goog:cdp.${event}`,
params: {
event,
params,
session: this.cdpSessionId,
},
},
this.id,
);
// Duplicate the event to the deprecated event name.
// https://github.com/GoogleChromeLabs/chromium-bidi/issues/2844
this.#eventManager.registerEvent(
{
type: 'event',
Expand Down
17 changes: 15 additions & 2 deletions src/bidiMapper/modules/session/SubscriptionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import type {BrowsingContextStorage} from '../context/BrowsingContextStorage.js';

import type {SubscriptionItem} from './EventManager.js';
import {isCdpEvent} from './events.js';
import {isCdpEvent, isDeprecatedCdpEvent} from './events.js';

/**
* Returns the cartesian product of the given arrays.
Expand Down Expand Up @@ -142,7 +142,7 @@ export class SubscriptionManager {
const priority = contextToEventMap.get(context)?.get(eventMethod);
// For CDP we can't provide specific event name when subscribing
// to the module directly.
// Because of that we need to see event `cdp` exits in the map.
// Because of that we need to see event `cdp` exists in the map.
if (isCdpEvent(eventMethod)) {
const cdpPriority = contextToEventMap
.get(context)
Expand All @@ -155,6 +155,19 @@ export class SubscriptionManager {
// to only one of the two
(priority ?? cdpPriority);
}
// https://github.com/GoogleChromeLabs/chromium-bidi/issues/2844.
if (isDeprecatedCdpEvent(eventMethod)) {
const cdpPriority = contextToEventMap
.get(context)
?.get(ChromiumBidi.BiDiModule.DeprecatedCdp);
// If we subscribe to the event directly and `cdp` module as well
// priority will be different we take minimal priority
return priority && cdpPriority
? Math.min(priority, cdpPriority)
: // At this point we know that we have subscribed
// to only one of the two
(priority ?? cdpPriority);
}
return priority;
})
.filter((p) => p !== undefined);
Expand Down
64 changes: 54 additions & 10 deletions src/bidiMapper/modules/session/events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,56 @@ import {expect} from 'chai';

import {ChromiumBidi} from '../../../protocol/protocol.js';

import {assertSupportedEvent, isCdpEvent} from './events.js';
import {
assertSupportedEvent,
isCdpEvent,
isDeprecatedCdpEvent,
} from './events.js';

const CDP_EVENTS = [
'goog:cdp',
'goog:cdp.event',
'goog:cdp.Debugger.breakpointResolved',
];
const DEPRECATED_CDP_EVENTS = [
'cdp',
'cdp.event',
'cdp.Debugger.breakpointResolved',
];
const NON_CDP_EVENTS = ['log', 'log.entryAdded'];

describe('event', () => {
describe('isCdpEvent', () => {
it('should return true for CDP events', () => {
expect(isCdpEvent('cdp')).to.be.true;
expect(isCdpEvent('cdp.event')).to.be.true;
});
for (const cdpEvent of CDP_EVENTS)
it(`should return true for CDP event '${cdpEvent}'`, () => {
expect(isCdpEvent(cdpEvent)).to.be.true;
});
for (const deprecatedCdpEvent of DEPRECATED_CDP_EVENTS)
it(`should return false for deprecated CDP event '${deprecatedCdpEvent}'`, () => {
expect(isCdpEvent(deprecatedCdpEvent)).to.be.false;
});

it('should return false for non-CDP events', () => {
expect(isCdpEvent('log')).to.be.false;
expect(isCdpEvent('log.entryAdded')).to.be.false;
});
for (const nonCdpEvent of NON_CDP_EVENTS)
it(`should return false for non-CDP event '${nonCdpEvent}'`, () => {
expect(isCdpEvent(nonCdpEvent)).to.be.false;
});
});

describe('isDeprecatedCdpEvent', () => {
for (const cdpEvent of CDP_EVENTS)
it(`should return false for CDP event '${cdpEvent}'`, () => {
expect(isDeprecatedCdpEvent(cdpEvent)).to.be.false;
});

for (const deprecatedCdpEvent of DEPRECATED_CDP_EVENTS)
it(`should return true for deprecated CDP event '${deprecatedCdpEvent}'`, () => {
expect(isDeprecatedCdpEvent(deprecatedCdpEvent)).to.be.true;
});

for (const nonCdpEvent of NON_CDP_EVENTS)
it(`should return false for non-CDP event '${nonCdpEvent}'`, () => {
expect(isDeprecatedCdpEvent(nonCdpEvent)).to.be.false;
});
});

describe('assertSupportedEvent', () => {
Expand All @@ -40,11 +77,18 @@ describe('event', () => {
}).to.throw('Unknown event: unknown');
});

it('should not throw for known events', () => {
it('should not throw for known deprecated CDP events', () => {
expect(() => {
assertSupportedEvent('cdp.Debugger.breakpointResolved');
assertSupportedEvent(ChromiumBidi.Log.EventNames.LogEntryAdded);
}).to.not.throw();
});

it('should not throw for known CDP events', () => {
expect(() => {
assertSupportedEvent('goog:cdp.Debugger.breakpointResolved');
assertSupportedEvent(ChromiumBidi.Log.EventNames.LogEntryAdded);
}).to.not.throw();
});
});
});
16 changes: 15 additions & 1 deletion src/bidiMapper/modules/session/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,28 @@ export function isCdpEvent(name: string): boolean {
name.split('.').at(0)?.startsWith(ChromiumBidi.BiDiModule.Cdp) ?? false
);
}
/**
* Returns true if the given event is a deprecated CDP event.
* @see https://chromedevtools.github.io/devtools-protocol/
*/
export function isDeprecatedCdpEvent(name: string): boolean {
return (
name.split('.').at(0)?.startsWith(ChromiumBidi.BiDiModule.DeprecatedCdp) ??
false
);
}

/**
* Asserts that the given event is known to BiDi or BiDi+, or throws otherwise.
*/
export function assertSupportedEvent(
name: string,
): asserts name is ChromiumBidi.EventNames {
if (!ChromiumBidi.EVENT_NAMES.has(name as never) && !isCdpEvent(name)) {
if (
!ChromiumBidi.EVENT_NAMES.has(name as never) &&
!isCdpEvent(name) &&
!isDeprecatedCdpEvent(name)
) {
throw new InvalidArgumentException(`Unknown event: ${name}`);
}
}
41 changes: 35 additions & 6 deletions src/protocol/cdp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ export type Command = {
export type CommandData =
| SendCommandCommand
| GetSessionCommand
| ResolveRealmCommand;
| ResolveRealmCommand
// https://github.com/GoogleChromeLabs/chromium-bidi/issues/2844
| DeprecatedSendCommandCommand
| DeprecatedGetSessionCommand
| DeprecatedResolveRealmCommand;

export type CommandResponse = {
type: 'success';
Expand All @@ -45,11 +49,16 @@ export type ResultData =
| GetSessionResult
| ResolveRealmResult;

export type SendCommandCommand = {
export type DeprecatedSendCommandCommand = {
method: 'cdp.sendCommand';
params: SendCommandParameters;
};

export type SendCommandCommand = {
method: 'goog:cdp.sendCommand';
params: SendCommandParameters;
};

export type SendCommandParameters<
Command extends
keyof ProtocolMapping.Commands = keyof ProtocolMapping.Commands,
Expand All @@ -64,11 +73,16 @@ export type SendCommandResult = {
session?: Protocol.Target.SessionID;
};

export type GetSessionCommand = {
export type DeprecatedGetSessionCommand = {
method: 'cdp.getSession';
params: GetSessionParameters;
};

export type GetSessionCommand = {
method: 'goog:cdp.getSession';
params: GetSessionParameters;
};

export type GetSessionParameters = {
context: BrowsingContext.BrowsingContext;
};
Expand All @@ -77,11 +91,16 @@ export type GetSessionResult = {
session?: Protocol.Target.SessionID;
};

export type ResolveRealmCommand = {
export type DeprecatedResolveRealmCommand = {
method: 'cdp.resolveRealm';
params: ResolveRealmParameters;
};

export type ResolveRealmCommand = {
method: 'goog:cdp.resolveRealm';
params: ResolveRealmParameters;
};

export type ResolveRealmParameters = {
realm: Script.Realm;
};
Expand All @@ -93,13 +112,23 @@ export type ResolveRealmResult = {
export type Event = {
type: 'event';
} & EventData;
export type EventData = EventDataFor<keyof ProtocolMapping.Events>;

export type EventDataFor<EventName extends keyof ProtocolMapping.Events> = {
export type EventData =
| EventDataFor<keyof ProtocolMapping.Events>
| DeprecatedEventDataFor<keyof ProtocolMapping.Events>;

export type DeprecatedEventDataFor<
EventName extends keyof ProtocolMapping.Events,
> = {
method: `cdp.${EventName}`;
params: EventParametersFor<EventName>;
};

export type EventDataFor<EventName extends keyof ProtocolMapping.Events> = {
method: `goog:cdp.${EventName}`;
params: EventParametersFor<EventName>;
};

export type EventParametersFor<EventName extends keyof ProtocolMapping.Events> =
{
event: EventName;
Expand Down
3 changes: 2 additions & 1 deletion src/protocol/chromium-bidi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export enum BiDiModule {
Bluetooth = 'bluetooth',
Browser = 'browser',
BrowsingContext = 'browsingContext',
Cdp = 'cdp',
Cdp = 'goog:cdp',
DeprecatedCdp = 'cdp',
Input = 'input',
Log = 'log',
Network = 'network',
Expand Down
Loading

0 comments on commit cbc4acc

Please sign in to comment.