Comparing version 1.11.1 to 1.11.2
@@ -59,2 +59,13 @@ ### Mobile JsonWire Protocol Methods ### | ||
#### -android datamatcher Locator Strategy #### | ||
Find elements in android applications using Espresso [Data Matcher](https://developer.android.com/reference/android/support/test/espresso/DataInteraction) | ||
e.g.: | ||
``` | ||
wd.elementsByAndroidDataMatcher(JSON.stringify({name: "hasEntry", args: ["title", "ViewTitle"]})', function(err, els){ | ||
console.log("number of clickable elements:", els.length); | ||
}); | ||
``` | ||
#### accessibility id #### | ||
@@ -61,0 +72,0 @@ |
@@ -37,3 +37,3 @@ var gulp = require('gulp'), | ||
}, | ||
bin: path.join(__dirname, 'node_modules/.bin/mocha'), | ||
bin: path.join(__dirname, 'node_modules/.bin/' + ((process.platform !== "win32") ? 'mocha' : 'mocha.cmd')), | ||
concurrency: args.concurrency | process.env.CONCURRENCY || 3 | ||
@@ -40,0 +40,0 @@ }; |
@@ -115,8 +115,10 @@ var utils = require("./utils"), | ||
// check to make sure we convert if necessary to element objects | ||
if(obj.value && typeof obj.value.ELEMENT !== "undefined") { | ||
obj.value = browser.newElement(obj.value.ELEMENT); | ||
var elId = utils.getElementId(obj.value); | ||
if(obj.value && typeof elId !== "undefined") { | ||
obj.value = browser.newElement(elId); | ||
} else if (Object.prototype.toString.call(obj.value) === "[object Array]") { | ||
for (var i = 0; i < obj.value.length; i++) { | ||
if (obj.value[i] && typeof obj.value[i].ELEMENT !== "undefined") { | ||
obj.value[i] = browser.newElement(obj.value[i].ELEMENT); | ||
elId = utils.getElementId(obj.value[i]); | ||
if (obj.value[i] && typeof elId !== "undefined") { | ||
obj.value[i] = browser.newElement(elId); | ||
} | ||
@@ -136,7 +138,8 @@ } | ||
{message:obj.value.message,cause:obj.value}));} | ||
if (!obj.value.ELEMENT) { | ||
var elId = utils.getElementId(obj.value); | ||
if (!elId) { | ||
cb(newError( | ||
{message:"no ELEMENT in response value field.",cause:obj})); | ||
} else { | ||
var el = browser.newElement(obj.value.ELEMENT); | ||
var el = browser.newElement(elId); | ||
cb(null, el); | ||
@@ -158,3 +161,5 @@ } | ||
for (i = 0; i < obj.value.length; i++) { | ||
var el = browser.newElement(obj.value[i].ELEMENT); | ||
var value = obj.value[i]; | ||
var elId = utils.getElementId(value); | ||
var el = browser.newElement(elId); | ||
elements.push(el); | ||
@@ -174,4 +179,5 @@ } | ||
var el; | ||
if (obj.value.ELEMENT){ | ||
el = browser.newElement(obj.value.ELEMENT); | ||
var elId = utils.getElementId(obj.value); | ||
if (elId){ | ||
el = browser.newElement(elId); | ||
cb(null, el); | ||
@@ -181,3 +187,4 @@ } else if (Array.isArray(obj.value)){ | ||
for (i = 0; i < obj.value.length; i++) { | ||
el = browser.newElement(obj.value[i].ELEMENT); | ||
elId = utils.getElementId(obj.value[i]); | ||
el = browser.newElement(elId); | ||
elements.push(el); | ||
@@ -184,0 +191,0 @@ } |
@@ -122,4 +122,9 @@ var async = require("async"); | ||
module.exports = { | ||
patch: function(browser) { | ||
_(deprecatedChain).methods().each(function(methodName) { | ||
patch: function (browser) { | ||
var chain = _(deprecatedChain); | ||
var functions = _.isFunction(chain.methods) ? | ||
chain.methods() : | ||
chain.functions(); | ||
functions.each(function (methodName) { | ||
browser[methodName] = deprecatedChain[methodName].bind(browser); | ||
@@ -126,0 +131,0 @@ }); |
@@ -24,2 +24,3 @@ var Args = require("vargs").Constructor, | ||
'-android uiautomator': 'ByAndroidUIAutomator', | ||
'-android datamatcher': 'ByAndroidDataMatcher', | ||
'-ios class chain': 'ByIosClassChain', | ||
@@ -50,3 +51,3 @@ '-ios predicate string': 'ByIosPredicateString', | ||
'-ios uiautomation', '-android uiautomator', 'accessibility id', | ||
'-ios class chain', '-ios predicate string', '-image', '-custom']; | ||
'-ios class chain', '-ios predicate string', '-image', '-custom', '-android datamatcher']; | ||
@@ -177,1 +178,33 @@ // chai-as-promised promisifier | ||
}; | ||
/** | ||
* Prefix all unofficial capabilities. Prefix with `wd` by default | ||
* or with whatever is provided in `caps.w3cPrefix` | ||
*/ | ||
exports.prefixCapabilities = function (caps) { | ||
var pairs = _.toPairs(caps); | ||
var prefixedCaps = {}; | ||
var w3cCapabilities = [ | ||
'browserName', 'browserVersion', 'platformName', 'acceptInsecureCerts', | ||
'pageLoadStrategy', 'proxy', 'setWindowRect', 'timeouts', 'unhandledPromptBehavior' | ||
]; | ||
var prefix = caps.w3cPrefix || 'wd'; | ||
for (var i=0; i<pairs.length; i++) { | ||
var key = pairs[i][0]; | ||
var value = pairs[i][1]; | ||
// If an unsupported cap has no prefix, add one. | ||
if (key.indexOf(':') < 0 && w3cCapabilities.indexOf(key) < 0) { | ||
prefixedCaps[prefix + ':' + key] = value; | ||
} else { | ||
prefixedCaps[key] = value; | ||
} | ||
} | ||
return prefixedCaps; | ||
}; | ||
var w3cElementKeyId = exports.w3cElementKeyId = "element-6066-11e4-a52e-4f735466cecf"; | ||
exports.getElementId = function (obj) { | ||
return _.isObject(obj) ? obj.ELEMENT || obj[w3cElementKeyId] : undefined; | ||
}; |
@@ -15,3 +15,4 @@ var EventEmitter = require('events').EventEmitter, | ||
Element = require('./element'), | ||
commands = require('./commands'); | ||
commands = require('./commands'), | ||
SAUCE_API_HOST = process.env["SAUCE_API_HOST"] || "saucelabs.com"; | ||
@@ -24,4 +25,4 @@ // Webdriver client main class | ||
this.configUrl = configUrl; | ||
this.sauceTestPageRoot = "https://saucelabs.com/jobs"; | ||
this.sauceRestRoot = "https://saucelabs.com/rest/v1"; | ||
this.sauceTestPageRoot = "https://" + SAUCE_API_HOST + "/jobs"; | ||
this.sauceRestRoot = "https://" + SAUCE_API_HOST + "/rest/v1"; | ||
// config url without auth | ||
@@ -99,5 +100,15 @@ this.noAuthConfigUrl = url.parse(url.format(this.configUrl)); | ||
var data = {}; | ||
// building request | ||
var data = {desiredCapabilities: _desired}; | ||
if (_desired.allowW3C || _desired.forceW3C) { | ||
data.capabilities = { | ||
alwaysMatch: utils.prefixCapabilities(_desired), | ||
firstMatch: [{}], | ||
}; | ||
} | ||
if (!_desired.forceW3C) { | ||
data.desiredCapabilities = _desired; | ||
} | ||
httpUtils.emit(this, httpOpts.method, url, data); | ||
@@ -104,0 +115,0 @@ |
@@ -11,3 +11,3 @@ { | ||
], | ||
"version": "1.11.1", | ||
"version": "1.11.2", | ||
"author": "Adam Christian <adam.christian@gmail.com>", | ||
@@ -62,3 +62,3 @@ "contributors": [ | ||
"express": "^4.16.3", | ||
"gulp": "3.9.1", | ||
"gulp": "^3.9.1", | ||
"gulp-jshint": "^2.1.0", | ||
@@ -65,0 +65,0 @@ "hbs": "4.0.1", |
@@ -17,3 +17,3 @@ # WD.js | ||
This library is designed to be a maleable implementation of the webdriver protocol in Node, exposing functionality via a number of programming paradigms. If you are looking for a more opinionated library, you might find [webdriver.io](http://webdriver.io/) interesting. | ||
This library is designed to be a maleable implementation of the webdriver protocol in Node, exposing functionality via a number of programming paradigms. If you are looking for a more polished, opinionated and active library - I would suggest [webdriver.io](http://webdriver.io/). | ||
@@ -20,0 +20,0 @@ ## Release Notes |
@@ -328,2 +328,76 @@ var nock = require('nock'), | ||
describe("by android datamatcher", function() { | ||
it("element methods should work", function(done) { | ||
nock.cleanAll(); | ||
server | ||
.post('/session/1234/element', {"using":"-android datamatcher","value":"random stuff"}) | ||
.times(2) | ||
.reply(200, { | ||
status: 0, | ||
sessionId: '1234', | ||
value: {ELEMENT: '0'}, | ||
}); | ||
server | ||
.post('/session/1234/elements', {"using":"-android datamatcher","value":"random stuff"}) | ||
.times(3) | ||
.reply(200, { | ||
status: 0, | ||
sessionId: '1234', | ||
value: [{ELEMENT: '0'}], | ||
}); | ||
browser | ||
.element('-android datamatcher', 'random stuff') | ||
.should.eventually.exist | ||
.elementByAndroidDataMatcher('random stuff') | ||
.should.eventually.exist | ||
.elementByAndroidDataMatcherOrNull('random stuff') | ||
.should.eventually.exist | ||
.elementByAndroidDataMatcherIfExists('random stuff') | ||
.should.eventually.exist | ||
.hasElementByAndroidDataMatcher('random stuff') | ||
.should.eventually.be.ok | ||
.nodeify(done); | ||
}); | ||
it("elements methods should work", function(done) { | ||
nock.cleanAll(); | ||
server | ||
.post('/session/1234/elements', {"using":"-android datamatcher","value":"random stuff"}) | ||
.times(2) | ||
.reply(200, { | ||
status: 0, | ||
sessionId: '1234', | ||
value: [{ELEMENT: '0'}], | ||
}); | ||
browser | ||
.elements('-android datamatcher', 'random stuff') | ||
.should.eventually.exist | ||
.elementsByAndroidDataMatcher('random stuff') | ||
.should.eventually.exist | ||
.nodeify(done); | ||
}); | ||
it("wait methods should work", function(done) { | ||
nock.cleanAll(); | ||
server | ||
.post('/session/1234/elements', {"using":"-android datamatcher","value":"random stuff"}) | ||
.times(3) | ||
.reply(200, { | ||
status: 0, | ||
sessionId: '1234', | ||
value: [{ELEMENT: '0'}], | ||
}); | ||
browser | ||
.waitForElement('-android datamatcher', 'random stuff') | ||
.should.eventually.exist | ||
.waitForElementByAndroidDataMatcher('random stuff') | ||
.should.eventually.exist | ||
.waitForElementsByAndroidDataMatcher('random stuff') | ||
.should.eventually.exist | ||
.nodeify(done); | ||
}); | ||
}); | ||
describe("by accessibility id", function() { | ||
@@ -330,0 +404,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1020949
140
15557
104