UNPKG

@freelancercom/blue-harvest

Version:
97 lines 4.88 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.retryingFind = void 0; const protractor_1 = require("protractor"); const logger_1 = require("./logger"); // tslint:disable:no-require-imports "browser_side_scripts.js" is a file // which is sent to the browser under test via webdriver's execute script. // It must be uncompiled JavaScript. const browserSideScripts = require('./browser_side_scripts.js'); /** * Retrying Find does several things to improve stability for tests. Throws * an error if the element is not found. Returns the found WebElement, or * true if the element was not desired and was not found. * * NOTE: We are attempting to deprecate all the extra retries here by hooking * Pantheon up to the standard task-based system that Protractor uses to ask * Angular when the page is stable. * * Current stability measures: * - Polling retry until the timeout is hit. * - Make sure the element is visible for two searches at least 0.5 seconds * apart. */ function retryingFind(locatorChain, timeout, description, options) { return __awaiter(this, void 0, void 0, function* () { let failure = 'Failure reason unknown'; let okSince = 0; const returnTimes = []; // Translate values into the form that BrowserSideFind expects. const browserSideLocators = locatorChain.map((positionalLocator) => { const loc = browserSideScripts.browserSideLocator(positionalLocator.locator); loc.direction = positionalLocator.position; return loc; }); try { return yield protractor_1.browser.wait(() => __awaiter(this, void 0, void 0, function* () { try { // TODO(ralphj): can we replace this with browser.findElement and use // the JS locator strategy? Probably not, because it sometimes returns // a boolean (in the 'not' case). const response = (yield protractor_1.browser.driver.executeScript(browserSideScripts.browserSideFind, browserSideLocators, options)); const returnTime = Date.now(); returnTimes.push(returnTime); // If the return value is a string, this is an error message, element // was not found (or was found if unexpected). if (typeof response === 'string') { failure = response; okSince = 0; return false; } // If the return value was a WebElement or true, the script was // successful. if (okSince === 0) { failure = options.wantZero ? 'Element was unseen, but must be unseen for at least 0.5s' : 'Element found, but must remain visible for at least 0.5s'; okSince = returnTime; } const ELEMENT_STABILITY_TIMEOUT = 500; if (returnTime - okSince >= ELEMENT_STABILITY_TIMEOUT) { return response; } else { return false; } } catch (executeScriptError) { failure = executeScriptError.message; return false; } }), timeout); } catch (waitTimeoutError) { const truncatedReturnTimes = returnTimes.length < 6 ? returnTimes : returnTimes.slice(0, 3).concat('...', returnTimes.slice(-3)); // Log the failure here as well as throwing it, so it shows up in place in // the test log. (0, logger_1.log)(failure); (0, logger_1.log)(`Browser-side find element tried ${returnTimes.length} times at: [${truncatedReturnTimes.join(', ')}]`); throw new Error(`Failed to find ${description}: ${failure}`); } }); } exports.retryingFind = retryingFind; //# sourceMappingURL=find.js.map