Skip to content

Commit 4a6c384

Browse files
authored
[bidi] Update browsing context create method (#13766)
1 parent fee33dd commit 4a6c384

File tree

6 files changed

+223
-22
lines changed

6 files changed

+223
-22
lines changed

java/src/org/openqa/selenium/bidi/browsingcontext/BrowsingContext.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ public BrowsingContext(WebDriver driver, WindowType type) {
105105
this.id = this.create(type);
106106
}
107107

108+
/*
109+
* @deprecated
110+
* Use {@link #BrowsingContext(WebDriver, CreateParameters)} instead.
111+
*/
112+
@Deprecated
108113
public BrowsingContext(WebDriver driver, WindowType type, String referenceContextId) {
109114
Require.nonNull("WebDriver", driver);
110115
Require.nonNull("Reference browsing context id", referenceContextId);
@@ -117,7 +122,19 @@ public BrowsingContext(WebDriver driver, WindowType type, String referenceContex
117122

118123
this.driver = driver;
119124
this.bidi = ((HasBiDi) driver).getBiDi();
120-
this.id = this.create(type, referenceContextId);
125+
this.id = this.create(new CreateContextParameters(type).referenceContext(referenceContextId));
126+
}
127+
128+
public BrowsingContext(WebDriver driver, CreateContextParameters parameters) {
129+
Require.nonNull("WebDriver", driver);
130+
131+
if (!(driver instanceof HasBiDi)) {
132+
throw new IllegalArgumentException("WebDriver instance must support BiDi protocol");
133+
}
134+
135+
this.driver = driver;
136+
this.bidi = ((HasBiDi) driver).getBiDi();
137+
this.id = this.create(parameters);
121138
}
122139

123140
public String getId() {
@@ -130,12 +147,9 @@ private String create(WindowType type) {
130147
"browsingContext.create", Map.of("type", type.toString()), browsingContextIdMapper));
131148
}
132149

133-
private String create(WindowType type, String referenceContext) {
150+
private String create(CreateContextParameters parameters) {
134151
return this.bidi.send(
135-
new Command<>(
136-
"browsingContext.create",
137-
Map.of("type", type.toString(), "referenceContext", referenceContext),
138-
browsingContextIdMapper));
152+
new Command<>("browsingContext.create", parameters.toMap(), browsingContextIdMapper));
139153
}
140154

141155
public NavigationResult navigate(String url) {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.bidi.browsingcontext;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
import org.openqa.selenium.WindowType;
23+
24+
public class CreateContextParameters {
25+
private final Map<String, Object> map = new HashMap<>();
26+
private final WindowType windowType;
27+
28+
public CreateContextParameters(WindowType type) {
29+
this.windowType = type;
30+
}
31+
32+
public CreateContextParameters referenceContext(String id) {
33+
map.put("referenceContext", id);
34+
return this;
35+
}
36+
37+
public CreateContextParameters background(boolean background) {
38+
map.put("background", background);
39+
return this;
40+
}
41+
42+
public CreateContextParameters userContext(String userContext) {
43+
map.put("userContext", userContext);
44+
return this;
45+
}
46+
47+
public Map<String, Object> toMap() {
48+
map.put("type", windowType.toString());
49+
return map;
50+
}
51+
}

java/test/org/openqa/selenium/bidi/browsingcontext/BrowsingContextTest.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.openqa.selenium.WebElement;
3838
import org.openqa.selenium.WindowType;
3939
import org.openqa.selenium.bidi.BiDiException;
40+
import org.openqa.selenium.bidi.module.Browser;
4041
import org.openqa.selenium.environment.webserver.AppServer;
4142
import org.openqa.selenium.environment.webserver.NettyAppServer;
4243
import org.openqa.selenium.environment.webserver.Page;
@@ -77,7 +78,10 @@ void canCreateAWindow() {
7778
@NotYetImplemented(IE)
7879
void canCreateAWindowWithAReferenceContext() {
7980
BrowsingContext browsingContext =
80-
new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
81+
new BrowsingContext(
82+
driver,
83+
new CreateContextParameters(WindowType.WINDOW)
84+
.referenceContext(driver.getWindowHandle()));
8185
assertThat(browsingContext.getId()).isNotEmpty();
8286
}
8387

@@ -94,10 +98,30 @@ void canCreateATab() {
9498
@NotYetImplemented(IE)
9599
void canCreateATabWithAReferenceContext() {
96100
BrowsingContext browsingContext =
97-
new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
101+
new BrowsingContext(
102+
driver,
103+
new CreateContextParameters(WindowType.TAB).referenceContext(driver.getWindowHandle()));
98104
assertThat(browsingContext.getId()).isNotEmpty();
99105
}
100106

107+
@Test
108+
@NotYetImplemented(SAFARI)
109+
@NotYetImplemented(IE)
110+
void canCreateAContextWithAllParameters() {
111+
Browser browser = new Browser(driver);
112+
String userContextId = browser.createUserContext();
113+
114+
CreateContextParameters parameters = new CreateContextParameters(WindowType.WINDOW);
115+
parameters
116+
.referenceContext(driver.getWindowHandle())
117+
.userContext(userContextId)
118+
.background(true);
119+
120+
BrowsingContext browsingContext = new BrowsingContext(driver, parameters);
121+
assertThat(browsingContext.getId()).isNotEmpty();
122+
assertThat(browsingContext.getId()).isNotEqualTo(driver.getWindowHandle());
123+
}
124+
101125
@Test
102126
@NotYetImplemented(SAFARI)
103127
@NotYetImplemented(IE)

javascript/node/selenium-webdriver/bidi/browsingContext.js

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const { BrowsingContextInfo } = require('./browsingContextTypes')
2020
const { SerializationOptions, ReferenceValue, RemoteValue } = require('./protocolValue')
2121
const { WebElement } = require('../lib/webdriver')
2222
const { CaptureScreenshotParameters } = require('./captureScreenshotParameters')
23+
const { CreateContextParameters } = require('./createContextParameters')
2324

2425
/**
2526
* Represents the locator to locate nodes in the browsing context.
@@ -110,34 +111,53 @@ class BrowsingContext {
110111
return this._id
111112
}
112113

113-
async init({ browsingContextId, type, referenceContext }) {
114+
async init({ browsingContextId = undefined, type = undefined, createParameters = undefined }) {
114115
if (!(await this._driver.getCapabilities()).get('webSocketUrl')) {
115116
throw Error('WebDriver instance must support BiDi protocol')
116117
}
117118

119+
if (browsingContextId === undefined && type === undefined && createParameters === undefined) {
120+
throw Error('Either BrowsingContextId or Type or CreateParameters must be provided')
121+
}
122+
123+
if (type === undefined && createParameters !== undefined) {
124+
throw Error('Type must be provided with CreateParameters')
125+
}
126+
118127
if (type !== undefined && !['window', 'tab'].includes(type)) {
119128
throw Error(`Valid types are 'window' & 'tab'. Received: ${type}`)
120129
}
121130

122131
this.bidi = await this._driver.getBidi()
123132
this._id =
124133
browsingContextId === undefined
125-
? (await this.create(type, referenceContext))['result']['context']
134+
? (await this.create(type, createParameters))['result']['context']
126135
: browsingContextId
127136
}
128137

129138
/**
130-
* Creates a browsing context for the given type and referenceContext
139+
* Creates a browsing context for the given type with the given parameters
131140
*/
132-
async create(type, referenceContext) {
141+
async create(type, createParameters = undefined) {
142+
if (createParameters !== undefined && (!createParameters) instanceof CreateContextParameters) {
143+
throw Error(`Pass in the instance of CreateContextParameters. Received: ${createParameters}`)
144+
}
145+
146+
let parameters = new Map()
147+
parameters.set('type', type)
148+
149+
if (createParameters !== undefined) {
150+
createParameters.asMap().forEach((value, key) => {
151+
parameters.set(key, value)
152+
})
153+
}
154+
133155
const params = {
134156
method: 'browsingContext.create',
135-
params: {
136-
type: type,
137-
referenceContext: referenceContext,
138-
},
157+
params: Object.fromEntries(parameters),
139158
}
140-
return await this.bidi.send(params)
159+
const res = await this.bidi.send(params)
160+
return res
141161
}
142162

143163
/**
@@ -635,12 +655,15 @@ class PrintResult {
635655
* @param driver
636656
* @param browsingContextId The browsing context of current window/tab
637657
* @param type "window" or "tab"
638-
* @param referenceContext To get a browsing context for this reference if passed
658+
* @param createParameters The parameters for creating a new browsing context
639659
* @returns {Promise<BrowsingContext>}
640660
*/
641-
async function getBrowsingContextInstance(driver, { browsingContextId, type, referenceContext }) {
661+
async function getBrowsingContextInstance(
662+
driver,
663+
{ browsingContextId = undefined, type = undefined, createParameters = undefined },
664+
) {
642665
let instance = new BrowsingContext(driver)
643-
await instance.init({ browsingContextId, type, referenceContext })
666+
await instance.init({ browsingContextId, type, createParameters })
644667
return instance
645668
}
646669

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
/**
19+
* Represents a set of parameters for creating a context.
20+
* Described in https://w3c.github.io/webdriver-bidi/#command-browsingContext-create.
21+
*/
22+
class CreateContextParameters {
23+
#map = new Map()
24+
25+
/**
26+
* Sets the reference context.
27+
* @param {string} id - The ID of the reference context.
28+
* @returns {CreateContextParameters} - The updated instance of CreateContextParameters for chaining.
29+
* @throws {Error} - If the provided ID is not a string.
30+
*/
31+
referenceContext(id) {
32+
if (typeof id !== 'string') {
33+
throw new Error(`ReferenceContext must be string. Received:'${id}'`)
34+
}
35+
this.#map.set('referenceContext', id)
36+
return this
37+
}
38+
39+
/**
40+
* Sets the background parameter.
41+
*
42+
* @param {boolean} background - The background value to set.
43+
* @returns {CreateContextParameters} - The updated instance of CreateContextParameters for chaining.
44+
* @throws {Error} - If the background parameter is not a boolean.
45+
*/
46+
background(background) {
47+
if (typeof background !== 'boolean') {
48+
throw new Error(`Background must be boolean. Received:'${background}'`)
49+
}
50+
this.#map.set('background', background)
51+
return this
52+
}
53+
54+
/**
55+
* Sets the user context.
56+
* @param {string} userContext - The user context to set.
57+
* @returns {CreateContextParameters} - The updated instance of CreateContextParameters for chaining.
58+
* @throws {Error} - If the userContext parameter is not a string.
59+
*/
60+
userContext(userContext) {
61+
if (typeof userContext !== 'string') {
62+
throw new Error(`UserContext must be string. Received:'${userContext}'`)
63+
}
64+
this.#map.set('userContext', userContext)
65+
return this
66+
}
67+
68+
asMap() {
69+
return this.#map
70+
}
71+
}
72+
73+
module.exports = { CreateContextParameters }

javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const BrowsingContext = require('../../bidi/browsingContext')
2424
const until = require('../../lib/until')
2525
const { Origin, CaptureScreenshotParameters } = require('../../bidi/captureScreenshotParameters')
2626
const { BoxClipRectangle, ElementClipRectangle } = require('../../bidi/clipRectangle')
27+
const { CreateContextParameters } = require('../../bidi/createContextParameters')
28+
const BrowserBiDi = require('../../bidi/browser')
2729

2830
suite(
2931
function (env) {
@@ -61,11 +63,25 @@ suite(
6163
it('can create a window with a reference context', async function () {
6264
const browsingContext = await BrowsingContext(driver, {
6365
type: 'window',
64-
referenceContext: await driver.getWindowHandle(),
66+
createParameters: new CreateContextParameters().referenceContext(await driver.getWindowHandle()),
6567
})
6668
assert.notEqual(browsingContext.id, null)
6769
})
6870

71+
it('can create a tab with all parameters', async function () {
72+
const browser = await BrowserBiDi(driver)
73+
const userContext = await browser.createUserContext()
74+
const browsingContext = await BrowsingContext(driver, {
75+
type: 'window',
76+
createParameters: new CreateContextParameters()
77+
.referenceContext(await driver.getWindowHandle())
78+
.background(true)
79+
.userContext(userContext),
80+
})
81+
assert.notEqual(browsingContext.id, null)
82+
assert.notEqual(browsingContext.id, await driver.getWindowHandle())
83+
})
84+
6985
it('can create a tab', async function () {
7086
const browsingContext = await BrowsingContext(driver, {
7187
type: 'tab',
@@ -76,7 +92,7 @@ suite(
7692
it('can create a tab with a reference context', async function () {
7793
const browsingContext = await BrowsingContext(driver, {
7894
type: 'tab',
79-
referenceContext: await driver.getWindowHandle(),
95+
referenceContext: new CreateContextParameters().referenceContext(await driver.getWindowHandle()),
8096
})
8197
assert.notEqual(browsingContext.id, null)
8298
})

0 commit comments

Comments
 (0)