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.
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);