Skip to content

Commit

Permalink
feat: implement browsingContext.traverseHistory (#1537)
Browse files Browse the repository at this point in the history
Fixed: #1532
  • Loading branch information
jrandolf-2 authored Nov 13, 2023
1 parent 85d1af7 commit 76ca291
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/bidiMapper/BidiNoOpParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ export class BidiNoOpParser implements IBidiParser {
): BrowsingContext.SetViewportParameters {
return params as BrowsingContext.SetViewportParameters;
}
parseTraverseHistoryParams(
params: unknown
): BrowsingContext.TraverseHistoryParameters {
return params as BrowsingContext.TraverseHistoryParameters;
}
// keep-sorted end

// CDP domain
Expand Down
3 changes: 3 additions & 0 deletions src/bidiMapper/BidiParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export interface IBidiParser {
parseSetViewportParams(
params: unknown
): BrowsingContext.SetViewportParameters;
parseTraverseHistoryParams(
params: unknown
): BrowsingContext.TraverseHistoryParameters;
// keep-sorted end

// CDP domain
Expand Down
4 changes: 3 additions & 1 deletion src/bidiMapper/CommandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ export class CommandProcessor extends EventEmitter<CommandProcessorEventsMap> {
this.#parser.parseSetViewportParams(command.params)
);
case 'browsingContext.traverseHistory':
break;
return await this.#browsingContextProcessor.traverseHistory(
this.#parser.parseTraverseHistoryParams(command.params)
);
// keep-sorted end

// CDP domain
Expand Down
23 changes: 23 additions & 0 deletions src/bidiMapper/domains/context/BrowsingContextImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ChromiumBidi,
InvalidArgumentException,
NoSuchElementException,
NoSuchHistoryEntryException,
Script,
UnableToCaptureScreenException,
UnknownErrorException,
Expand Down Expand Up @@ -962,6 +963,28 @@ export class BrowsingContextImpl {
async close(): Promise<void> {
await this.#cdpTarget.cdpClient.sendCommand('Page.close');
}

async traverseHistory(delta: number): Promise<void> {
if (delta === 0) {
return;
}

const history = await this.#cdpTarget.cdpClient.sendCommand(
'Page.getNavigationHistory'
);
const entry = history.entries[history.currentIndex + delta];
if (!entry) {
throw new NoSuchHistoryEntryException(
`No history entry at delta ${delta}`
);
}
await this.#cdpTarget.cdpClient.sendCommand('Page.navigateToHistoryEntry', {
entryId: entry.id,
});

this.#resetDeferredsIfFinished();
await this.lifecycleLoaded();
}
}

function getImageFormatParameters(
Expand Down
13 changes: 13 additions & 0 deletions src/bidiMapper/domains/context/BrowsingContextProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,19 @@ export class BrowsingContextProcessor {
return {};
}

async traverseHistory(
params: BrowsingContext.TraverseHistoryParameters
): Promise<BrowsingContext.TraverseHistoryResult> {
const context = this.#browsingContextStorage.getContext(params.context);
if (!context) {
throw new InvalidArgumentException(
`No browsing context with id ${params.context}`
);
}
await context.traverseHistory(params.delta);
return {};
}

async handleUserPrompt(
params: BrowsingContext.HandleUserPromptParameters
): Promise<EmptyResult> {
Expand Down
5 changes: 5 additions & 0 deletions src/bidiTab/BidiParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export class BidiParser implements IBidiParser {
): BrowsingContext.SetViewportParameters {
return Parser.BrowsingContext.parseSetViewportParams(params);
}
parseTraverseHistoryParams(
params: unknown
): BrowsingContext.TraverseHistoryParameters {
return Parser.BrowsingContext.parseTraverseHistoryParams(params);
}
// keep-sorted end

// CDP domain
Expand Down
9 changes: 9 additions & 0 deletions src/protocol-parser/protocol-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ export namespace BrowsingContext {
);
}

export function parseTraverseHistoryParams(
params: unknown
): Protocol.BrowsingContext.TraverseHistoryParameters {
return parseObject(
params,
WebDriverBidi.BrowsingContext.TraverseHistoryParametersSchema
);
}

export function parseHandleUserPromptParameters(
params: unknown
): Protocol.BrowsingContext.HandleUserPromptParameters {
Expand Down
80 changes: 80 additions & 0 deletions tests/browsing_context/test_traverse_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2023 Google LLC.
# Copyright (c) Microsoft Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest
from test_helpers import execute_command, goto_url

HISTORY_LENGTH = 2


@pytest.mark.asyncio
async def test_traverse_history(websocket, context_id, html):
for i in range(HISTORY_LENGTH + 1):
await goto_url(websocket, context_id, html(i))

await traverse_history(websocket, context_id, -2)
await assert_href_equals(websocket, context_id, html(HISTORY_LENGTH - 2))

await traverse_history(websocket, context_id, 2)
await assert_href_equals(websocket, context_id, html(HISTORY_LENGTH))

await traverse_history(websocket, context_id, -1)
await assert_href_equals(websocket, context_id, html(HISTORY_LENGTH - 1))

await traverse_history(websocket, context_id, 1)
await assert_href_equals(websocket, context_id, html(HISTORY_LENGTH))

await traverse_history(websocket, context_id, 0)
await assert_href_equals(websocket, context_id, html(HISTORY_LENGTH))


@pytest.mark.asyncio
async def test_traverse_history_no_entry(websocket, context_id, html):
await goto_url(websocket, context_id, html())

with pytest.raises(Exception,
match=str({
"error": "no such history entry",
"message": "No history entry at delta -2"
})):
await traverse_history(websocket, context_id, -2)


async def traverse_history(websocket, context_id, delta):
await execute_command(
websocket, {
"method": "browsingContext.traverseHistory",
"params": {
"context": context_id,
"delta": delta
}
})


async def assert_href_equals(websocket, context_id, href):
result = await execute_command(
websocket, {
"method": "script.evaluate",
"params": {
"expression": "window.location.href",
"target": {
"context": context_id
},
"resultOwnership": "none",
"awaitPromise": True
}
})

assert result["result"]["value"] == href

0 comments on commit 76ca291

Please sign in to comment.