1
1
var elementByRecursion = require ( './element-commands/_elementByRecursion.js' ) ;
2
2
var elementsByRecursion = require ( './element-commands/_elementsByRecursion.js' ) ;
3
+ var Element = require ( '../page-object/element.js' ) ;
3
4
4
5
module . exports = function ( Nightwatch ) {
5
6
@@ -164,35 +165,35 @@ module.exports = function(Nightwatch) {
164
165
* @api protocol
165
166
*/
166
167
Actions . element = function ( using , value , callback ) {
167
- if ( using == 'recursion' ) {
168
- return new elementByRecursion ( Nightwatch ) . command ( value , callback ) ;
168
+
169
+ var elem = Element . fromSelector ( value , using ) ;
170
+
171
+ if ( elem . locateStrategy == 'recursion' ) {
172
+
173
+ // when using recursion, the selector of the element is an
174
+ // array of elements which each need to individually
175
+ // and sequentially get resolved on top of each other
176
+
177
+ return new elementByRecursion ( Nightwatch ) . command ( elem . selector , callback ) ;
169
178
}
170
179
171
- return element ( using , value , callback ) ;
180
+ return element ( elem , callback ) ;
172
181
} ;
173
182
174
183
/*!
175
184
* element protocol action
176
185
*
177
- * @param {string } using
178
- * @param {string } value
186
+ * @param {Object } elem
179
187
* @param {function } callback
180
188
* @private
181
189
*/
182
- function element ( using , value , callback ) {
183
- var strategies = [ 'class name' , 'css selector' , 'id' , 'name' , 'link text' ,
184
- 'partial link text' , 'tag name' , 'xpath' ] ;
185
- using = using . toLocaleLowerCase ( ) ;
190
+ function element ( elem , callback ) {
186
191
187
- if ( strategies . indexOf ( using ) === - 1 ) {
188
- throw new Error ( 'Provided locating strategy is not supported: ' +
189
- using + '. It must be one of the following:\n' +
190
- strategies . join ( ', ' ) ) ;
191
- }
192
+ validateStrategy ( elem . locateStrategy ) ;
192
193
193
194
return postRequest ( '/element' , {
194
- using : using ,
195
- value : value
195
+ using : elem . locateStrategy ,
196
+ value : elem . selector
196
197
} , callback ) ;
197
198
}
198
199
@@ -207,19 +208,14 @@ module.exports = function(Nightwatch) {
207
208
* @api protocol
208
209
*/
209
210
Actions . elementIdElement = function ( id , using , value , callback ) {
210
- var strategies = [ 'class name' , 'css selector' , 'id' , 'name' , 'link text' ,
211
- 'partial link text' , 'tag name' , 'xpath' ] ;
212
- using = using . toLocaleLowerCase ( ) ;
213
211
214
- if ( strategies . indexOf ( using ) === - 1 ) {
215
- throw new Error ( 'Provided locating strategy is not supported: ' +
216
- using + '. It must be one of the following:\n' +
217
- strategies . join ( ', ' ) ) ;
218
- }
212
+ var elem = Element . fromSelector ( value , using ) ;
213
+
214
+ validateStrategy ( elem . locateStrategy ) ;
219
215
220
216
return postRequest ( '/element/' + id + '/element' , {
221
- using : using ,
222
- value : value
217
+ using : elem . locateStrategy ,
218
+ value : elem . selector
223
219
} , callback ) ;
224
220
} ;
225
221
@@ -234,32 +230,37 @@ module.exports = function(Nightwatch) {
234
230
* @api protocol
235
231
*/
236
232
Actions . elements = function ( using , value , callback ) {
237
- if ( using == 'recursion' ) {
238
- return new elementsByRecursion ( Nightwatch ) . command ( value , callback ) ;
233
+
234
+ var elem = Element . fromSelector ( value , using ) ;
235
+
236
+ if ( elem . locateStrategy == 'recursion' ) {
237
+
238
+ // when using recursion, the selector of the element is an
239
+ // array of elements which each need to individually
240
+ // and sequentially get resolved on top of each other
241
+
242
+ return new elementsByRecursion ( Nightwatch ) . command ( elem . selector , callback ) ;
239
243
}
240
244
241
- return elements ( using , value , callback ) ;
245
+ return elements ( elem , callback ) ;
242
246
} ;
243
247
244
248
/*!
245
249
* elements protocol action
246
250
*
247
- * @param {string } using
248
- * @param {string } value
251
+ * @param {Object } elem
249
252
* @param {function } callback
250
253
* @private
251
254
*/
252
- function elements ( using , value , callback ) {
253
- var check = / c l a s s n a m e | c s s s e l e c t o r | i d | n a m e | l i n k t e x t | p a r t i a l l i n k t e x t | t a g n a m e | x p a t h / gi;
254
- if ( ! check . test ( using ) ) {
255
- throw new Error ( 'Please provide any of the following using strings as the first parameter: ' +
256
- 'class name, css selector, id, name, link text, partial link text, tag name, or xpath. Given: ' + using ) ;
257
- }
255
+ function elements ( elem , callback ) {
256
+
257
+ validateStrategy ( elem . locateStrategy ) ;
258
258
259
259
return postRequest ( '/elements' , {
260
- using : using ,
261
- value : value
262
- } , callback ) ;
260
+ using : elem . locateStrategy ,
261
+ value : elem . selector
262
+ } , createIndexedElementCallback ( elem , callback )
263
+ ) ;
263
264
}
264
265
265
266
/**
@@ -273,21 +274,89 @@ module.exports = function(Nightwatch) {
273
274
* @api protocol
274
275
*/
275
276
Actions . elementIdElements = function ( id , using , value , callback ) {
277
+
278
+ var elem = Element . fromSelector ( value , using ) ;
279
+
280
+ validateStrategy ( elem . locateStrategy ) ;
281
+
282
+ return postRequest ( '/element/' + id + '/elements' , {
283
+ using : elem . locateStrategy ,
284
+ value : elem . selector
285
+ } , createIndexedElementCallback ( elem , callback )
286
+ ) ;
287
+ } ;
288
+
289
+ /**
290
+ * Wraps an elements protocol request callback to include logic to select
291
+ * a single element with an index if one was specified.
292
+ * @param {Object } elem
293
+ * @param {function } callback
294
+ * @private
295
+ */
296
+ function createIndexedElementCallback ( elem , callback ) {
297
+ return function ( result ) {
298
+
299
+ var usingIndex = elem . index != undefined ;
300
+ if ( usingIndex && result && result . status === 0 ) {
301
+
302
+ // if an element index is specified, we need to make sure its
303
+ // within the range of elements found. If not, we patch the
304
+ // result to show a failure
305
+
306
+ if ( result . value . length <= elem . index ) {
307
+
308
+ result . status = - 1 ;
309
+
310
+ var errorId = 'NoSuchElement' ;
311
+ var errorInfo = errorById ( errorId ) ;
312
+ if ( errorInfo ) {
313
+ result . message = errorInfo . message ;
314
+ result . errorStatus = errorInfo . status ;
315
+ }
316
+
317
+ } else {
318
+
319
+ // with a valid element index, make the results that element
320
+ // as the first and only result
321
+
322
+ result . value = [ result . value [ elem . index ] ] ;
323
+ }
324
+ }
325
+
326
+ return callback ( result ) ;
327
+ } ;
328
+ }
329
+
330
+ /**
331
+ * Looks up error status info from an id string rather than id number
332
+ */
333
+ function errorById ( id ) {
334
+ var errorCodes = require ( './errors.json' ) ;
335
+ for ( var status in errorCodes ) {
336
+ if ( errorCodes [ status ] . id === id ) {
337
+ return {
338
+ status : status ,
339
+ id : id ,
340
+ message : errorCodes [ status ] . message
341
+ } ;
342
+ }
343
+ }
344
+
345
+ return null ;
346
+ }
347
+
348
+ function validateStrategy ( using ) {
349
+
350
+ var usingLow = String ( using ) . toLocaleLowerCase ( ) ;
276
351
var strategies = [ 'class name' , 'css selector' , 'id' , 'name' , 'link text' ,
277
352
'partial link text' , 'tag name' , 'xpath' ] ;
278
- using = using . toLocaleLowerCase ( ) ;
279
353
280
- if ( strategies . indexOf ( using ) === - 1 ) {
354
+ if ( strategies . indexOf ( usingLow ) === - 1 ) {
281
355
throw new Error ( 'Provided locating strategy is not supported: ' +
282
356
using + '. It must be one of the following:\n' +
283
357
strategies . join ( ', ' ) ) ;
284
358
}
285
-
286
- return postRequest ( '/element/' + id + '/elements' , {
287
- using : using ,
288
- value : value
289
- } , callback ) ;
290
- } ;
359
+ }
291
360
292
361
/**
293
362
* Get the element on the page that currently has focus.
0 commit comments