Skip to content

Commit c9bc81a

Browse files
authored
[bidi][java] Add locate nodes command (#13445)
1 parent f09f064 commit c9bc81a

File tree

5 files changed

+551
-0
lines changed

5 files changed

+551
-0
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.openqa.selenium.bidi.browsingcontext;
1919

20+
import java.io.StringReader;
2021
import java.lang.reflect.Type;
2122
import java.util.ArrayList;
2223
import java.util.HashMap;
@@ -28,6 +29,7 @@
2829
import org.openqa.selenium.bidi.BiDi;
2930
import org.openqa.selenium.bidi.Command;
3031
import org.openqa.selenium.bidi.HasBiDi;
32+
import org.openqa.selenium.bidi.script.RemoteValue;
3133
import org.openqa.selenium.internal.Require;
3234
import org.openqa.selenium.json.Json;
3335
import org.openqa.selenium.json.JsonInput;
@@ -36,6 +38,8 @@
3638

3739
public class BrowsingContext {
3840

41+
private static final Json JSON = new Json();
42+
3943
private final String id;
4044
private final BiDi bidi;
4145
private static final String CONTEXT = "context";
@@ -338,6 +342,22 @@ public void forward() {
338342
this.traverseHistory(1);
339343
}
340344

345+
public List<RemoteValue> locateNodes(LocateNodeParameters parameters) {
346+
Map<String, Object> params = new HashMap<>(parameters.toMap());
347+
params.put("context", id);
348+
return this.bidi.send(
349+
new Command<>(
350+
"browsingContext.locateNodes",
351+
params,
352+
jsonInput -> {
353+
Map<String, Object> result = jsonInput.read(Map.class);
354+
try (StringReader reader = new StringReader(JSON.toJson(result.get("nodes")));
355+
JsonInput input = JSON.newInput(reader)) {
356+
return input.read(new TypeToken<List<RemoteValue>>() {}.getType());
357+
}
358+
}));
359+
}
360+
341361
public void close() {
342362
// This might need more clean up actions once the behavior is defined.
343363
// Specially when last tab or window is closed.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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.ArrayList;
21+
import java.util.HashMap;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Optional;
25+
import org.openqa.selenium.bidi.script.RemoteReference;
26+
import org.openqa.selenium.bidi.script.ResultOwnership;
27+
import org.openqa.selenium.bidi.script.SerializationOptions;
28+
29+
public class LocateNodeParameters {
30+
31+
private final Locator locator;
32+
private final Optional<Long> maxNodeCount;
33+
private final Optional<ResultOwnership> ownership;
34+
private final Optional<String> sandbox;
35+
private final Optional<SerializationOptions> serializationOptions;
36+
private final Optional<List<RemoteReference>> startNodes;
37+
38+
private LocateNodeParameters(Builder builder) {
39+
this.locator = builder.locator;
40+
this.maxNodeCount = Optional.ofNullable(builder.maxNodeCount);
41+
this.ownership = Optional.ofNullable(builder.ownership);
42+
this.sandbox = Optional.ofNullable(builder.sandbox);
43+
this.serializationOptions = Optional.ofNullable(builder.serializationOptions);
44+
this.startNodes = Optional.ofNullable(builder.startNodes);
45+
}
46+
47+
public Map<String, Object> toMap() {
48+
final Map<String, Object> map = new HashMap<>();
49+
50+
map.put("locator", locator.toMap());
51+
maxNodeCount.ifPresent(value -> map.put("maxNodeCount", value));
52+
ownership.ifPresent(value -> map.put("ownership", value.toString()));
53+
sandbox.ifPresent(value -> map.put("sandbox", value));
54+
serializationOptions.ifPresent(value -> map.put("serializationOptions", value.toJson()));
55+
startNodes.ifPresent(
56+
value -> {
57+
List<Map<String, Object>> startNodesJson = new ArrayList<>();
58+
value.forEach(remoteNode -> startNodesJson.add(remoteNode.toJson()));
59+
map.put("startNodes", startNodesJson);
60+
});
61+
62+
return map;
63+
}
64+
65+
public static class Builder {
66+
67+
private final Locator locator;
68+
private Long maxNodeCount = null;
69+
private ResultOwnership ownership;
70+
private String sandbox;
71+
private SerializationOptions serializationOptions;
72+
private List<RemoteReference> startNodes;
73+
74+
public Builder(Locator locator) {
75+
this.locator = locator;
76+
}
77+
78+
public Builder setMaxNodeCount(long maxNodeCount) {
79+
this.maxNodeCount = maxNodeCount;
80+
return this;
81+
}
82+
83+
public Builder setOwnership(ResultOwnership ownership) {
84+
this.ownership = ownership;
85+
return this;
86+
}
87+
88+
public Builder setSandbox(String sandbox) {
89+
this.sandbox = sandbox;
90+
return this;
91+
}
92+
93+
public Builder setSerializationOptions(SerializationOptions options) {
94+
this.serializationOptions = options;
95+
return this;
96+
}
97+
98+
public Builder setStartNodes(List<RemoteReference> startNodes) {
99+
this.startNodes = startNodes;
100+
return this;
101+
}
102+
103+
public LocateNodeParameters build() {
104+
return new LocateNodeParameters(this);
105+
}
106+
}
107+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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 java.util.Optional;
23+
24+
public class Locator {
25+
private enum Type {
26+
CSS("css"),
27+
INNER("innerText"),
28+
XPATH("xpath");
29+
30+
private final String value;
31+
32+
Type(String value) {
33+
this.value = value;
34+
}
35+
36+
@Override
37+
public String toString() {
38+
return value;
39+
}
40+
}
41+
42+
private final Type type;
43+
44+
private final String value;
45+
46+
private Optional<Boolean> ignoreCase = Optional.empty();
47+
48+
private Optional<String> matchType = Optional.empty();
49+
50+
private Optional<Long> maxDepth = Optional.empty();
51+
52+
private Locator(Type type, String value) {
53+
this.type = type;
54+
this.value = value;
55+
}
56+
57+
public Locator(
58+
Type type,
59+
String value,
60+
Optional<Boolean> ignoreCase,
61+
Optional<String> matchType,
62+
Optional<Long> maxDepth) {
63+
this.type = type;
64+
this.value = value;
65+
this.ignoreCase = ignoreCase;
66+
this.matchType = matchType;
67+
this.maxDepth = maxDepth;
68+
}
69+
70+
public static Locator css(String value) {
71+
return new Locator(Type.CSS, value);
72+
}
73+
74+
public static Locator innerText(
75+
String value,
76+
Optional<Boolean> ignoreCase,
77+
Optional<String> matchType,
78+
Optional<Long> maxDepth) {
79+
return new Locator(Type.INNER, value, ignoreCase, matchType, maxDepth);
80+
}
81+
82+
public static Locator innerText(String value) {
83+
return new Locator(Type.INNER, value);
84+
}
85+
86+
public static Locator xpath(String value) {
87+
return new Locator(Type.XPATH, value);
88+
}
89+
90+
public Map<String, Object> toMap() {
91+
final Map<String, Object> map = new HashMap<>();
92+
map.put("type", type.toString());
93+
map.put("value", value);
94+
95+
ignoreCase.ifPresent(val -> map.put("ignoreCase", val));
96+
matchType.ifPresent(val -> map.put("matchType", val));
97+
maxDepth.ifPresent(val -> map.put("maxDepth", val));
98+
99+
return map;
100+
}
101+
}

java/src/org/openqa/selenium/bidi/script/RemoteValue.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ private static Object deserializeValue(Object value, Type type) {
197197

198198
switch (type) {
199199
case ARRAY:
200+
case NODE_LIST:
200201
case SET:
201202
try (StringReader reader = new StringReader(JSON.toJson(value));
202203
JsonInput input = JSON.newInput(reader)) {

0 commit comments

Comments
 (0)