Skip to content

Commit 57de995

Browse files
committed
Implementing standard conformant protocol in firefox driver
1 parent 8c010da commit 57de995

File tree

9 files changed

+132
-24
lines changed

9 files changed

+132
-24
lines changed

java/client/src/org/openqa/selenium/firefox/internal/NewProfileExtensionConnection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.openqa.selenium.net.NetworkUtils;
3131
import org.openqa.selenium.remote.Command;
3232
import org.openqa.selenium.remote.HttpCommandExecutor;
33+
import org.openqa.selenium.remote.HttpCommandExecutorV1;
3334
import org.openqa.selenium.remote.Response;
3435
import org.openqa.selenium.remote.internal.CircularOutputStream;
3536

@@ -90,7 +91,7 @@ public void start() throws IOException {
9091

9192
process.clean(profile, profileDir);
9293

93-
delegate = new HttpCommandExecutor(buildUrl(host, port));
94+
delegate = new HttpCommandExecutorV1(buildUrl(host, port));
9495
delegate.setLocalLogs(logs);
9596
String firefoxLogFile = System.getProperty("webdriver.firefox.logfile");
9697

@@ -213,7 +214,7 @@ public void quit() {
213214
private static URL buildUrl(String host, int port) {
214215
String hostToUse = "localhost".equals(host) ? networkUtils.obtainLoopbackIp4Address() : host;
215216
try {
216-
return new URL("http", hostToUse, port, "/hub");
217+
return new URL("http", hostToUse, port, "/v1");
217218
} catch (MalformedURLException e) {
218219
throw new WebDriverException(e);
219220
}

java/client/src/org/openqa/selenium/remote/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ java_library(name = 'remote',
4040
'ExecuteMethod.java',
4141
'FileDetector.java',
4242
'HttpCommandExecutor.java',
43+
'HttpCommandExecutorV1.java',
4344
'HttpVerb.java',
4445
'JsonException.java',
4546
'JsonToBeanConverter.java',

java/client/src/org/openqa/selenium/remote/BeanToJsonConverter.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@
4747
public class BeanToJsonConverter {
4848

4949
private static final int MAX_DEPTH = 5;
50+
private final boolean v1; // W3C WebDriver Level 1 compatibility flag
51+
52+
public BeanToJsonConverter() {
53+
this(false);
54+
}
55+
56+
public BeanToJsonConverter(boolean v1) {
57+
this.v1 = v1;
58+
}
5059

5160
/**
5261
* Convert an object that may or may not be a JSONArray or JSONObject into its JSON string
@@ -190,9 +199,13 @@ private Object convertObject(Object toConvert, int maxDepth) throws Exception {
190199
}
191200

192201
if (toConvert instanceof SessionId) {
193-
JSONObject converted = new JSONObject();
194-
converted.put("value", toConvert.toString());
195-
return converted;
202+
if (v1) {
203+
return toConvert.toString();
204+
} else {
205+
JSONObject converted = new JSONObject();
206+
converted.put("value", toConvert.toString());
207+
return converted;
208+
}
196209
}
197210

198211
if (toConvert instanceof Capabilities) {

java/client/src/org/openqa/selenium/remote/HttpCommandExecutor.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,23 +282,11 @@ public Response execute(Command command) throws IOException {
282282
}
283283
}
284284

285-
CommandInfo info = nameToUrl.get(command.getName());
286285
try {
287-
HttpUriRequest httpMethod = info.getMethod(remoteServer, command);
286+
HttpUriRequest httpMethod = buildRequest(command);
288287

289288
setAcceptHeader(httpMethod);
290289

291-
if (httpMethod instanceof HttpPost) {
292-
String payload = new BeanToJsonConverter().convert(command.getParameters());
293-
((HttpPost) httpMethod).setEntity(new StringEntity(payload, "utf-8"));
294-
httpMethod.addHeader("Content-Type", "application/json; charset=utf-8");
295-
}
296-
297-
// Do not allow web proxy caches to cache responses to "get" commands
298-
if (httpMethod instanceof HttpGet) {
299-
httpMethod.addHeader("Cache-Control", "no-cache");
300-
}
301-
302290
log(LogType.PROFILER, new HttpProfilerLogEntry(command.getName(), true));
303291
HttpResponse response = fallBackExecute(context, httpMethod);
304292
log(LogType.PROFILER, new HttpProfilerLogEntry(command.getName(), false));
@@ -318,6 +306,23 @@ public Response execute(Command command) throws IOException {
318306
}
319307
}
320308

309+
protected HttpUriRequest buildRequest(Command command) throws UnsupportedEncodingException {
310+
HttpUriRequest httpMethod = nameToUrl.get(command.getName()).getMethod(remoteServer, command);
311+
312+
if (httpMethod instanceof HttpPost) {
313+
String payload = new BeanToJsonConverter().convert(command.getParameters());
314+
((HttpPost) httpMethod).setEntity(new StringEntity(payload, "utf-8"));
315+
httpMethod.addHeader("Content-Type", "application/json; charset=utf-8");
316+
}
317+
318+
// Do not allow web proxy caches to cache responses to "get" commands
319+
if (httpMethod instanceof HttpGet) {
320+
httpMethod.addHeader("Cache-Control", "no-cache");
321+
}
322+
323+
return httpMethod;
324+
}
325+
321326
private HttpResponse fallBackExecute(HttpContext context, HttpUriRequest httpMethod)
322327
throws IOException {
323328
try {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Copyright 2014 Selenium committers
3+
Copyright 2014 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.remote;
19+
20+
import org.apache.http.client.methods.HttpPost;
21+
import org.apache.http.client.methods.HttpUriRequest;
22+
import org.apache.http.entity.StringEntity;
23+
24+
import java.io.UnsupportedEncodingException;
25+
import java.net.URL;
26+
27+
/**
28+
* This implementation reifies HttpCommandExecutor to ensure W3C WebDriver Level 1 conformance.
29+
* To be merged to HttpCommandExecutor as soon as all drivers and the server are conformant.
30+
*/
31+
public class HttpCommandExecutorV1 extends HttpCommandExecutor {
32+
33+
public HttpCommandExecutorV1(URL addressOfRemoteServer) {
34+
super(addressOfRemoteServer);
35+
}
36+
37+
protected HttpUriRequest buildRequest(Command command) throws UnsupportedEncodingException {
38+
HttpUriRequest httpMethod = new HttpPost(getAddressOfRemoteServer().toString());
39+
40+
String payload = new BeanToJsonConverter(true).convert(command);
41+
((HttpPost) httpMethod).setEntity(new StringEntity(payload, "utf-8"));
42+
httpMethod.addHeader("Content-Type", "application/json; charset=utf-8");
43+
44+
return httpMethod;
45+
}
46+
47+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ java_library(name = "remote",
7676
"ExecuteMethod.java",
7777
"FileDetector.java",
7878
"HttpCommandExecutor.java",
79+
"HttpCommandExecutorV1.java",
7980
"HttpVerb.java",
8081
"LocalFileDetector.java",
8182
"RemoteExecuteMethod.java",

javascript/firefox-driver/js/dispatcher.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,31 @@ Dispatcher.notImplemented = function(request, response) {
4949
};
5050

5151

52+
/**
53+
* Execute a command
54+
* @param {Request} request The request to respond to.
55+
* @param {Response} response Class used to send the response.
56+
*/
57+
Dispatcher.prototype.execute_v1 = function(request, response) {
58+
var callback = function(jsonResponseString) {
59+
var jsonResponse = JSON.parse(jsonResponseString);
60+
// Going to need more granularity here I think.
61+
if (jsonResponse.status != bot.ErrorCode.SUCCESS) {
62+
response.setStatus(Response.INTERNAL_ERROR);
63+
}
64+
65+
response.setContentType('application/json');
66+
response.setBody(jsonResponseString);
67+
response.commit();
68+
};
69+
70+
// Dispatch the command.
71+
Components.classes['@googlecode.com/webdriver/command-processor;1'].
72+
getService(Components.interfaces.nsICommandProcessor).
73+
execute(request.getBody(), callback);
74+
};
75+
76+
5277
/**
5378
* Returns a function that translates a WebDriver HTTP request to a legacy
5479
* command.
@@ -261,11 +286,11 @@ Dispatcher.prototype.init_ = function() {
261286
this.bind_('/session/:sessionId/element/:id/click').
262287
on(Request.Method.POST, Dispatcher.executeAs('clickElement'));
263288
this.bind_('/session/:sessionId/moveto').
264-
on(Request.Method.POST, Dispatcher.executeAs('mouseMove'));
289+
on(Request.Method.POST, Dispatcher.executeAs('mouseMoveTo'));
265290
this.bind_('/session/:sessionId/buttondown').
266-
on(Request.Method.POST, Dispatcher.executeAs('mouseDown'));
291+
on(Request.Method.POST, Dispatcher.executeAs('mouseButtonDown'));
267292
this.bind_('/session/:sessionId/buttonup').
268-
on(Request.Method.POST, Dispatcher.executeAs('mouseUp'));
293+
on(Request.Method.POST, Dispatcher.executeAs('mouseButtonUp'));
269294
this.bind_('/session/:sessionId/click').
270295
on(Request.Method.POST, Dispatcher.executeAs('mouseClick'));
271296
this.bind_('/session/:sessionId/doubleclick').
@@ -308,6 +333,17 @@ Dispatcher.prototype.bind_ = function(path) {
308333
};
309334

310335

336+
/**
337+
* Dispatches a request to the appropriately registered handler.
338+
* @param {Request} request The request to dispatch.
339+
* @param {Response} response The request response.
340+
*/
341+
Dispatcher.prototype.dispatch_v1 = function(request, response) {
342+
var path = request.getPathInfo();
343+
request.setServletPath('/v1');
344+
this.execute_v1(request, response);
345+
};
346+
311347

312348
/**
313349
* Dispatches a request to the appropriately registered handler.

javascript/firefox-driver/js/firefoxDriver.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ FirefoxDriver.prototype.sendResponseFromSyntheticMouse_ = function(mouseReturnVa
10751075
}
10761076
};
10771077

1078-
FirefoxDriver.prototype.mouseMove = function(respond, parameters) {
1078+
FirefoxDriver.prototype.mouseMoveTo = function(respond, parameters) {
10791079
// Coordinate spaces in use:
10801080
// * Owner document space: Coordinates are relative to the top-left of the
10811081
// top-level document contained by the window handle containing the
@@ -1198,7 +1198,7 @@ FirefoxDriver.prototype.mouseMove = function(respond, parameters) {
11981198
}
11991199
};
12001200

1201-
FirefoxDriver.prototype.mouseDown = function(respond, parameters) {
1201+
FirefoxDriver.prototype.mouseButtonDown = function(respond, parameters) {
12021202
var doc = respond.session.getDocument();
12031203

12041204
if (!this.enableNativeEvents) {
@@ -1236,7 +1236,7 @@ FirefoxDriver.prototype.mouseDown = function(respond, parameters) {
12361236
respond.send();
12371237
};
12381238

1239-
FirefoxDriver.prototype.mouseUp = function(respond, parameters) {
1239+
FirefoxDriver.prototype.mouseButtonUp = function(respond, parameters) {
12401240
var doc = respond.session.getDocument();
12411241

12421242
if (!this.enableNativeEvents) {

javascript/firefox-driver/js/webdriverserver.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ WebDriverServer = function() {
5353
response.processAsync();
5454
dispatcher_.dispatch(new Request(request), new Response(response));
5555
}});
56+
this.server_.registerGlobHandler('.*/v1', { handle: function(request, response) {
57+
response.processAsync();
58+
dispatcher_.dispatch_v1(new Request(request), new Response(response));
59+
}});
5660
};
5761

5862

0 commit comments

Comments
 (0)