diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index eb9bb881601462..63c3ac38348ffa 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -20,6 +20,7 @@ const { BrowsingContextInfo } = require('./browsingContextTypes') const { SerializationOptions, ReferenceValue, RemoteValue } = require('./protocolValue') const { WebElement } = require('../lib/webdriver') const { CaptureScreenshotParameters } = require('./captureScreenshotParameters') +const { CreateContextParameters } = require('./createContextParameters') class Locator { static Type = Object.freeze({ @@ -79,11 +80,19 @@ class BrowsingContext { return this._id } - async init({ browsingContextId, type, referenceContext }) { + async init({ browsingContextId = undefined, type = undefined, createParameters = undefined }) { if (!(await this._driver.getCapabilities()).get('webSocketUrl')) { throw Error('WebDriver instance must support BiDi protocol') } + if (browsingContextId === undefined && type === undefined && createParameters === undefined) { + throw Error('Either BrowsingContextId or Type or CreateParameters must be provided') + } + + if (type === undefined && createParameters !== undefined) { + throw Error('Type must be provided with CreateParameters') + } + if (type !== undefined && !['window', 'tab'].includes(type)) { throw Error(`Valid types are 'window' & 'tab'. Received: ${type}`) } @@ -91,22 +100,33 @@ class BrowsingContext { this.bidi = await this._driver.getBidi() this._id = browsingContextId === undefined - ? (await this.create(type, referenceContext))['result']['context'] + ? (await this.create(type, createParameters))['result']['context'] : browsingContextId } /** - * Creates a browsing context for the given type and referenceContext + * Creates a browsing context for the given type with the given parameters */ - async create(type, referenceContext) { + async create(type, createParameters = undefined) { + if (createParameters !== undefined && (!createParameters) instanceof CreateContextParameters) { + throw Error(`Pass in the instance of CreateContextParameters. Received: ${createParameters}`) + } + + let parameters = new Map() + parameters.set('type', type) + + if (createParameters !== undefined) { + createParameters.asMap().forEach((value, key) => { + parameters.set(key, value) + }) + } + const params = { method: 'browsingContext.create', - params: { - type: type, - referenceContext: referenceContext, - }, + params: Object.fromEntries(parameters), } - return await this.bidi.send(params) + const res = await this.bidi.send(params) + return res } /** @@ -484,12 +504,15 @@ class PrintResult { * @param driver * @param browsingContextId The browsing context of current window/tab * @param type "window" or "tab" - * @param referenceContext To get a browsing context for this reference if passed + * @param createParameters The parameters for creating a new browsing context * @returns {Promise} */ -async function getBrowsingContextInstance(driver, { browsingContextId, type, referenceContext }) { +async function getBrowsingContextInstance( + driver, + { browsingContextId = undefined, type = undefined, createParameters = undefined }, +) { let instance = new BrowsingContext(driver) - await instance.init({ browsingContextId, type, referenceContext }) + await instance.init({ browsingContextId, type, createParameters }) return instance } diff --git a/javascript/node/selenium-webdriver/bidi/createContextParameters.js b/javascript/node/selenium-webdriver/bidi/createContextParameters.js new file mode 100644 index 00000000000000..9796a9829803b0 --- /dev/null +++ b/javascript/node/selenium-webdriver/bidi/createContextParameters.js @@ -0,0 +1,50 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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. + +class CreateContextParameters { + #map = new Map() + + referenceContext(id) { + if (typeof id !== 'string') { + throw new Error(`ReferenceContext must be string. Received:'${id}'`) + } + this.#map.set('referenceContext', id) + return this + } + + background(background) { + if (typeof background !== 'boolean') { + throw new Error(`Background must be boolean. Received:'${background}'`) + } + this.#map.set('background', background) + return this + } + + userContext(userContext) { + if (typeof userContext !== 'string') { + throw new Error(`UserContext must be string. Received:'${userContext}'`) + } + this.#map.set('userContext', userContext) + return this + } + + asMap() { + return this.#map + } +} + +module.exports = { CreateContextParameters } diff --git a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js index 1c7094accc2cbb..d4b77a84e184a1 100644 --- a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js @@ -25,6 +25,8 @@ const BrowsingContext = require('../../bidi/browsingContext') const until = require('../../lib/until') const { Origin, CaptureScreenshotParameters } = require('../../bidi/captureScreenshotParameters') const { BoxClipRectangle, ElementClipRectangle } = require('../../bidi/clipRectangle') +const { CreateContextParameters } = require('../../bidi/createContextParameters') +const BrowserBiDi = require('../../bidi/browser') suite( function (env) { @@ -62,11 +64,25 @@ suite( it('can create a window with a reference context', async function () { const browsingContext = await BrowsingContext(driver, { type: 'window', - referenceContext: await driver.getWindowHandle(), + createParameters: new CreateContextParameters().referenceContext(await driver.getWindowHandle()), }) assert.notEqual(browsingContext.id, null) }) + it('can create a tab with all parameters', async function () { + const browser = await BrowserBiDi(driver) + const userContext = await browser.createUserContext() + const browsingContext = await BrowsingContext(driver, { + type: 'window', + createParameters: new CreateContextParameters() + .referenceContext(await driver.getWindowHandle()) + .background(true) + .userContext(userContext), + }) + assert.notEqual(browsingContext.id, null) + assert.notEqual(browsingContext.id, await driver.getWindowHandle()) + }) + it('can create a tab', async function () { const browsingContext = await BrowsingContext(driver, { type: 'tab', @@ -77,7 +93,7 @@ suite( it('can create a tab with a reference context', async function () { const browsingContext = await BrowsingContext(driver, { type: 'tab', - referenceContext: await driver.getWindowHandle(), + referenceContext: new CreateContextParameters().referenceContext(await driver.getWindowHandle()), }) assert.notEqual(browsingContext.id, null) })