Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change interface to stem from wrapped driver.
- Loading branch information
1 parent
594bd47
commit cac5f25
Showing
12 changed files
with
618 additions
and
747 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
'use strict' | ||
|
||
/* ----------------------------------------------------------------------------- | ||
* dependencies | ||
* -------------------------------------------------------------------------- */ | ||
|
||
// 3rd party | ||
const wd = require('selenium-webdriver') | ||
|
||
// lib | ||
const Finder = require('./finder') | ||
|
||
/* ----------------------------------------------------------------------------- | ||
* private | ||
* -------------------------------------------------------------------------- */ | ||
|
||
const elementWaitMethods = new Set([ | ||
'elementIsEnabled', | ||
'elementIsDisabled', | ||
'elementIsSelected', | ||
'elementIsNotSelected', | ||
'elementIsVisible', | ||
'elementIsNotVisible', | ||
'stalenessOf', | ||
'elementTextContains', | ||
'elementTextIs', | ||
'elementTextMatches', | ||
'elementLocated' | ||
]) | ||
|
||
/* ----------------------------------------------------------------------------- | ||
* El | ||
* -------------------------------------------------------------------------- */ | ||
|
||
module.exports = class Driver extends Finder { | ||
|
||
get elementWaitMethods () { | ||
return elementWaitMethods | ||
} | ||
|
||
constructor (driver) { | ||
super(driver) | ||
this._driver = driver | ||
|
||
return this.proxyTo('_driver') | ||
} | ||
|
||
/* --------------------------------------------------------------------------- | ||
* actions | ||
* ------------------------------------------------------------------------ */ | ||
|
||
refresh () { | ||
return this._driver.navigate().refresh() | ||
} | ||
|
||
/* --------------------------------------------------------------------------- | ||
* wait | ||
* ------------------------------------------------------------------------ */ | ||
|
||
wait () { | ||
return this._driver.wait.apply(this._driver, arguments).then((result) => { | ||
return result instanceof wd.WebElement | ||
? this._createFromEl(result) | ||
: result | ||
}) | ||
} | ||
|
||
waitUntil (name, ...args) { | ||
// if a wd el is passed -> parse it into a raw WebElement | ||
if (args[0] && args[0]._el) { | ||
args[0] = args[0]._el | ||
} | ||
|
||
if (!this.elementWaitMethods.has(name) || args[0] instanceof wd.WebElement) { | ||
return this.wait(wd.until[name](...args)) | ||
} | ||
|
||
return this.find(args[0]) | ||
.then((el) => this.waitUntil(name, ...[el].concat(args.slice(1)))) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
'use strict' | ||
|
||
/* ----------------------------------------------------------------------------- | ||
* dependencies | ||
* -------------------------------------------------------------------------- */ | ||
|
||
// 3rd party | ||
const _ = require('lodash') | ||
const Promise = require('bluebird') | ||
|
||
/* ----------------------------------------------------------------------------- | ||
* El | ||
* -------------------------------------------------------------------------- */ | ||
|
||
module.exports = class Finder { | ||
|
||
static lookupUsing (primitives) { | ||
this.primitives = primitives | ||
} | ||
|
||
static createUsing (driver) { | ||
this.driver = driver | ||
} | ||
|
||
get children () { | ||
return {} | ||
} | ||
|
||
constructor (root) { | ||
this.root = root | ||
this.primitives = this.constructor.primitives | ||
this.driver = this.constructor.driver | ||
this.definitions = _.mapValues(this.children, this._parseChild) | ||
|
||
// alias | ||
this.find = this.findElement | ||
this.findAll = this.findElements | ||
} | ||
|
||
proxyTo (key) { | ||
return new Proxy(this, { | ||
get: (target, name) => name in target ? target[name] : target[key][name] | ||
}) | ||
} | ||
|
||
/* --------------------------------------------------------------------------- | ||
* find methods | ||
* ------------------------------------------------------------------------ */ | ||
|
||
findElement (_by, _options) { | ||
const { by, options } = this._normalizeFindArgs(_by, _options) | ||
|
||
return this.root.findElement(this._normalizeBy(by)) | ||
.then((el) => this._createFromEl(el, options)) | ||
} | ||
|
||
findElements (_by, _options) { | ||
const { by, options } = this._normalizeFindArgs(_by, _options) | ||
|
||
return this.root.findElements(this._normalizeBy(by)) | ||
.then((els) => Promise.map(els, (el) => this._createFromEl(el, options))) | ||
} | ||
|
||
findLast (by, options) { | ||
return this.findElements(by, options) | ||
.then((els) => _.last(els)) | ||
} | ||
|
||
findNth (by, n, options) { | ||
return this.findElements(by, options) | ||
.then((els) => els[n]) | ||
} | ||
|
||
/* --------------------------------------------------------------------------- | ||
* utils | ||
* ------------------------------------------------------------------------ */ | ||
|
||
_normalizeFindArgs (by, options) { | ||
if (_.isString(by) && by.startsWith('@child.') && this.definitions) { | ||
return this._normalizeFromDefinition(by, options) | ||
} | ||
|
||
return { | ||
by: this._normalizeBy(by), | ||
options: options | ||
} | ||
} | ||
|
||
_normalizeFromDefinition (by, options) { | ||
const definition = this.definitions[by.split('@child.')[1]] | ||
|
||
if (_.isUndefined(definition)) { | ||
throw new Error(`No child found by the name: ${by}`) | ||
} | ||
|
||
return { | ||
by: this._normalizeBy(definition.by), | ||
options: _.assign({}, _.omit(definition, 'by'), options) | ||
} | ||
} | ||
|
||
_normalizeBy (by) { | ||
if (_.isFunction(by) || _.isObject(by)) { | ||
return by | ||
} else if (_.isString(by)) { | ||
return { css: by } | ||
} else { | ||
throw new Error(`Unreconized lookup value`) | ||
} | ||
} | ||
|
||
_createFromEl (el, options = {}) { | ||
if (options.Class) { | ||
return Promise.resolve(new options.Class(el, options)) | ||
} | ||
|
||
return this.primitives.findByEl(el) | ||
.then((Class) => new Class(el, options)) | ||
} | ||
|
||
_parseChild (raw) { | ||
let definition | ||
|
||
if (_.isObject(raw)) { | ||
definition = raw | ||
} else if (_.isString(raw)) { | ||
definition = { by: raw } | ||
} | ||
|
||
if (!definition) { | ||
throw new Error(`Definition type not recognized`) | ||
} else if (!definition.by) { | ||
throw new Error(`Definition must contain lookup property`) | ||
} | ||
|
||
return definition | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.