Skip to content

Commit d69a533

Browse files
committed
Adding support for Blink-based Opera to Java binding
1 parent 2a9b686 commit d69a533

File tree

6 files changed

+643
-0
lines changed

6 files changed

+643
-0
lines changed

java/client/src/org/openqa/selenium/build.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ java_library(name = "client-combined",
9292
"//java/client/src/org/openqa/selenium/htmlunit",
9393
"//java/client/src/org/openqa/selenium/firefox",
9494
"//java/client/src/org/openqa/selenium/ie",
95+
"//java/client/src/org/openqa/selenium/opera",
9596
"//java/client/src/org/openqa/selenium/remote",
9697
"//java/client/src/org/openqa/selenium/safari",
9798
"//java/client/src/org/openqa/selenium/support",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
java_library(
2+
name = 'opera',
3+
srcs = glob(['*.java']),
4+
deps = [
5+
'//java/client/src/org/openqa/selenium:webdriver-api',
6+
'//java/client/src/org/openqa/selenium/logging:logging',
7+
'//java/client/src/org/openqa/selenium/net:net',
8+
'//java/client/src/org/openqa/selenium/remote:api',
9+
'//java/client/src/org/openqa/selenium/remote:capabilities',
10+
'//java/client/src/org/openqa/selenium/remote:remote',
11+
'//java/client/src/org/openqa/selenium/remote/service:service',
12+
'//third_party/java/gson:gson',
13+
'//third_party/java/guava-libraries:guava-libraries',
14+
],
15+
visibility = [ 'PUBLIC' ],
16+
)
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
Copyright 2012 Selenium committers
3+
Copyright 2012 Software Freedom Conservancy
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
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, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
19+
package org.openqa.selenium.opera;
20+
21+
import org.openqa.selenium.Capabilities;
22+
import org.openqa.selenium.WebDriver;
23+
import org.openqa.selenium.WebDriverException;
24+
import org.openqa.selenium.html5.LocalStorage;
25+
import org.openqa.selenium.html5.Location;
26+
import org.openqa.selenium.html5.LocationContext;
27+
import org.openqa.selenium.html5.SessionStorage;
28+
import org.openqa.selenium.html5.WebStorage;
29+
import org.openqa.selenium.remote.FileDetector;
30+
import org.openqa.selenium.remote.RemoteWebDriver;
31+
import org.openqa.selenium.remote.html5.RemoteLocationContext;
32+
import org.openqa.selenium.remote.html5.RemoteWebStorage;
33+
import org.openqa.selenium.remote.service.DriverCommandExecutor;
34+
35+
/**
36+
* A {@link WebDriver} implementation that controls a Blink-based Opera browser running on the local
37+
* machine. This class is provided as a convenience for easily testing the Chrome browser. The
38+
* control server which each instance communicates with will live and die with the instance.
39+
*
40+
* <p/>
41+
* To avoid unnecessarily restarting the OperaDriver server with each instance, use a
42+
* {@link RemoteWebDriver} coupled with the desired {@link OperaDriverService}, which is managed
43+
* separately. For example: <code><pre>
44+
*
45+
* import static org.junit.Assert.assertEquals;
46+
*
47+
* import org.junit.*;
48+
* import org.junit.runner.RunWith;
49+
* import org.junit.runners.JUnit4;
50+
* import org.openqa.selenium.opera.OperaDriverService;
51+
* import org.openqa.selenium.remote.DesiredCapabilities;
52+
* import org.openqa.selenium.remote.RemoteWebDriver;
53+
*
54+
* {@literal @RunWith(JUnit4.class)}
55+
* public class OperaTest extends TestCase {
56+
*
57+
* private static OperaDriverService service;
58+
* private WebDriver driver;
59+
*
60+
* {@literal @BeforeClass}
61+
* public static void createAndStartService() {
62+
* service = new OperaDriverService.Builder()
63+
* .usingDriverExecutable(new File("path/to/my/operadriver.exe"))
64+
* .usingAnyFreePort()
65+
* .build();
66+
* service.start();
67+
* }
68+
*
69+
* {@literal @AfterClass}
70+
* public static void createAndStopService() {
71+
* service.stop();
72+
* }
73+
*
74+
* {@literal @Before}
75+
* public void createDriver() {
76+
* driver = new RemoteWebDriver(service.getUrl(),
77+
* DesiredCapabilities.opera());
78+
* }
79+
*
80+
* {@literal @After}
81+
* public void quitDriver() {
82+
* driver.quit();
83+
* }
84+
*
85+
* {@literal @Test}
86+
* public void testGoogleSearch() {
87+
* driver.get("http://www.google.com");
88+
* WebElement searchBox = driver.findElement(By.name("q"));
89+
* searchBox.sendKeys("webdriver");
90+
* searchBox.quit();
91+
* assertEquals("webdriver - Google Search", driver.getTitle());
92+
* }
93+
* }
94+
* </pre></code>
95+
*
96+
* Note that unlike OperaDriver, RemoteWebDriver doesn't directly implement
97+
* role interfaces such as {@link LocationContext} and {@link WebStorage}.
98+
* Therefore, to access that functionality, it needs to be
99+
* {@link org.openqa.selenium.remote.Augmenter augmented} and then cast
100+
* to the appropriate interface.
101+
*
102+
* @see OperaDriverService#createDefaultService
103+
*/
104+
public class OperaDriver extends RemoteWebDriver
105+
implements LocationContext, WebStorage {
106+
107+
private RemoteLocationContext locationContext;
108+
private RemoteWebStorage webStorage;
109+
110+
/**
111+
* Creates a new OperaDriver using the {@link OperaDriverService#createDefaultService default}
112+
* server configuration.
113+
*
114+
* @see #OperaDriver(OperaDriverService, OperaOptions)
115+
*/
116+
public OperaDriver() {
117+
this(OperaDriverService.createDefaultService(), new OperaOptions());
118+
}
119+
120+
/**
121+
* Creates a new OperaDriver instance. The {@code service} will be started along with the driver,
122+
* and shutdown upon calling {@link #quit()}.
123+
*
124+
* @param service The service to use.
125+
* @see #OperaDriver(OperaDriverService, OperaOptions)
126+
*/
127+
public OperaDriver(OperaDriverService service) {
128+
this(service, new OperaOptions());
129+
}
130+
131+
/**
132+
* Creates a new OperaDriver instance. The {@code capabilities} will be passed to the
133+
* chromedriver service.
134+
*
135+
* @param capabilities The capabilities required from the OperaDriver.
136+
* @see #OperaDriver(OperaDriverService, Capabilities)
137+
*/
138+
public OperaDriver(Capabilities capabilities) {
139+
this(OperaDriverService.createDefaultService(), capabilities);
140+
}
141+
142+
/**
143+
* Creates a new OperaDriver instance with the specified options.
144+
*
145+
* @param options The options to use.
146+
* @see #OperaDriver(OperaDriverService, OperaOptions)
147+
*/
148+
public OperaDriver(OperaOptions options) {
149+
this(OperaDriverService.createDefaultService(), options);
150+
}
151+
152+
/**
153+
* Creates a new OperaDriver instance with the specified options. The {@code service} will be
154+
* started along with the driver, and shutdown upon calling {@link #quit()}.
155+
*
156+
* @param service The service to use.
157+
* @param options The options to use.
158+
*/
159+
public OperaDriver(OperaDriverService service, OperaOptions options) {
160+
this(service, options.toCapabilities());
161+
}
162+
163+
/**
164+
* Creates a new OperaDriver instance. The {@code service} will be started along with the
165+
* driver, and shutdown upon calling {@link #quit()}.
166+
*
167+
* @param service The service to use.
168+
* @param capabilities The capabilities required from the OperaDriver.
169+
*/
170+
public OperaDriver(OperaDriverService service, Capabilities capabilities) {
171+
super(new DriverCommandExecutor(service), capabilities);
172+
locationContext = new RemoteLocationContext(getExecuteMethod());
173+
webStorage = new RemoteWebStorage(getExecuteMethod());
174+
}
175+
176+
@Override
177+
public void setFileDetector(FileDetector detector) {
178+
throw new WebDriverException(
179+
"Setting the file detector only works on remote webdriver instances obtained " +
180+
"via RemoteWebDriver");
181+
}
182+
183+
@Override
184+
public LocalStorage getLocalStorage() {
185+
return webStorage.getLocalStorage();
186+
}
187+
188+
@Override
189+
public SessionStorage getSessionStorage() {
190+
return webStorage.getSessionStorage();
191+
}
192+
193+
@Override
194+
public Location location() {
195+
return locationContext.location();
196+
}
197+
198+
@Override
199+
public void setLocation(Location location) {
200+
locationContext.setLocation(location);
201+
}
202+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
Copyright 2011-2012 Selenium committers
3+
Copyright 2011-2012 Software Freedom Conservancy
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
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, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package org.openqa.selenium.opera;
19+
20+
import com.google.common.collect.ImmutableList;
21+
import com.google.common.collect.ImmutableMap;
22+
23+
import org.openqa.selenium.WebDriverException;
24+
import org.openqa.selenium.remote.service.DriverService;
25+
26+
import java.io.File;
27+
import java.io.IOException;
28+
29+
/**
30+
* Manages the life and death of a operadriver server.
31+
*/
32+
public class OperaDriverService extends DriverService {
33+
34+
/**
35+
* System property that defines the location of the operadriver executable that will be used by
36+
* the {@link #createDefaultService() default service}.
37+
*/
38+
public static final String OPERA_DRIVER_EXE_PROPERTY = "webdriver.opera.driver";
39+
40+
/**
41+
* System property that defines the location of the log that will be written by
42+
* the {@link #createDefaultService() default service}.
43+
*/
44+
public final static String OPERA_DRIVER_LOG_PROPERTY = "webdriver.opera.logfile";
45+
46+
/**
47+
* Boolean system property that defines whether the OperaDriver executable should be started
48+
* with verbose logging.
49+
*/
50+
public static final String OPERA_DRIVER_VERBOSE_LOG_PROPERTY =
51+
"webdriver.opera.verboseLogging";
52+
53+
/**
54+
* Boolean system property that defines whether the OperaDriver executable should be started
55+
* in silent mode.
56+
*/
57+
public static final String OPERA_DRIVER_SILENT_OUTPUT_PROPERTY =
58+
"webdriver.opera.silentOutput";
59+
60+
/**
61+
*
62+
* @param executable The operadriver executable.
63+
* @param port Which port to start the operadriver on.
64+
* @param args The arguments to the launched server.
65+
* @param environment The environment for the launched server.
66+
* @throws IOException If an I/O error occurs.
67+
*/
68+
public OperaDriverService(File executable, int port, ImmutableList<String> args,
69+
ImmutableMap<String, String> environment) throws IOException {
70+
super(executable, port, args, environment);
71+
}
72+
73+
/**
74+
* Configures and returns a new {@link OperaDriverService} using the default configuration. In
75+
* this configuration, the service will use the operadriver executable identified by the
76+
* {@link #OPERA_DRIVER_EXE_PROPERTY} system property. Each service created by this method will
77+
* be configured to use a free port on the current system.
78+
*
79+
* @return A new OperaDriverService using the default configuration.
80+
*/
81+
public static OperaDriverService createDefaultService() {
82+
return new Builder().usingAnyFreePort().build();
83+
}
84+
85+
/**
86+
* Builder used to configure new {@link OperaDriverService} instances.
87+
*/
88+
public static class Builder extends DriverService.Builder<OperaDriverService> {
89+
90+
private boolean verbose = Boolean.getBoolean(OPERA_DRIVER_VERBOSE_LOG_PROPERTY);
91+
private boolean silent = Boolean.getBoolean(OPERA_DRIVER_SILENT_OUTPUT_PROPERTY);
92+
93+
/**
94+
* Configures the driver server verbosity.
95+
*
96+
* @param verbose true for verbose output, false otherwise.
97+
* @return A self reference.
98+
*/
99+
public Builder withVerbose(boolean verbose) {
100+
this.verbose = verbose;
101+
return this;
102+
}
103+
104+
/**
105+
* Configures the driver server for silent output.
106+
*
107+
* @param silent true for silent output, false otherwise.
108+
* @return A self reference.
109+
*/
110+
public Builder withSilent(boolean silent) {
111+
this.silent = silent;
112+
return this;
113+
}
114+
115+
@Override
116+
protected File findDefaultExecutable() {
117+
return findExecutable("operadriver", OPERA_DRIVER_EXE_PROPERTY,
118+
"https://github.com/operasoftware/operachromiumdriver",
119+
"https://github.com/operasoftware/operachromiumdriver/releases");
120+
}
121+
122+
@Override
123+
protected ImmutableList<String> createArgs() {
124+
if (getLogFile() == null) {
125+
String logFilePath = System.getProperty(OPERA_DRIVER_LOG_PROPERTY);
126+
if (logFilePath != null) {
127+
withLogFile(new File(logFilePath));
128+
}
129+
}
130+
131+
ImmutableList.Builder<String> argsBuilder = ImmutableList.builder();
132+
argsBuilder.add(String.format("--port=%d", getPort()));
133+
if (getLogFile() != null) {
134+
argsBuilder.add(String.format("--log-path=%s", getLogFile().getAbsolutePath()));
135+
}
136+
if (verbose) {
137+
argsBuilder.add("--verbose");
138+
}
139+
if (silent) {
140+
argsBuilder.add("--silent");
141+
}
142+
143+
return argsBuilder.build();
144+
}
145+
146+
@Override
147+
protected OperaDriverService createDriverService(File exe, int port,
148+
ImmutableList<String> args,
149+
ImmutableMap<String, String> environment) {
150+
try {
151+
return new OperaDriverService(exe, port, args, environment);
152+
} catch (IOException e) {
153+
throw new WebDriverException(e);
154+
}
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)