mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 03:49:42 +00:00
Bug 1841018 - [bidi] Implement "browsingContext.traverseHistory" command. r=webdriver-reviewers,whimboo
Differential Revision: https://phabricator.services.mozilla.com/D193895
This commit is contained in:
parent
15c1a58822
commit
120294a016
@ -238,6 +238,9 @@ export function executeSoon(fn) {
|
||||
* @param {Condition} func
|
||||
* Function to run off the main thread.
|
||||
* @param {object=} options
|
||||
* @param {string=} options.errorMessage
|
||||
* Message to use to send a warning if ``timeout`` is over.
|
||||
* Defaults to `PollPromise timed out`.
|
||||
* @param {number=} options.timeout
|
||||
* Desired timeout if wanted. If 0 or less than the runtime evaluation
|
||||
* time of ``func``, ``func`` is guaranteed to run at least once.
|
||||
@ -257,7 +260,12 @@ export function executeSoon(fn) {
|
||||
* @throws {RangeError}
|
||||
* If `timeout` or `interval` are not unsigned integers.
|
||||
*/
|
||||
export function PollPromise(func, { timeout = null, interval = 10 } = {}) {
|
||||
export function PollPromise(func, options = {}) {
|
||||
const {
|
||||
errorMessage = "PollPromise timed out",
|
||||
interval = 10,
|
||||
timeout = null,
|
||||
} = options;
|
||||
const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
if (typeof func != "function") {
|
||||
@ -311,6 +319,9 @@ export function PollPromise(func, { timeout = null, interval = 10 } = {}) {
|
||||
timer.init(evalFn, interval, TYPE_REPEATING_SLACK);
|
||||
}).then(
|
||||
res => {
|
||||
if (Number.isInteger(timeout)) {
|
||||
lazy.logger.warn(`${errorMessage} after ${timeout} ms`);
|
||||
}
|
||||
timer.cancel();
|
||||
return res;
|
||||
},
|
||||
|
@ -27,6 +27,7 @@ const ERRORS = new Set([
|
||||
"NoSuchElementError",
|
||||
"NoSuchFrameError",
|
||||
"NoSuchHandleError",
|
||||
"NoSuchHistoryEntryError",
|
||||
"NoSuchInterceptError",
|
||||
"NoSuchNodeError",
|
||||
"NoSuchScriptError",
|
||||
@ -585,6 +586,21 @@ class NoSuchHandleError extends WebDriverError {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The entry of the history could not be found.
|
||||
*
|
||||
* @param {string=} message
|
||||
* Optional string describing error situation.
|
||||
* @param {object=} data
|
||||
* Additional error data helpful in diagnosing the error.
|
||||
*/
|
||||
class NoSuchHistoryEntryError extends WebDriverError {
|
||||
constructor(message, data = {}) {
|
||||
super(message, data);
|
||||
this.status = "no such history entry";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tried to remove an unknown network intercept.
|
||||
*
|
||||
@ -803,6 +819,7 @@ const STATUSES = new Map([
|
||||
["no such element", NoSuchElementError],
|
||||
["no such frame", NoSuchFrameError],
|
||||
["no such handle", NoSuchHandleError],
|
||||
["no such history entry", NoSuchHistoryEntryError],
|
||||
["no such intercept", NoSuchInterceptError],
|
||||
["no such node", NoSuchNodeError],
|
||||
["no such script", NoSuchScriptError],
|
||||
|
@ -22,6 +22,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
"chrome://remote/content/shared/NavigationManager.sys.mjs",
|
||||
NavigationListener:
|
||||
"chrome://remote/content/shared/listeners/NavigationListener.sys.mjs",
|
||||
PollPromise: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
pprint: "chrome://remote/content/shared/Format.sys.mjs",
|
||||
print: "chrome://remote/content/shared/PDF.sys.mjs",
|
||||
ProgressListener: "chrome://remote/content/shared/Navigate.sys.mjs",
|
||||
@ -89,6 +90,8 @@ export const OriginType = {
|
||||
viewport: "viewport",
|
||||
};
|
||||
|
||||
const TIMEOUT_SET_HISTORY_INDEX = 1000;
|
||||
|
||||
/**
|
||||
* Enum of user prompt types supported by the browsingContext.handleUserPrompt
|
||||
* command, these types can be retrieved from `dialog.args.promptType`.
|
||||
@ -1003,7 +1006,7 @@ class BrowsingContextModule extends Module {
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* Raised if an argument is of an invalid type or value.
|
||||
* @throws UnsupportedOperationError
|
||||
* @throws {UnsupportedOperationError}
|
||||
* Raised when the command is called on Android.
|
||||
*/
|
||||
async setViewport(options = {}) {
|
||||
@ -1080,6 +1083,64 @@ class BrowsingContextModule extends Module {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the history of a given context by a given delta.
|
||||
*
|
||||
* @param {object=} options
|
||||
* @param {string} options.context
|
||||
* Id of the browsing context.
|
||||
* @param {number} options.delta
|
||||
* The number of steps we have to traverse.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* Raised if an argument is of an invalid type or value.
|
||||
* @throws {NoSuchFrameException}
|
||||
* When a context is not available.
|
||||
* @throws {NoSuchHistoryEntryError}
|
||||
* When a requested history entry does not exist.
|
||||
*/
|
||||
async traverseHistory(options = {}) {
|
||||
const { context: contextId, delta } = options;
|
||||
|
||||
lazy.assert.string(
|
||||
contextId,
|
||||
`Expected "context" to be a string, got ${contextId}`
|
||||
);
|
||||
|
||||
const context = this.#getBrowsingContext(contextId);
|
||||
|
||||
lazy.assert.integer(delta);
|
||||
|
||||
const sessionHistory = context.sessionHistory;
|
||||
const allSteps = sessionHistory.count;
|
||||
const currentIndex = sessionHistory.index;
|
||||
const targetIndex = currentIndex + delta;
|
||||
const validEntry = targetIndex >= 0 && targetIndex < allSteps;
|
||||
|
||||
if (!validEntry) {
|
||||
throw new lazy.error.NoSuchHistoryEntryError(
|
||||
`History entry with delta ${delta} not found`
|
||||
);
|
||||
}
|
||||
|
||||
context.goToIndex(targetIndex);
|
||||
|
||||
// On some platforms the requested index isn't set immediately.
|
||||
await lazy.PollPromise(
|
||||
(resolve, reject) => {
|
||||
if (sessionHistory.index == targetIndex) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
{
|
||||
errorMessage: `History was not updated for index "${targetIndex}"`,
|
||||
timeout: TIMEOUT_SET_HISTORY_INDEX,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start and await a navigation on the provided BrowsingContext. Returns a
|
||||
* promise which resolves when the navigation is done according to the provided
|
||||
|
Loading…
x
Reference in New Issue
Block a user