selenium-webdriver 0.0.24 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. data/{common/src/rb/CHANGES → CHANGES} +13 -0
  2. data/{common/src/rb/README → README} +1 -1
  3. data/{common/src/rb/lib → lib}/selenium-webdriver.rb +0 -0
  4. data/{common/src/rb/lib → lib}/selenium/webdriver.rb +2 -1
  5. data/{common/src/rb/lib → lib}/selenium/webdriver/bridge_helper.rb +0 -0
  6. data/{common/src/rb/lib → lib}/selenium/webdriver/child_process.rb +0 -0
  7. data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome.rb +0 -0
  8. data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/bridge.rb +2 -2
  9. data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/command_executor.rb +0 -0
  10. data/lib/selenium/webdriver/chrome/extension.zip +0 -0
  11. data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/launcher.rb +26 -20
  12. data/{common/src/rb/lib → lib}/selenium/webdriver/core_ext/dir.rb +0 -0
  13. data/{common/src/rb/lib → lib}/selenium/webdriver/core_ext/string.rb +0 -0
  14. data/{common/src/rb/lib → lib}/selenium/webdriver/driver.rb +0 -0
  15. data/{common/src/rb/lib → lib}/selenium/webdriver/driver_extensions/takes_screenshot.rb +0 -0
  16. data/{common/src/rb/lib → lib}/selenium/webdriver/element.rb +0 -0
  17. data/{common/src/rb/lib → lib}/selenium/webdriver/error.rb +0 -0
  18. data/{common/src/rb/lib → lib}/selenium/webdriver/file_reaper.rb +2 -1
  19. data/{common/src/rb/lib → lib}/selenium/webdriver/find.rb +0 -0
  20. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox.rb +2 -1
  21. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/binary.rb +32 -6
  22. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/bridge.rb +0 -0
  23. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  24. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/launcher.rb +0 -0
  25. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  26. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  27. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/profile.rb +37 -72
  28. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/profiles_ini.rb +0 -0
  29. data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/util.rb +0 -0
  30. data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie.rb +2 -2
  31. data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/bridge.rb +7 -2
  32. data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/lib.rb +0 -0
  33. data/{jobbie/prebuilt/Win32/Release → lib/selenium/webdriver/ie/native/win32}/InternetExplorerDriver.dll +0 -0
  34. data/lib/selenium/webdriver/ie/native/x64/InternetExplorerDriver.dll +0 -0
  35. data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/util.rb +0 -0
  36. data/{common/src/rb/lib → lib}/selenium/webdriver/keys.rb +0 -0
  37. data/{common/src/rb/lib → lib}/selenium/webdriver/navigation.rb +0 -0
  38. data/{common/src/rb/lib → lib}/selenium/webdriver/options.rb +0 -0
  39. data/{common/src/rb/lib → lib}/selenium/webdriver/platform.rb +5 -1
  40. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote.rb +0 -0
  41. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/bridge.rb +0 -0
  42. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/capabilities.rb +0 -0
  43. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/commands.rb +0 -0
  44. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/common.rb +0 -0
  45. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/curb.rb +0 -0
  46. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/default.rb +5 -1
  47. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/response.rb +0 -0
  48. data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/server_error.rb +0 -0
  49. data/{common/src/rb/lib → lib}/selenium/webdriver/target_locator.rb +0 -0
  50. data/{common/src/rb/lib → lib}/selenium/webdriver/timeouts.rb +0 -0
  51. data/lib/selenium/webdriver/zip_helper.rb +30 -0
  52. metadata +73 -214
  53. data/COPYING +0 -204
  54. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  55. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  56. data/chrome/src/extension/background.html +0 -9
  57. data/chrome/src/extension/background.js +0 -1029
  58. data/chrome/src/extension/content_script.js +0 -1488
  59. data/chrome/src/extension/icons/busy.png +0 -0
  60. data/chrome/src/extension/icons/free.png +0 -0
  61. data/chrome/src/extension/manifest-nonwin.json +0 -19
  62. data/chrome/src/extension/manifest-win.json +0 -20
  63. data/chrome/src/extension/utils.js +0 -231
  64. data/common/src/js/abstractcommandprocessor.js +0 -132
  65. data/common/src/js/asserts.js +0 -296
  66. data/common/src/js/by.js +0 -149
  67. data/common/src/js/command.js +0 -380
  68. data/common/src/js/core/Blank.html +0 -7
  69. data/common/src/js/core/InjectedRemoteRunner.html +0 -8
  70. data/common/src/js/core/RemoteRunner.html +0 -101
  71. data/common/src/js/core/SeleniumLog.html +0 -109
  72. data/common/src/js/core/TestPrompt.html +0 -145
  73. data/common/src/js/core/TestRunner-splash.html +0 -55
  74. data/common/src/js/core/TestRunner.html +0 -165
  75. data/common/src/js/core/icons/all.png +0 -0
  76. data/common/src/js/core/icons/continue.png +0 -0
  77. data/common/src/js/core/icons/continue_disabled.png +0 -0
  78. data/common/src/js/core/icons/pause.png +0 -0
  79. data/common/src/js/core/icons/pause_disabled.png +0 -0
  80. data/common/src/js/core/icons/selected.png +0 -0
  81. data/common/src/js/core/icons/step.png +0 -0
  82. data/common/src/js/core/icons/step_disabled.png +0 -0
  83. data/common/src/js/core/lib/cssQuery/cssQuery-p.js +0 -6
  84. data/common/src/js/core/lib/cssQuery/src/cssQuery-level2.js +0 -142
  85. data/common/src/js/core/lib/cssQuery/src/cssQuery-level3.js +0 -150
  86. data/common/src/js/core/lib/cssQuery/src/cssQuery-standard.js +0 -53
  87. data/common/src/js/core/lib/cssQuery/src/cssQuery.js +0 -356
  88. data/common/src/js/core/lib/prototype.js +0 -2006
  89. data/common/src/js/core/lib/scriptaculous/builder.js +0 -101
  90. data/common/src/js/core/lib/scriptaculous/controls.js +0 -815
  91. data/common/src/js/core/lib/scriptaculous/dragdrop.js +0 -915
  92. data/common/src/js/core/lib/scriptaculous/effects.js +0 -958
  93. data/common/src/js/core/lib/scriptaculous/scriptaculous.js +0 -47
  94. data/common/src/js/core/lib/scriptaculous/slider.js +0 -283
  95. data/common/src/js/core/lib/scriptaculous/unittest.js +0 -383
  96. data/common/src/js/core/lib/snapsie.js +0 -91
  97. data/common/src/js/core/scripts/find_matching_child.js +0 -69
  98. data/common/src/js/core/scripts/htmlutils.js +0 -8716
  99. data/common/src/js/core/scripts/injection.html +0 -72
  100. data/common/src/js/core/scripts/selenium-api.js +0 -3291
  101. data/common/src/js/core/scripts/selenium-browserbot.js +0 -2457
  102. data/common/src/js/core/scripts/selenium-browserdetect.js +0 -153
  103. data/common/src/js/core/scripts/selenium-commandhandlers.js +0 -379
  104. data/common/src/js/core/scripts/selenium-executionloop.js +0 -175
  105. data/common/src/js/core/scripts/selenium-logging.js +0 -148
  106. data/common/src/js/core/scripts/selenium-remoterunner.js +0 -695
  107. data/common/src/js/core/scripts/selenium-testrunner.js +0 -1362
  108. data/common/src/js/core/scripts/selenium-version.js +0 -5
  109. data/common/src/js/core/scripts/ui-doc.html +0 -808
  110. data/common/src/js/core/scripts/ui-element.js +0 -1644
  111. data/common/src/js/core/scripts/ui-map-sample.js +0 -979
  112. data/common/src/js/core/scripts/user-extensions.js +0 -3
  113. data/common/src/js/core/scripts/user-extensions.js.sample +0 -75
  114. data/common/src/js/core/scripts/xmlextras.js +0 -153
  115. data/common/src/js/core/selenium-logo.png +0 -0
  116. data/common/src/js/core/selenium-test.css +0 -43
  117. data/common/src/js/core/selenium.css +0 -316
  118. data/common/src/js/core/xpath/dom.js +0 -566
  119. data/common/src/js/core/xpath/javascript-xpath-0.1.11.js +0 -2816
  120. data/common/src/js/core/xpath/util.js +0 -549
  121. data/common/src/js/core/xpath/xmltoken.js +0 -149
  122. data/common/src/js/core/xpath/xpath.js +0 -2481
  123. data/common/src/js/extension/README +0 -2
  124. data/common/src/js/extension/dommessenger.js +0 -152
  125. data/common/src/js/factory.js +0 -55
  126. data/common/src/js/future.js +0 -141
  127. data/common/src/js/jsunit.js +0 -40
  128. data/common/src/js/jsunit/app/css/jsUnitStyle.css +0 -50
  129. data/common/src/js/jsunit/app/css/readme +0 -10
  130. data/common/src/js/jsunit/app/emptyPage.html +0 -11
  131. data/common/src/js/jsunit/app/jsUnitCore.js +0 -534
  132. data/common/src/js/jsunit/app/jsUnitMockTimeout.js +0 -81
  133. data/common/src/js/jsunit/app/jsUnitTestManager.js +0 -705
  134. data/common/src/js/jsunit/app/jsUnitTestSuite.js +0 -44
  135. data/common/src/js/jsunit/app/jsUnitTracer.js +0 -102
  136. data/common/src/js/jsunit/app/jsUnitVersionCheck.js +0 -59
  137. data/common/src/js/jsunit/app/main-counts-errors.html +0 -12
  138. data/common/src/js/jsunit/app/main-counts-failures.html +0 -13
  139. data/common/src/js/jsunit/app/main-counts-runs.html +0 -13
  140. data/common/src/js/jsunit/app/main-counts.html +0 -21
  141. data/common/src/js/jsunit/app/main-data.html +0 -178
  142. data/common/src/js/jsunit/app/main-errors.html +0 -23
  143. data/common/src/js/jsunit/app/main-frame.html +0 -19
  144. data/common/src/js/jsunit/app/main-loader.html +0 -45
  145. data/common/src/js/jsunit/app/main-progress.html +0 -25
  146. data/common/src/js/jsunit/app/main-results.html +0 -67
  147. data/common/src/js/jsunit/app/main-status.html +0 -13
  148. data/common/src/js/jsunit/app/testContainer.html +0 -16
  149. data/common/src/js/jsunit/app/testContainerController.html +0 -77
  150. data/common/src/js/jsunit/app/xbDebug.js +0 -306
  151. data/common/src/js/jsunit/changelog.txt +0 -60
  152. data/common/src/js/jsunit/css/jsUnitStyle.css +0 -83
  153. data/common/src/js/jsunit/images/green.gif +0 -0
  154. data/common/src/js/jsunit/images/logo_jsunit.gif +0 -0
  155. data/common/src/js/jsunit/images/powerby-transparent.gif +0 -0
  156. data/common/src/js/jsunit/images/red.gif +0 -0
  157. data/common/src/js/jsunit/licenses/JDOM_license.txt +0 -56
  158. data/common/src/js/jsunit/licenses/Jetty_license.html +0 -213
  159. data/common/src/js/jsunit/licenses/MPL-1.1.txt +0 -470
  160. data/common/src/js/jsunit/licenses/gpl-2.txt +0 -340
  161. data/common/src/js/jsunit/licenses/index.html +0 -141
  162. data/common/src/js/jsunit/licenses/lgpl-2.1.txt +0 -504
  163. data/common/src/js/jsunit/licenses/mpl-tri-license-c.txt +0 -35
  164. data/common/src/js/jsunit/licenses/mpl-tri-license-html.txt +0 -35
  165. data/common/src/js/jsunit/readme.txt +0 -19
  166. data/common/src/js/jsunit/testRunner.html +0 -167
  167. data/common/src/js/jsunit/version.txt +0 -1
  168. data/common/src/js/key.js +0 -117
  169. data/common/src/js/localcommandprocessor.js +0 -171
  170. data/common/src/js/testcase.js +0 -219
  171. data/common/src/js/timing.js +0 -89
  172. data/common/src/js/webdriver.js +0 -860
  173. data/common/src/js/webelement.js +0 -483
  174. data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
  175. data/firefox/prebuilt/amd64/libnoblur64.so +0 -0
  176. data/firefox/prebuilt/i386/libnoblur.so +0 -0
  177. data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
  178. data/firefox/prebuilt/linux64/Release/libwebdriver-firefox.so +0 -0
  179. data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
  180. data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
  181. data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
  182. data/firefox/src/extension/chrome.manifest +0 -3
  183. data/firefox/src/extension/components/badCertListener.js +0 -295
  184. data/firefox/src/extension/components/dispatcher.js +0 -495
  185. data/firefox/src/extension/components/driver-component.js +0 -130
  186. data/firefox/src/extension/components/errorcode.js +0 -70
  187. data/firefox/src/extension/components/firefoxDriver.js +0 -831
  188. data/firefox/src/extension/components/json2.js +0 -273
  189. data/firefox/src/extension/components/keytest.html +0 -554
  190. data/firefox/src/extension/components/nsCommandProcessor.js +0 -684
  191. data/firefox/src/extension/components/promptService.js +0 -208
  192. data/firefox/src/extension/components/request.js +0 -219
  193. data/firefox/src/extension/components/response.js +0 -276
  194. data/firefox/src/extension/components/screenshooter.js +0 -81
  195. data/firefox/src/extension/components/session.js +0 -314
  196. data/firefox/src/extension/components/sessionstore.js +0 -226
  197. data/firefox/src/extension/components/socketListener.js +0 -435
  198. data/firefox/src/extension/components/utils.js +0 -1335
  199. data/firefox/src/extension/components/webLoadingListener.js +0 -57
  200. data/firefox/src/extension/components/webdriverserver.js +0 -110
  201. data/firefox/src/extension/components/wrappedElement.js +0 -706
  202. data/firefox/src/extension/content/fxdriver.xul +0 -30
  203. data/firefox/src/extension/content/server.js +0 -95
  204. data/firefox/src/extension/idl/nsICommandProcessor.idl +0 -38
  205. data/firefox/src/extension/idl/nsIResponseHandler.idl +0 -34
  206. data/firefox/src/extension/install.rdf +0 -29
  207. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
@@ -1,979 +0,0 @@
1
- // sample UI element mapping definition. This is for http://alistapart.com/,
2
- // a particularly well structured site on web design principles.
3
-
4
-
5
-
6
- // in general, the map should capture structural aspects of the system, instead
7
- // of "content". In other words, interactive elements / assertible elements
8
- // that can be counted on to always exist should be defined here. Content -
9
- // for example text or a link that appears in a blog entry - is always liable
10
- // to change, and will not be fun to represent in this way. You probably don't
11
- // want to be testing specific content anyway.
12
-
13
- // create the UI mapping object. THIS IS THE MOST IMPORTANT PART - DON'T FORGET
14
- // TO DO THIS! In order for it to come into play, a user extension must
15
- // construct the map in this way.
16
- var myMap = new UIMap();
17
-
18
-
19
-
20
-
21
- // any values which may appear multiple times can be defined as variables here.
22
- // For example, here we're enumerating a list of top level topics that will be
23
- // used as default argument values for several UI elements. Check out how
24
- // this variable is referenced further down.
25
- var topics = [
26
- 'Code',
27
- 'Content',
28
- 'Culture',
29
- 'Design',
30
- 'Process',
31
- 'User Science'
32
- ];
33
-
34
- // map subtopics to their parent topics
35
- var subtopics = {
36
- 'Browsers': 'Code'
37
- , 'CSS': 'Code'
38
- , 'Flash': 'Code'
39
- , 'HTML and XHTML': 'Code'
40
- , 'Scripting': 'Code'
41
- , 'Server Side': 'Code'
42
- , 'XML': 'Code'
43
- , 'Brand Arts': 'Content'
44
- , 'Community': 'Content'
45
- , 'Writing': 'Content'
46
- , 'Industry': 'Culture'
47
- , 'Politics and Money': 'Culture'
48
- , 'State of the Web': 'Culture'
49
- , 'Graphic Design': 'Design'
50
- , 'User Interface Design': 'Design'
51
- , 'Typography': 'Design'
52
- , 'Layout': 'Design'
53
- , 'Business': 'Process'
54
- , 'Creativity': 'Process'
55
- , 'Project Management and Workflow': 'Process'
56
- , 'Accessibility': 'User Science'
57
- , 'Information Architecture': 'User Science'
58
- , 'Usability': 'User Science'
59
- };
60
-
61
-
62
-
63
- // define UI elements common for all pages. This regular expression does the
64
- // trick. '^' is automatically prepended, and '$' is automatically postpended.
65
- // Please note that because the regular expression is being represented as a
66
- // string, all backslashes must be escaped with an additional backslash. Also
67
- // note that the URL being matched will always have any trailing forward slash
68
- // stripped.
69
- myMap.addPageset({
70
- name: 'allPages'
71
- , description: 'all alistapart.com pages'
72
- , pathRegexp: '.*'
73
- });
74
- myMap.addElement('allPages', {
75
- name: 'masthead'
76
- // the description should be short and to the point, usually no longer than
77
- // a single line
78
- , description: 'top level image link to site homepage'
79
- // make sure the function returns the XPath ... it's easy to leave out the
80
- // "return" statement by accident!
81
- , locator: "xpath=//*[@id='masthead']/a/img"
82
- , testcase1: {
83
- xhtml: '<h1 id="masthead"><a><img expected-result="1" /></a></h1>'
84
- }
85
- });
86
- myMap.addElement('allPages', {
87
- // be VERY CAREFUL to include commas in the correct place. Missing commas
88
- // and extra commas can cause lots of headaches when debugging map
89
- // definition files!!!
90
- name: 'current_issue'
91
- , description: 'top level link to issue currently being browsed'
92
- , locator: "//div[@id='ish']/a"
93
- , testcase1: {
94
- xhtml: '<div id="ish"><a expected-result="1"></a></div>'
95
- }
96
- });
97
- myMap.addElement('allPages', {
98
- name: 'section'
99
- , description: 'top level link to articles section'
100
- , args: [
101
- {
102
- name: 'section'
103
- , description: 'the name of the section'
104
- , defaultValues: [
105
- 'articles'
106
- , 'topics'
107
- , 'about'
108
- , 'contact'
109
- , 'contribute'
110
- , 'feed'
111
- ]
112
- }
113
- ]
114
- // getXPath has been deprecated by getLocator, but verify backward
115
- // compatability here
116
- , getXPath: function(args) {
117
- return "//li[@id=" + args.section.quoteForXPath() + "]/a";
118
- }
119
- , testcase1: {
120
- args: { section: 'feed' }
121
- , xhtml: '<ul><li id="feed"><a expected-result="1" /></li></ul>'
122
- }
123
- });
124
- myMap.addElement('allPages', {
125
- name: 'search_box'
126
- , description: 'site search input field'
127
- // xpath has been deprecated by locator, but verify backward compatability
128
- , xpath: "//input[@id='search']"
129
- , testcase1: {
130
- xhtml: '<input id="search" expected-result="1" />'
131
- }
132
- });
133
- myMap.addElement('allPages', {
134
- name: 'search_discussions'
135
- , description: 'site search include discussions checkbox'
136
- , locator: 'incdisc'
137
- , testcase1: {
138
- xhtml: '<input id="incdisc" expected-result="1" />'
139
- }
140
- });
141
- myMap.addElement('allPages', {
142
- name: 'search_submit'
143
- , description: 'site search submission button'
144
- , locator: 'submit'
145
- , testcase1: {
146
- xhtml: '<input id="submit" expected-result="1" />'
147
- }
148
- });
149
- myMap.addElement('allPages', {
150
- name: 'topics'
151
- , description: 'sidebar links to topic categories'
152
- , args: [
153
- {
154
- name: 'topic'
155
- , description: 'the name of the topic'
156
- , defaultValues: topics
157
- }
158
- ]
159
- , getLocator: function(args) {
160
- return "//div[@id='topiclist']/ul/li" +
161
- "/a[text()=" + args.topic.quoteForXPath() + "]";
162
- }
163
- , testcase1: {
164
- args: { topic: 'foo' }
165
- , xhtml: '<div id="topiclist"><ul><li>'
166
- + '<a expected-result="1">foo</a>'
167
- + '</li></ul></div>'
168
- }
169
- });
170
- myMap.addElement('allPages', {
171
- name: 'copyright'
172
- , description: 'footer link to copyright page'
173
- , getLocator: function(args) { return "//span[@class='copyright']/a"; }
174
- , testcase1: {
175
- xhtml: '<span class="copyright"><a expected-result="1" /></span>'
176
- }
177
- });
178
-
179
-
180
-
181
- // define UI elements for the homepage, i.e. "http://alistapart.com/", and
182
- // magazine issue pages, i.e. "http://alistapart.com/issues/234".
183
- myMap.addPageset({
184
- name: 'issuePages'
185
- , description: 'pages including magazine issues'
186
- , pathRegexp: '(issues/.+)?'
187
- });
188
- myMap.addElement('issuePages', {
189
- name: 'article'
190
- , description: 'front or issue page link to article'
191
- , args: [
192
- {
193
- name: 'index'
194
- , description: 'the index of the article'
195
- // an array of default values for the argument. A default
196
- // value is one that is passed to the getXPath() method of
197
- // the container UIElement object when trying to build an
198
- // element locator.
199
- //
200
- // range() may be used to count easily. Remember though that
201
- // the ending value does not include the right extreme; for
202
- // example range(1, 5) counts from 1 to 4 only.
203
- , defaultValues: range(1, 5)
204
- }
205
- ]
206
- , getLocator: function(args) {
207
- return "//div[@class='item'][" + args.index + "]/h4/a";
208
- }
209
- });
210
- myMap.addElement('issuePages', {
211
- name: 'author'
212
- , description: 'article author link'
213
- , args: [
214
- {
215
- name: 'index'
216
- , description: 'the index of the author, by article'
217
- , defaultValues: range(1, 5)
218
- }
219
- ]
220
- , getLocator: function(args) {
221
- return "//div[@class='item'][" + args.index + "]/h5/a";
222
- }
223
- });
224
- myMap.addElement('issuePages', {
225
- name: 'store'
226
- , description: 'alistapart.com store link'
227
- , locator: "//ul[@id='banners']/li/a[@title='ALA Store']/img"
228
- });
229
- myMap.addElement('issuePages', {
230
- name: 'special_article'
231
- , description: "editor's choice article link"
232
- , locator: "//div[@id='choice']/h4/a"
233
- });
234
- myMap.addElement('issuePages', {
235
- name: 'special_author'
236
- , description: "author link of editor's choice article"
237
- , locator: "//div[@id='choice']/h5/a"
238
- });
239
-
240
-
241
-
242
- // define UI elements for the articles page, i.e.
243
- // "http://alistapart.com/articles"
244
- myMap.addPageset({
245
- name: 'articleListPages'
246
- , description: 'page with article listings'
247
- , paths: [ 'articles' ]
248
- });
249
- myMap.addElement('articleListPages', {
250
- name: 'issue'
251
- , description: 'link to issue'
252
- , args: [
253
- {
254
- name: 'index'
255
- , description: 'the index of the issue on the page'
256
- , defaultValues: range(1, 10)
257
- }
258
- ]
259
- , getLocator: function(args) {
260
- return "//h2[@class='ishinfo'][" + args.index + ']/a';
261
- }
262
- , genericLocator: "//h2[@class='ishinfo']/a"
263
- });
264
- myMap.addElement('articleListPages', {
265
- name: 'article'
266
- , description: 'link to article, by issue and article number'
267
- , args: [
268
- {
269
- name: 'issue_index'
270
- , description: "the index of the article's issue on the page; "
271
- + 'typically five per page'
272
- , defaultValues: range(1, 6)
273
- }
274
- , {
275
- name: 'article_index'
276
- , description: 'the index of the article within the issue; '
277
- + 'typically two per issue'
278
- , defaultValues: range(1, 5)
279
- }
280
- ]
281
- , getLocator: function(args) {
282
- var xpath = "//h2[@class='ishinfo'][" + (args.issue_index || 1) + ']'
283
- + "/following-sibling::div[@class='item']"
284
- + '[' + (args.article_index || 1) + "]/h3[@class='title']/a";
285
- return xpath;
286
- }
287
- , genericLocator: "//h2[@class='ishinfo']"
288
- + "/following-sibling::div[@class='item']/h3[@class='title']/a"
289
- });
290
- myMap.addElement('articleListPages', {
291
- name: 'author'
292
- , description: 'article author link, by issue and article'
293
- , args: [
294
- {
295
- name: 'issue_index'
296
- , description: "the index of the article's issue on the page; \
297
- typically five per page"
298
- , defaultValues: range(1, 6)
299
- }
300
- , {
301
- name: 'article_index'
302
- , description: "the index of the article within the issue; \
303
- typically two articles per issue"
304
- , defaultValues: range(1, 3)
305
- }
306
- ]
307
- // this XPath uses the "following-sibling" axis. The div elements for
308
- // the articles in an issue are not children, but siblings of the h2
309
- // element identifying the article.
310
- , getLocator: function(args) {
311
- var xpath = "//h2[@class='ishinfo'][" + (args.issue_index || 1) + ']'
312
- + "/following-sibling::div[@class='item']"
313
- + '[' + (args.article_index || 1) + "]/h4[@class='byline']/a";
314
- return xpath;
315
- }
316
- , genericLocator: "//h2[@class='ishinfo']"
317
- + "/following-sibling::div[@class='item']/h4[@class='byline']/a"
318
- });
319
- myMap.addElement('articleListPages', {
320
- name: 'next_page'
321
- , description: 'link to next page of articles (older)'
322
- , locator: "//a[contains(text(),'Next page')]"
323
- });
324
- myMap.addElement('articleListPages', {
325
- name: 'previous_page'
326
- , description: 'link to previous page of articles (newer)'
327
- , locator: "//a[contains(text(),'Previous page')]"
328
- });
329
-
330
-
331
-
332
- // define UI elements for specific article pages, i.e.
333
- // "http://alistapart.com/articles/culturalprobe"
334
- myMap.addPageset({
335
- name: 'articlePages'
336
- , description: 'pages for actual articles'
337
- , pathRegexp: 'articles/.+'
338
- });
339
- myMap.addElement('articlePages', {
340
- name: 'title'
341
- , description: 'article title loop-link'
342
- , locator: "//div[@id='content']/h1[@class='title']/a"
343
- });
344
- myMap.addElement('articlePages', {
345
- name: 'author'
346
- , description: 'article author link'
347
- , locator: "//div[@id='content']/h3[@class='byline']/a"
348
- });
349
- myMap.addElement('articlePages', {
350
- name: 'article_topics'
351
- , description: 'links to topics under which article is published, before \
352
- article content'
353
- , args: [
354
- {
355
- name: 'topic'
356
- , description: 'the name of the topic'
357
- , defaultValues: keys(subtopics)
358
- }
359
- ]
360
- , getLocator: function(args) {
361
- return "//ul[@id='metastuff']/li/a"
362
- + "[@title=" + args.topic.quoteForXPath() + "]";
363
- }
364
- });
365
- myMap.addElement('articlePages', {
366
- name: 'discuss'
367
- , description: 'link to article discussion area, before article content'
368
- , locator: "//ul[@id='metastuff']/li[@class='discuss']/p/a"
369
- });
370
- myMap.addElement('articlePages', {
371
- name: 'related_topics'
372
- , description: 'links to topics under which article is published, after \
373
- article content'
374
- , args: [
375
- {
376
- name: 'topic'
377
- , description: 'the name of the topic'
378
- , defaultValues: keys(subtopics)
379
- }
380
- ]
381
- , getLocator: function(args) {
382
- return "//div[@id='learnmore']/p/a"
383
- + "[@title=" + args.topic.quoteForXPath() + "]";
384
- }
385
- });
386
- myMap.addElement('articlePages', {
387
- name: 'join_discussion'
388
- , description: 'link to article discussion area, after article content'
389
- , locator: "//div[@class='discuss']/p/a"
390
- });
391
-
392
-
393
-
394
- myMap.addPageset({
395
- name: 'topicListingPages'
396
- , description: 'top level listing of topics'
397
- , paths: [ 'topics' ]
398
- });
399
- myMap.addElement('topicListingPages', {
400
- name: 'topic'
401
- , description: 'link to topic category'
402
- , args: [
403
- {
404
- name: 'topic'
405
- , description: 'the name of the topic'
406
- , defaultValues: topics
407
- }
408
- ]
409
- , getLocator: function(args) {
410
- return "//div[@id='content']/h2/a"
411
- + "[text()=" + args.topic.quoteForXPath() + "]";
412
- }
413
- });
414
- myMap.addElement('topicListingPages', {
415
- name: 'subtopic'
416
- , description: 'link to subtopic category'
417
- , args: [
418
- {
419
- name: 'subtopic'
420
- , description: 'the name of the subtopic'
421
- , defaultValues: keys(subtopics)
422
- }
423
- ]
424
- , getLocator: function(args) {
425
- return "//div[@id='content']" +
426
- "/descendant::a[text()=" + args.subtopic.quoteForXPath() + "]";
427
- }
428
- });
429
-
430
- // the following few subtopic page UI elements are very similar. Define UI
431
- // elements for the code page, which is a subpage under topics, i.e.
432
- // "http://alistapart.com/topics/code/"
433
- myMap.addPageset({
434
- name: 'subtopicListingPages'
435
- , description: 'pages listing subtopics'
436
- , pathPrefix: 'topics/'
437
- , paths: [
438
- 'code'
439
- , 'content'
440
- , 'culture'
441
- , 'design'
442
- , 'process'
443
- , 'userscience'
444
- ]
445
- });
446
- myMap.addElement('subtopicListingPages', {
447
- name: 'subtopic'
448
- , description: 'link to a subtopic category'
449
- , args: [
450
- {
451
- name: 'subtopic'
452
- , description: 'the name of the subtopic'
453
- , defaultValues: keys(subtopics)
454
- }
455
- ]
456
- , getLocator: function(args) {
457
- return "//div[@id='content']/h2" +
458
- "/a[text()=" + args.subtopic.quoteForXPath() + "]";
459
- }
460
- });
461
-
462
-
463
-
464
- // subtopic articles page
465
- myMap.addPageset({
466
- name: 'subtopicArticleListingPages'
467
- , description: 'pages listing the articles for a given subtopic'
468
- , pathRegexp: 'topics/[^/]+/.+'
469
- });
470
- myMap.addElement('subtopicArticleListingPages', {
471
- name: 'article'
472
- , description: 'link to a subtopic article'
473
- , args: [
474
- {
475
- name: 'index'
476
- , description: 'the index of the article'
477
- , defaultValues: range(1, 51) // the range seems unlimited ...
478
- }
479
- ]
480
- , getLocator: function(args) {
481
- return "//div[@id='content']/div[@class='item']"
482
- + "[" + args.index + "]/h3/a";
483
- }
484
- , testcase1: {
485
- args: { index: 2 }
486
- , xhtml: '<div id="content"><div class="item" /><div class="item">'
487
- + '<h3><a expected-result="1" /></h3></div></div>'
488
- }
489
- });
490
- myMap.addElement('subtopicArticleListingPages', {
491
- name: 'author'
492
- , description: "link to a subtopic article author's page"
493
- , args: [
494
- {
495
- name: 'article_index'
496
- , description: 'the index of the authored article'
497
- , defaultValues: range(1, 51)
498
- }
499
- , {
500
- name: 'author_index'
501
- , description: 'the index of the author when there are multiple'
502
- , defaultValues: range(1, 4)
503
- }
504
- ]
505
- , getLocator: function(args) {
506
- return "//div[@id='content']/div[@class='item'][" +
507
- args.article_index + "]/h4/a[" +
508
- (args.author_index ? args.author_index : '1') + ']';
509
- }
510
- });
511
- myMap.addElement('subtopicArticleListingPages', {
512
- name: 'issue'
513
- , description: 'link to issue a subtopic article appears in'
514
- , args: [
515
- {
516
- name: 'index'
517
- , description: 'the index of the subtopic article'
518
- , defaultValues: range(1, 51)
519
- }
520
- ]
521
- , getLocator: function(args) {
522
- return "//div[@id='content']/div[@class='item']"
523
- + "[" + args.index + "]/h5/a";
524
- }
525
- });
526
-
527
-
528
-
529
- myMap.addPageset({
530
- name: 'aboutPages'
531
- , description: 'the website about page'
532
- , paths: [ 'about' ]
533
- });
534
- myMap.addElement('aboutPages', {
535
- name: 'crew'
536
- , description: 'link to site crew member bio or personal website'
537
- , args: [
538
- {
539
- name: 'role'
540
- , description: 'the role of the crew member'
541
- , defaultValues: [
542
- 'ALA Crew'
543
- , 'Support'
544
- , 'Emeritus'
545
- ]
546
- }
547
- , {
548
- name: 'role_index'
549
- , description: 'the index of the member within the role'
550
- , defaultValues: range(1, 20)
551
- }
552
- , {
553
- name: 'member_index'
554
- , description: 'the index of the member within the role title'
555
- , defaultValues: range(1, 5)
556
- }
557
- ]
558
- , getLocator: function(args) {
559
- // the first role is kind of funky, and requires a conditional to
560
- // build the XPath correctly. Its header looks like this:
561
- //
562
- // <h3>
563
- // <span class="caps">ALA 4</span>.0 <span class="caps">CREW</span>
564
- // </h3>
565
- //
566
- // This kind of complexity is a little daunting, but you can see
567
- // how the format can handle it relatively easily and concisely.
568
- if (args.role == 'ALA Crew') {
569
- var selector = "descendant::text()='CREW'";
570
- }
571
- else {
572
- var selector = "text()=" + args.role.quoteForXPath();
573
- }
574
- var xpath =
575
- "//div[@id='secondary']/h3[" + selector + ']' +
576
- "/following-sibling::dl/dt[" + (args.role_index || 1) + ']' +
577
- '/a[' + (args.member_index || '1') + ']';
578
- return xpath;
579
- }
580
- });
581
-
582
-
583
-
584
- myMap.addPageset({
585
- name: 'searchResultsPages'
586
- , description: 'pages listing search results'
587
- , paths: [ 'search' ]
588
- });
589
- myMap.addElement('searchResultsPages', {
590
- name: 'result_link'
591
- , description: 'search result link'
592
- , args: [
593
- {
594
- name: 'index'
595
- , description: 'the index of the search result'
596
- , defaultValues: range(1, 11)
597
- }
598
- ]
599
- , getLocator: function(args) {
600
- return "//div[@id='content']/ul[" + args.index + ']/li/h3/a';
601
- }
602
- });
603
- myMap.addElement('searchResultsPages', {
604
- name: 'more_results_link'
605
- , description: 'next or previous results link at top or bottom of page'
606
- , args: [
607
- {
608
- name: 'direction'
609
- , description: 'next or previous results page'
610
- // demonstrate a method which acquires default values from the
611
- // document object. Such default values may contain EITHER commas
612
- // OR equals signs, but NOT BOTH.
613
- , getDefaultValues: function(inDocument) {
614
- var defaultValues = [];
615
- var divs = inDocument.getElementsByTagName('div');
616
- for (var i = 0; i < divs.length; ++i) {
617
- if (divs[i].className == 'pages') {
618
- break;
619
- }
620
- }
621
- var links = divs[i].getElementsByTagName('a');
622
- for (i = 0; i < links.length; ++i) {
623
- defaultValues.push(links[i].innerHTML
624
- .replace(/^\xab\s*/, "")
625
- .replace(/\s*\bb$/, "")
626
- .replace(/\s*\d+$/, ""));
627
- }
628
- return defaultValues;
629
- }
630
- }
631
- , {
632
- name: 'position'
633
- , description: 'position of the link'
634
- , defaultValues: ['top', 'bottom']
635
- }
636
- ]
637
- , getLocator: function(args) {
638
- return "//div[@id='content']/div[@class='pages']["
639
- + (args.position == 'top' ? '1' : '2') + ']'
640
- + "/a[contains(text(), "
641
- + (args.direction ? args.direction.quoteForXPath() : undefined)
642
- + ")]";
643
- }
644
- });
645
-
646
-
647
-
648
- myMap.addPageset({
649
- name: 'commentsPages'
650
- , description: 'pages listing comments made to an article'
651
- , pathRegexp: 'comments/.+'
652
- });
653
- myMap.addElement('commentsPages', {
654
- name: 'article_link'
655
- , description: 'link back to the original article'
656
- , locator: "//div[@id='content']/h1[@class='title']/a"
657
- });
658
- myMap.addElement('commentsPages', {
659
- name: 'comment_link'
660
- , description: 'same-page link to comment'
661
- , args: [
662
- {
663
- name: 'index'
664
- , description: 'the index of the comment'
665
- , defaultValues: range(1, 11)
666
- }
667
- ]
668
- , getLocator: function(args) {
669
- return "//div[@class='content']/div[contains(@class, 'comment')]" +
670
- '[' + args.index + ']/h4/a[2]';
671
- }
672
- });
673
- myMap.addElement('commentsPages', {
674
- name: 'paging_link'
675
- , description: 'links to more pages of comments'
676
- , args: [
677
- {
678
- name: 'dest'
679
- , description: 'the destination page'
680
- , defaultValues: ['next', 'prev'].concat(range(1, 16))
681
- }
682
- , {
683
- name: 'position'
684
- , description: 'position of the link'
685
- , defaultValues: ['top', 'bottom']
686
- }
687
- ]
688
- , getLocator: function(args) {
689
- var dest = args.dest;
690
- var xpath = "//div[@id='content']/div[@class='pages']" +
691
- '[' + (args.position == 'top' ? '1' : '2') + ']/p';
692
- if (dest == 'next' || dest == 'prev') {
693
- xpath += "/a[contains(text(), " + dest.quoteForXPath() + ")]";
694
- }
695
- else {
696
- xpath += "/a[text()=" + dest.quoteForXPath() + "]";
697
- }
698
- return xpath;
699
- }
700
- });
701
-
702
-
703
-
704
- myMap.addPageset({
705
- name: 'authorPages'
706
- , description: 'personal pages for each author'
707
- , pathRegexp: 'authors/[a-z]/.+'
708
- });
709
- myMap.addElement('authorPages', {
710
- name: 'article'
711
- , description: "link to article written by this author.\n"
712
- + 'This description has a line break.'
713
- , args: [
714
- {
715
- name: 'index'
716
- , description: 'index of the article on the page'
717
- , defaultValues: range(1, 11)
718
- }
719
- ]
720
- , getLocator: function(args) {
721
- var index = args.index;
722
- // try out the CSS locator!
723
- //return "//h4[@class='title'][" + index + "]/a";
724
- return 'css=h4.title:nth-child(' + index + ') > a';
725
- }
726
- , testcase1: {
727
- args: { index: '2' }
728
- , xhtml: '<h4 class="title" /><h4 class="title">'
729
- + '<a expected-result="1" /></h4>'
730
- }
731
- });
732
-
733
-
734
-
735
- // test the offset locator. Something like the following can be recorded:
736
- // ui=qaPages::content()//a[contains(text(),'May I quote from your articles?')]
737
- myMap.addPageset({
738
- name: 'qaPages'
739
- , description: 'question and answer pages'
740
- , pathRegexp: 'qa'
741
- });
742
- myMap.addElement('qaPages', {
743
- name: 'content'
744
- , description: 'the content pane containing the q&a entries'
745
- , locator: "//div[@id='content' and "
746
- + "child::h1[text()='Questions and Answers']]"
747
- , getOffsetLocator: UIElement.defaultOffsetLocatorStrategy
748
- });
749
- myMap.addElement('qaPages', {
750
- name: 'last_updated'
751
- , description: 'displays the last update date'
752
- // demonstrate calling getLocator() for another UI element within a
753
- // getLocator(). The former must have already been added to the map. And
754
- // obviously, you can't randomly combine different locator types!
755
- , locator: myMap.getUIElement('qaPages', 'content').getLocator() + '/p/em'
756
- });
757
-
758
-
759
-
760
- //******************************************************************************
761
-
762
- var myRollupManager = new RollupManager();
763
-
764
- // though the description element is required, its content is free form. You
765
- // might want to create a documentation policy as given below, where the pre-
766
- // and post-conditions of the rollup are spelled out.
767
- //
768
- // To take advantage of a "heredoc" like syntax for longer descriptions,
769
- // add a backslash to the end of the current line and continue the string on
770
- // the next line.
771
- myRollupManager.addRollupRule({
772
- name: 'navigate_to_subtopic_article_listing'
773
- , description: 'drill down to the listing of articles for a given subtopic \
774
- from the section menu, then the topic itself.'
775
- , pre: 'current page contains the section menu (most pages should)'
776
- , post: 'navigated to the page listing all articles for a given subtopic'
777
- , args: [
778
- {
779
- name: 'subtopic'
780
- , description: 'the subtopic whose article listing to navigate to'
781
- , exampleValues: keys(subtopics)
782
- }
783
- ]
784
- , commandMatchers: [
785
- {
786
- command: 'clickAndWait'
787
- , target: 'ui=allPages::section\\(section=topics\\)'
788
- // must escape parentheses in the the above target, since the
789
- // string is being used as a regular expression. Again, backslashes
790
- // in strings must be escaped too.
791
- }
792
- , {
793
- command: 'clickAndWait'
794
- , target: 'ui=topicListingPages::topic\\(.+'
795
- }
796
- , {
797
- command: 'clickAndWait'
798
- , target: 'ui=subtopicListingPages::subtopic\\(.+'
799
- , updateArgs: function(command, args) {
800
- // don't bother stripping the "ui=" prefix from the locator
801
- // here; we're just using UISpecifier to parse the args out
802
- var uiSpecifier = new UISpecifier(command.target);
803
- args.subtopic = uiSpecifier.args.subtopic;
804
- return args;
805
- }
806
- }
807
- ]
808
- , getExpandedCommands: function(args) {
809
- var commands = [];
810
- var topic = subtopics[args.subtopic];
811
- var subtopic = args.subtopic;
812
- commands.push({
813
- command: 'clickAndWait'
814
- , target: 'ui=allPages::section(section=topics)'
815
- });
816
- commands.push({
817
- command: 'clickAndWait'
818
- , target: 'ui=topicListingPages::topic(topic=' + topic + ')'
819
- });
820
- commands.push({
821
- command: 'clickAndWait'
822
- , target: 'ui=subtopicListingPages::subtopic(subtopic=' + subtopic
823
- + ')'
824
- });
825
- commands.push({
826
- command: 'verifyLocation'
827
- , target: 'regexp:.+/topics/.+/.+'
828
- });
829
- return commands;
830
- }
831
- });
832
-
833
-
834
-
835
- myRollupManager.addRollupRule({
836
- name: 'replace_click_with_clickAndWait'
837
- , description: 'replaces commands where a click was detected with \
838
- clickAndWait instead'
839
- , alternateCommand: 'clickAndWait'
840
- , commandMatchers: [
841
- {
842
- command: 'click'
843
- , target: 'ui=subtopicArticleListingPages::article\\(.+'
844
- }
845
- ]
846
- , expandedCommands: []
847
- });
848
-
849
-
850
-
851
- myRollupManager.addRollupRule({
852
- name: 'navigate_to_subtopic_article'
853
- , description: 'navigate to an article listed under a subtopic.'
854
- , pre: 'current page contains the section menu (most pages should)'
855
- , post: 'navigated to an article page'
856
- , args: [
857
- {
858
- name: 'subtopic'
859
- , description: 'the subtopic whose article listing to navigate to'
860
- , exampleValues: keys(subtopics)
861
- }
862
- , {
863
- name: 'index'
864
- , description: 'the index of the article in the listing'
865
- , exampleValues: range(1, 11)
866
- }
867
- ]
868
- , commandMatchers: [
869
- {
870
- command: 'rollup'
871
- , target: 'navigate_to_subtopic_article_listing'
872
- , value: 'subtopic\\s*=.+'
873
- , updateArgs: function(command, args) {
874
- var args1 = parse_kwargs(command.value);
875
- args.subtopic = args1.subtopic;
876
- return args;
877
- }
878
- }
879
- , {
880
- command: 'clickAndWait'
881
- , target: 'ui=subtopicArticleListingPages::article\\(.+'
882
- , updateArgs: function(command, args) {
883
- var uiSpecifier = new UISpecifier(command.target);
884
- args.index = uiSpecifier.args.index;
885
- return args;
886
- }
887
- }
888
- ]
889
- /*
890
- // this is pretty much equivalent to the commandMatchers immediately above.
891
- // Seems more verbose and less expressive, doesn't it? But sometimes you
892
- // might prefer the flexibility of a function.
893
- , getRollup: function(commands) {
894
- if (commands.length >= 2) {
895
- command1 = commands[0];
896
- command2 = commands[1];
897
- var args1 = parse_kwargs(command1.value);
898
- try {
899
- var uiSpecifier = new UISpecifier(command2.target
900
- .replace(/^ui=/, ''));
901
- }
902
- catch (e) {
903
- return false;
904
- }
905
- if (command1.command == 'rollup' &&
906
- command1.target == 'navigate_to_subtopic_article_listing' &&
907
- args1.subtopic &&
908
- command2.command == 'clickAndWait' &&
909
- uiSpecifier.pagesetName == 'subtopicArticleListingPages' &&
910
- uiSpecifier.elementName == 'article') {
911
- var args = {
912
- subtopic: args1.subtopic
913
- , index: uiSpecifier.args.index
914
- };
915
- return {
916
- command: 'rollup'
917
- , target: this.name
918
- , value: to_kwargs(args)
919
- , replacementIndexes: [ 0, 1 ]
920
- };
921
- }
922
- }
923
- return false;
924
- }
925
- */
926
- , getExpandedCommands: function(args) {
927
- var commands = [];
928
- commands.push({
929
- command: 'rollup'
930
- , target: 'navigate_to_subtopic_article_listing'
931
- , value: to_kwargs({ subtopic: args.subtopic })
932
- });
933
- var uiSpecifier = new UISpecifier(
934
- 'subtopicArticleListingPages'
935
- , 'article'
936
- , { index: args.index });
937
- commands.push({
938
- command: 'clickAndWait'
939
- , target: 'ui=' + uiSpecifier.toString()
940
- });
941
- commands.push({
942
- command: 'verifyLocation'
943
- , target: 'regexp:.+/articles/.+'
944
- });
945
- return commands;
946
- }
947
- });
948
-
949
-
950
-
951
-
952
-
953
-
954
-
955
-
956
-
957
-
958
-
959
-
960
-
961
-
962
-
963
-
964
-
965
-
966
-
967
-
968
-
969
-
970
-
971
-
972
-
973
-
974
-
975
-
976
-
977
-
978
-
979
-