Skip to content

Commit 66e4787

Browse files
Delta456navin772pujagani
authored
[java][BiDi] implement emulation (#16070)
Co-authored-by: Navin Chandra <[email protected]> Co-authored-by: Puja Jagani <[email protected]>
1 parent 7d0646a commit 66e4787

File tree

10 files changed

+531
-0
lines changed

10 files changed

+531
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
load("//java:defs.bzl", "java_library")
2+
3+
java_library(
4+
name = "emulation",
5+
srcs = glob(
6+
[
7+
"*.java",
8+
],
9+
),
10+
visibility = [
11+
"//java/src/org/openqa/selenium/bidi:__subpackages__",
12+
"//java/src/org/openqa/selenium/remote:__pkg__",
13+
"//java/test/org/openqa/selenium/bidi:__subpackages__",
14+
"//java/test/org/openqa/selenium/grid:__subpackages__",
15+
],
16+
deps = [
17+
"//java/src/org/openqa/selenium:core",
18+
"//java/src/org/openqa/selenium/bidi",
19+
"//java/src/org/openqa/selenium/bidi/browsingcontext",
20+
"//java/src/org/openqa/selenium/json",
21+
"//java/src/org/openqa/selenium/remote/http",
22+
],
23+
)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.emulation;
19+
20+
import java.util.Map;
21+
import org.openqa.selenium.WebDriver;
22+
import org.openqa.selenium.bidi.BiDi;
23+
import org.openqa.selenium.bidi.Command;
24+
import org.openqa.selenium.bidi.HasBiDi;
25+
import org.openqa.selenium.internal.Require;
26+
27+
public class Emulation {
28+
private final BiDi bidi;
29+
30+
public Emulation(WebDriver driver) {
31+
Require.nonNull("WebDriver", driver);
32+
33+
if (!(driver instanceof HasBiDi)) {
34+
throw new IllegalArgumentException("WebDriver must implement BiDi interface");
35+
}
36+
37+
this.bidi = ((HasBiDi) driver).getBiDi();
38+
}
39+
40+
public Map<String, Object> setGeolocationOverride(SetGeolocationOverrideParameters parameters) {
41+
Require.nonNull("SetGeolocationOverride parameters", parameters);
42+
43+
return bidi.send(
44+
new Command<>("emulation.setGeolocationOverride", parameters.toMap(), Map.class));
45+
}
46+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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.emulation;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
public class GeolocationCoordinates {
24+
private final Map<String, Object> map = new HashMap<>();
25+
26+
public GeolocationCoordinates(double latitude, double longitude) {
27+
if (latitude < -90.0 || latitude > 90.0) {
28+
throw new IllegalArgumentException("Latitude must be between -90.0 and 90.0");
29+
}
30+
if (longitude < -180.0 || longitude > 180.0) {
31+
throw new IllegalArgumentException("Longitude must be between -180.0 and 180.0");
32+
}
33+
34+
map.put("latitude", latitude);
35+
map.put("longitude", longitude);
36+
map.put("accuracy", 1.0); // Default accuracy
37+
}
38+
39+
public GeolocationCoordinates accuracy(double accuracy) {
40+
if (accuracy < 0.0) {
41+
throw new IllegalArgumentException("Accuracy must be >= 0.0");
42+
}
43+
map.put("accuracy", accuracy);
44+
return this;
45+
}
46+
47+
public GeolocationCoordinates altitude(Double altitude) {
48+
if (altitude != null) {
49+
map.put("altitude", altitude);
50+
}
51+
return this;
52+
}
53+
54+
public GeolocationCoordinates altitudeAccuracy(Double altitudeAccuracy) {
55+
if (altitudeAccuracy != null) {
56+
if (!map.containsKey("altitude")) {
57+
throw new IllegalArgumentException("altitudeAccuracy cannot be set without altitude");
58+
}
59+
if (altitudeAccuracy < 0.0) {
60+
throw new IllegalArgumentException("Altitude accuracy must be >= 0.0");
61+
}
62+
map.put("altitudeAccuracy", altitudeAccuracy);
63+
}
64+
return this;
65+
}
66+
67+
public GeolocationCoordinates heading(Double heading) {
68+
if (heading != null) {
69+
if (heading < 0.0 || heading >= 360.0) {
70+
throw new IllegalArgumentException("Heading must be between 0.0 and 360.0");
71+
}
72+
map.put("heading", heading);
73+
}
74+
return this;
75+
}
76+
77+
public GeolocationCoordinates speed(Double speed) {
78+
if (speed != null) {
79+
if (speed < 0.0) {
80+
throw new IllegalArgumentException("Speed must be >= 0.0");
81+
}
82+
map.put("speed", speed);
83+
}
84+
return this;
85+
}
86+
87+
public double getLatitude() {
88+
return (Double) map.get("latitude");
89+
}
90+
91+
public double getLongitude() {
92+
return (Double) map.get("longitude");
93+
}
94+
95+
public double getAccuracy() {
96+
return (Double) map.get("accuracy");
97+
}
98+
99+
public Double getAltitude() {
100+
return (Double) map.get("altitude");
101+
}
102+
103+
public Double getAltitudeAccuracy() {
104+
return (Double) map.get("altitudeAccuracy");
105+
}
106+
107+
public Double getHeading() {
108+
return (Double) map.get("heading");
109+
}
110+
111+
public Double getSpeed() {
112+
return (Double) map.get("speed");
113+
}
114+
115+
public Map<String, Object> toMap() {
116+
return Map.copyOf(map);
117+
}
118+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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.emulation;
19+
20+
import java.util.Map;
21+
22+
public class GeolocationPositionError {
23+
24+
public Map<String, Object> toMap() {
25+
String type = "positionUnavailable";
26+
return Map.of("type", type);
27+
}
28+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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.emulation;
19+
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
public class SetGeolocationOverrideParameters {
25+
private final Map<String, Object> map = new HashMap<>();
26+
27+
// Constructor for coordinates - must specify either contexts or userContexts later
28+
public SetGeolocationOverrideParameters(GeolocationCoordinates coordinates) {
29+
if (coordinates == null) {
30+
throw new IllegalArgumentException("GeolocationCoordinates cannot be null");
31+
}
32+
map.put("coordinates", coordinates.toMap());
33+
}
34+
35+
// Constructor for error - must specify either contexts or userContexts later
36+
public SetGeolocationOverrideParameters(GeolocationPositionError error) {
37+
if (error == null) {
38+
throw new IllegalArgumentException("GeolocationPositionError cannot be null");
39+
}
40+
map.put("error", error.toMap());
41+
}
42+
43+
public SetGeolocationOverrideParameters contexts(List<String> contexts) {
44+
if (contexts == null || contexts.isEmpty()) {
45+
throw new IllegalArgumentException("Contexts cannot be null or empty");
46+
}
47+
if (map.containsKey("userContexts")) {
48+
throw new IllegalArgumentException("Cannot specify both contexts and userContexts");
49+
}
50+
map.put("contexts", contexts);
51+
return this;
52+
}
53+
54+
public SetGeolocationOverrideParameters userContexts(List<String> userContexts) {
55+
if (userContexts == null || userContexts.isEmpty()) {
56+
throw new IllegalArgumentException("User contexts cannot be null or empty");
57+
}
58+
if (map.containsKey("contexts")) {
59+
throw new IllegalArgumentException("Cannot specify both contexts and userContexts");
60+
}
61+
map.put("userContexts", userContexts);
62+
return this;
63+
}
64+
65+
public Map<String, Object> toMap() {
66+
// Validate that either contexts or userContexts is set
67+
if (!map.containsKey("contexts") && !map.containsKey("userContexts")) {
68+
throw new IllegalStateException("Must specify either contexts or userContexts");
69+
}
70+
return Map.copyOf(map);
71+
}
72+
}

java/src/org/openqa/selenium/bidi/module/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ java_library(
2020
"//java/src/org/openqa/selenium/bidi",
2121
"//java/src/org/openqa/selenium/bidi/browser",
2222
"//java/src/org/openqa/selenium/bidi/browsingcontext",
23+
"//java/src/org/openqa/selenium/bidi/emulation",
2324
"//java/src/org/openqa/selenium/bidi/log",
2425
"//java/src/org/openqa/selenium/bidi/network",
2526
"//java/src/org/openqa/selenium/bidi/permissions",

java/src/org/openqa/selenium/remote/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ java_export(
2828
"//java/src/org/openqa/selenium/bidi",
2929
"//java/src/org/openqa/selenium/bidi:augmenter",
3030
"//java/src/org/openqa/selenium/bidi/browsingcontext",
31+
"//java/src/org/openqa/selenium/bidi/emulation",
3132
"//java/src/org/openqa/selenium/bidi/log",
3233
"//java/src/org/openqa/selenium/bidi/module",
3334
"//java/src/org/openqa/selenium/bidi/network",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
load("@rules_jvm_external//:defs.bzl", "artifact")
2+
load("//java:defs.bzl", "JUNIT5_DEPS", "java_selenium_test_suite")
3+
4+
java_selenium_test_suite(
5+
name = "large-tests",
6+
size = "large",
7+
srcs = glob(["*Test.java"]),
8+
browsers = [
9+
"firefox",
10+
"chrome",
11+
"edge",
12+
],
13+
tags = [
14+
"selenium-remote",
15+
],
16+
deps = [
17+
"//java/src/org/openqa/selenium/bidi",
18+
"//java/src/org/openqa/selenium/bidi/browsingcontext",
19+
"//java/src/org/openqa/selenium/bidi/emulation",
20+
"//java/src/org/openqa/selenium/bidi/log",
21+
"//java/src/org/openqa/selenium/bidi/module",
22+
"//java/src/org/openqa/selenium/bidi/network",
23+
"//java/src/org/openqa/selenium/bidi/script",
24+
"//java/src/org/openqa/selenium/firefox",
25+
"//java/src/org/openqa/selenium/grid/security",
26+
"//java/src/org/openqa/selenium/json",
27+
"//java/src/org/openqa/selenium/remote",
28+
"//java/src/org/openqa/selenium/support",
29+
"//java/test/org/openqa/selenium/environment",
30+
"//java/test/org/openqa/selenium/testing:annotations",
31+
"//java/test/org/openqa/selenium/testing:test-base",
32+
"//java/test/org/openqa/selenium/testing/drivers",
33+
artifact("com.google.guava:guava"),
34+
artifact("org.junit.jupiter:junit-jupiter-api"),
35+
artifact("org.assertj:assertj-core"),
36+
] + JUNIT5_DEPS,
37+
)

0 commit comments

Comments
 (0)