From c067461bec4fd2ce84f2a7c31b893ac789e1a7a1 Mon Sep 17 00:00:00 2001 From: "Evgeny V. Generalov" Date: Thu, 15 Mar 2018 00:47:20 +0300 Subject: [PATCH 1/2] feat: add query methods (#173) --- lib/browser/new-browser.js | 71 ++++++++++++++++++-------------- lib/tests-api/actions-builder.js | 2 +- lib/tests-api/find-func.js | 15 ++++++- test/unit/browser/new-browser.js | 2 - 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/lib/browser/new-browser.js b/lib/browser/new-browser.js index 6d62ee311..8a0c71188 100644 --- a/lib/browser/new-browser.js +++ b/lib/browser/new-browser.js @@ -103,7 +103,6 @@ module.exports = class NewBrowser extends Browser { .then((calibration) => this._setCalibration(calibration)); }) .then(() => this.buildScripts()) - .then(() => this.chooseLocator()) .catch((e) => { if (e.code === 'ECONNREFUSED') { return Promise.reject(new GeminiError( @@ -222,10 +221,6 @@ module.exports = class NewBrowser extends Browser { return this._calibration && this._calibration.needsCompatLib; } - chooseLocator() { - this.findElement = this._needsCompatLib ? this._findElementScript : this._findElementWd; - } - reset() { // We can't use findElement here because it requires page with body tag return this.evalScript('document.body') @@ -263,33 +258,14 @@ module.exports = class NewBrowser extends Browser { .then((handle) => this._wd.maximize(handle)); } - findElement() { - throw new Error('findElement is called before appropriate locator is chosen'); - } - - _findElementWd(selector) { - return this._wd.elementByCssSelector(selector) - .catch((error) => { - if (error.status === WdErrors.ELEMENT_NOT_FOUND) { - error.selector = selector; - } - return Promise.reject(error); - }); - } - - _findElementScript(selector) { - return this._clientBridge.call('queryFirst', [selector]) - .then((element) => { - if (element) { - return element; - } + findElement(selector, syntax = 'css') { + const locator = this._needsCompatLib ? ScriptLocator(this._clientBridge) : WdLocator(this._wd); - const error = new Error('Unable to find element'); - error.status = WdErrors.ELEMENT_NOT_FOUND; - error.selector = selector; + if (!locator[syntax]) { + throw new Error(`${syntax} isn't supported by locator`); + } - return Promise.reject(error); - }); + return locator[syntax](selector); } prepareScreenshot(selectors, opts) { @@ -317,3 +293,38 @@ module.exports = class NewBrowser extends Browser { return `[${this.id} (${this.sessionId})]`; } }; + +function WdLocator(wd) { + const tryFind = (find) => (selector) => find(selector) + .catch((error) => { + if (error.status === WdErrors.ELEMENT_NOT_FOUND) { + error.selector = selector; + } + return Promise.reject(error); + }); + + return { + css: tryFind(wd.elementByCssSelector.bind(wd)), + link: tryFind(wd.elementByLinkText.bind(wd)), + xpath: tryFind(wd.elementByXPath.bind(wd)) + }; +} + +function ScriptLocator(clientBridge) { + return { + css(selector) { + return clientBridge.call('queryFirst', [selector]) + .then((element) => { + if (element) { + return element; + } + + const error = new Error('Unable to find element'); + error.status = WdErrors.ELEMENT_NOT_FOUND; + error.selector = selector; + + return Promise.reject(error); + }); + } + }; +} diff --git a/lib/tests-api/actions-builder.js b/lib/tests-api/actions-builder.js index b61d61a09..184ccac2c 100644 --- a/lib/tests-api/actions-builder.js +++ b/lib/tests-api/actions-builder.js @@ -379,7 +379,7 @@ function findElement(element, browser) { element = find(element); } - return browser.findElement(element._selector) + return browser.findElement(element._selector, element._syntax) .then((foundElement) => { element.cache = element.cache || {}; element.cache[browser.sessionId] = foundElement; diff --git a/lib/tests-api/find-func.js b/lib/tests-api/find-func.js index 69cf3be56..6a3ec5f4a 100644 --- a/lib/tests-api/find-func.js +++ b/lib/tests-api/find-func.js @@ -1,6 +1,6 @@ 'use strict'; -exports.find = function(selector) { +function createElementFinder(selector, syntax) { if (typeof selector !== 'string') { throw new Error('find argument should be a string'); } @@ -10,6 +10,17 @@ exports.find = function(selector) { value: selector, enumerable: false, writable: false + }, + _syntax: { + value: syntax, + enumerable: false, + writable: false } }); -}; +} + +exports.find = Object.assign( + (selector) => createElementFinder(selector, 'css'), + ['css', 'link', 'xpath'] + .reduce((o, syntax) => Object.assign(o, {[syntax]: selector => createElementFinder(selector, syntax)}), {}) +); diff --git a/test/unit/browser/new-browser.js b/test/unit/browser/new-browser.js index ff6e72163..466b5ec03 100644 --- a/test/unit/browser/new-browser.js +++ b/test/unit/browser/new-browser.js @@ -413,8 +413,6 @@ describe('browser/new-browser', () => { beforeEach(() => { browser = makeBrowser({browserName: 'browser', version: '1.0'}); - - browser.chooseLocator(); }); it('should reset mouse position', () => { From eaff8b633207a37f1487d569086a1b3183d0f167 Mon Sep 17 00:00:00 2001 From: Evgeniy Generalov Date: Sat, 7 Apr 2018 13:47:05 +0300 Subject: [PATCH 2/2] fix: test stubs for wd methods --- test/unit/browser/new-browser.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/unit/browser/new-browser.js b/test/unit/browser/new-browser.js index 466b5ec03..5fb828528 100644 --- a/test/unit/browser/new-browser.js +++ b/test/unit/browser/new-browser.js @@ -27,6 +27,8 @@ describe('browser/new-browser', () => { windowHandle: sinon.stub().returns(Promise.resolve({})), moveTo: sinon.stub().returns(Promise.resolve()), elementByCssSelector: sinon.stub().returns(Promise.resolve()), + elementByLinkText: sinon.stub().returns(Promise.resolve()), + elementByXPath: sinon.stub().returns(Promise.resolve()), on: sinon.stub(), currentContext: sinon.stub().returns(Promise.resolve()), context: sinon.stub().returns(Promise.resolve()),