-
-
Notifications
You must be signed in to change notification settings - Fork 8k
/
ChromiumDriver.java
282 lines (244 loc) · 9.75 KB
/
ChromiumDriver.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
// 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.chromium;
import org.openqa.selenium.BuildInfo;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Credentials;
import org.openqa.selenium.HasAuthentication;
import org.openqa.selenium.ImmutableCapabilities;
import org.openqa.selenium.PersistentCapabilities;
import org.openqa.selenium.WebDriver;
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.HasDevTools;
import org.openqa.selenium.devtools.noop.NoOpCdpInfo;
import org.openqa.selenium.html5.LocalStorage;
import org.openqa.selenium.html5.Location;
import org.openqa.selenium.html5.LocationContext;
import org.openqa.selenium.html5.SessionStorage;
import org.openqa.selenium.html5.WebStorage;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.logging.EventType;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.mobile.NetworkConnection;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.FileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.html5.RemoteLocationContext;
import org.openqa.selenium.remote.html5.RemoteWebStorage;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.mobile.RemoteNetworkConnection;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.logging.Logger;
import static org.openqa.selenium.remote.Browser.CHROME;
import static org.openqa.selenium.remote.Browser.EDGE;
import static org.openqa.selenium.remote.Browser.OPERA;
/**
* A {@link WebDriver} implementation that controls a Chromium browser running on the local machine.
* It is used as the base class for Chromium-based browser drivers (Chrome, Edgium).
*/
public class ChromiumDriver extends RemoteWebDriver implements
HasAuthentication,
HasCasting,
HasCdp,
HasDevTools,
HasLaunchApp,
HasLogEvents,
HasNetworkConditions,
HasPermissions,
LocationContext,
NetworkConnection,
WebStorage {
public static final Predicate<String> IS_CHROMIUM_BROWSER = name ->
CHROME.is(name) ||
EDGE.is(name) ||
OPERA.is(name);
private static final Logger LOG = Logger.getLogger(ChromiumDriver.class.getName());
private final Capabilities capabilities;
private final RemoteLocationContext locationContext;
private final RemoteWebStorage webStorage;
private final RemoteNetworkConnection networkConnection;
private final HasNetworkConditions networkConditions;
private final HasPermissions permissions;
private final HasLaunchApp launch;
private final Optional<Connection> connection;
private final Optional<DevTools> devTools;
protected HasCasting casting;
protected HasCdp cdp;
protected ChromiumDriver(CommandExecutor commandExecutor, Capabilities capabilities, String capabilityKey) {
super(commandExecutor, capabilities);
locationContext = new RemoteLocationContext(getExecuteMethod());
webStorage = new RemoteWebStorage(getExecuteMethod());
permissions = new AddHasPermissions().getImplementation(getCapabilities(), getExecuteMethod());
networkConnection = new RemoteNetworkConnection(getExecuteMethod());
networkConditions = new AddHasNetworkConditions().getImplementation(getCapabilities(), getExecuteMethod());
launch = new AddHasLaunchApp().getImplementation(getCapabilities(), getExecuteMethod());
HttpClient.Factory factory = HttpClient.Factory.createDefault();
Capabilities originalCapabilities = super.getCapabilities();
Optional<URI> cdpUri = CdpEndpointFinder.getReportedUri(capabilityKey, originalCapabilities)
.flatMap(uri -> CdpEndpointFinder.getCdpEndPoint(factory, uri));
connection = cdpUri.map(uri -> new Connection(
factory.createClient(ClientConfig.defaultConfig().baseUri(uri)),
uri.toString()));
CdpInfo cdpInfo = new CdpVersionFinder().match(originalCapabilities.getBrowserVersion())
.orElseGet(() -> {
LOG.warning(
String.format(
"Unable to find version of CDP to use for %s. You may need to " +
"include a dependency on a specific version of the CDP using " +
"something similar to " +
"`org.seleniumhq.selenium:selenium-devtools-v86:%s` where the " +
"version (\"v86\") matches the version of the chromium-based browser " +
"you're using and the version number of the artifact is the same " +
"as Selenium's.",
capabilities.getBrowserVersion(),
new BuildInfo().getReleaseLabel()));
return new NoOpCdpInfo();
});
devTools = connection.map(conn -> new DevTools(cdpInfo::getDomains, conn));
this.capabilities = cdpUri.map(uri -> new ImmutableCapabilities(
new PersistentCapabilities(originalCapabilities)
.setCapability("se:cdp", uri.toString())
.setCapability(
"se:cdpVersion", originalCapabilities.getBrowserVersion())))
.orElse(new ImmutableCapabilities(originalCapabilities));
}
@Override
public Capabilities getCapabilities() {
return capabilities;
}
@Override
public void setFileDetector(FileDetector detector) {
throw new WebDriverException(
"Setting the file detector only works on remote webdriver instances obtained " +
"via RemoteWebDriver");
}
@Override
public <X> void onLogEvent(EventType<X> kind) {
Require.nonNull("Event type", kind);
kind.initializeListener(this);
}
@Override
public void register(Predicate<URI> whenThisMatches, Supplier<Credentials> useTheseCredentials) {
Require.nonNull("Check to use to see how we should authenticate", whenThisMatches);
Require.nonNull("Credentials to use when authenticating", useTheseCredentials);
getDevTools().createSessionIfThereIsNotOne(getWindowHandle());
getDevTools().getDomains().network().addAuthHandler(whenThisMatches, useTheseCredentials);
}
@Override
public LocalStorage getLocalStorage() {
return webStorage.getLocalStorage();
}
@Override
public SessionStorage getSessionStorage() {
return webStorage.getSessionStorage();
}
@Override
public Location location() {
return locationContext.location();
}
@Override
public void setLocation(Location location) {
Require.nonNull("Location", location);
locationContext.setLocation(location);
}
@Override
public ConnectionType getNetworkConnection() {
return networkConnection.getNetworkConnection();
}
@Override
public ConnectionType setNetworkConnection(ConnectionType type) {
Require.nonNull("Network Connection Type", type);
return networkConnection.setNetworkConnection(type);
}
@Override
public void launchApp(String id) {
Require.nonNull("Launch App ID", id);
launch.launchApp(id);
}
@Override
public Map<String, Object> executeCdpCommand(String commandName, Map<String, Object> parameters) {
Require.nonNull("Command Name", commandName);
return cdp.executeCdpCommand(commandName, parameters);
}
@Override
public Optional<DevTools> maybeGetDevTools() {
return devTools;
}
@Override
public List<Map<String, String>> getCastSinks() {
return casting.getCastSinks();
}
@Override
public String getCastIssueMessage() {
return casting.getCastIssueMessage();
}
@Override
public void selectCastSink(String deviceName) {
Require.nonNull("Device Name", deviceName);
casting.selectCastSink(deviceName);
}
@Override
public void startDesktopMirroring(String deviceName) {
Require.nonNull("Device Name", deviceName);
casting.startDesktopMirroring(deviceName);
}
@Override
public void startTabMirroring(String deviceName) {
Require.nonNull("Device Name", deviceName);
casting.startTabMirroring(deviceName);
}
@Override
public void stopCasting(String deviceName) {
Require.nonNull("Device Name", deviceName);
casting.stopCasting(deviceName);
}
@Override
public void setPermission(String name, String value) {
Require.nonNull("Permission Name", name);
Require.nonNull("Permission Value", value);
permissions.setPermission(name, value);
}
@Override
public ChromiumNetworkConditions getNetworkConditions() {
return networkConditions.getNetworkConditions();
}
@Override
public void setNetworkConditions(ChromiumNetworkConditions networkConditions) {
Require.nonNull("Network Conditions", networkConditions);
this.networkConditions.setNetworkConditions(networkConditions);
}
@Override
public void deleteNetworkConditions() {
networkConditions.deleteNetworkConditions();
}
@Override
public void quit() {
connection.ifPresent(Connection::close);
super.quit();
}
}