selenium-webdriver 4.0.0 → 4.1.0

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.
package/io/index.js CHANGED
@@ -19,7 +19,6 @@
19
19
 
20
20
  const fs = require('fs')
21
21
  const path = require('path')
22
- const rimraf = require('rimraf')
23
22
  const tmp = require('tmp')
24
23
 
25
24
  /**
@@ -52,24 +51,16 @@ function checkedCall(fn) {
52
51
  * @return {!Promise} A promise to be resolved when the operation has
53
52
  * completed.
54
53
  */
55
- exports.rmDir = function (dirPath) {
54
+ function rmDir(dirPath) {
56
55
  return new Promise(function (fulfill, reject) {
57
- var numAttempts = 0
58
- attemptRm()
59
- function attemptRm() {
60
- numAttempts += 1
61
- rimraf(dirPath, function (err) {
62
- if (err) {
63
- if (err.code && err.code === 'ENOTEMPTY' && numAttempts < 2) {
64
- attemptRm()
65
- return
66
- }
67
- reject(err)
68
- } else {
69
- fulfill()
70
- }
71
- })
72
- }
56
+ fs.rm(dirPath, { recursive: true, maxRetries: 2 }, function (err) {
57
+ if (err && err.code === 'ENOENT') {
58
+ fulfill()
59
+ } else if (err) {
60
+ reject(err)
61
+ }
62
+ fulfill()
63
+ })
73
64
  })
74
65
  }
75
66
 
@@ -79,12 +70,12 @@ exports.rmDir = function (dirPath) {
79
70
  * @param {string} dst The destination file.
80
71
  * @return {!Promise<string>} A promise for the copied file's path.
81
72
  */
82
- exports.copy = function (src, dst) {
73
+ function copy(src, dst) {
83
74
  return new Promise(function (fulfill, reject) {
84
- var rs = fs.createReadStream(src)
75
+ const rs = fs.createReadStream(src)
85
76
  rs.on('error', reject)
86
77
 
87
- var ws = fs.createWriteStream(dst)
78
+ const ws = fs.createWriteStream(dst)
88
79
  ws.on('error', reject)
89
80
  ws.on('close', () => fulfill(dst))
90
81
 
@@ -102,20 +93,19 @@ exports.copy = function (src, dst) {
102
93
  * @return {!Promise<string>} A promise for the destination
103
94
  * directory's path once all files have been copied.
104
95
  */
105
- exports.copyDir = function (src, dst, opt_exclude) {
106
- var predicate = opt_exclude
96
+ function copyDir(src, dst, opt_exclude) {
97
+ let predicate = opt_exclude
107
98
  if (opt_exclude && typeof opt_exclude !== 'function') {
108
99
  predicate = function (p) {
109
100
  return !opt_exclude.test(p)
110
101
  }
111
102
  }
112
103
 
113
- // TODO(jleyba): Make this function completely async.
114
104
  if (!fs.existsSync(dst)) {
115
105
  fs.mkdirSync(dst)
116
106
  }
117
107
 
118
- var files = fs.readdirSync(src)
108
+ let files = fs.readdirSync(src)
119
109
  files = files.map(function (file) {
120
110
  return path.join(src, file)
121
111
  })
@@ -153,8 +143,7 @@ exports.exists = function (aPath) {
153
143
  if (type !== 'string') {
154
144
  reject(TypeError(`expected string path, but got ${type}`))
155
145
  } else {
156
- // eslint-disable-next-line node/no-deprecated-api
157
- fs.exists(aPath, fulfill)
146
+ fulfill(fs.existsSync(aPath))
158
147
  }
159
148
  })
160
149
  }
@@ -174,18 +163,16 @@ exports.stat = function stat(aPath) {
174
163
  * @param {string} aPath The path to remove.
175
164
  * @return {!Promise} A promise for when the file has been removed.
176
165
  */
177
- exports.unlink = function (aPath) {
166
+ function unlink(aPath) {
178
167
  return new Promise(function (fulfill, reject) {
179
- // eslint-disable-next-line node/no-deprecated-api
180
- fs.exists(aPath, function (exists) {
181
- if (exists) {
182
- fs.unlink(aPath, function (err) {
183
- ;(err && reject(err)) || fulfill()
184
- })
185
- } else {
186
- fulfill()
187
- }
188
- })
168
+ const exists = fs.existsSync(aPath)
169
+ if (exists) {
170
+ fs.unlink(aPath, function (err) {
171
+ ;(err && reject(err)) || fulfill()
172
+ })
173
+ } else {
174
+ fulfill()
175
+ }
189
176
  })
190
177
  }
191
178
 
@@ -193,7 +180,7 @@ exports.unlink = function (aPath) {
193
180
  * @return {!Promise<string>} A promise for the path to a temporary directory.
194
181
  * @see https://www.npmjs.org/package/tmp
195
182
  */
196
- exports.tmpDir = function () {
183
+ function tmpDir() {
197
184
  return checkedCall((callback) => tmp.dir({ unsafeCleanup: true }, callback))
198
185
  }
199
186
 
@@ -202,7 +189,7 @@ exports.tmpDir = function () {
202
189
  * @return {!Promise<string>} A promise for the path to a temporary file.
203
190
  * @see https://www.npmjs.org/package/tmp
204
191
  */
205
- exports.tmpFile = function (opt_options) {
192
+ function tmpFile(opt_options) {
206
193
  return checkedCall((callback) => {
207
194
  /** check fixed in v > 0.2.1 if
208
195
  * (typeof options === 'function') {
@@ -222,7 +209,7 @@ exports.tmpFile = function (opt_options) {
222
209
  * @return {?string} Path to the located file, or {@code null} if it could
223
210
  * not be found.
224
211
  */
225
- exports.findInPath = function (file, opt_checkCwd) {
212
+ function findInPath(file, opt_checkCwd) {
226
213
  const dirs = []
227
214
  if (opt_checkCwd) {
228
215
  dirs.push(process.cwd())
@@ -249,7 +236,7 @@ exports.findInPath = function (file, opt_checkCwd) {
249
236
  * @return {!Promise<!Buffer>} A promise that will resolve with a buffer of the
250
237
  * file contents.
251
238
  */
252
- exports.read = function (aPath) {
239
+ function read(aPath) {
253
240
  return checkedCall((callback) => fs.readFile(aPath, callback))
254
241
  }
255
242
 
@@ -261,7 +248,7 @@ exports.read = function (aPath) {
261
248
  * @return {!Promise} A promise that will resolve when the operation has
262
249
  * completed.
263
250
  */
264
- exports.write = function (aPath, data) {
251
+ function write(aPath, data) {
265
252
  return checkedCall((callback) => fs.writeFile(aPath, data, callback))
266
253
  }
267
254
 
@@ -272,7 +259,7 @@ exports.write = function (aPath, data) {
272
259
  * @return {!Promise<string>} A promise that will resolve with the path of the
273
260
  * created directory.
274
261
  */
275
- exports.mkdir = function (aPath) {
262
+ function mkdir(aPath) {
276
263
  return checkedCall((callback) => {
277
264
  fs.mkdir(aPath, undefined, (err) => {
278
265
  if (err && err.code !== 'EEXIST') {
@@ -291,7 +278,7 @@ exports.mkdir = function (aPath) {
291
278
  * @return {!Promise<string>} A promise that will resolve with the path of the
292
279
  * created directory.
293
280
  */
294
- exports.mkdirp = function mkdirp(dir) {
281
+ function mkdirp(dir) {
295
282
  return checkedCall((callback) => {
296
283
  fs.mkdir(dir, undefined, (err) => {
297
284
  if (!err) {
@@ -327,7 +314,7 @@ exports.mkdirp = function mkdirp(dir) {
327
314
  * resolve with a list of entries seen. For each entry, the recorded path
328
315
  * will be relative to `rootPath`.
329
316
  */
330
- exports.walkDir = function (rootPath) {
317
+ function walkDir(rootPath) {
331
318
  const seen = []
332
319
  return (function walk(dir) {
333
320
  return checkedCall((callback) => fs.readdir(dir, callback)).then((files) =>
@@ -346,3 +333,17 @@ exports.walkDir = function (rootPath) {
346
333
  )
347
334
  })(rootPath).then(() => seen)
348
335
  }
336
+
337
+ // PUBLIC API
338
+ module.exports.walkDir = walkDir
339
+ module.exports.rmDir = rmDir
340
+ module.exports.mkdirp = mkdirp
341
+ module.exports.mkdir = mkdir
342
+ module.exports.write = write
343
+ module.exports.read = read
344
+ module.exports.findInPath = findInPath
345
+ module.exports.tmpFile = tmpFile
346
+ module.exports.tmpDir = tmpDir
347
+ module.exports.unlink = unlink
348
+ module.exports.copy = copy
349
+ module.exports.copyDir = copyDir
@@ -109,8 +109,8 @@ function gd(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4
109
109
  function hd(a){return a.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,"")}function id(a){var b=[];Yc?jd(a,b):kd(a,b);a=qa(b,hd);return hd(a.join("\n")).replace(/\xa0/g," ")}
110
110
  function ld(a,b,c){if(S(a,"BR"))b.push("");else{var d=S(a,"TD"),e=V(a,"display"),f=!d&&!(0<=oa(md,e)),g=void 0!==a.previousElementSibling?a.previousElementSibling:gb(a.previousSibling);g=g?V(g,"display"):"";var h=V(a,"float")||V(a,"cssFloat")||V(a,"styleFloat");!f||"run-in"==g&&"none"==h||/^[\s\xa0]*$/.test(b[b.length-1]||"")||b.push("");var n=ed(a),u=null,p=null;n&&(u=V(a,"white-space"),p=V(a,"text-transform"));l(a.childNodes,function(G){c(G,b,n,u,p)});a=b[b.length-1]||"";!d&&"table-cell"!=e||!a||
111
111
  za(a)||(b[b.length-1]+=" ");f&&"run-in"!=e&&!/^[\s\xa0]*$/.test(a)&&b.push("")}}function kd(a,b){ld(a,b,function(c,d,e,f,g){3==c.nodeType&&e?nd(c,d,f,g):S(c)&&kd(c,d)})}var md="inline inline-block inline-table none table-cell table-column table-column-group".split(" ");
112
- function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));
113
- b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
112
+ function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(t?/(^|\s|\b)(\S)/g:/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",
113
+ 0)&&(a=a.substr(1));b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
114
114
  function pd(a,b,c,d,e){if(3==a.nodeType&&c)nd(a,b,d,e);else if(S(a))if(S(a,"CONTENT")||S(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=S(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),l(a,function(g){pd(g,b,c,d,e)})):jd(a,b)}else if(S(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)l(a.childNodes,function(g){pd(g,b,c,d,e)}),a=a.olderShadowRoot}else jd(a,b)}
115
115
  function jd(a,b){a.shadowRoot&&l(a.shadowRoot.childNodes,function(c){pd(c,b,!0,null,null)});ld(a,b,function(c,d,e,f,g){var h=null;1==c.nodeType?h=c:3==c.nodeType&&(h=c);null!=h&&(null!=h.assignedSlot||h.getDestinationInsertionPoints&&0<h.getDestinationInsertionPoints().length)||pd(c,d,e,f,g)})};var qd={C:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=eb(b),d="string"===typeof a?c.a.getElementById(a):a;return d?Uc(d,"id")==a&&b!=d&&hb(b,d)?d:ua(mb(c,"*"),function(e){return Uc(e,"id")==a&&b!=e&&hb(b,e)}):null},j:function(a,b){if(!a)return[];if(qd.C(b,a))try{return b.querySelectorAll("#"+qd.T(a))}catch(c){return[]}b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"id")==a})},T:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
116
116
  "\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)};
package/lib/by.js CHANGED
@@ -190,11 +190,9 @@ class By {
190
190
  * @return {function(!./webdriver.WebDriver): !Promise}
191
191
  * A new JavaScript-based locator function.
192
192
  */
193
- static js(script, var_args) { // eslint-disable-line
194
- // eslint-disable-line
195
- let args = Array.prototype.slice.call(arguments, 0)
193
+ static js(script, ...var_args) {
196
194
  return function (driver) {
197
- return driver.executeScript.apply(driver, args)
195
+ return driver.executeScript.call(driver, script, ...var_args)
198
196
  }
199
197
  }
200
198
 
@@ -277,7 +275,7 @@ function withTagName(tagName) {
277
275
  * @returns {RelativeBy}
278
276
  */
279
277
  function locateWith(by) {
280
- return new RelativeBy(getLocator(by));
278
+ return new RelativeBy(getLocator(by))
281
279
  }
282
280
 
283
281
  function getLocator(locatorOrElement) {
@@ -431,4 +429,5 @@ module.exports = {
431
429
  withTagName: withTagName,
432
430
  locateWith: locateWith,
433
431
  checkedLocator: check,
432
+ escapeCss: escapeCss
434
433
  }
@@ -83,7 +83,7 @@ const Platform = {
83
83
  *
84
84
  * @record
85
85
  */
86
- function Timeouts() { }
86
+ function Timeouts() {}
87
87
 
88
88
  /**
89
89
  * Defines when, in milliseconds, to interrupt a script that is being
package/lib/command.js CHANGED
@@ -168,6 +168,11 @@ const Name = {
168
168
  GET_ALERT_TEXT: 'getAlertText',
169
169
  SET_ALERT_TEXT: 'setAlertValue',
170
170
 
171
+ // Shadow DOM Commands
172
+ GET_SHADOW_ROOT: 'getShadowRoot',
173
+ FIND_ELEMENT_FROM_SHADOWROOT: 'findElementFromShadowRoot',
174
+ FIND_ELEMENTS_FROM_SHADOWROOT: 'findElementsFromShadowRoot',
175
+
171
176
  GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes',
172
177
  GET_LOG: 'getLog',
173
178
  GET_SESSION_LOGS: 'getSessionLogs',
package/lib/error.js CHANGED
@@ -39,6 +39,16 @@ class WebDriverError extends Error {
39
39
  }
40
40
  }
41
41
 
42
+ /**
43
+ * Indicates the shadow root is no longer attached to the DOM
44
+ */
45
+ class DetachedShadowRootError extends WebDriverError {
46
+ /** @param {string=} opt_error the error message, if any. */
47
+ constructor(opt_error) {
48
+ super(opt_error)
49
+ }
50
+ }
51
+
42
52
  /**
43
53
  * Indicates a {@linkplain ./webdriver.WebElement#click click command} could not
44
54
  * completed because the click target is obscured by other elements on the
@@ -201,6 +211,16 @@ class NoSuchElementError extends WebDriverError {
201
211
  }
202
212
  }
203
213
 
214
+ /**
215
+ * A ShadowRoot could not be located on the element
216
+ */
217
+ class NoSuchShadowRootError extends WebDriverError {
218
+ /** @param {string=} opt_error the error message, if any. */
219
+ constructor(opt_error) {
220
+ super(opt_error);
221
+ }
222
+ }
223
+
204
224
  /**
205
225
  * A request to switch to a frame could not be satisfied because the frame
206
226
  * could not be found.
@@ -420,6 +440,7 @@ const LEGACY_ERROR_CODE_TO_TYPE = new Map([
420
440
 
421
441
  const ERROR_CODE_TO_TYPE = new Map([
422
442
  ['unknown error', WebDriverError],
443
+ ['detached shadow root', DetachedShadowRootError],
423
444
  ['element click intercepted', ElementClickInterceptedError],
424
445
  ['element not interactable', ElementNotInteractableError],
425
446
  ['element not selectable', ElementNotSelectableError],
@@ -436,6 +457,7 @@ const ERROR_CODE_TO_TYPE = new Map([
436
457
  ['no such cookie', NoSuchCookieError],
437
458
  ['no such element', NoSuchElementError],
438
459
  ['no such frame', NoSuchFrameError],
460
+ ['no such shadow root', NoSuchShadowRootError],
439
461
  ['no such window', NoSuchWindowError],
440
462
  ['script timeout', ScriptTimeoutError],
441
463
  ['session not created', SessionNotCreatedError],
@@ -569,6 +591,7 @@ module.exports = {
569
591
  ErrorCode,
570
592
 
571
593
  WebDriverError,
594
+ DetachedShadowRootError,
572
595
  ElementClickInterceptedError,
573
596
  ElementNotInteractableError,
574
597
  ElementNotSelectableError,
@@ -584,6 +607,7 @@ module.exports = {
584
607
  NoSuchCookieError,
585
608
  NoSuchElementError,
586
609
  NoSuchFrameError,
610
+ NoSuchShadowRootError,
587
611
  NoSuchSessionError,
588
612
  NoSuchWindowError,
589
613
  ScriptTimeoutError,
package/lib/http.js CHANGED
@@ -31,7 +31,7 @@ const error = require('./error')
31
31
  const logging = require('./logging')
32
32
  const promise = require('./promise')
33
33
  const { Session } = require('./session')
34
- const { WebElement } = require('./webdriver')
34
+ const { WebElement, ShadowRoot } = require('./webdriver')
35
35
 
36
36
  const getAttribute = requireAtom(
37
37
  'get-attribute.js',
@@ -63,8 +63,8 @@ function requireAtom(module, bazelTarget) {
63
63
  console.log(ex2)
64
64
  throw Error(
65
65
  `Failed to import atoms module ${module}. If running in dev mode, you` +
66
- ` need to run \`bazel build ${bazelTarget}\` from the project` +
67
- `root: ${ex}`
66
+ ` need to run \`bazel build ${bazelTarget}\` from the project` +
67
+ `root: ${ex}`
68
68
  )
69
69
  }
70
70
  }
@@ -173,7 +173,7 @@ var CommandSpec // eslint-disable-line
173
173
  /** @typedef {function(!cmd.Command): !cmd.Command} */
174
174
  var CommandTransformer // eslint-disable-line
175
175
 
176
- class InternalTypeError extends TypeError {}
176
+ class InternalTypeError extends TypeError { }
177
177
 
178
178
  /**
179
179
  * @param {!cmd.Command} command The initial command.
@@ -421,6 +421,10 @@ const W3C_COMMAND_MAP = new Map([
421
421
  ],
422
422
  // print page.
423
423
  [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],
424
+ // Shadow Root
425
+ [cmd.Name.GET_SHADOW_ROOT, get('/session/:sessionId/element/:id/shadow')],
426
+ [cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/element')],
427
+ [cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT, post('/session/:sessionId/shadow/:id/elements')],
424
428
  // Log extensions.
425
429
  [cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],
426
430
  [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/se/log/types')],
@@ -441,7 +445,7 @@ class Client {
441
445
  * @return {!Promise<Response>} A promise that will be fulfilled with the
442
446
  * server's response.
443
447
  */
444
- send(httpRequest) {} // eslint-disable-line
448
+ send(httpRequest) { } // eslint-disable-line
445
449
  }
446
450
 
447
451
  /**
@@ -584,7 +588,7 @@ class Executor {
584
588
  // No implementations use the `capabilities` key yet...
585
589
  let capabilities = value.capabilities || value.value
586
590
  return new Session(
587
- /** @type {{sessionId: string}} */ (value).sessionId,
591
+ /** @type {{sessionId: string}} */(value).sessionId,
588
592
  capabilities
589
593
  )
590
594
  }
package/lib/until.js CHANGED
@@ -137,13 +137,14 @@ exports.alertIsPresent = function alertIsPresent() {
137
137
  * @return {!Condition<boolean>} The new condition.
138
138
  */
139
139
  exports.titleIs = function titleIs(title) {
140
- return new Condition('for title to be ' + JSON.stringify(title), function (
141
- driver
142
- ) {
143
- return driver.getTitle().then(function (t) {
144
- return t === title
145
- })
146
- })
140
+ return new Condition(
141
+ 'for title to be ' + JSON.stringify(title),
142
+ function (driver) {
143
+ return driver.getTitle().then(function (t) {
144
+ return t === title
145
+ })
146
+ }
147
+ )
147
148
  }
148
149
 
149
150
  /**
@@ -188,13 +189,14 @@ exports.titleMatches = function titleMatches(regex) {
188
189
  * @return {!Condition<boolean>} The new condition.
189
190
  */
190
191
  exports.urlIs = function urlIs(url) {
191
- return new Condition('for URL to be ' + JSON.stringify(url), function (
192
- driver
193
- ) {
194
- return driver.getCurrentUrl().then(function (u) {
195
- return u === url
196
- })
197
- })
192
+ return new Condition(
193
+ 'for URL to be ' + JSON.stringify(url),
194
+ function (driver) {
195
+ return driver.getCurrentUrl().then(function (u) {
196
+ return u === url
197
+ })
198
+ }
199
+ )
198
200
  }
199
201
 
200
202
  /**