Skip to content

Commit 6cfcb59

Browse files
authored
[java] Add support to create a BiDi session
1 parent daa1f03 commit 6cfcb59

File tree

13 files changed

+838
-1
lines changed

13 files changed

+838
-1
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load("@rules_jvm_external//:defs.bzl", "artifact")
2+
load("//common:defs.bzl", "copy_file")
3+
load("//java:defs.bzl", "java_library")
4+
5+
java_library(
6+
name = "bidi",
7+
srcs = glob(["*.java"]),
8+
visibility = [
9+
"//java/src/org/openqa/selenium/bidi:__subpackages__",
10+
"//java/src/org/openqa/selenium/firefox:__subpackages__",
11+
],
12+
deps = [
13+
"//java/src/org/openqa/selenium:core",
14+
"//java/src/org/openqa/selenium/json",
15+
"//java/src/org/openqa/selenium/remote",
16+
artifact("com.google.guava:guava"),
17+
],
18+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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;
19+
20+
import com.google.common.collect.ImmutableMap;
21+
22+
import java.io.Closeable;
23+
import java.time.Duration;
24+
import java.util.Collections;
25+
import java.util.function.Consumer;
26+
27+
import org.openqa.selenium.internal.Require;
28+
29+
public class BiDi implements Closeable {
30+
31+
private final Duration timeout = Duration.ofSeconds(30);
32+
private final Connection connection;
33+
private final BiDiSessionStatus status;
34+
35+
public BiDi(Connection connection) {
36+
this.connection = Require.nonNull("WebSocket connection", connection);
37+
this.status =
38+
send(new Command<>("session.status", Collections.emptyMap(), BiDiSessionStatus.class));
39+
}
40+
41+
@Override
42+
public void close() {
43+
clearListeners();
44+
disconnectSession();
45+
}
46+
47+
public void disconnectSession() {
48+
// TODO: Identify how to close a BiDi session.
49+
// Seems like https://w3c.github.io/webdriver-bidi/#issue-9f7aff26 needs to be fleshed out.
50+
}
51+
52+
public <X> X send(Command<X> command) {
53+
Require.nonNull("Command to send", command);
54+
return connection.sendAndWait(command, timeout);
55+
}
56+
57+
public <X> void addListener(Event<X> event, Consumer<X> handler) {
58+
Require.nonNull("Event to listen for", event);
59+
Require.nonNull("Handler to call", handler);
60+
61+
send(new Command<>("session.subscribe",
62+
ImmutableMap.of("events", Collections.singletonList(event.getMethod()))));
63+
64+
connection.addListener(event, handler);
65+
}
66+
67+
public void clearListeners() {
68+
send(new Command<>("session.unsubscribe", Collections.emptyMap()));
69+
connection.clearListeners();
70+
}
71+
72+
public BiDiSessionStatus getBidiSessionStatus() {
73+
return status;
74+
}
75+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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;
19+
20+
import org.openqa.selenium.WebDriverException;
21+
22+
public class BiDiException extends WebDriverException {
23+
24+
public BiDiException(Throwable cause) {
25+
this(cause.getMessage(), cause);
26+
}
27+
28+
public BiDiException(String message) {
29+
this(message, null);
30+
}
31+
32+
public BiDiException(String message, Throwable cause) {
33+
super(message, cause);
34+
addInfo(WebDriverException.DRIVER_INFO, "BiDi Connection");
35+
}
36+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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;
19+
20+
import static java.util.Collections.unmodifiableMap;
21+
22+
import org.openqa.selenium.internal.Require;
23+
import org.openqa.selenium.json.JsonInput;
24+
25+
import java.util.Map;
26+
import java.util.TreeMap;
27+
28+
public class BiDiSessionStatus {
29+
30+
private final boolean ready;
31+
private final String message;
32+
33+
public BiDiSessionStatus(boolean ready, String message) {
34+
this.ready = Require.nonNull("Session's readiness", ready);
35+
this.message = Require.nonNull("Message", message);
36+
}
37+
38+
public static BiDiSessionStatus fromJson(JsonInput input) {
39+
boolean ready = false;
40+
String message = null;
41+
42+
input.beginObject();
43+
while (input.hasNext()) {
44+
switch (input.nextName()) {
45+
case "ready":
46+
ready = input.read(Boolean.class);
47+
break;
48+
49+
case "message":
50+
message = input.read(String.class);
51+
break;
52+
53+
default:
54+
input.skipValue();
55+
break;
56+
}
57+
}
58+
input.endObject();
59+
60+
return new BiDiSessionStatus(ready, message);
61+
}
62+
63+
public boolean isReady() {
64+
return ready;
65+
}
66+
67+
public String getMessage() {
68+
return message;
69+
}
70+
71+
private Map<String, Object> toJson() {
72+
Map<String, Object> toReturn = new TreeMap<>();
73+
toReturn.put("ready", ready);
74+
toReturn.put("message", message);
75+
76+
return unmodifiableMap(toReturn);
77+
}
78+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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;
19+
20+
import com.google.common.collect.ImmutableMap;
21+
22+
import org.openqa.selenium.internal.Require;
23+
import org.openqa.selenium.json.JsonInput;
24+
25+
import java.lang.reflect.Type;
26+
import java.util.Map;
27+
import java.util.function.Function;
28+
29+
public class Command<X> {
30+
31+
private final String method;
32+
private final Map<String, Object> params;
33+
private final Function<JsonInput, X> mapper;
34+
35+
public Command(String method, Map<String, Object> params) {
36+
this(method, params, Object.class);
37+
}
38+
39+
public Command(String method, Map<String, Object> params, Type typeOfX) {
40+
this(method, params, input -> input.read(Require.nonNull("Type to convert to", typeOfX)));
41+
}
42+
43+
private Command(String method, Map<String, Object> params, Function<JsonInput, X> mapper) {
44+
this.method = Require.nonNull("Method name", method);
45+
this.params = ImmutableMap.copyOf(Require.nonNull("Command parameters", params));
46+
this.mapper = Require.nonNull("Mapper for result", mapper);
47+
}
48+
49+
public String getMethod() {
50+
return method;
51+
}
52+
53+
public Map<String, Object> getParams() {
54+
return params;
55+
}
56+
57+
Function<JsonInput, X> getMapper() {
58+
return mapper;
59+
}
60+
}

0 commit comments

Comments
 (0)