UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

530 lines (484 loc) 85.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); require("source-map-support/register"); var _chai = _interopRequireDefault(require("chai")); var _path = _interopRequireDefault(require("path")); var _chaiAsPromised = _interopRequireDefault(require("chai-as-promised")); var _sinon = _interopRequireDefault(require("sinon")); var _ = require("../../.."); var _find = require("../../../lib/basedriver/commands/find"); var _appiumSupport = require("appium-support"); const should = _chai.default.should(); _chai.default.use(_chaiAsPromised.default); class TestDriver extends _.BaseDriver { async getWindowSize() {} async getScreenshot() {} } const CUSTOM_FIND_MODULE = _path.default.resolve(__dirname, '..', '..', '..', '..', 'test', 'basedriver', 'fixtures', 'custom-element-finder'); const BAD_CUSTOM_FIND_MODULE = _path.default.resolve(__dirname, '..', '..', '..', '..', 'test', 'basedriver', 'fixtures', 'custom-element-finder-bad'); const TINY_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N0NDMDM4MDM4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6N0NDMDM4MDQ4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3Q0MwMzgwMTg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3Q0MwMzgwMjg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpdvJjQAAAAlSURBVHjaJInBEQAACIKw/Xe2Ul5wYBtwmJqkk4+zfvUQVoABAEg0EfrZwc0hAAAAAElFTkSuQmCC'; const TINY_PNG_DIMS = [4, 4]; describe('finding elements by image', function () { describe('findElement', function () { it('should use a different special method to find element by image', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'findByImage').returns(true); _sinon.default.stub(d, 'findElOrElsWithProcessing').returns(false); await d.findElement(_find.IMAGE_STRATEGY, 'foo').should.eventually.be.true; await d.findElements(_find.IMAGE_STRATEGY, 'foo').should.eventually.be.true; }); it('should not be able to find image element from any other element', async function () { const d = new TestDriver(); await d.findElementFromElement(_find.IMAGE_STRATEGY, 'foo', 'elId').should.eventually.be.rejectedWith(/Locator Strategy.+is not supported/); await d.findElementsFromElement(_find.IMAGE_STRATEGY, 'foo', 'elId').should.eventually.be.rejectedWith(/Locator Strategy.+is not supported/); }); }); describe('findByImage', function () { const rect = { x: 10, y: 20, width: 30, height: 40 }; const size = { width: 100, height: 200 }; const screenshot = 'iVBORfoo'; const template = 'iVBORbar'; function basicStub(driver) { const sizeStub = _sinon.default.stub(driver, 'getWindowSize').returns(size); const screenStub = _sinon.default.stub(driver, 'getScreenshotForImageFind').returns(screenshot); const compareStub = _sinon.default.stub(driver, 'compareImages').returns({ rect }); return { sizeStub, screenStub, compareStub }; } function basicImgElVerify(imgElProto, driver) { const imgElId = imgElProto.ELEMENT; driver._imgElCache.has(imgElId).should.be.true; const imgEl = driver._imgElCache.get(imgElId); (imgEl instanceof _.ImageElement).should.be.true; imgEl.rect.should.eql(rect); return imgEl; } it('should find an image element happypath', async function () { const d = new TestDriver(); basicStub(d); const imgElProto = await d.findByImage(template, { multiple: false }); basicImgElVerify(imgElProto, d); }); it('should find image elements happypath', async function () { const d = new TestDriver(); basicStub(d); const els = await d.findByImage(template, { multiple: true }); els.should.have.length(1); basicImgElVerify(els[0], d); }); it('should fail if driver does not support getWindowSize', async function () { const d = new _.BaseDriver(); await d.findByImage(template, { multiple: false }).should.eventually.be.rejectedWith(/driver does not support/); }); it('should fix template size if requested', async function () { const d = new TestDriver(); const newTemplate = 'iVBORbaz'; const { compareStub } = basicStub(d); await d.settings.update({ fixImageTemplateSize: true }); _sinon.default.stub(d, 'ensureTemplateSize').returns(newTemplate); const imgElProto = await d.findByImage(template, { multiple: false }); const imgEl = basicImgElVerify(imgElProto, d); imgEl.template.should.eql(newTemplate); compareStub.args[0][2].should.eql(newTemplate); }); it('should fix template size scale if requested', async function () { const d = new TestDriver(); const newTemplate = 'iVBORbaz'; const { compareStub } = basicStub(d); await d.settings.update({ fixImageTemplateScale: true }); _sinon.default.stub(d, 'fixImageTemplateScale').returns(newTemplate); const imgElProto = await d.findByImage(template, { multiple: false }); const imgEl = basicImgElVerify(imgElProto, d); imgEl.template.should.eql(newTemplate); compareStub.args[0][2].should.eql(newTemplate); }); it('should not fix template size scale if it is not requested', async function () { const d = new TestDriver(); const newTemplate = 'iVBORbaz'; basicStub(d); await d.settings.update({}); _sinon.default.stub(d, 'fixImageTemplateScale').returns(newTemplate); d.fixImageTemplateScale.callCount.should.eql(0); }); it('should throw an error if template match fails', async function () { const d = new TestDriver(); const { compareStub } = basicStub(d); compareStub.throws(new Error('Cannot find any occurrences')); await d.findByImage(template, { multiple: false }).should.eventually.be.rejectedWith(/element could not be located/); }); it('should return empty array for multiple elements if template match fails', async function () { const d = new TestDriver(); const { compareStub } = basicStub(d); compareStub.throws(new Error('Cannot find any occurrences')); await d.findByImage(template, { multiple: true }).should.eventually.eql([]); }); it('should respect implicit wait', async function () { const d = new TestDriver(); d.setImplicitWait(10); const { compareStub } = basicStub(d); compareStub.onCall(0).throws(new Error('Cannot find any occurrences')); const imgElProto = await d.findByImage(template, { multiple: false }); basicImgElVerify(imgElProto, d); compareStub.callCount.should.eql(2); }); it('should not add element to cache and return it directly when checking staleness', async function () { const d = new TestDriver(); basicStub(d); const imgEl = await d.findByImage(template, { multiple: false, shouldCheckStaleness: true }); (imgEl instanceof _.ImageElement).should.be.true; d._imgElCache.has(imgEl.id).should.be.false; imgEl.rect.should.eql(rect); }); }); describe('fixImageTemplateScale', function () { it('should not fix template size scale if no scale value', async function () { const newTemplate = 'iVBORbaz'; await _find.helpers.fixImageTemplateScale(newTemplate, { fixImageTemplateScale: true }).should.eventually.eql(newTemplate); }); it('should not fix template size scale if it is null', async function () { const newTemplate = 'iVBORbaz'; await _find.helpers.fixImageTemplateScale(newTemplate, null).should.eventually.eql(newTemplate); }); it('should not fix template size scale if it is not number', async function () { const newTemplate = 'iVBORbaz'; await _find.helpers.fixImageTemplateScale(newTemplate, 'wrong-scale').should.eventually.eql(newTemplate); }); it('should fix template size scale', async function () { const actual = 'iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAWElEQVR4AU3BQRWAQAhAwa/PGBsEgrC16AFBKEIPXW7OXO+Rmey9iQjMjHFzrLUwM7qbqmLcHKpKRFBVuDvj4agq3B1VRUQYT2bS3QwRQVUZF/CaGRHB3wc1vSZbHO5+BgAAAABJRU5ErkJggg=='; await _find.helpers.fixImageTemplateScale(TINY_PNG, { fixImageTemplateScale: true, xScale: 1.5, yScale: 1.5 }).should.eventually.eql(actual); }); it('should not fix template size scale because of fixImageTemplateScale is false', async function () { await _find.helpers.fixImageTemplateScale(TINY_PNG, { fixImageTemplateScale: false, xScale: 1.5, yScale: 1.5 }).should.eventually.eql(TINY_PNG); }); it('should fix template size scale with default scale', async function () { const actual = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwUlEQVR4AaXBPUsrQQCG0SeX+cBdkTjwTpG1NPgLpjY/fW1stt4UYmm2cJqwMCsaw70uJJ3CBc9Z/P3Cl+12S9u2tG1L27bEGLm/v2ez2bDZbJDEd/7wS4YT7z3X19fc3Nxwd3dHXdd47xnHkefnZ8ZxpKoq6rqmqiqMMcwMJ1VV0TQN0zThnOPj44O6rsk503UdkmiahqZpWK1WGGOYGU7quqZpGqy1SCLnTM6Z19dXcs5IYpomrLVI4uLigpnhpKoqVqsVkjgcDjw9PdF1HTlnuq5DEs45JHE4HDgznByPR97e3pimiVIK4zhyPB7x3hNCIITA5eUl3nsWiwVnhpNSCsMwsNvtGIaB/X5PKQVJpJSQxHq9RhLOOc4MJ9M0sdvt2G639H3PTBIxRiQhCUnEGLHWcmY4KaUwDAN93/P4+MhyuSSlhCRSSkjCOYe1FmstZ6bve2YvLy/s93tmy+USSUhCEpIIIfAd8/DwwOz9/Z1SCpJIKSGJ9XqNJJxz/MS0bcvs6uoKScQYkYQkJBFjxFrLT0zbtsxub29JKSGJlBKScM5hrcVay09MzplZjJHPz0+894QQCCHwP/7wS/8A4e6nAg+R8LwAAAAASUVORK5CYII='; await _find.helpers.fixImageTemplateScale(TINY_PNG, { defaultImageTemplateScale: 4.0 }).should.eventually.eql(actual); }); it('should fix template size scale with default scale and image scale', async function () { const actual = 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACaUlEQVR4AbXBMWvrWBSF0c9BsFPtW91UR1U6+///FKlKKt8qqnyqnMozggkI8xgMj6x1uv+L/6zryrIsrOvKsiys68qyLFwuF87nM5fLhfP5zOVy4Xw+84wXftkLv2ziQBK26b0TEVQVu4jANrvM5Hq9spOEJCQhCUlI4mjiQBK26b1TVewkYRvb7DKTMQaZiW1s01rDNraRxNHEgSRaa1QVO0m01jjKTDKTXe+d3jtVxU4SjyYOJGGbnSRs03snM8lMMpPb7UZmkplEBFXFThK2eTRxIAnbSMI2VcX39zdjDMYYZCaZyRiDMQZVxU4StqkqHk0cSEISf5KZ7DKTMQbLsrCTRGuN3jtVxaOJg6qiqqgqqoqqoqoYY5CZ7GwTEdzvd97f34kIeu/YRhKPJg6qiswkM7ndbmQmmUlmkpnsbBMR2CYimOeZ3ju2kcSjiYOqIjP5+vpi2za2bWPbNo5aa7TW2PXe6b3Te6e1hiQeTRxUFbfbjW3bGGNwvV4ZY2Ab27TWsI1tbGMb27TWsI0kHk0cVBWZybZtXK9XPj8/+fj4YJ5nIoLWGraJCOZ5RhKSkIQkJPFo4qCqyEy2bWOMwefnJ+u6cjqdsM3ONvM8cz6feca0ris/rtcrmcnONhHB/X7n/f2diKD3jm0k8axpWRZ+ZCaZyc42EYFtIoJ5num9YxtJPGta15U/sY1tdm9vb/Te6b1jG0k8a1qWhR+2sU1rjdYatrGNbWxjm9YaknjWtK4rPyKCiKC1hm0igojg9fUVSUhCEpJ41rQsC0e22dkmIrhcLvyNF/7H6XTib73wy174Zf8AJEsePtlPj10AAAAASUVORK5CYII='; await _find.helpers.fixImageTemplateScale(TINY_PNG, { defaultImageTemplateScale: 4.0, fixImageTemplateScale: true, xScale: 1.5, yScale: 1.5 }).should.eventually.eql(actual); }); it('should not fix template size scale with default scale and image scale', async function () { const actual = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwUlEQVR4AaXBPUsrQQCG0SeX+cBdkTjwTpG1NPgLpjY/fW1stt4UYmm2cJqwMCsaw70uJJ3CBc9Z/P3Cl+12S9u2tG1L27bEGLm/v2ez2bDZbJDEd/7wS4YT7z3X19fc3Nxwd3dHXdd47xnHkefnZ8ZxpKoq6rqmqiqMMcwMJ1VV0TQN0zThnOPj44O6rsk503UdkmiahqZpWK1WGGOYGU7quqZpGqy1SCLnTM6Z19dXcs5IYpomrLVI4uLigpnhpKoqVqsVkjgcDjw9PdF1HTlnuq5DEs45JHE4HDgznByPR97e3pimiVIK4zhyPB7x3hNCIITA5eUl3nsWiwVnhpNSCsMwsNvtGIaB/X5PKQVJpJSQxHq9RhLOOc4MJ9M0sdvt2G639H3PTBIxRiQhCUnEGLHWcmY4KaUwDAN93/P4+MhyuSSlhCRSSkjCOYe1FmstZ6bve2YvLy/s93tmy+USSUhCEpIIIfAd8/DwwOz9/Z1SCpJIKSGJ9XqNJJxz/MS0bcvs6uoKScQYkYQkJBFjxFrLT0zbtsxub29JKSGJlBKScM5hrcVay09MzplZjJHPz0+894QQCCHwP/7wS/8A4e6nAg+R8LwAAAAASUVORK5CYII='; await _find.helpers.fixImageTemplateScale(TINY_PNG, { defaultImageTemplateScale: 4.0, fixImageTemplateScale: false, xScale: 1.5, yScale: 1.5 }).should.eventually.eql(actual); }); it('should not fix template size scale because of ignoreDefaultImageTemplateScale', async function () { await _find.helpers.fixImageTemplateScale(TINY_PNG, { defaultImageTemplateScale: 4.0, ignoreDefaultImageTemplateScale: true }).should.eventually.eql(TINY_PNG); }); it('should ignore defaultImageTemplateScale to fix template size scale because of ignoreDefaultImageTemplateScale', async function () { const actual = 'iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAWElEQVR4AU3BQRWAQAhAwa/PGBsEgrC16AFBKEIPXW7OXO+Rmey9iQjMjHFzrLUwM7qbqmLcHKpKRFBVuDvj4agq3B1VRUQYT2bS3QwRQVUZF/CaGRHB3wc1vSZbHO5+BgAAAABJRU5ErkJggg=='; await _find.helpers.fixImageTemplateScale(TINY_PNG, { defaultImageTemplateScale: 4.0, ignoreDefaultImageTemplateScale: true, fixImageTemplateScale: true, xScale: 1.5, yScale: 1.5 }).should.eventually.eql(actual); }); }); describe('ensureTemplateSize', function () { it('should not resize the template if it is smaller than the screen', async function () { const screen = TINY_PNG_DIMS.map(n => n * 2); const d = new TestDriver(); await d.ensureTemplateSize(TINY_PNG, ...screen).should.eventually.eql(TINY_PNG); }); it('should not resize the template if it is the same size as the screen', async function () { const d = new TestDriver(); await d.ensureTemplateSize(TINY_PNG, ...TINY_PNG_DIMS).should.eventually.eql(TINY_PNG); }); it('should resize the template if it is bigger than the screen', async function () { const d = new TestDriver(); const screen = TINY_PNG_DIMS.map(n => n / 2); const newTemplate = await d.ensureTemplateSize(TINY_PNG, ...screen); newTemplate.should.not.eql(TINY_PNG); newTemplate.length.should.be.below(TINY_PNG.length); }); }); describe('getScreenshotForImageFind', function () { it('should fail if driver does not support getScreenshot', async function () { const d = new _.BaseDriver(); await d.getScreenshotForImageFind().should.eventually.be.rejectedWith(/driver does not support/); }); it('should not adjust or verify screenshot if asked not to by settings', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG); d.settings.update({ fixImageFindScreenshotDims: false }); const screen = TINY_PNG_DIMS.map(n => n + 1); const { b64Screenshot, scale } = await d.getScreenshotForImageFind(...screen); b64Screenshot.should.eql(TINY_PNG); should.equal(scale, undefined); }); it('should return screenshot without adjustment if it matches screen size', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG); const { b64Screenshot, scale } = await d.getScreenshotForImageFind(...TINY_PNG_DIMS); b64Screenshot.should.eql(TINY_PNG); should.equal(scale, undefined); }); it('should return scaled screenshot with same aspect ratio if matching screen aspect ratio', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG); const screen = TINY_PNG_DIMS.map(n => n * 1.5); const { b64Screenshot, scale } = await d.getScreenshotForImageFind(...screen); b64Screenshot.should.not.eql(TINY_PNG); const screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot); screenshotObj.bitmap.width.should.eql(screen[0]); screenshotObj.bitmap.height.should.eql(screen[1]); scale.should.eql({ xScale: 1.5, yScale: 1.5 }); }); it('should return scaled screenshot with different aspect ratio if not matching screen aspect ratio', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG); let screen = [TINY_PNG_DIMS[0] * 2, TINY_PNG_DIMS[1] * 3]; let expectedScale = { xScale: 2.67, yScale: 4 }; const { b64Screenshot, scale } = await d.getScreenshotForImageFind(...screen); b64Screenshot.should.not.eql(TINY_PNG); let screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot); screenshotObj.bitmap.width.should.eql(screen[0]); screenshotObj.bitmap.height.should.eql(screen[1]); scale.xScale.toFixed(2).should.eql(expectedScale.xScale.toString()); scale.yScale.should.eql(expectedScale.yScale); screen = [TINY_PNG_DIMS[0] * 3, TINY_PNG_DIMS[1] * 2]; expectedScale = { xScale: 4, yScale: 2.67 }; const { b64Screenshot: newScreen, scale: newScale } = await d.getScreenshotForImageFind(...screen); newScreen.should.not.eql(TINY_PNG); screenshotObj = await _appiumSupport.imageUtil.getJimpImage(newScreen); screenshotObj.bitmap.width.should.eql(screen[0]); screenshotObj.bitmap.height.should.eql(screen[1]); newScale.xScale.should.eql(expectedScale.xScale); newScale.yScale.toFixed(2).should.eql(expectedScale.yScale.toString()); }); it('should return scaled screenshot with different aspect ratio if not matching screen aspect ratio with fixImageTemplateScale', async function () { const d = new TestDriver(); _sinon.default.stub(d, 'getScreenshot').returns(TINY_PNG); let screen = [TINY_PNG_DIMS[0] * 2, TINY_PNG_DIMS[1] * 3]; let expectedScale = { xScale: 2.67, yScale: 4 }; const { b64Screenshot, scale } = await d.getScreenshotForImageFind(...screen); b64Screenshot.should.not.eql(TINY_PNG); let screenshotObj = await _appiumSupport.imageUtil.getJimpImage(b64Screenshot); screenshotObj.bitmap.width.should.eql(screen[0]); screenshotObj.bitmap.height.should.eql(screen[1]); scale.xScale.toFixed(2).should.eql(expectedScale.xScale.toString()); scale.yScale.should.eql(expectedScale.yScale); await _find.helpers.fixImageTemplateScale(b64Screenshot, { fixImageTemplateScale: true, scale }).should.eventually.eql('iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMCAYAAABfnvydAAAAJ0lEQVR4AYXBAQEAIACDMKR/p0fTBrKdbZcPCRIkSJAgQYIECRIkPAzBA1TpeNwZAAAAAElFTkSuQmCC'); screen = [TINY_PNG_DIMS[0] * 3, TINY_PNG_DIMS[1] * 2]; expectedScale = { xScale: 4, yScale: 2.67 }; const { b64Screenshot: newScreen, scale: newScale } = await d.getScreenshotForImageFind(...screen); newScreen.should.not.eql(TINY_PNG); screenshotObj = await _appiumSupport.imageUtil.getJimpImage(newScreen); screenshotObj.bitmap.width.should.eql(screen[0]); screenshotObj.bitmap.height.should.eql(screen[1]); newScale.xScale.should.eql(expectedScale.xScale); newScale.yScale.toFixed(2).should.eql(expectedScale.yScale.toString()); await _find.helpers.fixImageTemplateScale(newScreen, { fixImageTemplateScale: true, scale }).should.eventually.eql('iVBORw0KGgoAAAANSUhEUgAAAAwAAAAICAYAAADN5B7xAAAAI0lEQVR4AZXBAQEAMAyDMI5/T5W2ayB5245AIokkkkgiiST6+W4DTLyo5PUAAAAASUVORK5CYII='); }); }); }); describe('custom element finding plugins', function () { it('should find a single element using a custom finder', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.eql('bar'); }); it('should not require selector prefix if only one find plugin is registered', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'foo').should.eventually.eql('bar'); }); it('should find multiple elements using a custom finder', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElements(_find.CUSTOM_STRATEGY, 'f:foos').should.eventually.eql(['baz1', 'baz2']); }); it('should give a hint to the plugin about whether multiple are requested', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foos').should.eventually.eql('bar1'); }); it('should be able to use multiple find modules', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE, g: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.eql('bar'); await d.findElement(_find.CUSTOM_STRATEGY, 'g:foo').should.eventually.eql('bar'); }); it('should throw an error if customFindModules is not set', async function () { const d = new _.BaseDriver(); await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/customFindModules/); }); it('should throw an error if customFindModules is the wrong shape', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = CUSTOM_FIND_MODULE; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/customFindModules/); }); it('should throw an error if customFindModules is size > 1 and no selector prefix is used', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE, g: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'foo').should.eventually.be.rejectedWith(/multiple element finding/i); }); it('should throw an error in attempt to use unregistered plugin', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE, g: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'z:foo').should.eventually.be.rejectedWith(/was not registered/); }); it('should throw an error if plugin cannot be loaded', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: './foo.js' }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/could not load/i); }); it('should throw an error if plugin is not the right shape', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: BAD_CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:foo').should.eventually.be.rejectedWith(/constructed correctly/i); }); it('should pass on an error thrown by the finder itself', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:error').should.eventually.be.rejectedWith(/plugin error/i); }); it('should throw no such element error if element not found', async function () { const d = new _.BaseDriver(); d.opts.customFindModules = { f: CUSTOM_FIND_MODULE }; await d.findElement(_find.CUSTOM_STRATEGY, 'f:nope').should.eventually.be.rejectedWith(/could not be located/); }); });require('source-map-support').install(); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvYmFzZWRyaXZlci9jb21tYW5kcy9maW5kLXNwZWNzLmpzIl0sIm5hbWVzIjpbInNob3VsZCIsImNoYWkiLCJ1c2UiLCJjaGFpQXNQcm9taXNlZCIsIlRlc3REcml2ZXIiLCJCYXNlRHJpdmVyIiwiZ2V0V2luZG93U2l6ZSIsImdldFNjcmVlbnNob3QiLCJDVVNUT01fRklORF9NT0RVTEUiLCJwYXRoIiwicmVzb2x2ZSIsIl9fZGlybmFtZSIsIkJBRF9DVVNUT01fRklORF9NT0RVTEUiLCJUSU5ZX1BORyIsIlRJTllfUE5HX0RJTVMiLCJkZXNjcmliZSIsIml0IiwiZCIsInNpbm9uIiwic3R1YiIsInJldHVybnMiLCJmaW5kRWxlbWVudCIsIklNQUdFX1NUUkFURUdZIiwiZXZlbnR1YWxseSIsImJlIiwidHJ1ZSIsImZpbmRFbGVtZW50cyIsImZpbmRFbGVtZW50RnJvbUVsZW1lbnQiLCJyZWplY3RlZFdpdGgiLCJmaW5kRWxlbWVudHNGcm9tRWxlbWVudCIsInJlY3QiLCJ4IiwieSIsIndpZHRoIiwiaGVpZ2h0Iiwic2l6ZSIsInNjcmVlbnNob3QiLCJ0ZW1wbGF0ZSIsImJhc2ljU3R1YiIsImRyaXZlciIsInNpemVTdHViIiwic2NyZWVuU3R1YiIsImNvbXBhcmVTdHViIiwiYmFzaWNJbWdFbFZlcmlmeSIsImltZ0VsUHJvdG8iLCJpbWdFbElkIiwiRUxFTUVOVCIsIl9pbWdFbENhY2hlIiwiaGFzIiwiaW1nRWwiLCJnZXQiLCJJbWFnZUVsZW1lbnQiLCJlcWwiLCJmaW5kQnlJbWFnZSIsIm11bHRpcGxlIiwiZWxzIiwiaGF2ZSIsImxlbmd0aCIsIm5ld1RlbXBsYXRlIiwic2V0dGluZ3MiLCJ1cGRhdGUiLCJmaXhJbWFnZVRlbXBsYXRlU2l6ZSIsImFyZ3MiLCJmaXhJbWFnZVRlbXBsYXRlU2NhbGUiLCJjYWxsQ291bnQiLCJ0aHJvd3MiLCJFcnJvciIsInNldEltcGxpY2l0V2FpdCIsIm9uQ2FsbCIsInNob3VsZENoZWNrU3RhbGVuZXNzIiwiaWQiLCJmYWxzZSIsImhlbHBlcnMiLCJhY3R1YWwiLCJ4U2NhbGUiLCJ5U2NhbGUiLCJkZWZhdWx0SW1hZ2VUZW1wbGF0ZVNjYWxlIiwiaWdub3JlRGVmYXVsdEltYWdlVGVtcGxhdGVTY2FsZSIsInNjcmVlbiIsIm1hcCIsIm4iLCJlbnN1cmVUZW1wbGF0ZVNpemUiLCJub3QiLCJiZWxvdyIsImdldFNjcmVlbnNob3RGb3JJbWFnZUZpbmQiLCJmaXhJbWFnZUZpbmRTY3JlZW5zaG90RGltcyIsImI2NFNjcmVlbnNob3QiLCJzY2FsZSIsImVxdWFsIiwidW5kZWZpbmVkIiwic2NyZWVuc2hvdE9iaiIsImltYWdlVXRpbCIsImdldEppbXBJbWFnZSIsImJpdG1hcCIsImV4cGVjdGVkU2NhbGUiLCJ0b0ZpeGVkIiwidG9TdHJpbmciLCJuZXdTY3JlZW4iLCJuZXdTY2FsZSIsIm9wdHMiLCJjdXN0b21GaW5kTW9kdWxlcyIsImYiLCJDVVNUT01fU1RSQVRFR1kiLCJnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQSxNQUFNQSxNQUFNLEdBQUdDLGNBQUtELE1BQUwsRUFBZjs7QUFDQUMsY0FBS0MsR0FBTCxDQUFTQyx1QkFBVDs7QUFHQSxNQUFNQyxVQUFOLFNBQXlCQyxZQUF6QixDQUFvQztBQUNsQyxRQUFNQyxhQUFOLEdBQXVCLENBQUU7O0FBQ3pCLFFBQU1DLGFBQU4sR0FBdUIsQ0FBRTs7QUFGUzs7QUFLcEMsTUFBTUMsa0JBQWtCLEdBQUdDLGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQyxJQUFwQyxFQUEwQyxJQUExQyxFQUN6QixNQUR5QixFQUNqQixZQURpQixFQUNILFVBREcsRUFDUyx1QkFEVCxDQUEzQjs7QUFFQSxNQUFNQyxzQkFBc0IsR0FBR0gsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLElBQXhCLEVBQThCLElBQTlCLEVBQW9DLElBQXBDLEVBQTBDLElBQTFD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