Skip to content

Commit ecea48d

Browse files
authored
[java][cdp] Allow reusing DevTools instance upon calling close() (#11704)
Fixes #11704
1 parent ed0fe60 commit ecea48d

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

java/src/org/openqa/selenium/devtools/Connection.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.util.concurrent.Executor;
4343
import java.util.concurrent.Executors;
4444
import java.util.concurrent.TimeoutException;
45+
import java.util.concurrent.atomic.AtomicBoolean;
4546
import java.util.concurrent.atomic.AtomicLong;
4647
import java.util.concurrent.locks.Lock;
4748
import java.util.concurrent.locks.ReadWriteLock;
@@ -65,17 +66,29 @@ public class Connection implements Closeable {
6566
return thread;
6667
});
6768
private static final AtomicLong NEXT_ID = new AtomicLong(1L);
68-
private final WebSocket socket;
69+
private WebSocket socket;
6970
private final Map<Long, Consumer<Either<Throwable, JsonInput>>> methodCallbacks = new ConcurrentHashMap<>();
7071
private final ReadWriteLock callbacksLock = new ReentrantReadWriteLock(true);
7172
private final Multimap<Event<?>, Consumer<?>> eventCallbacks = HashMultimap.create();
7273
private final HttpClient client;
74+
private final String url;
75+
private final AtomicBoolean isClosed;
7376

7477
public Connection(HttpClient client, String url) {
7578
Require.nonNull("HTTP client", client);
7679
Require.nonNull("URL to connect to", url);
80+
this.url = url;
7781
this.client = client;
78-
socket = this.client.openSocket(new HttpRequest(GET, url), new Listener());
82+
this.socket = this.client.openSocket(new HttpRequest(GET, url), new Listener());
83+
this.isClosed = new AtomicBoolean();
84+
}
85+
86+
boolean isClosed() {
87+
return isClosed.get();
88+
}
89+
90+
void reopen() {
91+
this.socket = this.client.openSocket(new HttpRequest(GET, url), new Listener());
7992
}
8093

8194
private static class NamedConsumer<X> implements Consumer<X> {
@@ -190,6 +203,7 @@ public void clearListeners() {
190203
public void close() {
191204
socket.close();
192205
client.close();
206+
this.isClosed.set(true);
193207
}
194208

195209
private class Listener implements WebSocket.Listener {

java/src/org/openqa/selenium/devtools/DevTools.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ public void createSession() {
118118
* @param windowHandle result of {@link WebDriver#getWindowHandle()}, optional.
119119
*/
120120
public void createSession(String windowHandle) {
121+
if (connection.isClosed()) {
122+
connection.reopen();
123+
}
121124
TargetID targetId = findTarget(windowHandle);
122125

123126
// Starts the session
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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.devtools;
19+
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
import org.junit.jupiter.api.Test;
23+
import org.openqa.selenium.WebDriver;
24+
import org.openqa.selenium.remote.Augmenter;
25+
26+
class DevToolsReuseTest extends DevToolsTestBase {
27+
28+
@Test
29+
public void shouldBeAbleToCloseDevToolsAndCreateNewInstance() {
30+
WebDriver driver = new Augmenter().augment(this.driver);
31+
32+
DevTools devTools = ((HasDevTools) driver).getDevTools();
33+
devTools.createSession();
34+
addConsoleLogListener(devTools);
35+
36+
devTools.close();
37+
38+
devTools = ((HasDevTools) driver).getDevTools();
39+
devTools.createSession();
40+
addConsoleLogListener(devTools);
41+
42+
devTools.close();
43+
}
44+
45+
private static void addConsoleLogListener(DevTools devTools) {
46+
devTools.getDomains().events().addConsoleListener(
47+
consoleEvent -> assertThat(consoleEvent.getMessages()).contains("Hello, world!"));
48+
}
49+
}

0 commit comments

Comments
 (0)