Skip to content

Commit

Permalink
[cdp] Move shared logic for finding endpoints to a shared location
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Mar 23, 2021
1 parent f1307e5 commit 38f393a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.devtools.Connection;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -33,14 +29,10 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import static java.net.HttpURLConnection.HTTP_OK;
import static org.openqa.selenium.json.Json.MAP_TYPE;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.devtools.CdpEndpointFinder.getCdpEndPoint;

public class ChromiumDevToolsLocator {

private static final Json JSON = new Json();
private static final Logger LOG = Logger.getLogger(ChromiumDevToolsLocator.class.getName());

public static Optional<URI> getReportedUri(String capabilityKey, Capabilities caps) {
Expand Down Expand Up @@ -72,36 +64,6 @@ public static Optional<URI> getReportedUri(String capabilityKey, Capabilities ca
}
}

public static Optional<URI> getCdpEndPoint(
HttpClient.Factory clientFactory,
URI reportedUri) {
Require.nonNull("HTTP client factory", clientFactory);
Require.nonNull("DevTools URI", reportedUri);

ClientConfig config = ClientConfig.defaultConfig().baseUri(reportedUri);
HttpClient client = clientFactory.createClient(config);

HttpResponse res = client.execute(new HttpRequest(GET, "/json/version"));
if (res.getStatus() != HTTP_OK) {
return Optional.empty();
}

Map<String, Object> versionData = JSON.toType(string(res), MAP_TYPE);
Object raw = versionData.get("webSocketDebuggerUrl");

if (!(raw instanceof String)) {
return Optional.empty();
}

String debuggerUrl = (String) raw;
try {
return Optional.of(new URI(debuggerUrl));
} catch (URISyntaxException e) {
LOG.warning("Invalid URI for endpoint " + raw);
return Optional.empty();
}
}

public static Optional<Connection> getChromeConnector(
HttpClient.Factory clientFactory,
Capabilities caps,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.devtools;

import org.openqa.selenium.internal.Require;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;

import static java.net.HttpURLConnection.HTTP_OK;
import static org.openqa.selenium.json.Json.MAP_TYPE;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;

public class CdpEndpointFinder {

private static final Logger LOG = Logger.getLogger(CdpEndpointFinder.class.getName());
private static final Json JSON = new Json();

public static Optional<URI> getCdpEndPoint(HttpClient.Factory clientFactory, URI reportedUri) {
Require.nonNull("HTTP client factory", clientFactory);
Require.nonNull("DevTools URI", reportedUri);

ClientConfig config = ClientConfig.defaultConfig().baseUri(reportedUri);
HttpClient client = clientFactory.createClient(config);

HttpResponse res = client.execute(new HttpRequest(GET, "/json/version"));
if (res.getStatus() != HTTP_OK) {
return Optional.empty();
}

Map<String, Object> versionData = JSON.toType(string(res), MAP_TYPE);
Object raw = versionData.get("webSocketDebuggerUrl");

if (!(raw instanceof String)) {
return Optional.empty();
}

String debuggerUrl = (String) raw;
try {
return Optional.of(new URI(debuggerUrl));
} catch (URISyntaxException e) {
LOG.warning("Invalid URI for endpoint " + raw);
return Optional.empty();
}
}

}
40 changes: 12 additions & 28 deletions java/client/src/org/openqa/selenium/firefox/FirefoxDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,27 @@

package org.openqa.selenium.firefox;

import static java.net.HttpURLConnection.HTTP_OK;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonMap;
import static org.openqa.selenium.json.Json.MAP_TYPE;
import static org.openqa.selenium.remote.CapabilityType.PROXY;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ImmutableCapabilities;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.devtools.CdpEndpointFinder;
import org.openqa.selenium.devtools.CdpInfo;
import org.openqa.selenium.devtools.CdpVersionFinder;
import org.openqa.selenium.devtools.Connection;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.DevToolsException;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.noop.NoOpCdpInfo;
import org.openqa.selenium.html5.LocalStorage;
import org.openqa.selenium.html5.SessionStorage;
import org.openqa.selenium.html5.WebStorage;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.FileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
Expand All @@ -54,19 +46,20 @@
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpMethod;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.service.DriverCommandExecutor;
import org.openqa.selenium.remote.service.DriverService;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.StreamSupport;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonMap;
import static org.openqa.selenium.remote.CapabilityType.PROXY;

/**
* An implementation of the {#link WebDriver} interface that drives Firefox.
* <p>
Expand Down Expand Up @@ -334,23 +327,14 @@ public DevTools getDevTools() {
if (debuggerAddress == null) {
throw new WebDriverException("This version of Firefox or geckodriver does not support CDP");
}

try {
URI uri = new URI(String.format("http://%s", debuggerAddress));
ClientConfig config = ClientConfig.defaultConfig().baseUri(uri);
HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();
HttpClient client = clientFactory.createClient(config);

HttpResponse res = client.execute(new HttpRequest(GET, "/json/version"));
if (res.getStatus() != HTTP_OK) {
throw new WebDriverException("Could not obtain information about CDP version supported by the driver");
}
Map<String, Object> versionData = new Json().toType(string(res), MAP_TYPE);
Object debuggerUrl = versionData.get("webSocketDebuggerUrl");
if (!(debuggerUrl instanceof String)) {
throw new WebDriverException("The driver did not provide CDP endpoint");
}

URI wsUri = new URI((String) debuggerUrl);

URI uri = new URI(String.format("http://%s", debuggerAddress));
URI wsUri = CdpEndpointFinder.getCdpEndPoint(clientFactory, uri)
.orElseThrow(() -> new DevToolsException("Unable to determine URI to connect to from " + debuggerAddress));

ClientConfig wsConfig = ClientConfig.defaultConfig().baseUri(wsUri);
HttpClient wsClient = clientFactory.createClient(wsConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.chromium.ChromiumDevToolsLocator;
import org.openqa.selenium.devtools.CdpEndpointFinder;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.BinaryMessage;
Expand Down Expand Up @@ -76,15 +77,15 @@ public Optional<Consumer<Message>> apply(String uri, Consumer<Message> downstrea

// Using strings here to avoid Node depending upon specific drivers.
Optional<URI> cdpUri = ChromiumDevToolsLocator.getReportedUri("goog:chromeOptions", caps)
.flatMap(reported -> ChromiumDevToolsLocator.getCdpEndPoint(clientFactory, reported));
.flatMap(reported -> CdpEndpointFinder.getCdpEndPoint(clientFactory, reported));
if (cdpUri.isPresent()) {
LOG.fine("Chrome endpoint found");
return cdpUri.map(cdp -> createCdpEndPoint(cdp, downstream));
}

LOG.fine("Searching for edge options");
cdpUri = ChromiumDevToolsLocator.getReportedUri("ms:edgeOptions", caps)
.flatMap(reported -> ChromiumDevToolsLocator.getCdpEndPoint(clientFactory, reported));
.flatMap(reported -> CdpEndpointFinder.getCdpEndPoint(clientFactory, reported));
return cdpUri.map(cdp -> createCdpEndPoint(cdp, downstream));
}

Expand Down

0 comments on commit 38f393a

Please sign in to comment.