selenium-webdriver 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
- data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
- data/chrome/src/extension/background.html +9 -0
- data/chrome/src/extension/background.js +933 -0
- data/chrome/src/extension/content_script.js +1286 -0
- data/chrome/src/extension/manifest-nonwin.json +15 -0
- data/chrome/src/extension/manifest-win.json +16 -0
- data/chrome/src/extension/toolstrip.html +28 -0
- data/chrome/src/extension/utils.js +196 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +8 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +324 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +70 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +119 -0
- data/common/src/js/abstractcommandprocessor.js +161 -0
- data/common/src/js/asserts.js +296 -0
- data/common/src/js/by.js +147 -0
- data/common/src/js/command.js +274 -0
- data/common/src/js/context.js +58 -0
- data/common/src/js/extension/README +2 -0
- data/common/src/js/extension/dommessenger.js +152 -0
- data/common/src/js/factory.js +55 -0
- data/common/src/js/future.js +118 -0
- data/common/src/js/key.js +117 -0
- data/common/src/js/localcommandprocessor.js +181 -0
- data/common/src/js/logging.js +249 -0
- data/common/src/js/testrunner.js +605 -0
- data/common/src/js/timing.js +89 -0
- data/common/src/js/wait.js +199 -0
- data/common/src/js/webdriver.js +853 -0
- data/common/src/js/webelement.js +683 -0
- data/common/src/rb/lib/selenium-webdriver.rb +1 -0
- data/common/src/rb/lib/selenium/webdriver.rb +52 -0
- data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +88 -0
- data/common/src/rb/lib/selenium/webdriver/child_process.rb +85 -0
- data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +41 -0
- data/common/src/rb/lib/selenium/webdriver/driver.rb +128 -0
- data/common/src/rb/lib/selenium/webdriver/element.rb +126 -0
- data/common/src/rb/lib/selenium/webdriver/error.rb +68 -0
- data/common/src/rb/lib/selenium/webdriver/find.rb +69 -0
- data/common/src/rb/lib/selenium/webdriver/navigation.rb +23 -0
- data/common/src/rb/lib/selenium/webdriver/options.rb +50 -0
- data/common/src/rb/lib/selenium/webdriver/platform.rb +82 -0
- data/common/src/rb/lib/selenium/webdriver/target_locator.rb +23 -0
- data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
- data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
- data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
- data/firefox/src/extension/chrome.manifest +3 -0
- data/firefox/src/extension/components/context.js +37 -0
- data/firefox/src/extension/components/driver-component.js +127 -0
- data/firefox/src/extension/components/firefoxDriver.js +706 -0
- data/firefox/src/extension/components/json2.js +273 -0
- data/firefox/src/extension/components/keytest.html +554 -0
- data/firefox/src/extension/components/nsCommandProcessor.js +586 -0
- data/firefox/src/extension/components/screenshooter.js +70 -0
- data/firefox/src/extension/components/socketListener.js +185 -0
- data/firefox/src/extension/components/utils.js +1200 -0
- data/firefox/src/extension/components/webLoadingListener.js +57 -0
- data/firefox/src/extension/components/webdriverserver.js +101 -0
- data/firefox/src/extension/components/wrappedElement.js +609 -0
- data/firefox/src/extension/content/fxdriver.xul +30 -0
- data/firefox/src/extension/content/server.js +95 -0
- data/firefox/src/extension/idl/nsICommandProcessor.idl +38 -0
- data/firefox/src/extension/idl/nsIResponseHandler.idl +34 -0
- data/firefox/src/extension/install.rdf +29 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +21 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +86 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +426 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +82 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +132 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +174 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +60 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +23 -0
- data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +14 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +552 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +94 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +147 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +16 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +374 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/capabilities.rb +105 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +53 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +71 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +43 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +32 -0
- metadata +182 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2007-2009 WebDriver committers
|
|
3
|
+
Copyright 2007-2009 Google Inc.
|
|
4
|
+
Portions copyright 2007 ThoughtWorks, Inc
|
|
5
|
+
|
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License.
|
|
8
|
+
You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
See the License for the specific language governing permissions and
|
|
16
|
+
limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @fileoverview Messenger service used to communicate with the current web
|
|
21
|
+
* page through custom DOM events.
|
|
22
|
+
*
|
|
23
|
+
* <p>The DomMessenger will listen for {@code webdriverCommand} events on the
|
|
24
|
+
* document. The event target should be a node whose {@code command} attribute
|
|
25
|
+
* is a JSON string with the command to execute.
|
|
26
|
+
*
|
|
27
|
+
* <p>Once the command has been executed, the response will be stored as a JSON
|
|
28
|
+
* string in the {@code response} attribute of the node that dispatched the
|
|
29
|
+
* original {@code webdriverCommand} event. The DomMessenger will then dispatch
|
|
30
|
+
* a {@code webdriverResponse} event on that node to notify the page that a
|
|
31
|
+
* response is ready.
|
|
32
|
+
*
|
|
33
|
+
* @author jmleyba@gmail.com (Jason Leyba)
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The DomMessenger is used to communicate with the current webpage through
|
|
39
|
+
* custom events fired on the DOM.
|
|
40
|
+
*
|
|
41
|
+
* @param { {execute: function(string, function(string))} } commandProcessor The
|
|
42
|
+
* object to send commands to for execution. The object should have a single
|
|
43
|
+
* method, {@code execute}, that takes two arguments: the command to execute
|
|
44
|
+
* as a JSON string, and a callback for the command response (specified as a
|
|
45
|
+
* JSON string).
|
|
46
|
+
* @constructor
|
|
47
|
+
*/
|
|
48
|
+
var DomMessenger = function(commandProcessor) {
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The object to use as a command processor.
|
|
52
|
+
* @type { {execute: function(string, function(string))} }
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
this.commandProcessor_ = commandProcessor;
|
|
56
|
+
|
|
57
|
+
var self = this; // TODO(jmleyba): bind
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* EventListener for {@code COMMAND_EVENT}s.
|
|
61
|
+
* @type {function(Event)}
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
this.commandEventListener_ = function(e) {
|
|
65
|
+
self.onCommand(e);
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Attributes used to pass information between the extension and the current
|
|
72
|
+
* web page.
|
|
73
|
+
* @enum {string}
|
|
74
|
+
*/
|
|
75
|
+
DomMessenger.Attribute = {
|
|
76
|
+
COMMAND: 'command',
|
|
77
|
+
RESPONSE: 'response'
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Custom event types used to signal a new message either to or from the current
|
|
83
|
+
* web page.
|
|
84
|
+
* @enum {string}
|
|
85
|
+
*/
|
|
86
|
+
DomMessenger.EventType = {
|
|
87
|
+
COMMAND: 'webdriverCommand',
|
|
88
|
+
RESPONSE: 'webdriverResponse'
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Called when a page loads to
|
|
94
|
+
* Called when a page loads so an element can be injected for communicating with
|
|
95
|
+
* the web page.
|
|
96
|
+
*/
|
|
97
|
+
DomMessenger.prototype.onPageLoad = function(e) {
|
|
98
|
+
// Annotate the documentElement to signal to the client that webdriver is
|
|
99
|
+
// installed.
|
|
100
|
+
var doc = e.originalTarget || e.target;
|
|
101
|
+
doc.documentElement.setAttribute('webdriver', true);
|
|
102
|
+
doc.addEventListener(
|
|
103
|
+
DomMessenger.EventType.COMMAND, this.commandEventListener_, true);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Called when a page unloads; removes the command event listener.
|
|
109
|
+
* @param {Event} e The unload event, whose target is the document that was
|
|
110
|
+
* unloaded.
|
|
111
|
+
*/
|
|
112
|
+
DomMessenger.prototype.onPageUnload = function(e) {
|
|
113
|
+
var doc = e.originalTarget || e.target;
|
|
114
|
+
doc.removeEventListener(
|
|
115
|
+
DomMessenger.EventType.COMMAND, this.commandEventListener_, true);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Handles {@code COMMAND_EVENT}s. The command should be stored as a JSON string
|
|
121
|
+
* in the {@code COMMAND_ATTRIBUTE}.
|
|
122
|
+
* @param {Event} e The command event.
|
|
123
|
+
*/
|
|
124
|
+
DomMessenger.prototype.onCommand = function(e) {
|
|
125
|
+
var client = e.target;
|
|
126
|
+
var command = client.getAttribute(DomMessenger.Attribute.COMMAND);
|
|
127
|
+
|
|
128
|
+
if (!command) {
|
|
129
|
+
throw Error('No command specified');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
var self = this; // TODO(jmleyba): bind
|
|
133
|
+
this.commandProcessor_.execute(command, function(response) {
|
|
134
|
+
self.dispatchResponse(client, response);
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Dispatches a {@code RESPONSE_EVENT} to notify the appropriate page that a
|
|
141
|
+
* command it gave completed execution.
|
|
142
|
+
* @param {Node} client The DOM node that issued the command this response is
|
|
143
|
+
* for.
|
|
144
|
+
* @param {string} response Response to a command as a JSON string.
|
|
145
|
+
*/
|
|
146
|
+
DomMessenger.prototype.dispatchResponse = function(client, response) {
|
|
147
|
+
client.setAttribute(DomMessenger.Attribute.RESPONSE, response);
|
|
148
|
+
var evt = client.ownerDocument.createEvent('Event');
|
|
149
|
+
evt.initEvent(DomMessenger.EventType.RESPONSE,
|
|
150
|
+
/*canBubble=*/true, /*cancellable=*/true);
|
|
151
|
+
client.dispatchEvent(evt);
|
|
152
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** @license
|
|
2
|
+
Copyright 2007-2009 WebDriver committers
|
|
3
|
+
Copyright 2007-2009 Google Inc.
|
|
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
|
+
* @fileoverview Provides factory methods for creating new instances of
|
|
20
|
+
* {@code webdriver.WebDriver}.
|
|
21
|
+
* @author jmleyba@gmail.com (Jason Leyba)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
goog.provide('webdriver.factory');
|
|
25
|
+
|
|
26
|
+
goog.require('goog.userAgent');
|
|
27
|
+
goog.require('webdriver.LocalCommandProcessor');
|
|
28
|
+
goog.require('webdriver.WebDriver');
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new {@code webdriver.WebDriver} instance that uses an
|
|
33
|
+
* {@code webdriver.AbstractCommandProcessor}. This driver will only be able to
|
|
34
|
+
* perform the most basic of commands: sleeping and calling user defined
|
|
35
|
+
* functions.
|
|
36
|
+
* @return {webdriver.WebDriver} A new WebDriver instance.
|
|
37
|
+
*/
|
|
38
|
+
webdriver.factory.createAbstractDriver = function() {
|
|
39
|
+
return new webdriver.WebDriver(new webdriver.AbstractCommandProcessor());
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new {@code webdriver.WebDriver} instance that uses a
|
|
45
|
+
* CommandProcessor directly accessible to the current JavaScript engine.
|
|
46
|
+
* Currently, only Firefox is supported, but IE and Google Chrome support is
|
|
47
|
+
* planned.
|
|
48
|
+
* TODO(jmleyba): Add support for Internet Explorer and Goolge Chrome.
|
|
49
|
+
* @return {webdriver.WebDriver} A new WebDriver instance.
|
|
50
|
+
* @throws If called from a JavaScript engine that does not have support for a
|
|
51
|
+
* local CommandProcessor.
|
|
52
|
+
*/
|
|
53
|
+
webdriver.factory.createLocalWebDriver = function() {
|
|
54
|
+
return new webdriver.WebDriver(new webdriver.LocalCommandProcessor());
|
|
55
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/** @license
|
|
2
|
+
Copyright 2007-2009 WebDriver committers
|
|
3
|
+
Copyright 2007-2009 Google Inc.
|
|
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
|
+
* @fileoverview Defines a class for representing the result of an asynchronous
|
|
20
|
+
* {@code webdriver.Command}.
|
|
21
|
+
* @author jmleyba@gmail.com (Jason Leyba)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
goog.provide('webdriver.Future');
|
|
25
|
+
|
|
26
|
+
goog.require('goog.events.EventType');
|
|
27
|
+
goog.require('goog.events.EventTarget');
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Represents the result of an asynchronous {@code webdriver.Command}. Methods
|
|
32
|
+
* are provided to check if the result has been set and to retrieve the result.
|
|
33
|
+
* <p/>
|
|
34
|
+
* This instance will dispatch a {@code goog.events.EventType.CHANGE} event when
|
|
35
|
+
* its value is set. An {@code Error} will be thrown if {@code #getValue()} is
|
|
36
|
+
* called before the value has been set.
|
|
37
|
+
* @param {webdriver.WebDriver} driver The WebDriver instance that will
|
|
38
|
+
* eventually set this instance's value.
|
|
39
|
+
* @constructor
|
|
40
|
+
* @extends {goog.events.EventTarget}
|
|
41
|
+
*/
|
|
42
|
+
webdriver.Future = function(driver) {
|
|
43
|
+
goog.events.EventTarget.call(this);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The WebDriver that will eventaully set this instance's value.
|
|
47
|
+
* @type {webdriver.WebDriver}
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
this.driver_ = driver;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The value of this Future.
|
|
54
|
+
* @type {*}
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
this.value_ = webdriver.Future.NOT_SET_;
|
|
58
|
+
};
|
|
59
|
+
goog.inherits(webdriver.Future, goog.events.EventTarget);
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A special place-holder value used to represent that the result for a future
|
|
64
|
+
* has not been computed yet.
|
|
65
|
+
* @type {Object}
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
webdriver.Future.NOT_SET_ = {};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @return {*} The value of this Future.
|
|
73
|
+
* @throws If the value has not been set yet.
|
|
74
|
+
*/
|
|
75
|
+
webdriver.Future.prototype.getValue = function() {
|
|
76
|
+
if (this.value_ === webdriver.Future.NOT_SET_) {
|
|
77
|
+
throw new Error('Value has not been set yet');
|
|
78
|
+
}
|
|
79
|
+
return this.value_;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @return {webdriver.WebDriver} The WebDriver that set/will set this Future's
|
|
85
|
+
* value.
|
|
86
|
+
*/
|
|
87
|
+
webdriver.Future.prototype.getDriver = function() {
|
|
88
|
+
return this.driver_;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Sets the value of this Future. Dispatches a
|
|
94
|
+
* {@code goog.events.EventType.CHANGE} event.
|
|
95
|
+
* @param {*} value The new value.
|
|
96
|
+
*/
|
|
97
|
+
webdriver.Future.prototype.setValue = function(value) {
|
|
98
|
+
this.value_ = value;
|
|
99
|
+
this.dispatchEvent(goog.events.EventType.CHANGE);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Sets the value of this future from the value of a Response object.
|
|
105
|
+
* @param {webdriver.Response} response The webdriver.Response to set the value
|
|
106
|
+
* from.
|
|
107
|
+
*/
|
|
108
|
+
webdriver.Future.prototype.setValueFromResponse = function(response) {
|
|
109
|
+
this.setValue(response.value);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @return {boolean} Whether this future has had its value set.
|
|
115
|
+
*/
|
|
116
|
+
webdriver.Future.prototype.isSet = function() {
|
|
117
|
+
return this.value_ !== webdriver.Future.NOT_SET_;
|
|
118
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/** @license
|
|
2
|
+
Copyright 2007-2009 WebDriver committers
|
|
3
|
+
Copyright 2007-2009 Google Inc.
|
|
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
|
+
goog.provide('webdriver.Key');
|
|
19
|
+
|
|
20
|
+
goog.require('goog.array');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Representations of pressable keys that aren't text. These are stored in
|
|
25
|
+
* the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to
|
|
26
|
+
* http://www.google.com.au/search?&q=unicode+pua&btnG=Search
|
|
27
|
+
* @enum {string}
|
|
28
|
+
*/
|
|
29
|
+
webdriver.Key = {
|
|
30
|
+
NULL: '\uE000',
|
|
31
|
+
CANCEL: '\uE001', // ^break
|
|
32
|
+
HELP: '\uE002',
|
|
33
|
+
BACK_SPACE: '\uE003',
|
|
34
|
+
TAB: '\uE004',
|
|
35
|
+
CLEAR: '\uE005',
|
|
36
|
+
RETURN: '\uE006',
|
|
37
|
+
ENTER: '\uE007',
|
|
38
|
+
SHIFT: '\uE008',
|
|
39
|
+
LEFT_SHIFT: '\uE008', // alias
|
|
40
|
+
CONTROL: '\uE009',
|
|
41
|
+
LEFT_CONTROL: '\uE009', // alias
|
|
42
|
+
ALT: '\uE00A',
|
|
43
|
+
LEFT_ALT: '\uE00A', // alias
|
|
44
|
+
PAUSE: '\uE00B',
|
|
45
|
+
ESCAPE: '\uE00C',
|
|
46
|
+
SPACE: '\uE00D',
|
|
47
|
+
PAGE_UP: '\uE00E',
|
|
48
|
+
PAGE_DOWN: '\uE00F',
|
|
49
|
+
END: '\uE010',
|
|
50
|
+
HOME: '\uE011',
|
|
51
|
+
LEFT: '\uE012',
|
|
52
|
+
ARROW_LEFT: '\uE012', // alias
|
|
53
|
+
UP: '\uE013',
|
|
54
|
+
ARROW_UP: '\uE013', // alias
|
|
55
|
+
RIGHT: '\uE014',
|
|
56
|
+
ARROW_RIGHT: '\uE014', // alias
|
|
57
|
+
DOWN: '\uE015',
|
|
58
|
+
ARROW_DOWN: '\uE015', // alias
|
|
59
|
+
INSERT: '\uE016',
|
|
60
|
+
DELETE: '\uE017',
|
|
61
|
+
SEMICOLON: '\uE018',
|
|
62
|
+
EQUALS: '\uE019',
|
|
63
|
+
|
|
64
|
+
NUMPAD0: '\uE01A', // number pad keys
|
|
65
|
+
NUMPAD1: '\uE01B',
|
|
66
|
+
NUMPAD2: '\uE01C',
|
|
67
|
+
NUMPAD3: '\uE01D',
|
|
68
|
+
NUMPAD4: '\uE01E',
|
|
69
|
+
NUMPAD5: '\uE01F',
|
|
70
|
+
NUMPAD6: '\uE020',
|
|
71
|
+
NUMPAD7: '\uE021',
|
|
72
|
+
NUMPAD8: '\uE022',
|
|
73
|
+
NUMPAD9: '\uE023',
|
|
74
|
+
MULTIPLY: '\uE024',
|
|
75
|
+
ADD: '\uE025',
|
|
76
|
+
SEPARATOR: '\uE026',
|
|
77
|
+
SUBTRACT: '\uE027',
|
|
78
|
+
DECIMAL: '\uE028',
|
|
79
|
+
DIVIDE: '\uE029',
|
|
80
|
+
|
|
81
|
+
F1: '\uE031', // function keys
|
|
82
|
+
F2: '\uE032',
|
|
83
|
+
F3: '\uE033',
|
|
84
|
+
F4: '\uE034',
|
|
85
|
+
F5: '\uE035',
|
|
86
|
+
F6: '\uE036',
|
|
87
|
+
F7: '\uE037',
|
|
88
|
+
F8: '\uE038',
|
|
89
|
+
F9: '\uE039',
|
|
90
|
+
F10: '\uE03A',
|
|
91
|
+
F11: '\uE03B',
|
|
92
|
+
F12: '\uE03C',
|
|
93
|
+
|
|
94
|
+
COMMAND: '\uE03D', // Apple command key
|
|
95
|
+
META: '\uE03D' // alias for Windows key
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Simulate pressing many keys at once in a "chord". Takes a sequence of
|
|
100
|
+
* Keys.XXXX or strings; appends each of the values to a string, and adds the
|
|
101
|
+
* chord termination key (Keys.NULL) and returns the resultant string.
|
|
102
|
+
*
|
|
103
|
+
* Note: when the low-level webdriver key handlers see Keys.NULL, active
|
|
104
|
+
* modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event.
|
|
105
|
+
*
|
|
106
|
+
* @param {string|webdriver.Key} var_args The key sequence to concatenate.
|
|
107
|
+
* @see http://code.google.com/p/webdriver/issues/detail?id=79
|
|
108
|
+
*/
|
|
109
|
+
webdriver.Key.chord = function(var_args) {
|
|
110
|
+
var sequence = goog.array.reduce(
|
|
111
|
+
goog.array.slice(arguments, 0),
|
|
112
|
+
function(str, key) {
|
|
113
|
+
return str + key;
|
|
114
|
+
}, '');
|
|
115
|
+
sequence += webdriver.Key.NULL;
|
|
116
|
+
return sequence;
|
|
117
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/** @license
|
|
2
|
+
Copyright 2007-2009 WebDriver committers
|
|
3
|
+
Copyright 2007-2009 Google Inc.
|
|
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
|
+
* @fileoverview Defines a command processor that uses a browser
|
|
20
|
+
* extension/plugin object available to the Javascript on the page.
|
|
21
|
+
* @author jmleyba@gmail.com (Jason Leyba)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
goog.provide('webdriver.LocalCommandProcessor');
|
|
25
|
+
|
|
26
|
+
goog.require('goog.array');
|
|
27
|
+
goog.require('goog.dom');
|
|
28
|
+
goog.require('goog.events');
|
|
29
|
+
goog.require('goog.json');
|
|
30
|
+
goog.require('goog.object');
|
|
31
|
+
goog.require('webdriver.AbstractCommandProcessor');
|
|
32
|
+
goog.require('webdriver.CommandName');
|
|
33
|
+
goog.require('webdriver.Context');
|
|
34
|
+
goog.require('webdriver.Response');
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Command processor that uses a browser extension/plugin exposed to the page
|
|
39
|
+
* for executing WebDriver commands.
|
|
40
|
+
* @param {goog.dom.DomHelper} opt_dom The DomHelper for this instance to use;
|
|
41
|
+
* defaults to a DomHelper for the current document.
|
|
42
|
+
* @constructor
|
|
43
|
+
* @extends {webdriver.AbstractCommandProcessor}
|
|
44
|
+
*/
|
|
45
|
+
webdriver.LocalCommandProcessor = function(opt_dom) {
|
|
46
|
+
webdriver.AbstractCommandProcessor.call(this);
|
|
47
|
+
// TODO(jmleyba): IE, Chrome, et al. support
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The DomHelper for this instance to use.
|
|
51
|
+
* @type {goog.dom.DomHelper}
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
this.dom_ = opt_dom || goog.dom.getDomHelper();
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The element to use for communicating with the extension.
|
|
58
|
+
* @type {Element}
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
this.documentElement_ = this.dom_.getDocument().documentElement;
|
|
62
|
+
|
|
63
|
+
// Verify the extension is installed by checking for the webdriver attribute
|
|
64
|
+
// on the documentElement.
|
|
65
|
+
var webdriverAttribute = this.documentElement_.getAttribute('webdriver');
|
|
66
|
+
if (!webdriverAttribute) {
|
|
67
|
+
throw Error(
|
|
68
|
+
'The current browser does not support a LocalCommandProcessor');
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
goog.inherits(webdriver.LocalCommandProcessor,
|
|
72
|
+
webdriver.AbstractCommandProcessor);
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The custom event types used to communicate with the browser extension.
|
|
77
|
+
* @enum {string}
|
|
78
|
+
*/
|
|
79
|
+
webdriver.LocalCommandProcessor.EventType_ = {
|
|
80
|
+
COMMAND: 'webdriverCommand',
|
|
81
|
+
RESPONSE: 'webdriverResponse'
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The attributes used to store information passed to the browser extension.
|
|
87
|
+
* @enum {string}
|
|
88
|
+
*/
|
|
89
|
+
webdriver.LocalCommandProcessor.MessageAttribute_ = {
|
|
90
|
+
COMMAND: 'command',
|
|
91
|
+
RESPONSE: 'response'
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @override
|
|
97
|
+
*/
|
|
98
|
+
webdriver.LocalCommandProcessor.prototype.dispose = function() {
|
|
99
|
+
goog.events.removeAll(this.documentElement_,
|
|
100
|
+
webdriver.LocalCommandProcessor.EventType_.RESPONSE);
|
|
101
|
+
webdriver.LocalCommandProcessor.superClass_.dispose.call(this);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Event handler for command responses.
|
|
107
|
+
* @param {webdriver.Command} command The initiating command.
|
|
108
|
+
* @param {Event} e The response event. The target should be a node with a
|
|
109
|
+
* {@code response} attribute.
|
|
110
|
+
*/
|
|
111
|
+
webdriver.LocalCommandProcessor.onResponse_ = function(command, e) {
|
|
112
|
+
// It is technically possible that the response could be for a different
|
|
113
|
+
// command, but this should be prevented by code higher in the WebDriverJS
|
|
114
|
+
// stack, so we don't do any error checking here.
|
|
115
|
+
if (e.type != webdriver.LocalCommandProcessor.EventType_.RESPONSE) {
|
|
116
|
+
throw Error('Not a response event!');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
var jsonResponse = e.target.getAttribute(
|
|
120
|
+
webdriver.LocalCommandProcessor.MessageAttribute_.RESPONSE);
|
|
121
|
+
if (!jsonResponse) {
|
|
122
|
+
throw Error('Empty response!');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var rawResponse = goog.json.parse(jsonResponse);
|
|
126
|
+
webdriver.logging.info(
|
|
127
|
+
'receiving:\n' +
|
|
128
|
+
webdriver.logging.describe(rawResponse, ' '));
|
|
129
|
+
|
|
130
|
+
var response = new webdriver.Response(
|
|
131
|
+
rawResponse['isError'],
|
|
132
|
+
webdriver.Context.fromString(rawResponse['context']),
|
|
133
|
+
rawResponse['response']);
|
|
134
|
+
response.extraData['resultType'] = rawResponse['resultType'];
|
|
135
|
+
|
|
136
|
+
// Only code in this file should be dispatching command events and listening
|
|
137
|
+
// for response events, so this is safe. If someone else decided to attach a
|
|
138
|
+
// listener anyway, tough luck.
|
|
139
|
+
goog.events.removeAll(
|
|
140
|
+
e.target, webdriver.LocalCommandProcessor.EventType_.RESPONSE);
|
|
141
|
+
command.setResponse(response);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @override
|
|
147
|
+
*/
|
|
148
|
+
webdriver.LocalCommandProcessor.prototype.executeDriverCommand = function(
|
|
149
|
+
command, sessionId, context) {
|
|
150
|
+
if (command.name == webdriver.CommandName.SEND_KEYS) {
|
|
151
|
+
command.parameters = [command.parameters.join('')];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
var jsonCommand = {
|
|
155
|
+
'commandName': command.name,
|
|
156
|
+
'context': context.toString(),
|
|
157
|
+
'parameters': command.parameters
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (command.element) {
|
|
161
|
+
jsonCommand['elementId'] = command.element.getId().getValue();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
webdriver.logging.info(
|
|
165
|
+
'sending:\n' +
|
|
166
|
+
webdriver.logging.describe(jsonCommand, ' '));
|
|
167
|
+
|
|
168
|
+
this.documentElement_.setAttribute(
|
|
169
|
+
webdriver.LocalCommandProcessor.MessageAttribute_.COMMAND,
|
|
170
|
+
goog.json.serialize(jsonCommand));
|
|
171
|
+
|
|
172
|
+
goog.events.listen(this.documentElement_,
|
|
173
|
+
webdriver.LocalCommandProcessor.EventType_.RESPONSE,
|
|
174
|
+
goog.bind(webdriver.LocalCommandProcessor.onResponse_, null, command));
|
|
175
|
+
|
|
176
|
+
var commandEvent = this.dom_.getDocument().createEvent('Event');
|
|
177
|
+
commandEvent.initEvent(
|
|
178
|
+
webdriver.LocalCommandProcessor.EventType_.COMMAND,
|
|
179
|
+
/*canBubble=*/true, /*cancelable=*/true);
|
|
180
|
+
this.documentElement_.dispatchEvent(commandEvent);
|
|
181
|
+
};
|