nemo-view
Advanced tools
Comparing version 3.0.0-alpha.3 to 3.0.0
# nemo-view changelog | ||
## v3.0.0 | ||
* publish major version (tag=se3) | ||
## v3.0.0-alpha | ||
@@ -7,2 +11,16 @@ | ||
## v2.2.2 | ||
* add back package-lock.json after reading docs https://docs.npmjs.com/files/package-lock.json (reading docs is good) | ||
## v2.2.1 | ||
* remove package-lock.json | ||
## v2.2.0 | ||
* Adding the ability to select options by value and text as generic methods | ||
* Updated documentation to describe element list functionality | ||
* es6 changes | ||
## v2.1.2 | ||
@@ -9,0 +27,0 @@ |
'use strict'; | ||
module.exports = function (nemo) { | ||
module.exports = nemo => { | ||
return function locatex(locatorJSON) { | ||
var locale = nemo._config.get('data:locale') || 'default'; | ||
var localizedLocatorJSON = locatorJSON[locale] || locatorJSON['default'] || locatorJSON; | ||
const locale = nemo._config.get('data:locale') || 'default'; | ||
let localizedLocatorJSON = locatorJSON[locale] || locatorJSON['default'] || locatorJSON; | ||
return localizedLocatorJSON; | ||
}; | ||
}; |
'use strict'; | ||
var Drivex = require('selenium-drivex'); | ||
var Locatex = require('./locatex'); | ||
var _ = require('lodash'); | ||
var normalize = require('./normalize'); | ||
var debug = require('debug'); | ||
var log = debug('nemo-view:log'); | ||
const Drivex = require('selenium-drivex'); | ||
const Locatex = require('./locatex'); | ||
const _ = require('lodash'); | ||
const normalize = require('./normalize'); | ||
const debug = require('debug'); | ||
const log = debug('nemo-view:log'); | ||
var Locreator = function (nemo) { | ||
log('creating Locreator instance'); | ||
this.nemo = nemo; | ||
this.drivex = Drivex(nemo.driver, nemo.wd); | ||
this.locatex = Locatex(nemo); | ||
this.normify = this.normalize = function (locator) { | ||
return normalize(nemo, locator); | ||
}; | ||
}; | ||
Locreator.prototype.addGenericMethods = function generics() { | ||
log('adding generic methods'); | ||
var normify = this.normify; | ||
var drivex = this.drivex; | ||
var nemo = this.nemo; | ||
class Locreator { | ||
nemo.view._find = function (locator, parentElement) { | ||
return drivex.find(normify(locator), parentElement); | ||
}; | ||
nemo.view._finds = function (locator, parentElement) { | ||
return drivex.finds(normify(locator), parentElement); | ||
}; | ||
nemo.view._present = function (locator, parentElement) { | ||
return drivex.present(normify(locator), parentElement); | ||
}; | ||
nemo.view._visible = function (locator, parentElement) { | ||
return drivex.visible(normify(locator), parentElement); | ||
}; | ||
nemo.view._wait = function (locator, timeout, msg) { | ||
return drivex.waitForElementPromise(normify(locator), timeout, msg); | ||
}; | ||
nemo.view._waitVisible = function (locator, timeout, msg) { | ||
return drivex.waitForElementVisiblePromise(normify(locator), timeout || 5000, msg); | ||
}; | ||
nemo.view._firstVisible = function (_locatorObject, timeout) { | ||
//transform _locatorObject to use native selenium-webdriver Locator format | ||
var locatorObject = _.transform(_locatorObject, function (result, n, key) { | ||
result[key] = normify(_locatorObject[key]); | ||
}); | ||
return drivex.firstVisible(locatorObject, timeout); | ||
}; | ||
}; | ||
constructor(nemo) { | ||
log('creating Locreator instance'); | ||
this.nemo = nemo; | ||
this.drivex = Drivex(nemo.driver, nemo.wd); | ||
this.locatex = Locatex(nemo); | ||
this.normify = this.normalize = (locator) => normalize(nemo, locator); | ||
} | ||
addGenericMethods() { | ||
log('adding generic methods'); | ||
const normify = this.normify; | ||
const drivex = this.drivex; | ||
let nemo = this.nemo; | ||
Locreator.prototype.addStarMethods = function addStarMethods(locatorId, locatorJSON, parentWebElement) { | ||
log('add star methods for %s', locatorId); | ||
var locatorObject = {}; | ||
var drivex = this.drivex; | ||
var locreator = this; | ||
var locator = function () { | ||
return locreator.normify(locreator.locatex(locatorJSON)); | ||
}; | ||
nemo.view._find = (locator, parentElement) => drivex.find(normify(locator), parentElement); | ||
//this is an error check. if an error thrown, invalid locatorJSON. | ||
locator(); | ||
nemo.view._finds = (locator, parentElement) => drivex.finds(normify(locator), parentElement); | ||
locatorObject[locatorId] = function () { | ||
return drivex.find(locator(), parentWebElement); | ||
}; | ||
locatorObject[locatorId + 'By'] = function () { | ||
return locator(); | ||
}; | ||
locatorObject[locatorId + 'Present'] = function () { | ||
return drivex.present(locator(), parentWebElement); | ||
}; | ||
locatorObject[locatorId + 'Wait'] = function (timeout, msg) { | ||
return drivex.waitForElementPromise(locator(), timeout || 5000, msg || 'Wait failed for locator [' + locatorId + ']'); | ||
}; | ||
locatorObject[locatorId + 'WaitVisible'] = function (timeout, msg) { | ||
return drivex.waitForElementVisiblePromise(locator(), timeout || 5000, msg || 'WaitVisible failed for locator [' + locatorId + ']'); | ||
}; | ||
locatorObject[locatorId + 'Visible'] = function () { | ||
return drivex.visible(locator(), parentWebElement); | ||
}; | ||
locatorObject[locatorId + 'OptionText'] = function (optionText) { | ||
return drivex.selectByOptionText(locator(), optionText, parentWebElement); | ||
}; | ||
locatorObject[locatorId + 'OptionValue'] = function (optionValue) { | ||
return drivex.selectByOptionValue(locator(), optionValue, parentWebElement); | ||
}; | ||
locatorObject[locatorId + 'TextEquals'] = function (value) { | ||
return drivex.validateText(locator(), parentWebElement, value) ; | ||
}; | ||
locatorObject[locatorId + 'AttrEquals'] = function (attribute, value) { | ||
return drivex.validateAttributeValue(locator(), parentWebElement, attribute, value); | ||
}; | ||
return locatorObject; | ||
}; | ||
nemo.view._present = (locator, parentElement) => drivex.present(normify(locator), parentElement); | ||
Locreator.prototype.addGroup = function (locatorId, locatorJSON) { | ||
var nemo = this.nemo; | ||
var drivex = this.drivex; | ||
var locreator = this; | ||
return function () { //give back the nemo.view.viewname.list() function | ||
var localizedJSON = locreator.locatex(locatorJSON); | ||
return drivex.finds(locreator.normify(localizedJSON)).then(function (parentWebElements) { | ||
return nemo.wd.promise.map(parentWebElements, function (parentWebElement) { | ||
var parentObject = {}; | ||
Object.keys(localizedJSON.Elements).forEach(function (childLocatorId) { | ||
var childLocatorJSON = localizedJSON.Elements[childLocatorId]; | ||
var starMethods = locreator.addStarMethods(childLocatorId, childLocatorJSON, parentWebElement); | ||
_.merge(parentObject, starMethods); | ||
}); | ||
return parentObject; | ||
}); | ||
}); | ||
}; | ||
}; | ||
nemo.view._visible = (locator, parentElement) => drivex.visible(normify(locator), parentElement); | ||
nemo.view._wait = (locator, timeout, msg) => drivex.waitForElementPromise(normify(locator), timeout, msg); | ||
nemo.view._waitVisible = (locator, timeout, msg) => drivex.waitForElementVisiblePromise(normify(locator), timeout || 5000, msg); | ||
nemo.view._optionText = (locator, optionText, parentElement) => drivex.selectByOptionText(normify(locator), optionText, parentElement); | ||
nemo.view._optionValue = (locator, optionValue, parentElement) => drivex.selectByOptionValue(normify(locator), optionValue, parentElement); | ||
nemo.view._firstVisible = (_locatorObject, timeout) => { | ||
//transform _locatorObject to use native selenium-webdriver Locator format | ||
const locatorObject = _.transform(_locatorObject, function (result, n, key) { | ||
result[key] = normify(_locatorObject[key]); | ||
}); | ||
return drivex.firstVisible(locatorObject, timeout); | ||
}; | ||
} | ||
addStarMethods(locatorId, locatorJSON, parentWebElement) { | ||
log('add star methods for %s', locatorId); | ||
let locatorObject = {}; | ||
const drivex = this.drivex; | ||
let locreator = this; | ||
const locator = () => locreator.normify(locreator.locatex(locatorJSON)); | ||
//this is an error check. if an error thrown, invalid locatorJSON. | ||
locator(); | ||
locatorObject[locatorId] = () => drivex.find(locator(), parentWebElement); | ||
locatorObject[locatorId + 'By'] = () => locator(); | ||
locatorObject[locatorId + 'Present'] = () => drivex.present(locator(), parentWebElement); | ||
locatorObject[locatorId + 'Wait'] = (timeout, msg) => drivex.waitForElementPromise(locator(), timeout || 5000, msg || 'Wait failed for locator [' + locatorId + ']'); | ||
locatorObject[locatorId + 'WaitVisible'] = (timeout, msg) => drivex.waitForElementVisiblePromise(locator(), timeout || 5000, msg || 'WaitVisible failed for locator [' + locatorId + ']'); | ||
locatorObject[locatorId + 'Visible'] = () => drivex.visible(locator(), parentWebElement); | ||
locatorObject[locatorId + 'OptionText'] = (optionText) => drivex.selectByOptionText(locator(), optionText, parentWebElement); | ||
locatorObject[locatorId + 'OptionValue'] = (optionValue) => drivex.selectByOptionValue(locator(), optionValue, parentWebElement); | ||
locatorObject[locatorId + 'TextEquals'] = (value) => drivex.validateText(locator(), parentWebElement, value); | ||
locatorObject[locatorId + 'AttrEquals'] = (attribute, value) => drivex.validateAttributeValue(locator(), parentWebElement, attribute, value); | ||
return locatorObject; | ||
} | ||
addGroup(locatorJSON) { | ||
const nemo = this.nemo; | ||
const drivex = this.drivex; | ||
let locreator = this; | ||
return () => { //give back the nemo.view.viewname.list() function | ||
const localizedJSON = locreator.locatex(locatorJSON); | ||
return drivex.finds(locreator.normify(localizedJSON)).then((parentWebElements) => { | ||
return nemo.wd.promise.map(parentWebElements, (parentWebElement) => { | ||
let parentObject = {}; | ||
Object.keys(localizedJSON.Elements).forEach((childLocatorId) => { | ||
const childLocatorJSON = localizedJSON.Elements[childLocatorId]; | ||
const starMethods = locreator.addStarMethods(childLocatorId, childLocatorJSON, parentWebElement); | ||
_.merge(parentObject, starMethods); | ||
}); | ||
return parentObject; | ||
}); | ||
}); | ||
}; | ||
} | ||
} | ||
module.exports = Locreator; |
@@ -9,5 +9,5 @@ 'use strict'; | ||
*/ | ||
var _splitLocator = function (nemo, locatorString) { | ||
var strategy = locatorString.substr(0, locatorString.indexOf(':')); | ||
var locator = ''; | ||
const _splitLocator = (nemo, locatorString) => { | ||
let strategy = locatorString.substr(0, locatorString.indexOf(':')); | ||
let locator = ''; | ||
if (strategy.length > 0 && nemo.wd.By[strategy] !== undefined) { | ||
@@ -20,3 +20,3 @@ locator = locatorString.substr(locatorString.indexOf(':') + 1, locatorString.length); | ||
var jsonLocator = { | ||
const jsonLocator = { | ||
'type': strategy, | ||
@@ -36,7 +36,7 @@ 'locator': locator | ||
module.exports = function normalize(nemo, _locator) { | ||
var locator = _locator; | ||
var normalizedLocator; | ||
let locator = _locator; | ||
let normalizedLocator; | ||
//get a hold of webdriver.Locator. It's the same for all strategies. | ||
var Locator = nemo.wd.By.id('xyz').constructor; | ||
const Locator = nemo.wd.By.id('xyz').constructor; | ||
if (locator instanceof Locator) { | ||
@@ -43,0 +43,0 @@ return locator; //already normalized |
@@ -27,9 +27,9 @@ /*───────────────────────────────────────────────────────────────────────────*\ | ||
*/ | ||
var _ = require('lodash'); | ||
const _ = require('lodash'); | ||
module.exports = function View(nemo, locreator, viewJSON) { | ||
return _.transform(viewJSON, function (_viewObject, n, locatorId) { | ||
var locatorJSON = viewJSON[locatorId]; | ||
return _.transform(viewJSON, (_viewObject, n, locatorId) => { | ||
const locatorJSON = viewJSON[locatorId]; | ||
if (locreator.locatex(locatorJSON).Elements) { | ||
_viewObject[locatorId] = locreator.addGroup(locatorId, locatorJSON); | ||
_viewObject[locatorId] = locreator.addGroup(locatorJSON); | ||
} else { | ||
@@ -36,0 +36,0 @@ _.merge(_viewObject, locreator.addStarMethods(locatorId, locatorJSON)); |
{ | ||
"name": "nemo-view", | ||
"version": "3.0.0-alpha.3", | ||
"version": "3.0.0", | ||
"description": "selenium-webdriver abstractions and locator organization plugin for nemo", | ||
@@ -8,3 +8,4 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "grunt" | ||
"test": "grunt", | ||
"test:unit": "grunt simplemocha" | ||
}, | ||
@@ -40,3 +41,5 @@ "repository": { | ||
"Vidya Aravind <varavind@paypal.com>", | ||
"Alex Feldman <afeldman@paypal.com>" | ||
"Alex Feldman <afeldman@paypal.com>", | ||
"Jonathan Samines <jn.samines@gmail.com>", | ||
"Samdish Suri <sasuri@paypal.com>" | ||
], | ||
@@ -43,0 +46,0 @@ "licenses": [ |
## nemo-view | ||
View Interface for nemo views | ||
View Interface for nemo views. | ||
@@ -10,3 +10,3 @@ [![Build Status](https://travis-ci.org/paypal/nemo-view.svg?branch=master)](https://travis-ci.org/paypal/nemo-view) | ||
1. Add dependencies to package.json and install. | ||
1. Add dependencies to your `package.json` file and install | ||
@@ -20,3 +20,3 @@ ```javascript | ||
2. Add plugins to your nemo config JSON object | ||
2. Add `nemo-view` to your plugins nemo config | ||
@@ -51,5 +51,3 @@ ```javascript | ||
Where `type` is any of the locator strategies here: http://selenium.googlecode.com/git/docs/api/javascript/namespace_webdriver_By.html. | ||
A `locator` or `type` CANNOT be empty/blank/absent in JSON object representation of `locatorDefinition`. An error will be thrown during the setup of nemo-view | ||
If `type` under `locatorDefinition` is invalid (not amongst [allowed types](http://selenium.googlecode.com/git/docs/api/javascript/namespace_webdriver_By.html)) then an error is thrown as well. | ||
Where `type` is any of the [selenium locator strategies](http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/by_exports_By.html). A `locator` or `type` CANNOT be empty/blank/absent in JSON object representation of `locatorDefinition`. An error will be thrown during the setup of nemo-view. If `type` under `locatorDefinition` is invalid (not amongst [allowed types](http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/by_exports_By.html)) then an error is thrown as well. | ||
@@ -62,3 +60,3 @@ | ||
``` | ||
String of the form `<type>:<locator>`or `<locator>` (where `<type>` will be assumed as css) | ||
String of the form `<type>:<locator>` or `<locator>` (where `<type>` will be assumed as css) | ||
@@ -113,2 +111,3 @@ | ||
``` | ||
`nemo-view` supports for adding JavaScript-style comments in your json files as each file is processed by using [shush](https://github.com/krakenjs/shush) | ||
@@ -131,2 +130,4 @@ | ||
nemo.view._waitVisible | ||
nemo.view._optionValue | ||
nemo.view._optionText | ||
nemo.view._firstVisible | ||
@@ -143,2 +144,3 @@ | ||
}); | ||
after(function (done) { | ||
@@ -152,2 +154,3 @@ nemo.driver.quit().then(done); | ||
}); | ||
it('should use the form view to enter values and write to outy div @useView@', function (done) { | ||
@@ -200,10 +203,12 @@ nemo.view._find('css:#outy').getTagName().then(function (tn) { | ||
}); | ||
after(function(done) { | ||
nemo.driver.quit().then(done); | ||
}); | ||
beforeEach(function (done) { | ||
nemo.driver.get(nemo.data.baseUrl); | ||
util.waitForJSReady(nemo).then(util.doneSuccess(done), util.doneError(done)); | ||
}); | ||
it('should use the form view to enter values and write to outy div @useView@', function (done) { | ||
@@ -227,2 +232,3 @@ nemo.view.form.fooText().sendKeys('foo'); | ||
``` | ||
### Combining methods from with and without locator files | ||
@@ -264,3 +270,3 @@ | ||
#### _find(locatorString[, parentWebElement]) | ||
#### _find(locatorDefinition[, parentWebElement]) | ||
@@ -273,3 +279,3 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _finds(locatorString[, parentWebElement]) | ||
#### _finds(locatorDefinition[, parentWebElement]) | ||
@@ -283,3 +289,3 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _present(locatorString[, parentWebElement]) | ||
#### _present(locatorDefinition[, parentWebElement]) | ||
@@ -292,3 +298,3 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _visible(locatorString[, parentWebElement]) | ||
#### _visible(locatorDefinition[, parentWebElement]) | ||
@@ -301,3 +307,3 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _wait(locatorString[, timeout [, msg]]) | ||
#### _wait(locatorDefinition[, timeout [, msg]]) | ||
@@ -312,3 +318,3 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _waitVisible(locatorString[, timeout [, msg]]) | ||
#### _waitVisible(locatorDefinition[, timeout [, msg]]) | ||
@@ -323,2 +329,18 @@ `@argument locatorDefinition {String|Object}` - Please see `locatorDefinition` above | ||
#### _optionValue(locatorDefinition, value [, parentWebElement]) | ||
`@argument locatorDefinition {String|Object}}` - Please see `locatorDefinition` above | ||
`@argument value {String}` - the value attribute of the option you wish to select | ||
`@argument parentWebElement {WebElement} (optional, default driver)` - parent WebElement to search elements underneath | ||
#### _optionText(locatorDefinition, text [, parentWebElement]) | ||
`@argument locatorDefinition {String|Object}}` - Please see `locatorDefinition` above | ||
`@argument text {String}` - The text in the option you wish to select | ||
`@argument parentWebElement {WebElement} (optional, default driver)` - parent WebElement to search elements underneath | ||
#### _firstVisible(locatorObject[, timeout]) | ||
@@ -328,2 +350,3 @@ | ||
value is a `locatorDefinition` (see above). Example would be: | ||
```javascript | ||
@@ -372,4 +395,34 @@ { | ||
* arguments: none | ||
* returns: Promise which resolves to WebElement or rejected | ||
* returns: Promise which resolves to a WebElement or to a list if a *list locator* is used. Rejects if an error occurs. | ||
##### The list locator | ||
This is a special locator, which let's you find lists of related elements. For example, given the locator file `formElementList.json`: | ||
```json | ||
{ | ||
"inputGroup": { | ||
"locator": "div.fielder", | ||
"type": "css", | ||
"Elements": { | ||
"text": "input.texty", | ||
"button": "input[type='button']" | ||
} | ||
} | ||
} | ||
``` | ||
You will get a list of items, each with two properties `text` and `button` which themselves return WebElements when called. | ||
```js | ||
nemo.view.formElementList | ||
.inputGroup() | ||
.then((elements) => { | ||
elements.forEach(function (el) { | ||
el.text().sendKeys('abcd'); | ||
el.button().click(); | ||
}) | ||
}); | ||
``` | ||
#### [locatorName]By | ||
@@ -486,7 +539,7 @@ | ||
* How to run unit tests? | ||
* `grunt simplemocha` will just run unit tests | ||
* `grunt` - default grunt task will run linting as well as unit tests | ||
* `npm run test:unit` will just run unit tests | ||
* `npm test` - default grunt task will run linting as well as unit tests | ||
* To run directly using mocha assuming its globally installed on your system `mocha -t 60s` | ||
* Or a specific test, `mocha --grep @_visible@withParent@negative@ -t 60s` | ||
* Run using mocha on a specific test, `mocha --grep @_visible@withParent@negative@ -t 60s` | ||
* Or post `npm install` on nemo-view module, you can run `node_modules/.bin/mocha --grep @_visible@withParent@negative@ -t 60s` | ||
@@ -5,3 +5,3 @@ 'use strict'; | ||
var called = false; | ||
return function (err) { | ||
return (err) => { | ||
if (!!called) { | ||
@@ -8,0 +8,0 @@ return undefined; |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
526
0
40512
13
302
1