diff options
Diffstat (limited to 'node_modules/selenium-webdriver/lib')
| -rw-r--r-- | node_modules/selenium-webdriver/lib/by.js | 8 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/command.js | 2 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/firefox/webdriver.xpi | bin | 703396 -> 712979 bytes | |||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/http.js | 93 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/test/data/click_tests/disabled_element.html | 12 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/test/data/nestedElements.html | 11 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/test/index.js | 3 | ||||
| -rw-r--r-- | node_modules/selenium-webdriver/lib/webdriver.js | 127 | 
8 files changed, 201 insertions, 55 deletions
diff --git a/node_modules/selenium-webdriver/lib/by.js b/node_modules/selenium-webdriver/lib/by.js index 8c718be64..fc74b2056 100644 --- a/node_modules/selenium-webdriver/lib/by.js +++ b/node_modules/selenium-webdriver/lib/by.js @@ -259,6 +259,14 @@ function check(locator) {    if (locator instanceof By || typeof locator === 'function') {      return locator;    } + +  if (locator +      && typeof locator === 'object' +      && typeof locator.using === 'string' +      && typeof locator.value === 'string') { +    return new By(locator.using, locator.value); +  } +    for (let key in locator) {      if (locator.hasOwnProperty(key) && By.hasOwnProperty(key)) {        return By[key](locator[key]); diff --git a/node_modules/selenium-webdriver/lib/command.js b/node_modules/selenium-webdriver/lib/command.js index c9a366e4e..39db8c451 100644 --- a/node_modules/selenium-webdriver/lib/command.js +++ b/node_modules/selenium-webdriver/lib/command.js @@ -150,6 +150,8 @@ const Name = {    TAKE_ELEMENT_SCREENSHOT: 'takeElementScreenshot',    IMPLICITLY_WAIT: 'implicitlyWait',    SET_SCRIPT_TIMEOUT: 'setScriptTimeout', + +  GET_TIMEOUT: 'getTimeout',    SET_TIMEOUT: 'setTimeout',    ACCEPT_ALERT: 'acceptAlert', diff --git a/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi b/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi Binary files differindex a7b0fa3a7..6c69f1d32 100644 --- a/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi +++ b/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi diff --git a/node_modules/selenium-webdriver/lib/http.js b/node_modules/selenium-webdriver/lib/http.js index 136a48e63..e141bf190 100644 --- a/node_modules/selenium-webdriver/lib/http.js +++ b/node_modules/selenium-webdriver/lib/http.js @@ -225,6 +225,7 @@ const COMMAND_MAP = new Map([      [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')],      [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')],      [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')], +    [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],      [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],      [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')],      [cmd.Name.CLICK, post('/session/:sessionId/click')], @@ -256,6 +257,10 @@ const COMMAND_MAP = new Map([  /** @const {!Map<string, (CommandSpec|CommandTransformer)>} */  const W3C_COMMAND_MAP = new Map([    [cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')], +  [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert/text')], +  [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert/text')], +  [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/alert/accept')], +  [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/alert/dismiss')],    [cmd.Name.GET_ELEMENT_ATTRIBUTE, (cmd) => {      return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name');    }], @@ -264,11 +269,15 @@ const W3C_COMMAND_MAP = new Map([    [cmd.Name.IS_ELEMENT_DISPLAYED, (cmd) => {      return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id');    }], +  [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute/sync')], +  [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute/async')],    [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/maximize')],    [cmd.Name.GET_WINDOW_POSITION, get('/session/:sessionId/window/position')],    [cmd.Name.SET_WINDOW_POSITION, post('/session/:sessionId/window/position')],    [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/size')],    [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/size')], +  [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window')], +  [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window/handles')],  ]); @@ -428,34 +437,29 @@ class Executor {        return doSend(this, request).then(response => {          this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`); -        let parsed = -            parseHttpResponse( -                command, /** @type {!Response} */ (response), this.w3c); +        let httpResponse = /** @type {!Response} */(response); +        let {isW3C, value} = parseHttpResponse(command, httpResponse);          if (command.getName() === cmd.Name.NEW_SESSION              || command.getName() === cmd.Name.DESCRIBE_SESSION) { -          if (!parsed || !parsed['sessionId']) { +          if (!value || !value.sessionId) {              throw new error.WebDriverError( -                'Unable to parse new session response: ' + response.body); +                `Unable to parse new session response: ${response.body}`);            }            // The remote end is a W3C compliant server if there is no `status`            // field in the response. This is not applicable for the DESCRIBE_SESSION            // command, which is not defined in the W3C spec.            if (command.getName() === cmd.Name.NEW_SESSION) { -            this.w3c = this.w3c || !('status' in parsed); +            this.w3c = this.w3c || isW3C;            } -          return new Session(parsed['sessionId'], parsed['value']); +          // No implementations use the `capabilities` key yet... +          let capabilities = value.capabilities || value.value; +          return new Session(value.sessionId, capabilities);          } -        if (parsed -            && typeof parsed === 'object' -            && 'value' in parsed) { -          let value = parsed['value']; -          return typeof value === 'undefined' ? null : value; -        } -        return parsed; +        return typeof value === 'undefined' ? null : value;        });      });    } @@ -481,40 +485,45 @@ function tryParse(str) {   *   * @param {!cmd.Command} command The command the response is for.   * @param {!Response} httpResponse The HTTP response to parse. - * @param {boolean} w3c Whether the response should be processed using the - *     W3C wire protocol. - * @return {?} The parsed response. + * @return {{isW3C: boolean, value: ?}} An object describing the parsed + *     response. This object will have two fields: `isW3C` indicates whether + *     the response looks like it came from a remote end that conforms with the + *     W3C WebDriver spec, and `value`, the actual response value.   * @throws {WebDriverError} If the HTTP response is an error.   */ -function parseHttpResponse(command, httpResponse, w3c) { -  let parsed = tryParse(httpResponse.body); -  if (parsed !== undefined) { -    if (httpResponse.status < 200) { -      // This should never happen, but throw the raw response so -      // users report it. -      throw new error.WebDriverError( -          `Unexpected HTTP response:\n${httpResponse}`); -    } +function parseHttpResponse(command, httpResponse) { +  if (httpResponse.status < 200) { +    // This should never happen, but throw the raw response so users report it. +    throw new error.WebDriverError( +        `Unexpected HTTP response:\n${httpResponse}`); +  } -    if (w3c) { -      if (httpResponse.status > 399) { -        error.throwDecodedError(parsed); +  let parsed = tryParse(httpResponse.body); +  if (parsed && typeof parsed === 'object') { +    let value = parsed.value; +    let isW3C = +        value !== null && typeof value === 'object' +            && typeof parsed.status === 'undefined'; + +    if (!isW3C) { +      error.checkLegacyResponse(parsed); + +      // Adjust legacy new session responses to look like W3C to simplify +      // later processing. +      if (command.getName() === cmd.Name.NEW_SESSION +          || command.getName() == cmd.Name.DESCRIBE_SESSION) { +        value = parsed;        } -      return parsed; -    } -    // If this is a new session command, we need to check for a W3C compliant -    // error object. This is necessary since a successful new session command -    // is what puts the executor into W3C mode. -    if (httpResponse.status > 399 -        && (command.getName() == cmd.Name.NEW_SESSION -            || command.getName() === cmd.Name.DESCRIBE_SESSION) -        && error.isErrorResponse(parsed)) { -      error.throwDecodedError(parsed); +    } else if (httpResponse.status > 399) { +      error.throwDecodedError(value);      } -    error.checkLegacyResponse(parsed); -    return parsed; +    return {isW3C, value}; +  } + +  if (parsed !== undefined) { +    return {isW3C: false, value: parsed};    }    let value = httpResponse.body.replace(/\r\n/g, '\n'); @@ -527,7 +536,7 @@ function parseHttpResponse(command, httpResponse, w3c) {      throw new error.WebDriverError(value);    } -  return value || null; +  return {isW3C: false, value: value || null};  } diff --git a/node_modules/selenium-webdriver/lib/test/data/click_tests/disabled_element.html b/node_modules/selenium-webdriver/lib/test/data/click_tests/disabled_element.html new file mode 100644 index 000000000..7113e1bc0 --- /dev/null +++ b/node_modules/selenium-webdriver/lib/test/data/click_tests/disabled_element.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> +  <title>Clicking on a disabled element</title> +</head> +<body> +<h1>See below</h1> +<form action="POST"> +  <input name="disabled" disabled="disabled" /> +</form> +</body> +</html>
\ No newline at end of file diff --git a/node_modules/selenium-webdriver/lib/test/data/nestedElements.html b/node_modules/selenium-webdriver/lib/test/data/nestedElements.html index cf00083cf..88eda51fe 100644 --- a/node_modules/selenium-webdriver/lib/test/data/nestedElements.html +++ b/node_modules/selenium-webdriver/lib/test/data/nestedElements.html @@ -5,6 +5,15 @@    <div id="test_id_div">    	<p id="test_id">inside</p>    </div> +  <div id="test_special_chars"> +    <p id="white space">space</p> +    <p id="css#.chars">css escapes</p> +  </div> +  <div id="test_special_chars_2"> +    <p id="white space">second copy for testing plural findElements</p> +    <p id="css#.chars">second copy</p> +  </div> +  <form method="get" action="resultPage.html" name="form1" style="display: block">      Here's a checkbox: <input type="checkbox" id="checky" name="checky" value="furrfu"/><br/>      <select name="selectomatic" id="1"> @@ -152,4 +161,4 @@    <span class="oneother">But not me</span>  </div>  </body> -</html>
\ No newline at end of file +</html> diff --git a/node_modules/selenium-webdriver/lib/test/index.js b/node_modules/selenium-webdriver/lib/test/index.js index b3275ccbb..7dd1a1fc8 100644 --- a/node_modules/selenium-webdriver/lib/test/index.js +++ b/node_modules/selenium-webdriver/lib/test/index.js @@ -50,6 +50,7 @@ var NATIVE_BROWSERS = [  ]; +var noBuild = /^1|true$/i.test(process.env['SELENIUM_NO_BUILD']);  var serverJar = process.env['SELENIUM_SERVER_JAR'];  var remoteUrl = process.env['SELENIUM_REMOTE_URL'];  var useLoopback = process.env['SELENIUM_USE_LOOP_BACK'] == '1'; @@ -225,7 +226,7 @@ function suite(fn, opt_options) {    try {      before(function() { -      if (isDevMode) { +      if (isDevMode && !noBuild) {          return build.of(              '//javascript/atoms/fragments:is-displayed',              '//javascript/webdriver/atoms:getAttribute') diff --git a/node_modules/selenium-webdriver/lib/webdriver.js b/node_modules/selenium-webdriver/lib/webdriver.js index c8d04e82a..1c63112d7 100644 --- a/node_modules/selenium-webdriver/lib/webdriver.js +++ b/node_modules/selenium-webdriver/lib/webdriver.js @@ -1327,6 +1327,91 @@ class Options {    }    /** +   * Schedules a command to fetch the timeouts currently configured for the +   * current session. +   * +   * @return {!promise.Thenable<{script: number, +   *                             pageLoad: number, +   *                             implicit: number}>} A promise that will be +   *     resolved with the timeouts currently configured for the current +   *     session. +   * @see #setTimeouts() +   */ +  getTimeouts() { +    return this.driver_.schedule( +        new command.Command(command.Name.GET_TIMEOUT), +        `WebDriver.manage().getTimeouts()`) +  } + +  /** +   * Schedules a command to set timeout durations associated with the current +   * session. +   * +   * The following timeouts are supported (all timeouts are specified in +   * milliseconds): +   * +   * -  `implicit` specifies the maximum amount of time to wait for an element +   *    locator to succeed when {@linkplain WebDriver#findElement locating} +   *    {@linkplain WebDriver#findElements elements} on the page. +   *    Defaults to 0 milliseconds. +   * +   * -  `pageLoad` specifies the maximum amount of time to wait for a page to +   *    finishing loading. Defaults to 300000 milliseconds. +   * +   * -  `script` specifies the maximum amount of time to wait for an +   *    {@linkplain WebDriver#executeScript evaluated script} to run. If set to +   *    `null`, the script timeout will be indefinite. +   *    Defaults to 30000 milliseconds. +   * +   * @param {{script: (number|null|undefined), +   *          pageLoad: (number|null|undefined), +   *          implicit: (number|null|undefined)}} conf +   *     The desired timeout configuration. +   * @return {!promise.Thenable<void>} A promise that will be resolved when the +   *     timeouts have been set. +   * @throws {!TypeError} if an invalid options object is provided. +   * @see #getTimeouts() +   * @see <https://w3c.github.io/webdriver/webdriver-spec.html#dfn-set-timeouts> +   */ +  setTimeouts({script, pageLoad, implicit} = {}) { +    let cmd = new command.Command(command.Name.SET_TIMEOUT); + +    let valid = false; +    function setParam(key, value) { +      if (value === null || typeof value === 'number') { +        valid = true; +        cmd.setParameter(key, value); +      } else if (typeof value !== 'undefined') { +        throw TypeError( +            'invalid timeouts configuration:' +                + ` expected "${key}" to be a number, got ${typeof value}`); +      } +    } +    setParam('implicit', implicit); +    setParam('pageLoad', pageLoad); +    setParam('script', script); + +    if (valid) { +      return this.driver_.schedule(cmd, `WebDriver.manage().setTimeouts()`) +          .catch(() => { +            // Fallback to the legacy method. +            let cmds = []; +            if (typeof script === 'number') { +              cmds.push(legacyTimeout(this.driver_, 'script', script)); +            } +            if (typeof implicit === 'number') { +              cmds.push(legacyTimeout(this.driver_, 'implicit', implicit)); +            } +            if (typeof pageLoad === 'number') { +              cmds.push(legacyTimeout(this.driver_, 'page load', pageLoad)); +            } +            return Promise.all(cmds); +          }); +    } +    throw TypeError('no timeouts specified'); +  } + +  /**     * @return {!Logs} The interface for managing driver     *     logs.     */ @@ -1336,6 +1421,7 @@ class Options {    /**     * @return {!Timeouts} The interface for managing driver timeouts. +   * @deprecated Use {@link #setTimeouts()} instead.     */    timeouts() {      return new Timeouts(this.driver_); @@ -1351,6 +1437,22 @@ class Options {  /** + * @param {!WebDriver} driver + * @param {string} type + * @param {number} ms + * @return {!promise.Thenable<void>} + */ +function legacyTimeout(driver, type, ms) { +  return driver.schedule( +      new command.Command(command.Name.SET_TIMEOUT) +          .setParameter('type', type) +          .setParameter('ms', ms), +      `WebDriver.manage().setTimeouts({${type}: ${ms}})`); +} + + + +/**   * A record object describing a browser cookie.   *   * @record @@ -1432,6 +1534,9 @@ Options.Cookie.prototype.expiry;   *   *    webdriver.manage().timeouts()   * + * @deprecated This has been deprecated in favor of + *     {@link Options#setTimeouts()}, which supports setting multiple timeouts + *     at once.   * @see WebDriver#manage()   * @see Options#timeouts()   */ @@ -1465,9 +1570,11 @@ class Timeouts {     * @param {number} ms The amount of time to wait, in milliseconds.     * @return {!promise.Thenable<void>} A promise that will be resolved     *     when the implicit wait timeout has been set. +   * @deprecated Use {@link Options#setTimeouts() +   *     driver.manage().setTimeouts({implicit: ms})}.     */    implicitlyWait(ms) { -    return this._scheduleCommand(ms, 'implicit', 'implicitlyWait'); +    return this.driver_.manage().setTimeouts({implicit: ms});    }    /** @@ -1478,9 +1585,11 @@ class Timeouts {     * @param {number} ms The amount of time to wait, in milliseconds.     * @return {!promise.Thenable<void>} A promise that will be resolved     *     when the script timeout has been set. +   * @deprecated Use {@link Options#setTimeouts() +   *     driver.manage().setTimeouts({script: ms})}.     */    setScriptTimeout(ms) { -    return this._scheduleCommand(ms, 'script', 'setScriptTimeout'); +    return this.driver_.manage().setTimeouts({script: ms});    }    /** @@ -1491,17 +1600,11 @@ class Timeouts {     * @param {number} ms The amount of time to wait, in milliseconds.     * @return {!promise.Thenable<void>} A promise that will be resolved     *     when the timeout has been set. +   * @deprecated Use {@link Options#setTimeouts() +   *     driver.manage().setTimeouts({pageLoad: ms})}.     */    pageLoadTimeout(ms) { -    return this._scheduleCommand(ms, 'page load', 'pageLoadTimeout'); -  } - -  _scheduleCommand(ms, timeoutIdentifier, timeoutName) { -    return this.driver_.schedule( -        new command.Command(command.Name.SET_TIMEOUT). -            setParameter('type', timeoutIdentifier). -            setParameter('ms', ms), -        `WebDriver.manage().timeouts().${timeoutName}(${ms})`); +    return this.driver_.manage().setTimeouts({pageLoad: ms});    }  } @@ -2083,6 +2186,7 @@ class WebElement {      if (!this.driver_.fileDetector_) {        return this.schedule_(            new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). +              setParameter('text', keys).                setParameter('value', keys),            'WebElement.sendKeys()');      } @@ -2098,6 +2202,7 @@ class WebElement {        }).then(function(keys) {          return element.schedule_(              new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). +                setParameter('text', keys).                  setParameter('value', keys.split('')),              'WebElement.sendKeys()');        });  | 
