selenium-webdriver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  2. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  3. data/chrome/src/extension/background.html +9 -0
  4. data/chrome/src/extension/background.js +933 -0
  5. data/chrome/src/extension/content_script.js +1286 -0
  6. data/chrome/src/extension/manifest-nonwin.json +15 -0
  7. data/chrome/src/extension/manifest-win.json +16 -0
  8. data/chrome/src/extension/toolstrip.html +28 -0
  9. data/chrome/src/extension/utils.js +196 -0
  10. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +8 -0
  11. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +324 -0
  12. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +70 -0
  13. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +119 -0
  14. data/common/src/js/abstractcommandprocessor.js +161 -0
  15. data/common/src/js/asserts.js +296 -0
  16. data/common/src/js/by.js +147 -0
  17. data/common/src/js/command.js +274 -0
  18. data/common/src/js/context.js +58 -0
  19. data/common/src/js/extension/README +2 -0
  20. data/common/src/js/extension/dommessenger.js +152 -0
  21. data/common/src/js/factory.js +55 -0
  22. data/common/src/js/future.js +118 -0
  23. data/common/src/js/key.js +117 -0
  24. data/common/src/js/localcommandprocessor.js +181 -0
  25. data/common/src/js/logging.js +249 -0
  26. data/common/src/js/testrunner.js +605 -0
  27. data/common/src/js/timing.js +89 -0
  28. data/common/src/js/wait.js +199 -0
  29. data/common/src/js/webdriver.js +853 -0
  30. data/common/src/js/webelement.js +683 -0
  31. data/common/src/rb/lib/selenium-webdriver.rb +1 -0
  32. data/common/src/rb/lib/selenium/webdriver.rb +52 -0
  33. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +88 -0
  34. data/common/src/rb/lib/selenium/webdriver/child_process.rb +85 -0
  35. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +41 -0
  36. data/common/src/rb/lib/selenium/webdriver/driver.rb +128 -0
  37. data/common/src/rb/lib/selenium/webdriver/element.rb +126 -0
  38. data/common/src/rb/lib/selenium/webdriver/error.rb +68 -0
  39. data/common/src/rb/lib/selenium/webdriver/find.rb +69 -0
  40. data/common/src/rb/lib/selenium/webdriver/navigation.rb +23 -0
  41. data/common/src/rb/lib/selenium/webdriver/options.rb +50 -0
  42. data/common/src/rb/lib/selenium/webdriver/platform.rb +82 -0
  43. data/common/src/rb/lib/selenium/webdriver/target_locator.rb +23 -0
  44. data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
  45. data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
  46. data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
  47. data/firefox/src/extension/chrome.manifest +3 -0
  48. data/firefox/src/extension/components/context.js +37 -0
  49. data/firefox/src/extension/components/driver-component.js +127 -0
  50. data/firefox/src/extension/components/firefoxDriver.js +706 -0
  51. data/firefox/src/extension/components/json2.js +273 -0
  52. data/firefox/src/extension/components/keytest.html +554 -0
  53. data/firefox/src/extension/components/nsCommandProcessor.js +586 -0
  54. data/firefox/src/extension/components/screenshooter.js +70 -0
  55. data/firefox/src/extension/components/socketListener.js +185 -0
  56. data/firefox/src/extension/components/utils.js +1200 -0
  57. data/firefox/src/extension/components/webLoadingListener.js +57 -0
  58. data/firefox/src/extension/components/webdriverserver.js +101 -0
  59. data/firefox/src/extension/components/wrappedElement.js +609 -0
  60. data/firefox/src/extension/content/fxdriver.xul +30 -0
  61. data/firefox/src/extension/content/server.js +95 -0
  62. data/firefox/src/extension/idl/nsICommandProcessor.idl +38 -0
  63. data/firefox/src/extension/idl/nsIResponseHandler.idl +34 -0
  64. data/firefox/src/extension/install.rdf +29 -0
  65. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +21 -0
  66. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +86 -0
  67. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +426 -0
  68. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +82 -0
  69. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +132 -0
  70. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +174 -0
  71. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +60 -0
  72. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +23 -0
  73. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  74. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  75. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +14 -0
  76. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +552 -0
  77. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +94 -0
  78. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +147 -0
  79. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +16 -0
  80. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +374 -0
  81. data/remote/client/src/rb/lib/selenium/webdriver/remote/capabilities.rb +105 -0
  82. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +53 -0
  83. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +71 -0
  84. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +43 -0
  85. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +32 -0
  86. metadata +182 -0
@@ -0,0 +1,70 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+ class CommandExecutor
5
+ TEMPLATE = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n%s"
6
+
7
+ def initialize
8
+ @server = TCPServer.new("0.0.0.0", 9700)
9
+ @queue = Queue.new
10
+ @accepted_any = false
11
+ @next_socket = nil
12
+
13
+ Thread.new { start_run_loop }
14
+ end
15
+
16
+ def execute(command)
17
+ until accepted_any?
18
+ Thread.pass
19
+ sleep 0.01
20
+ end
21
+
22
+ json = command.to_json
23
+ data = TEMPLATE % [json.length, json]
24
+
25
+ @next_socket.write data
26
+ @next_socket.close
27
+
28
+ JSON.parse read_response(@queue.pop)
29
+ end
30
+
31
+ private
32
+
33
+ def start_run_loop
34
+ loop do
35
+ socket = @server.accept
36
+ @queue << socket
37
+
38
+ unless accepted_any?
39
+ read_response socket
40
+ @queue.pop
41
+ end
42
+
43
+ @accepted_any ||= true
44
+ end
45
+ end
46
+
47
+ def read_response(socket)
48
+ result = ''
49
+
50
+ seen_double_crlf = false
51
+ while !socket.closed? && ((line = socket.gets.chomp) != "EOResponse")
52
+ seen_double_crlf = true if line.empty?
53
+ result << "#{line}\n" if seen_double_crlf
54
+ end
55
+
56
+ @next_socket = socket
57
+
58
+ result.strip!
59
+ # p result
60
+ result
61
+ end
62
+
63
+ def accepted_any?
64
+ @accepted_any
65
+ end
66
+
67
+ end # CommandExecutor
68
+ end # Chrome
69
+ end # WebDriver
70
+ end # Selenium
@@ -0,0 +1,119 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+ class Launcher
5
+ include FileUtils
6
+
7
+ attr_reader :pid
8
+
9
+ def self.launcher
10
+ launcher = case Platform.os
11
+ when :windows
12
+ WindowsLauncher.new
13
+ when :macosx
14
+ MacOSXLauncher.new
15
+ when :unix
16
+ UnixLauncher.new
17
+ else
18
+ raise "unknown OS: #{Platform.os}"
19
+ end
20
+
21
+ launcher
22
+ end
23
+
24
+ def launch
25
+ create_extension
26
+ create_profile
27
+ launch_chrome
28
+
29
+ pid
30
+ end
31
+
32
+ def kill
33
+ @process.kill
34
+ end
35
+
36
+ private
37
+
38
+ def create_extension
39
+ ext_files.each { |file| cp file, tmp_extension_dir }
40
+
41
+ if Platform.win?
42
+ cp linked_lib_path, tmp_extension_dir
43
+ mv "#{tmp_extension_dir}/manifest-win.json", "#{tmp_extension_dir}/manifest.json"
44
+ else
45
+ mv "#{tmp_extension_dir}/manifest-nonwin.json", "#{tmp_extension_dir}/manifest.json"
46
+ end
47
+ end
48
+
49
+ def create_profile
50
+ touch "#{tmp_profile_dir}/First Run Dev"
51
+ end
52
+
53
+ def launch_chrome
54
+ @process = ChildProcess.new Platform.wrap_in_quotes_if_necessary(binary_path),
55
+ "--load-extension=#{Platform.wrap_in_quotes_if_necessary tmp_extension_dir}",
56
+ "--user-data-dir=#{Platform.wrap_in_quotes_if_necessary tmp_profile_dir}",
57
+ "--activate-on-launch",
58
+ "--disable-hang-monitor",
59
+ "--disable-popup-blocking",
60
+ "--disable-prompt-on-repost",
61
+ "about:blank"
62
+ @process.start
63
+ end
64
+
65
+ def ext_files
66
+ Dir["#{ext_path}/*"]
67
+ end
68
+
69
+ def ext_path
70
+ @ext_path ||= "#{WebDriver.root}/chrome/src/extension"
71
+ end
72
+
73
+ def tmp_extension_dir
74
+ @tmp_extension_dir ||= begin
75
+ dir = Dir.mktmpdir("webdriver-chrome-extension")
76
+ Platform.make_writable(dir)
77
+
78
+ dir
79
+ end
80
+ end
81
+
82
+ def tmp_profile_dir
83
+ @tmp_profile_dir ||= begin
84
+ dir = Dir.mktmpdir("webdriver-chrome-profile")
85
+ Platform.make_writable(dir)
86
+
87
+ dir
88
+ end
89
+ end
90
+
91
+ class WindowsLauncher < Launcher
92
+ def linked_lib_path
93
+ # TODO: x64
94
+ @linked_lib_path ||= "#{WebDriver.root}/chrome/prebuilt/Win32/Release/npchromedriver.dll"
95
+ end
96
+
97
+ def binary_path
98
+ @binary_path ||= "#{Platform.home}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe"
99
+ end
100
+
101
+ end
102
+
103
+ class UnixLauncher < Launcher
104
+ def binary_path
105
+ @binary_path ||= "/usr/bin/google-chrome"
106
+ end
107
+
108
+ end
109
+
110
+ class MacOSXLauncher < UnixLauncher
111
+ def binary_path
112
+ @binary_path ||= "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
113
+ end
114
+ end
115
+
116
+ end # Launcher
117
+ end # Chrome
118
+ end # WebDriver
119
+ end # Selenium
@@ -0,0 +1,161 @@
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 Base class for all WebDriver command processors.
20
+ * @author jmleyba@gmail.com (Jason Leyba)
21
+ */
22
+
23
+ goog.provide('webdriver.AbstractCommandProcessor');
24
+
25
+ goog.require('goog.Disposable');
26
+ goog.require('goog.array');
27
+ goog.require('goog.object');
28
+ goog.require('webdriver.CommandName');
29
+ goog.require('webdriver.Context');
30
+ goog.require('webdriver.Future');
31
+ goog.require('webdriver.Response');
32
+ goog.require('webdriver.timing');
33
+
34
+
35
+ /**
36
+ * Base class for all WebDriver command processors.
37
+ * @constructor
38
+ * @extends {goog.Disposable}
39
+ */
40
+ webdriver.AbstractCommandProcessor = function() {
41
+ goog.Disposable.call(this);
42
+ };
43
+ goog.inherits(webdriver.AbstractCommandProcessor, goog.Disposable);
44
+
45
+
46
+ /**
47
+ * Updates a {@code webdriver.Command} instance so that any parameters that
48
+ * are {@code webdriver.Future} values are converted to their asynchronously set
49
+ * values.
50
+ * @param {webdriver.Command} command The command object to modify.
51
+ * @throws If an attempt is made to fetch the value of a
52
+ * {@code webdriver.Future} that hasn't been computed yet.
53
+ * @private
54
+ */
55
+ webdriver.AbstractCommandProcessor.resolveFutureParams_ = function(
56
+ command) {
57
+ function getValue(obj) {
58
+ if (obj instanceof webdriver.Future) {
59
+ return obj.getValue();
60
+ } else if (goog.isFunction(obj)) {
61
+ return obj;
62
+ } else if (goog.isObject(obj)) {
63
+ goog.object.forEach(obj, function(value, key) {
64
+ obj[key] = getValue(value);
65
+ });
66
+ }
67
+ return obj;
68
+ }
69
+
70
+ command.parameters = goog.array.map(command.parameters, function(param) {
71
+ if (goog.isArray(param)) {
72
+ return goog.array.map(param, getValue);
73
+ } else {
74
+ return getValue(param);
75
+ }
76
+ });
77
+ };
78
+
79
+
80
+ /**
81
+ * Executes a command.
82
+ * @param {webdriver.Command} command The command to execute.
83
+ * @param {string} sessionId The current session ID.
84
+ * @param {webdriver.Context} context The context to execute the command in.
85
+ */
86
+ webdriver.AbstractCommandProcessor.prototype.execute = function(command,
87
+ sessionId,
88
+ context) {
89
+ webdriver.AbstractCommandProcessor.resolveFutureParams_(command);
90
+ switch (command.name) {
91
+ case webdriver.CommandName.SLEEP:
92
+ var ms = command.parameters[0];
93
+ webdriver.timing.setTimeout(function() {
94
+ command.setResponse(new webdriver.Response(false, context, ms));
95
+ }, ms);
96
+ break;
97
+
98
+ case webdriver.CommandName.WAIT:
99
+ var callback = goog.bind(this.waitCallback_, this, command, context);
100
+ command.parameters[0].start(callback);
101
+ break;
102
+
103
+ case webdriver.CommandName.FUNCTION:
104
+ try {
105
+ var result = command.parameters[0]();
106
+ command.setResponse(new webdriver.Response(false, context, result));
107
+ } catch (ex) {
108
+ command.setResponse(new webdriver.Response(true, context, null, ex));
109
+ }
110
+ break;
111
+
112
+ default:
113
+ try {
114
+ this.executeDriverCommand(command, sessionId, context);
115
+ } catch (ex) {
116
+ command.setResponse(new webdriver.Response(true, context, null, ex));
117
+ }
118
+ break;
119
+ }
120
+ };
121
+
122
+
123
+ /**
124
+ * Callback for {@code webdriver.CommandName.WAIT} commands.
125
+ * @param {webdriver.Command} command The wait command.
126
+ * @param {webdriver.Context} context The context the command executed in.
127
+ * @param {boolean} isTimeout Whether the wait finished from a timeout.
128
+ * @param {number} elapsedTime The amount of time spent waiting, in
129
+ * milliseconds.
130
+ * @param {Error} opt_ex If defined, an error that caused the wait to terminate
131
+ * early.
132
+ */
133
+ webdriver.AbstractCommandProcessor.prototype.waitCallback_ = function(
134
+ command, context, isTimeout, elapsedTime, opt_ex) {
135
+ var message;
136
+ if (opt_ex) {
137
+ message = 'Error';
138
+ } else if (isTimeout) {
139
+ message = 'Timeout';
140
+ } else {
141
+ message = 'Ready';
142
+ }
143
+ var response = new webdriver.Response(isTimeout || opt_ex, context,
144
+ message + ' after ' + elapsedTime + 'ms');
145
+ if (opt_ex) {
146
+ response.errors.push(opt_ex);
147
+ }
148
+ command.setResponse(response);
149
+ };
150
+
151
+
152
+ /**
153
+ * Sends a command to be executed by a browser driver. This method must be
154
+ * implemented by each subclass.
155
+ * @param {webdriver.Command} command The command to execute.
156
+ * @param {string} sessionId The current session ID.
157
+ * @param {webdriver.Context} context The context to execute the command in.
158
+ * @protected
159
+ */
160
+ webdriver.AbstractCommandProcessor.prototype.executeDriverCommand =
161
+ goog.abstractMethod;
@@ -0,0 +1,296 @@
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 Assertion functions for use in webdriver test cases.
20
+ * @author jmleyba@gmail.com (Jason Leyba)
21
+ */
22
+
23
+ goog.provide('webdriver.asserts');
24
+
25
+ goog.require('goog.math.Coordinate');
26
+ goog.require('goog.string');
27
+ goog.require('webdriver.Future');
28
+
29
+
30
+ /**
31
+ * @param {webdriver.Future|Object} obj The object to get the value form.
32
+ * @return {*} The value of the given object.
33
+ */
34
+ webdriver.asserts.getValue_ = function(obj) {
35
+ return obj instanceof webdriver.Future ? obj.getValue() : obj;
36
+ };
37
+
38
+
39
+ /**
40
+ * Returns a string with the following format: "<$value> ($type)" where $value
41
+ * is the String representation of the {@code obj} and $type is its type.
42
+ * @param {*} obj The object to build a string for.
43
+ * @return {string} A string describing the given object.
44
+ */
45
+ webdriver.asserts.objToString = function(obj) {
46
+ var value = webdriver.asserts.getValue_(obj);
47
+ var valueStr = goog.isDef(value) ? String(value) : 'undefined';
48
+ return '<' + valueStr + '> (' + goog.typeOf(value) + ')';
49
+ };
50
+
51
+
52
+ /**
53
+ * A class for determining if a value matches a defined criteria.
54
+ * @param {function} matchFn A function that takes a single argument and whether
55
+ * that argument matches the criteria defined by this Matcher.
56
+ * @param {function} describeFn A function that returns a string describing the
57
+ * criteria for this matcher. The string returned by this function should
58
+ * finish this sentence: "Expected to..."
59
+ * @constructor
60
+ */
61
+ webdriver.asserts.Matcher = function(matchFn, describeFn) {
62
+ this.matches = matchFn;
63
+ this.describe = describeFn;
64
+ };
65
+
66
+
67
+ /**
68
+ * Factory method for a {@code webdriver.asserts.Matcher} that does a
69
+ * {@code ===} comparison between the expected and actual values.
70
+ * @param {*} expected The expected value.
71
+ * @return {webdriver.asserts.Matcher} An equality matcher.
72
+ */
73
+ webdriver.asserts.Matcher.equals = function(expected) {
74
+ return new webdriver.asserts.Matcher(
75
+ function (actual) {
76
+ return webdriver.asserts.getValue_(expected) ===
77
+ webdriver.asserts.getValue_(actual);
78
+ },
79
+ function () {
80
+ return 'equal ' + webdriver.asserts.objToString(expected);
81
+ });
82
+ };
83
+ goog.exportSymbol('equals', webdriver.asserts.Matcher.equals);
84
+ goog.exportSymbol('is', webdriver.asserts.Matcher.equals);
85
+
86
+
87
+ /**
88
+ * Creates a {@code webdriver.asserts.Matcher} that tests if the actual
89
+ * value contains the expected value.
90
+ * @param {string} expected The string expected to be in the actual value.
91
+ * @return {webdriver.asserts.Matcher} A new matcher.
92
+ */
93
+ webdriver.asserts.Matcher.contains = function(expected) {
94
+ return new webdriver.asserts.Matcher(
95
+ function (actual) {
96
+ var ev = webdriver.asserts.getValue_(expected);
97
+ var av = webdriver.asserts.getValue_(actual);
98
+ return goog.string.contains(av, ev);
99
+ },
100
+ function () {
101
+ return 'contain ' + webdriver.asserts.objToString(expected);
102
+ });
103
+ };
104
+ goog.exportSymbol('contains', webdriver.asserts.Matcher.contains);
105
+
106
+
107
+ /**
108
+ * Creates a {@code webdriver.asserts.Matcher} that tests if the actual value
109
+ * matches the given regular expression.
110
+ * @param {RegEx} regex The expected regular expression.
111
+ * @return {webdriver.asserts.Matcher} A new matcher.
112
+ */
113
+ webdriver.asserts.Matcher.matchesRegex = function(regex) {
114
+ if (!(regex instanceof RegExp)) {
115
+ throw new Error('IllegalArgument; must be a RegExp, but was: ' + regex +
116
+ '(' + goog.typeOf(regex) + ')');
117
+ }
118
+ return new webdriver.asserts.Matcher(
119
+ function (actual) {
120
+ var av = webdriver.asserts.getValue_(actual);
121
+ return av.match(regex) != null;
122
+ },
123
+ function () {
124
+ return 'match regex ' + regex;
125
+ });
126
+ };
127
+ goog.exportSymbol('matchesRegex', webdriver.asserts.Matcher.matchesRegex);
128
+
129
+
130
+ /**
131
+ * Creates a {@code webdriver.asserts.Matcher} that tests if the actual value
132
+ * starts with the given string.
133
+ * @param {string} expected The expected beginning of the tested string.
134
+ * @return {webdriver.asserts.Matcher} A new matcher.
135
+ */
136
+ webdriver.asserts.Matcher.startsWith = function(expected) {
137
+ return new webdriver.asserts.Matcher(
138
+ function (actual) {
139
+ var ev = webdriver.asserts.getValue_(expected);
140
+ var av = webdriver.asserts.getValue_(actual);
141
+ return goog.string.startsWith(av, ev);
142
+ },
143
+ function () {
144
+ return 'start with ' + webdriver.asserts.objToString(expected);
145
+ });
146
+ };
147
+ goog.exportSymbol('startsWith', webdriver.asserts.Matcher.startsWith);
148
+
149
+
150
+ /**
151
+ * Creates a {@code webdriver.asserts.Matcher} that tests if the actual value is
152
+ * the same location as the expected value.
153
+ * @param {goog.math.Coordinate} expected The expected location, or a future
154
+ * whose pending result is the expected location.
155
+ * @return {webdriver.asserts.Matcher} A new matcher.
156
+ */
157
+ webdriver.asserts.Matcher.isTheSameLocationAs = function(expected) {
158
+ return new webdriver.asserts.Matcher(
159
+ function (actual) {
160
+ var ev = webdriver.asserts.getValue_(expected);
161
+ var av = webdriver.asserts.getValue_(actual);
162
+ return goog.math.Coordinate.equals(ev, av);
163
+ },
164
+ function () {
165
+ return 'equal ' + webdriver.asserts.getValueAndType_(expected);
166
+ });
167
+ }
168
+ goog.exportSymbol('isTheSameLocationAs',
169
+ webdriver.asserts.Matcher.isTheSameLocationAs);
170
+
171
+
172
+ /**
173
+ * Verifies that that given value matches the provided {@code Matcher}. This
174
+ * method has two signatures based on the number of arguments:
175
+ * Two arguments:
176
+ * assertThat(actualValue, matcher)
177
+ * Three arguments:
178
+ * assertThat(failureMessage, actualValue, matcher)
179
+ * @param {string} failureMessage The message to include in the resulting error
180
+ * if actualValue does not match matcher.
181
+ * @param {webdriver.Future|Object} The actual value to verify.
182
+ * @param {webdriver.asserts.Matcher} matcher The object to match the actual
183
+ * value against. If not an instanceof {@code webdriver.Matcher}, will
184
+ * default to the matcher returned by the {@code webdriver.equals} factory
185
+ * function.
186
+ */
187
+ webdriver.asserts.assertThat = function(a, b, opt_c) {
188
+ var args = goog.array.slice(arguments, 0);
189
+ var message = args.length > 2 ? (args[0] + '\n') : '';
190
+ var future = args.length > 2 ? args[1] : args[0];
191
+
192
+ var matcher = args.length > 2 ? args[2] : args[1];
193
+ if (!(matcher instanceof webdriver.asserts.Matcher)) {
194
+ matcher = webdriver.asserts.Matcher.equals(matcher);
195
+ }
196
+
197
+ var doAssertion = function() {
198
+ if (!matcher.matches(future)) {
199
+ throw new Error(message +
200
+ 'Expected to ' + matcher.describe() +
201
+ '\n but was ' + webdriver.asserts.objToString(future));
202
+ }
203
+ }
204
+
205
+ if (future instanceof webdriver.Future) {
206
+ // Schedule a function with the Future's controlling driver so the value
207
+ // is verified after it has been set.
208
+ future.getDriver().callFunction(doAssertion);
209
+ } else {
210
+ doAssertion();
211
+ }
212
+ };
213
+ goog.exportSymbol('assertThat', webdriver.asserts.assertThat);
214
+
215
+
216
+ // ----------------------------------------------------------------------------
217
+ // Define some common xUnit paradigm assertion functions, but do not override
218
+ // any pre-existing function (e.g. if the jsapi is being used with the jsunit
219
+ // library.
220
+ // ----------------------------------------------------------------------------
221
+
222
+ goog.global.fail = goog.global.fail || function(opt_msg) {
223
+ var msg = 'Call to fail()';
224
+ if (opt_msg) {
225
+ msg += ': ' + opt_msg;
226
+ }
227
+ throw new Error(msg);
228
+ };
229
+
230
+
231
+ goog.global.assertEquals = goog.global.assertEquals || function(a, b, opt_c) {
232
+ var args = goog.array.slice(arguments, 0);
233
+ var msg = args.length > 2 ? args[0] : '';
234
+ var expected = args.length > 2 ? args[1] : args[0];
235
+ var actual = args.length > 2 ? args[2] : args[1];
236
+ if (expected !== actual) {
237
+ webdriver.asserts.assertThat(msg, actual, equals(expected));
238
+ }
239
+ };
240
+
241
+
242
+ goog.global.assertTrue = goog.global.assertTrue || function(a, opt_b) {
243
+ var args = goog.array.slice(arguments, 0);
244
+ if (args.length > 1) {
245
+ goog.global.assertEquals(args[0], true, args[1]);
246
+ } else {
247
+ goog.global.assertEquals(true, args[0]);
248
+ }
249
+ };
250
+
251
+
252
+ goog.global.assertFalse = goog.global.assertFalse || function(a, opt_b) {
253
+ var args = goog.array.slice(arguments, 0);
254
+ if (args.length > 1) {
255
+ goog.global.assertEquals(args[0], false, args[1]);
256
+ } else {
257
+ goog.global.assertEquals(false, args[0]);
258
+ }
259
+ };
260
+
261
+
262
+ /**
263
+ * Utility function for inverting a value. If the input is a...
264
+ * <ul>
265
+ * <li>{@code webdriver.asserts.Matcher}, returns a new Matcher that inverts
266
+ * the result of the input</li>
267
+ * <li>{@code webdriver.Future}, returns a new Future whose result will be the
268
+ * inverse of hte input</li>
269
+ * <li>any other type of object, it will be converted to a boolean and
270
+ * inverted</li>
271
+ * </ul>
272
+ * @param {*) input The value to invert.
273
+ * @return {webdriver.asserts.Matcher|webdriver.Future|boolean} The inverted
274
+ * value according to the rules defined above.
275
+ */
276
+ webdriver.not = function(input) {
277
+ if (input instanceof webdriver.Future) {
278
+ var invertedFuture = new webdriver.Future(input.getDriver());
279
+ goog.events.listen(input, goog.events.EventType.CHANGE,
280
+ function() {
281
+ invertedFuture.setValue(!!!input.getValue());
282
+ });
283
+ return invertedFuture;
284
+ } else if (input instanceof webdriver.asserts.Matcher) {
285
+ return new webdriver.asserts.Matcher(
286
+ function (actual) {
287
+ return !input.matches(actual);
288
+ },
289
+ function () {
290
+ return 'not ' + input.describe();
291
+ });
292
+ } else {
293
+ return !!!value;
294
+ }
295
+ };
296
+ goog.exportSymbol('not', webdriver.not);