How to use this.implicitWait method in Appium Base Driver

Best JavaScript code snippet using appium-base-driver

webdriver.js

Source:webdriver.js Github

copy

Full Screen

1// Licensed to the Software Freedom Conservancy (SFC) under one2// or more contributor license agreements.  See the NOTICE file3// distributed with this work for additional information4// regarding copyright ownership.  The SFC licenses this file5// to you under the Apache License, Version 2.0 (the6// "License"); you may not use this file except in compliance7// with the License.  You may obtain a copy of the License at8//9//   http://www.apache.org/licenses/LICENSE-2.010//11// Unless required by applicable law or agreed to in writing,12// software distributed under the License is distributed on an13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY14// KIND, either express or implied.  See the License for the15// specific language governing permissions and limitations16// under the License.17import webdriver from 'selenium-webdriver'18import { absolutifyUrl } from './utils'19import {20  composePreprocessors,21  preprocessArray,22  interpolateString,23  interpolateScript,24} from './preprocessors'25import { AssertionError, VerificationError } from './errors'26const {27  By,28  Condition,29  until,30  Key,31  WebElement,32  WebElementCondition,33  WebElementPromise,34} = webdriver35const { TimeoutError } = webdriver.error36const POLL_TIMEOUT = 5037const DEFAULT_CAPABILITIES = {38  browserName: 'chrome',39}40const state = Symbol('state')41export default class WebDriverExecutor {42  constructor({ driver, capabilities, server, hooks, implicitWait }) {43    if (driver) {44      this.driver = driver45    } else {46      this.capabilities = capabilities || DEFAULT_CAPABILITIES47      this.server = server48    }49    this.implicitWait = implicitWait || 5 * 100050    this.hooks = hooks51    this.waitForNewWindow = this.waitForNewWindow.bind(this)52  }53  async init({ baseUrl, logger, variables }) {54    this.baseUrl = baseUrl55    this.variables = variables56    this.logger = logger57    this[state] = {}58    if (!this.driver) {59      this.driver = await new webdriver.Builder()60        .withCapabilities(this.capabilities)61        .usingServer(this.server)62        .build()63    }64    this.initialized = true65  }66  async cancel() {67    if (this.cancellable) {68      await this.cancellable.cancel()69    }70  }71  async cleanup() {72    if (this.initialized) {73      await this.driver.quit()74      this.driver = undefined75      this.initialized = false76    }77  }78  isAlive() {79    // webdriver will throw for us, but not necessarily for all commands80    // TODO: check if there are commands that will succeed if we always return true81    return true82  }83  name(command) {84    if (!command) {85      return 'skip'86    }87    const upperCase = command.charAt(0).toUpperCase() + command.slice(1)88    const func = 'do' + upperCase89    if (!this[func]) {90      throw new Error(`Unknown command ${command}`)91    }92    return func93  }94  async executeHook(hook, ...args) {95    if (this.hooks && this.hooks[hook]) {96      await this.hooks[hook].apply(this, args)97    }98  }99  async beforeCommand(commandObject) {100    if (commandObject.opensWindow) {101      this[state].openedWindows = await this.driver.getAllWindowHandles()102    }103    await this.executeHook('onBeforeCommand', { command: commandObject })104  }105  async afterCommand(commandObject) {106    this.cancellable = undefined107    if (commandObject.opensWindow) {108      const handle = await this.wait(109        this.waitForNewWindow,110        commandObject.windowTimeout111      )112      this.variables.set(commandObject.windowHandleName, handle)113      await this.executeHook('onWindowAppeared', {114        command: commandObject,115        windowHandleName: commandObject.windowHandleName,116        windowHandle: handle,117      })118    }119    await this.executeHook('onAfterCommand', { command: commandObject })120  }121  async waitForNewWindow() {122    const currentHandles = await this.driver.getAllWindowHandles()123    return currentHandles.find(124      handle => !this[state].openedWindows.includes(handle)125    )126  }127  registerCommand(commandName, fn) {128    this['do' + commandName.charAt(0).toUpperCase() + commandName.slice(1)] = fn129  }130  // Commands go after this line131  async skip() {132    return Promise.resolve()133  }134  // window commands135  async doOpen(url) {136    await this.driver.get(absolutifyUrl(url, this.baseUrl))137  }138  async doSetWindowSize(widthXheight) {139    const [width, height] = widthXheight.split('x')140    await this.driver141      .manage()142      .window()143      .setSize(parseInt(width), parseInt(height))144  }145  async doSelectWindow(handleLocator) {146    const prefix = 'handle='147    if (handleLocator.startsWith(prefix)) {148      const handle = handleLocator.substr(prefix.length)149      await this.driver.switchTo().window(handle)150      await this.executeHook('onWindowSwitched', {151        windowHandle: handle,152      })153    } else {154      throw new Error(155        'Invalid window handle given (e.g. handle=${handleVariable})'156      )157    }158  }159  async doClose() {160    await this.driver.close()161  }162  async doSelectFrame(locator) {163    const targetLocator = this.driver.switchTo()164    if (locator === 'relative=top') {165      await targetLocator.defaultContent()166    } else if (locator === 'relative=parent') {167      await targetLocator.parentFrame()168    } else if (locator.startsWith('index=')) {169      await targetLocator.frame(+locator.substr('index='.length))170    } else {171      const element = await this.waitForElement(locator)172      await targetLocator.frame(element)173    }174  }175  async doSubmit() {176    throw new Error(177      '"submit" is not a supported command in Selenium WebDriver. Please re-record the step.'178    )179  }180  // mouse commands181  async doAddSelection(locator, optionLocator, commandObject = {}) {182    const element = await this.waitForElement(183      locator,184      commandObject.targetFallback185    )186    const option = await element.findElement(parseOptionLocator(optionLocator))187    const selections = await this.driver.executeScript(188      'return arguments[0].selectedOptions',189      element190    )191    if (!(await findElement(selections, option))) {192      await option.click()193    }194  }195  async doRemoveSelection(locator, optionLocator, commandObject = {}) {196    const element = await this.waitForElement(197      locator,198      commandObject.targetFallback199    )200    if (!(await element.getAttribute('multiple'))) {201      throw new Error('Given element is not a multiple select type element')202    }203    const option = await element.findElement(parseOptionLocator(optionLocator))204    const selections = await this.driver.executeScript(205      'return arguments[0].selectedOptions',206      element207    )208    if (await findElement(selections, option)) {209      await option.click()210    }211  }212  async doCheck(locator, _, commandObject = {}) {213    const element = await this.waitForElement(214      locator,215      commandObject.targetFallback216    )217    if (!(await element.isSelected())) {218      await element.click()219    }220  }221  async doUncheck(locator, _, commandObject = {}) {222    const element = await this.waitForElement(223      locator,224      commandObject.targetFallback225    )226    if (await element.isSelected()) {227      await element.click()228    }229  }230  async doClick(locator, _, commandObject = {}) {231    const element = await this.waitForElement(232      locator,233      commandObject.targetFallback234    )235    await element.click()236  }237  async doClickAt(locator, coordString, commandObject = {}) {238    const coords = parseCoordString(coordString)239    const element = await this.waitForElement(240      locator,241      commandObject.targetFallback242    )243    await this.driver244      .actions({ bridge: true })245      .move({ origin: element, ...coords })246      .click()247      .perform()248  }249  async doDoubleClick(locator, _, commandObject = {}) {250    const element = await this.waitForElement(251      locator,252      commandObject.targetFallback253    )254    await this.driver255      .actions({ bridge: true })256      .doubleClick(element)257      .perform()258  }259  async doDoubleClickAt(locator, coordString, commandObject = {}) {260    const coords = parseCoordString(coordString)261    const element = await this.waitForElement(262      locator,263      commandObject.targetFallback264    )265    await this.driver266      .actions({ bridge: true })267      .move({ origin: element, ...coords })268      .doubleClick()269      .perform()270  }271  async doDragAndDropToObject(dragLocator, dropLocator, commandObject = {}) {272    const drag = await this.waitForElement(273      dragLocator,274      commandObject.targetFallback275    )276    const drop = await this.waitForElement(277      dropLocator,278      commandObject.valueFallback279    )280    await this.driver281      .actions({ bridge: true })282      .dragAndDrop(drag, drop)283      .perform()284  }285  async doMouseDown(locator, _, commandObject = {}) {286    const element = await this.waitForElement(287      locator,288      commandObject.targetFallback289    )290    await this.driver291      .actions({ bridge: true })292      .move({ origin: element })293      .press()294      .perform()295  }296  async doMouseDownAt(locator, coordString, commandObject = {}) {297    const coords = parseCoordString(coordString)298    const element = await this.waitForElement(299      locator,300      commandObject.targetFallback301    )302    await this.driver303      .actions({ bridge: true })304      .move({ origin: element, ...coords })305      .press()306      .perform()307  }308  async doMouseMoveAt(locator, coordString, commandObject = {}) {309    const coords = parseCoordString(coordString)310    const element = await this.waitForElement(311      locator,312      commandObject.targetFallback313    )314    await this.driver315      .actions({ bridge: true })316      .move({ origin: element, ...coords })317      .perform()318  }319  async doMouseOut(locator, _, commandObject = {}) {320    const element = await this.waitForElement(321      locator,322      commandObject.targetFallback323    )324    const [rect, vp] = await this.driver.executeScript(325      'return [arguments[0].getBoundingClientRect(), {height: window.innerHeight, width: window.innerWidth}];',326      element327    )328    // try top329    if (rect.top > 0) {330      const y = -(rect.height / 2 + 1)331      return await this.driver332        .actions({ bridge: true })333        .move({ origin: element, y })334        .perform()335    }336    // try right337    else if (vp.width > rect.right) {338      const x = rect.right / 2 + 1339      return await this.driver340        .actions({ bridge: true })341        .move({ origin: element, x })342        .perform()343    }344    // try bottom345    else if (vp.height > rect.bottom) {346      const y = rect.height / 2 + 1347      return await this.driver348        .actions({ bridge: true })349        .move({ origin: element, y })350        .perform()351    }352    // try left353    else if (rect.left > 0) {354      const x = parseInt(-(rect.right / 2))355      return await this.driver356        .actions({ bridge: true })357        .move({ origin: element, x })358        .perform()359    }360    throw new Error(361      'Unable to perform mouse out as the element takes up the entire viewport'362    )363  }364  async doMouseOver(locator, _, commandObject = {}) {365    const element = await this.waitForElement(366      locator,367      commandObject.targetFallback368    )369    await this.driver370      .actions({ bridge: true })371      .move({ origin: element })372      .perform()373  }374  async doMouseUp(locator, _, commandObject = {}) {375    const element = await this.waitForElement(376      locator,377      commandObject.targetFallback378    )379    await this.driver380      .actions({ bridge: true })381      .move({ origin: element })382      .release()383      .perform()384  }385  async doMouseUpAt(locator, coordString, commandObject = {}) {386    const coords = parseCoordString(coordString)387    const element = await this.waitForElement(388      locator,389      commandObject.targetFallback390    )391    await this.driver392      .actions({ bridge: true })393      .move({ origin: element, ...coords })394      .release()395      .perform()396  }397  async doSelect(locator, optionLocator, commandObject = {}) {398    const element = await this.waitForElement(399      locator,400      commandObject.targetFallback401    )402    const option = await element.findElement(parseOptionLocator(optionLocator))403    await option.click()404  }405  // keyboard commands406  async doEditContent(locator, value, commandObject = {}) {407    const element = await this.waitForElement(408      locator,409      commandObject.targetFallback410    )411    await this.driver.executeScript(412      "if(arguments[0].contentEditable === 'true') {arguments[0].innerText = arguments[1]} else {throw new Error('Element is not content editable')}",413      element,414      value415    )416  }417  async doType(locator, value, commandObject = {}) {418    const element = await this.waitForElement(419      locator,420      commandObject.targetFallback421    )422    await element.clear()423    await element.sendKeys(value)424  }425  async doSendKeys(locator, value, commandObject = {}) {426    const element = await this.waitForElement(427      locator,428      commandObject.targetFallback429    )430    await element.sendKeys(...value)431  }432  // wait commands433  async doWaitForElementEditable(locator, timeout) {434    const element = await this.driver.findElement(parseLocator(locator))435    await this.wait(436      async () => await this.isElementEditable(element),437      parseInt(timeout),438      'Timed out waiting for element to be editable'439    )440  }441  async doWaitForElementNotEditable(locator, timeout) {442    const element = await this.driver.findElement(parseLocator(locator))443    await this.wait(444      async () => !(await this.isElementEditable(element)),445      parseInt(timeout),446      'Timed out waiting for element to not be editable'447    )448  }449  async doWaitForElementPresent(locator, timeout) {450    await this.wait(451      until.elementLocated(parseLocator(locator)),452      parseInt(timeout)453    )454  }455  async doWaitForElementNotPresent(locator, timeout) {456    const parsedLocator = parseLocator(locator)457    const elements = await this.driver.findElements(parsedLocator)458    if (elements.length !== 0) {459      await this.wait(until.stalenessOf(elements[0]), parseInt(timeout))460    }461  }462  async doWaitForElementVisible(locator, timeout) {463    const startTime = new Date()464    const element = await this.wait(465      until.elementLocated(parseLocator(locator)),466      parseInt(timeout)467    )468    const elapsed = new Date() - startTime469    await this.wait(until.elementIsVisible(element), timeout - elapsed)470  }471  async doWaitForElementNotVisible(locator, timeout) {472    const parsedLocator = parseLocator(locator)473    const elements = await this.driver.findElements(parsedLocator)474    if (elements.length > 0) {475      await this.wait(until.elementIsNotVisible(elements[0]), parseInt(timeout))476    }477  }478  // script commands479  async doRunScript(script) {480    await this.driver.executeScript(script.script, ...script.argv)481  }482  async doExecuteScript(script, optionalVariable) {483    const result = await this.driver.executeScript(484      script.script,485      ...script.argv486    )487    if (optionalVariable) {488      this.variables.set(optionalVariable, result)489    }490  }491  async doExecuteAsyncScript(script, optionalVariable) {492    const result = await this.driver.executeAsyncScript(493      `var callback = arguments[arguments.length - 1];${script.script}.then(callback).catch(callback);`,494      ...script.argv495    )496    if (optionalVariable) {497      this.variables.set(optionalVariable, result)498    }499  }500  // alert commands501  async doAcceptAlert() {502    await this.driver503      .switchTo()504      .alert()505      .accept()506  }507  async doAcceptConfirmation() {508    await this.driver509      .switchTo()510      .alert()511      .accept()512  }513  async doAnswerPrompt(optAnswer) {514    const alert = await this.driver.switchTo().alert()515    if (optAnswer) {516      await alert.sendKeys(optAnswer)517    }518    await alert.accept()519  }520  async doDismissConfirmation() {521    await this.driver522      .switchTo()523      .alert()524      .dismiss()525  }526  async doDismissPrompt() {527    await this.driver528      .switchTo()529      .alert()530      .dismiss()531  }532  // store commands533  async doStore(string, variable) {534    this.variables.set(variable, string)535    return Promise.resolve()536  }537  async doStoreAttribute(attributeLocator, variable) {538    const attributePos = attributeLocator.lastIndexOf('@')539    const elementLocator = attributeLocator.slice(0, attributePos)540    const attributeName = attributeLocator.slice(attributePos + 1)541    const element = await this.waitForElement(elementLocator)542    const value = await element.getAttribute(attributeName)543    this.variables.set(variable, value)544  }545  async doStoreElementCount(locator, variable) {546    const elements = await this.driver.findElements(parseLocator(locator))547    this.variables.set(variable, elements.length)548  }549  async doStoreJson(json, variable) {550    this.variables.set(variable, JSON.parse(json))551    return Promise.resolve()552  }553  async doStoreText(locator, variable, commandObject = {}) {554    const element = await this.waitForElement(555      locator,556      commandObject.targetFallback557    )558    const text = await element.getText()559    this.variables.set(variable, text)560  }561  async doStoreTitle(variable) {562    const title = await this.driver.getTitle()563    this.variables.set(variable, title)564  }565  async doStoreValue(locator, variable, commandObject = {}) {566    const element = await this.waitForElement(567      locator,568      commandObject.targetFallback569    )570    const value = await element.getAttribute('value')571    this.variables.set(variable, value)572  }573  async doStoreWindowHandle(variable) {574    const handle = await this.driver.getWindowHandle()575    this.variables.set(variable, handle)576    await this.executeHook('onStoreWindowHandle', {577      windowHandle: handle,578      windowHandleName: variable,579    })580  }581  // assertions582  async doAssert(variableName, value) {583    const variable = `${this.variables.get(variableName)}`584    if (variable != value) {585      throw new AssertionError(586        "Actual value '" + variable + "' did not match '" + value + "'"587      )588    }589  }590  async doAssertAlert(expectedText) {591    const alert = await this.driver.switchTo().alert()592    const actualText = await alert.getText()593    if (actualText !== expectedText) {594      throw new AssertionError(595        "Actual alert text '" +596          actualText +597          "' did not match '" +598          expectedText +599          "'"600      )601    }602  }603  async doAssertConfirmation(expectedText) {604    const alert = await this.driver.switchTo().alert()605    const actualText = await alert.getText()606    if (actualText !== expectedText) {607      throw new AssertionError(608        "Actual confirm text '" +609          actualText +610          "' did not match '" +611          expectedText +612          "'"613      )614    }615  }616  async doAssertEditable(locator, _, commandObject = {}) {617    const element = await this.waitForElement(618      locator,619      commandObject.targetFallback620    )621    if (!(await this.isElementEditable(element))) {622      throw new AssertionError('Element is not editable')623    }624  }625  async doAssertNotEditable(locator, _, commandObject = {}) {626    const element = await this.waitForElement(627      locator,628      commandObject.targetFallback629    )630    if (await this.isElementEditable(element)) {631      throw new AssertionError('Element is editable')632    }633  }634  async doAssertPrompt(expectedText) {635    const alert = await this.driver.switchTo().alert()636    const actualText = await alert.getText()637    if (actualText !== expectedText) {638      throw new AssertionError(639        "Actual prompt text '" +640          actualText +641          "' did not match '" +642          expectedText +643          "'"644      )645    }646  }647  async doAssertTitle(title) {648    const actualTitle = await this.driver.getTitle()649    if (title != actualTitle) {650      throw new AssertionError(651        "Actual value '" + actualTitle + "' did not match '" + title + "'"652      )653    }654  }655  async doAssertElementPresent(locator, _, commandObject = {}) {656    await this.waitForElement(locator, commandObject.targetFallback)657  }658  async doAssertElementNotPresent(locator) {659    const elements = await this.driver.findElements(parseLocator(locator))660    if (elements.length) {661      throw new AssertionError('Unexpected element was found in page')662    }663  }664  async doAssertText(locator, value, commandObject = {}) {665    const element = await this.waitForElement(666      locator,667      commandObject.targetFallback668    )669    const text = await element.getText()670    if (text !== value) {671      throw new AssertionError(672        "Actual value '" + text + "' did not match '" + value + "'"673      )674    }675  }676  async doAssertNotText(locator, value, commandObject = {}) {677    const element = await this.waitForElement(678      locator,679      commandObject.targetFallback680    )681    const text = await element.getText()682    if (text === value) {683      throw new AssertionError(684        "Actual value '" + text + "' did match '" + value + "'"685      )686    }687  }688  async doAssertValue(locator, value, commandObject = {}) {689    const element = await this.waitForElement(690      locator,691      commandObject.targetFallback692    )693    const elementValue = await element.getAttribute('value')694    if (elementValue !== value) {695      throw new AssertionError(696        "Actual value '" + elementValue + "' did not match '" + value + "'"697      )698    }699  }700  // not generally implemented701  async doAssertNotValue(locator, value, commandObject = {}) {702    const element = await this.waitForElement(703      locator,704      commandObject.targetFallback705    )706    const elementValue = await element.getAttribute('value')707    if (elementValue === value) {708      throw new AssertionError(709        "Actual value '" + elementValue + "' did match '" + value + "'"710      )711    }712  }713  async doAssertChecked(locator, _, commandObject = {}) {714    const element = await this.waitForElement(715      locator,716      commandObject.targetFallback717    )718    if (!(await element.isSelected())) {719      throw new AssertionError('Element is not checked, expected to be checked')720    }721  }722  async doAssertNotChecked(locator, _, commandObject = {}) {723    const element = await this.waitForElement(724      locator,725      commandObject.targetFallback726    )727    if (await element.isSelected()) {728      throw new AssertionError('Element is checked, expected to be unchecked')729    }730  }731  async doAssertSelectedValue(locator, value, commandObject = {}) {732    const element = await this.waitForElement(733      locator,734      commandObject.targetFallback735    )736    const elementValue = await element.getAttribute('value')737    if (elementValue !== value) {738      throw new AssertionError(739        "Actual value '" + elementValue + "' did not match '" + value + "'"740      )741    }742  }743  async doAssertNotSelectedValue(locator, value, commandObject = {}) {744    const element = await this.waitForElement(745      locator,746      commandObject.targetFallback747    )748    const elementValue = await element.getAttribute('value')749    if (elementValue === value) {750      throw new AssertionError(751        "Actual value '" + elementValue + "' did match '" + value + "'"752      )753    }754  }755  async doAssertSelectedLabel(locator, label, commandObject = {}) {756    const element = await this.waitForElement(757      locator,758      commandObject.targetFallback759    )760    const selectedValue = await element.getAttribute('value')761    const selectedOption = await element.findElement(762      By.xpath(`option[@value="${selectedValue}"]`)763    )764    const selectedOptionLabel = await selectedOption.getText()765    if (selectedOptionLabel !== label) {766      throw new AssertionError(767        "Actual value '" +768          selectedOptionLabel +769          "' did not match '" +770          label +771          "'"772      )773    }774  }775  async doAssertNotSelectedLabel(locator, label, commandObject = {}) {776    const element = await this.waitForElement(777      locator,778      commandObject.targetFallback779    )780    const selectedValue = await element.getAttribute('value')781    const selectedOption = await element.findElement(782      By.xpath(`option[@value="${selectedValue}"]`)783    )784    const selectedOptionLabel = await selectedOption.getText()785    if (selectedOptionLabel === label) {786      throw new AssertionError(787        "Actual value '" + selectedOptionLabel + "' not match '" + label + "'"788      )789    }790  }791  // other commands792  async doDebugger() {793    throw new Error('`debugger` is not supported in this run mode')794  }795  async doEcho(string) {796    if (this.logger) {797      this.logger.log(`echo: ${string}`)798    }799  }800  async doPause(time) {801    await this.driver.sleep(time)802  }803  async doRun() {804    throw new Error('`run` is not supported in this run mode')805  }806  async doSetSpeed() {807    throw new Error('`set speed` is not supported in this run mode')808  }809  async evaluateConditional(script) {810    const result = await this.driver.executeScript(811      `return (${script.script})`,812      ...script.argv813    )814    return {815      value: !!result,816    }817  }818  async waitForElement(locator, fallback) {819    const elementLocator = parseLocator(locator)820    try {821      return await this.wait(822        until.elementLocated(elementLocator),823        this.implicitWait824      )825    } catch (err) {826      if (fallback) {827        for (let i = 0; i < fallback.length; i++) {828          try {829            let loc = parseLocator(fallback[i][0])830            return await this.driver.findElement(loc)831          } catch (e) {832            // try the next one833          }834        }835      }836      throw err837    }838  }839  async isElementEditable(element) {840    const { enabled, readonly } = await this.driver.executeScript(841      'return { enabled: !arguments[0].disabled, readonly: arguments[0].readOnly };',842      element843    )844    return enabled && !readonly845  }846  async wait(847    condition,848    timeout = 0,849    message = undefined,850    pollTimeout = POLL_TIMEOUT851  ) {852    if (typeof timeout !== 'number' || timeout < 0) {853      throw TypeError('timeout must be a number >= 0: ' + timeout)854    }855    if (typeof pollTimeout !== 'number' || pollTimeout < 0) {856      throw TypeError('pollTimeout must be a number >= 0: ' + pollTimeout)857    }858    if (condition && typeof condition.then === 'function') {859      return new Promise((resolve, reject) => {860        if (!timeout) {861          resolve(condition)862          return863        }864        let start = Date.now()865        let timer = setTimeout(function() {866          timer = null867          reject(868            new TimeoutError(869              (message ? `${message}\n` : '') +870                'Timed out waiting for promise to resolve after ' +871                (Date.now() - start) +872                'ms'873            )874          )875        }, timeout)876        const clearTimer = () => timer && clearTimeout(timer)877        condition.then(878          function(value) {879            clearTimer()880            resolve(value)881          },882          function(error) {883            clearTimer()884            reject(error)885          }886        )887      })888    }889    let fn = condition890    if (condition instanceof Condition) {891      message = message || condition.description()892      fn = condition.fn893    }894    if (typeof fn !== 'function') {895      throw TypeError(896        'Wait condition must be a promise-like object, function, or a ' +897          'Condition object'898      )899    }900    const { driver } = this901    function evaluateCondition() {902      return new Promise((resolve, reject) => {903        try {904          resolve(fn(driver))905        } catch (ex) {906          reject(ex)907        }908      })909    }910    let result = new Promise((resolve, reject) => {911      const startTime = Date.now()912      let cancelled = false913      let resolveCancel914      const cancelPromise = new Promise(res => {915        resolveCancel = res916      })917      this.cancellable = {918        cancel: () => {919          cancelled = true920          return cancelPromise921        },922      }923      const pollCondition = async () => {924        evaluateCondition().then(value => {925          const elapsed = Date.now() - startTime926          if (cancelled) {927            resolveCancel()928            reject(new Error('Aborted by user'))929            this.cancellable = undefined930          } else if (value) {931            resolve(value)932            this.cancellable = undefined933          } else if (timeout && elapsed >= timeout) {934            reject(935              new TimeoutError(936                (message ? `${message}\n` : '') +937                  `Wait timed out after ${elapsed}ms`938              )939            )940            this.cancellable = undefined941          } else {942            setTimeout(pollCondition, pollTimeout)943          }944        }, reject)945      }946      pollCondition()947    })948    if (condition instanceof WebElementCondition) {949      result = new WebElementPromise(950        driver,951        result.then(function(value) {952          if (!(value instanceof WebElement)) {953            throw TypeError(954              'WebElementCondition did not resolve to a WebElement: ' +955                Object.prototype.toString.call(value)956            )957          }958          return value959        })960      )961    }962    return result963  }964}965WebDriverExecutor.prototype.doOpen = composePreprocessors(966  interpolateString,967  WebDriverExecutor.prototype.doOpen968)969WebDriverExecutor.prototype.doSetWindowSize = composePreprocessors(970  interpolateString,971  WebDriverExecutor.prototype.doSetWindowSize972)973WebDriverExecutor.prototype.doSelectWindow = composePreprocessors(974  interpolateString,975  WebDriverExecutor.prototype.doSelectWindow976)977WebDriverExecutor.prototype.doSelectFrame = composePreprocessors(978  interpolateString,979  WebDriverExecutor.prototype.doSelectFrame980)981WebDriverExecutor.prototype.doAnswerPrompt = composePreprocessors(982  interpolateString,983  null,984  WebDriverExecutor.prototype.doAnswerPrompt985)986WebDriverExecutor.prototype.doAddSelection = composePreprocessors(987  interpolateString,988  interpolateString,989  {990    targetFallback: preprocessArray(interpolateString),991    valueFallback: preprocessArray(interpolateString),992  },993  WebDriverExecutor.prototype.doAddSelection994)995WebDriverExecutor.prototype.doRemoveSelection = composePreprocessors(996  interpolateString,997  interpolateString,998  {999    targetFallback: preprocessArray(interpolateString),1000    valueFallback: preprocessArray(interpolateString),1001  },1002  WebDriverExecutor.prototype.doRemoveSelection1003)1004WebDriverExecutor.prototype.doCheck = composePreprocessors(1005  interpolateString,1006  null,1007  { targetFallback: preprocessArray(interpolateString) },1008  WebDriverExecutor.prototype.doCheck1009)1010WebDriverExecutor.prototype.doUncheck = composePreprocessors(1011  interpolateString,1012  null,1013  { targetFallback: preprocessArray(interpolateString) },1014  WebDriverExecutor.prototype.doUncheck1015)1016WebDriverExecutor.prototype.doClick = composePreprocessors(1017  interpolateString,1018  null,1019  { targetFallback: preprocessArray(interpolateString) },1020  WebDriverExecutor.prototype.doClick1021)1022WebDriverExecutor.prototype.doClickAt = composePreprocessors(1023  interpolateString,1024  interpolateString,1025  { targetFallback: preprocessArray(interpolateString) },1026  WebDriverExecutor.prototype.doClickAt1027)1028WebDriverExecutor.prototype.doDoubleClick = composePreprocessors(1029  interpolateString,1030  null,1031  { targetFallback: preprocessArray(interpolateString) },1032  WebDriverExecutor.prototype.doDoubleClick1033)1034WebDriverExecutor.prototype.doDoubleClickAt = composePreprocessors(1035  interpolateString,1036  interpolateString,1037  { targetFallback: preprocessArray(interpolateString) },1038  WebDriverExecutor.prototype.doDoubleClickAt1039)1040WebDriverExecutor.prototype.doDragAndDropToObject = composePreprocessors(1041  interpolateString,1042  interpolateString,1043  {1044    targetFallback: preprocessArray(interpolateString),1045    valueFallback: preprocessArray(interpolateString),1046  },1047  WebDriverExecutor.prototype.doDragAndDropToObject1048)1049WebDriverExecutor.prototype.doMouseDown = composePreprocessors(1050  interpolateString,1051  null,1052  {1053    targetFallback: preprocessArray(interpolateString),1054  },1055  WebDriverExecutor.prototype.doMouseDown1056)1057WebDriverExecutor.prototype.doMouseDownAt = composePreprocessors(1058  interpolateString,1059  interpolateString,1060  {1061    targetFallback: preprocessArray(interpolateString),1062  },1063  WebDriverExecutor.prototype.doMouseDownAt1064)1065WebDriverExecutor.prototype.doMouseMoveAt = composePreprocessors(1066  interpolateString,1067  interpolateString,1068  {1069    targetFallback: preprocessArray(interpolateString),1070  },1071  WebDriverExecutor.prototype.doMouseMoveAt1072)1073WebDriverExecutor.prototype.doMouseOut = composePreprocessors(1074  interpolateString,1075  null,1076  {1077    targetFallback: preprocessArray(interpolateString),1078  },1079  WebDriverExecutor.prototype.doMouseOut1080)1081WebDriverExecutor.prototype.doMouseOver = composePreprocessors(1082  interpolateString,1083  null,1084  {1085    targetFallback: preprocessArray(interpolateString),1086  },1087  WebDriverExecutor.prototype.doMouseOver1088)1089WebDriverExecutor.prototype.doMouseUp = composePreprocessors(1090  interpolateString,1091  null,1092  {1093    targetFallback: preprocessArray(interpolateString),1094  },1095  WebDriverExecutor.prototype.doMouseUp1096)1097WebDriverExecutor.prototype.doMouseUpAt = composePreprocessors(1098  interpolateString,1099  interpolateString,1100  {1101    targetFallback: preprocessArray(interpolateString),1102  },1103  WebDriverExecutor.prototype.doMouseUpAt1104)1105WebDriverExecutor.prototype.doSelect = composePreprocessors(1106  interpolateString,1107  interpolateString,1108  {1109    targetFallback: preprocessArray(interpolateString),1110    valueFallback: preprocessArray(interpolateString),1111  },1112  WebDriverExecutor.prototype.doSelect1113)1114WebDriverExecutor.prototype.doEditContent = composePreprocessors(1115  interpolateString,1116  interpolateString,1117  {1118    targetFallback: preprocessArray(interpolateString),1119  },1120  WebDriverExecutor.prototype.doEditContent1121)1122WebDriverExecutor.prototype.doType = composePreprocessors(1123  interpolateString,1124  interpolateString,1125  { targetFallback: preprocessArray(interpolateString) },1126  WebDriverExecutor.prototype.doType1127)1128WebDriverExecutor.prototype.doSendKeys = composePreprocessors(1129  interpolateString,1130  preprocessKeys,1131  { targetFallback: preprocessArray(interpolateString) },1132  WebDriverExecutor.prototype.doSendKeys1133)1134WebDriverExecutor.prototype.doRunScript = composePreprocessors(1135  interpolateScript,1136  WebDriverExecutor.prototype.doRunScript1137)1138WebDriverExecutor.prototype.doExecuteScript = composePreprocessors(1139  interpolateScript,1140  null,1141  WebDriverExecutor.prototype.doExecuteScript1142)1143WebDriverExecutor.prototype.doExecuteAsyncScript = composePreprocessors(1144  interpolateScript,1145  null,1146  WebDriverExecutor.prototype.doExecuteAsyncScript1147)1148WebDriverExecutor.prototype.doStore = composePreprocessors(1149  interpolateString,1150  null,1151  WebDriverExecutor.prototype.doStore1152)1153WebDriverExecutor.prototype.doStoreAttribute = composePreprocessors(1154  interpolateString,1155  null,1156  { targetFallback: preprocessArray(interpolateString) },1157  WebDriverExecutor.prototype.doStoreAttribute1158)1159WebDriverExecutor.prototype.doStoreElementCount = composePreprocessors(1160  interpolateString,1161  null,1162  { targetFallback: preprocessArray(interpolateString) },1163  WebDriverExecutor.prototype.doStoreElementCount1164)1165WebDriverExecutor.prototype.doStoreJson = composePreprocessors(1166  interpolateString,1167  null,1168  WebDriverExecutor.prototype.doStoreJson1169)1170WebDriverExecutor.prototype.doStoreText = composePreprocessors(1171  interpolateString,1172  null,1173  { targetFallback: preprocessArray(interpolateString) },1174  WebDriverExecutor.prototype.doStoreText1175)1176WebDriverExecutor.prototype.doStoreValue = composePreprocessors(1177  interpolateString,1178  null,1179  { targetFallback: preprocessArray(interpolateString) },1180  WebDriverExecutor.prototype.doStoreValue1181)1182WebDriverExecutor.prototype.doAssert = composePreprocessors(1183  null,1184  interpolateString,1185  WebDriverExecutor.prototype.doAssert1186)1187WebDriverExecutor.prototype.doAssertAlert = composePreprocessors(1188  interpolateString,1189  null,1190  WebDriverExecutor.prototype.doAssertAlert1191)1192WebDriverExecutor.prototype.doAssertConfirmation = composePreprocessors(1193  interpolateString,1194  null,1195  WebDriverExecutor.prototype.doAssertConfirmation1196)1197WebDriverExecutor.prototype.doAssertEditable = composePreprocessors(1198  interpolateString,1199  null,1200  { targetFallback: preprocessArray(interpolateString) },1201  WebDriverExecutor.prototype.doAssertEditable1202)1203WebDriverExecutor.prototype.doAssertNotEditable = composePreprocessors(1204  interpolateString,1205  null,1206  { targetFallback: preprocessArray(interpolateString) },1207  WebDriverExecutor.prototype.doAssertNotEditable1208)1209WebDriverExecutor.prototype.doAssertPrompt = composePreprocessors(1210  interpolateString,1211  null,1212  WebDriverExecutor.prototype.doAssertPrompt1213)1214WebDriverExecutor.prototype.doAssertText = composePreprocessors(1215  interpolateString,1216  interpolateString,1217  WebDriverExecutor.prototype.doAssertText1218)1219WebDriverExecutor.prototype.doEcho = composePreprocessors(1220  interpolateString,1221  WebDriverExecutor.prototype.doEcho1222)1223function createVerifyCommands(Executor) {1224  Object.getOwnPropertyNames(Executor.prototype)1225    .filter(command => /^doAssert/.test(command))1226    .forEach(assertion => {1227      const verify = assertion.replace('doAssert', 'doVerify')1228      Executor.prototype[verify] = {1229        // creating the function inside an object since function declared in an1230        // object are named after the property, thus creating dyanmic named funcs1231        // also in order to be able to call(this) the function has to be normal1232        // declaration rather than arrow, as arrow will be bound to1233        // createVerifyCommands context which is undefined1234        [verify]: async function(...args) {1235          try {1236            return await Executor.prototype[assertion].call(this, ...args)1237          } catch (err) {1238            if (err instanceof AssertionError) {1239              throw new VerificationError(err.message)1240            }1241            throw err1242          }1243        },1244      }[verify]1245    })1246}1247createVerifyCommands(WebDriverExecutor)1248function parseLocator(locator) {1249  if (/^\/\//.test(locator)) {1250    return By.xpath(locator)1251  }1252  const fragments = locator.split('=')1253  const type = fragments.shift()1254  const selector = fragments.join('=')1255  if (LOCATORS[type] && selector) {1256    return LOCATORS[type](selector)1257  } else {1258    throw new Error(type ? `Unknown locator ${type}` : "Locator can't be empty")1259  }1260}1261function parseOptionLocator(locator) {1262  const fragments = locator.split('=')1263  const type = fragments.shift()1264  const selector = fragments.join('=')1265  if (OPTIONS_LOCATORS[type] && selector) {1266    return OPTIONS_LOCATORS[type](selector)1267  } else if (!selector) {1268    // no selector strategy given, assuming label1269    return OPTIONS_LOCATORS['label'](type)1270  } else {1271    throw new Error(1272      type ? `Unknown selection locator ${type}` : "Locator can't be empty"1273    )1274  }1275}1276function parseCoordString(coord) {1277  const [x, y] = coord.split(',').map(n => parseInt(n))1278  return {1279    x,1280    y,1281  }1282}1283function preprocessKeys(_str, variables) {1284  const str = interpolateString(_str, variables)1285  let keys = []1286  let match = str.match(/\$\{\w+\}/g)1287  if (!match) {1288    keys.push(str)1289  } else {1290    let i = 01291    while (i < str.length) {1292      let currentKey = match.shift(),1293        currentKeyIndex = str.indexOf(currentKey, i)1294      if (currentKeyIndex > i) {1295        // push the string before the current key1296        keys.push(str.substr(i, currentKeyIndex - i))1297        i = currentKeyIndex1298      }1299      if (currentKey) {1300        if (/^\$\{KEY_\w+\}/.test(currentKey)) {1301          // is a key1302          let keyName = currentKey.match(/\$\{KEY_(\w+)\}/)[1]1303          let key = Key[keyName]1304          if (key) {1305            keys.push(key)1306          } else {1307            throw new Error(`Unrecognised key ${keyName}`)1308          }1309        } else {1310          // not a key, and not a stored variable, push it as-is1311          keys.push(currentKey)1312        }1313        i += currentKey.length1314      } else if (i < str.length) {1315        // push the rest of the string1316        keys.push(str.substr(i, str.length))1317        i = str.length1318      }1319    }1320  }1321  return keys1322}1323const LOCATORS = {1324  id: By.id,1325  name: By.name,1326  link: By.linkText,1327  linkText: By.linkText,1328  partialLinkText: By.partialLinkText,1329  css: By.css,1330  xpath: By.xpath,1331}1332const OPTIONS_LOCATORS = {1333  id: id => By.css(`*[id="${id}"]`),1334  value: value => By.css(`*[value="${value}"]`),1335  label: label => By.xpath(`//option[. = '${label}']`),1336  index: index => By.css(`*:nth-child(${index})`),1337}1338async function findElement(elements, element) {1339  const id = await element.getId()1340  for (let i = 0; i < elements.length; i++) {1341    if ((await elements[i].getId()) === id) {1342      return true1343    }1344  }1345  return false...

Full Screen

Full Screen

selenium-runner.js

Source:selenium-runner.js Github

copy

Full Screen

1/*2 * Copyright 2005 Shinya Kasatani3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 *      http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16/*17 * Code for running Selenium inside Selenium IDE window.18 * This file should be read by the debugger using SubScript Loader.19 */20//21// Patches for Selenium functions22//23MozillaBrowserBot.prototype.__defineGetter__("baseUrl", function() {24  if (!this._baseUrl) {25    LOG.warn("Base URL is not set. Updating base URL from current window.");26    this._baseUrl = editor.getPathAndUpdateBaseURL(this.browserbot.getCurrentWindow())[1];27  }28  return this._baseUrl;29});30MozillaBrowserBot.prototype.__defineSetter__("baseUrl", function(baseUrl) {31  this._baseUrl = baseUrl;32});33MozillaBrowserBot.prototype.setIFrameLocation = function(iframe, location) {34  if (iframe.src) {35    iframe.src = location;36  } else {37    iframe.contentWindow.location.href = location;38  }39};40MozillaBrowserBot.prototype.getReadyState = function(windowObject, currentDocument) {41  var doc = currentDocument;42  if (doc.wrappedJSObject) {43    // document may be wrapped with XPCNativeWrapper, which doesn't allow access to readyState property44    doc = doc.wrappedJSObject;45  }46  if (doc.readyState) {47    return doc.readyState;48  } else {49    return null;50  }51};52MozillaBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) {53  if (windowToModify.wrappedJSObject) {54    windowToModify = windowToModify.wrappedJSObject;55  }56  return BrowserBot.prototype.modifyWindowToRecordPopUpDialogs.call(this, windowToModify, browserBot);57};58//Samit: Fix: Fixing the Alerts not working in Selenium IDE v1.0.11/1259MozillaBrowserBot.prototype.windowNeedsModifying = function(win, uniqueId) {60  if (!win[uniqueId]) {61    win[uniqueId] = 1;62    return true;63  }64  return false;65};66Selenium.prototype.doPause = function(waitTime) {67  currentTest.pauseInterval = waitTime;68};69Selenium.prototype.doEcho = function(message) {70  LOG.info("echo: " + message);71};72Selenium.prototype.doSetSpeed = function(speed) {73  var milliseconds = parseInt(speed);74  if (milliseconds < 0) milliseconds = 0;75  editor.setInterval(milliseconds);76};77Selenium.prototype.getSpeed = function() {78  return editor.getInterval();79};80// doStore* methods are copied from selenium-testrunner.js81Selenium.prototype.doStoreText = function(target, varName) {82  var element = this.page().findElement(target);83  storedVars[varName] = getText(element);84};85Selenium.prototype.doStoreAttribute = function(target, varName) {86  storedVars[varName] = this.page().findAttribute(target);87};88Selenium.prototype.doStore = function(value, varName) {89  storedVars[varName] = value;90};91storedVars.nbsp = String.fromCharCode(160);92storedVars.space = ' ';93function build_sendkeys_maps() {94//  add_sendkeys_key("NULL", '\uE000');95//  add_sendkeys_key("CANCEL", '\uE001'); // ^break96//  add_sendkeys_key("HELP", '\uE002');97  add_sendkeys_key("BACKSPACE", '\uE003', "BKSP");98  add_sendkeys_key("TAB", '\uE004');99//  add_sendkeys_key("CLEAR", '\uE005');100//  add_sendkeys_key("RETURN", '\uE006');101  add_sendkeys_key("ENTER", '\uE007');102  add_sendkeys_key("SHIFT", '\uE008');103  add_sendkeys_key("CONTROL", '\uE009', "CTRL");104  add_sendkeys_key("ALT", '\uE00A');105  add_sendkeys_key("PAUSE", '\uE00B');106  add_sendkeys_key("ESC", '\uE00C', "ESCAPE");107  add_sendkeys_key("SPACE", '\uE00D');108  add_sendkeys_key("PAGE_UP", '\uE00E', "PGUP");109  add_sendkeys_key("PAGE_DOWN", '\uE00F', "PGDN");110  add_sendkeys_key("END", '\uE010');111  add_sendkeys_key("HOME", '\uE011');112  add_sendkeys_key("LEFT", '\uE012');113  add_sendkeys_key("UP", '\uE013');114  add_sendkeys_key("RIGHT", '\uE014');115  add_sendkeys_key("DOWN", '\uE015');116  add_sendkeys_key("INSERT", '\uE016', "INS");117  add_sendkeys_key("DELETE", '\uE017', "DEL");118  add_sendkeys_key("SEMICOLON", '\uE018');119  add_sendkeys_key("EQUALS", '\uE019');120  add_sendkeys_key("NUMPAD0", '\uE01A', "N0", "NUM_ZERO");  // number pad keys121  add_sendkeys_key("NUMPAD1", '\uE01B', "N1", "NUM_ONE");122  add_sendkeys_key("NUMPAD2", '\uE01C', "N2", "NUM_TWO");123  add_sendkeys_key("NUMPAD3", '\uE01D', "N3", "NUM_THREE");124  add_sendkeys_key("NUMPAD4", '\uE01E', "N4", "NUM_FOUR");125  add_sendkeys_key("NUMPAD5", '\uE01F', "N5", "NUM_FIVE");126  add_sendkeys_key("NUMPAD6", '\uE020', "N6", "NUM_SIX");127  add_sendkeys_key("NUMPAD7", '\uE021', "N7", "NUM_SEVEN");128  add_sendkeys_key("NUMPAD8", '\uE022', "N8", "NUM_EIGHT");129  add_sendkeys_key("NUMPAD9", '\uE023', "N9", "NUM_NINE");130  add_sendkeys_key("MULTIPLY", '\uE024', "MUL", "NUM_MULTIPLY");131  add_sendkeys_key("ADD", '\uE025', "PLUS", "NUM_PLUS");132  add_sendkeys_key("SEPARATOR", '\uE026', "SEP");133  add_sendkeys_key("SUBTRACT", '\uE027', "MINUS", "NUM_MINUS");134  add_sendkeys_key("DECIMAL", '\uE028', "PERIOD", "NUM_PERIOD");135  add_sendkeys_key("DIVIDE", '\uE029', "DIV", "NUM_DIVISION");136  add_sendkeys_key("F1", '\uE031');  // function keys137  add_sendkeys_key("F2", '\uE032');138  add_sendkeys_key("F3", '\uE033');139  add_sendkeys_key("F4", '\uE034');140  add_sendkeys_key("F5", '\uE035');141  add_sendkeys_key("F6", '\uE036');142  add_sendkeys_key("F7", '\uE037');143  add_sendkeys_key("F8", '\uE038');144  add_sendkeys_key("F9", '\uE039');145  add_sendkeys_key("F10", '\uE03A');146  add_sendkeys_key("F11", '\uE03B');147  add_sendkeys_key("F12", '\uE03C');148  add_sendkeys_key("META", '\uE03D', "COMMAND");149}150function add_sendkeys_key(key, unicodeChar, alias, botKey) {151  botKey = botKey || key;152  if (bot.Keyboard.Keys[botKey]) {153    storedVars['KEY_' + key] = unicodeChar;154    if (alias) {155      storedVars['KEY_' + alias] = unicodeChar;156    }157    return true;158  }159  return false;160}161build_sendkeys_maps();162var IDETestLoop = classCreate();163objectExtend(IDETestLoop.prototype, TestLoop.prototype);164objectExtend(IDETestLoop.prototype, {165  start : function() {166    selenium.reset();167    selenium.doSetTimeout(editor.app.getOptions().timeout);168    LOG.debug("currentTest.start()");169    this.continueTest();170  },171  initialize: function(commandFactory, handler) {172    TestLoop.call(this, commandFactory);173    this.handler = handler;174  },175  continueTestWhenConditionIsTrue: function() {176    if (shouldAbortCurrentCommand()) {177      this.result = {};178      this.result.failed = true;179      this.result.failureMessage = "interrupted";180      this.commandComplete(this.result);181      this.continueTest();182    } else {183      TestLoop.prototype.continueTestWhenConditionIsTrue.call(this);184    }185  },186  nextCommand: function() {187    if (testCase.debugContext.debugIndex >= 0)188      editor.view.rowUpdated(testCase.debugContext.debugIndex);189    var command = testCase.debugContext.nextCommand();190    if (command == null) return null;191    return new SeleniumCommand(command.command, command.target, command.value);192  },193  commandStarted: function() {194    // editor.setState("playing");195    //setState(Debugger.PLAYING);196    editor.view.rowUpdated(testCase.debugContext.debugIndex);197    editor.view.scrollToRow(testCase.debugContext.debugIndex);198  },199  commandComplete: function(result) {200    this._checkExpectedFailure(result);201    if (result.failed) {202      //TODO Samit: Remove this workaround and try to connect to selenium server before starting test203      if (result.failureMessage.t && result.failureMessage.t === 'RemoteConnectError') {204        result.failureMessage = result.failureMessage.m;  //unwrap message205        setState(Debugger.PAUSED);206      }207      LOG.error(result.failureMessage);208      testCase.debugContext.failed = true;209      testCase.debugContext.currentCommand().result = 'failed';210      testCase.debugContext.currentCommand().failureMessage = result.failureMessage;211    } else if (result.passed) {212      testCase.debugContext.currentCommand().result = 'passed';213    } else {214      testCase.debugContext.currentCommand().result = 'done';215    }216    editor.view.rowUpdated(testCase.debugContext.debugIndex);217  },218  commandError: function(errorMessage) {219    var tempResult = {};220    tempResult.passed = false;221    tempResult.failed = true;222    tempResult.error = true;223    tempResult.failureMessage = errorMessage;224    this._checkExpectedFailure(tempResult);225    if (!tempResult.passed) {226      LOG.debug("commandError");227      testCase.debugContext.failed = true;228      testCase.debugContext.currentCommand().result = 'failed';229      testCase.debugContext.currentCommand().failureMessage = errorMessage;230      editor.view.rowUpdated(testCase.debugContext.debugIndex);231    }232  },233  // override _testComplete to ensure testComplete is called even when234  // ensureNoUnhandledPopups throws any errors235  _testComplete: function() {236    try {237      selenium.ensureNoUnhandledPopups();238    } catch (e) {239      LOG.error(e);240    }241    this.testComplete();242  },243  testComplete: function() {244    LOG.debug("testComplete: failed=" + testCase.debugContext.failed);245    currentTest = null;246    //editor.setState(null);247    //editor.view.rowUpdated(testCase.debugContext.debugIndex);248    var failed = testCase.debugContext.failed;249    testCase.debugContext.reset();250    if (this.handler && this.handler.testComplete) this.handler.testComplete(failed);251  },252  // overide _executeCurrentCommand so we can collect stats of the commands executed253  _executeCurrentCommand : function() {254    /**255     * Execute the current command.256     *257     * @return a function which will be used to determine when258     * execution can continue, or null if we can continue immediately259     */260    var command = this.currentCommand;261    LOG.info("Executing: |" + command.command + " | " + command.target + " | " + command.value + " |");262    var handler = this.commandFactory.getCommandHandler(command.command);263    if (handler == null) {264      throw new SeleniumError("Unknown command: '" + command.command + "'");265    }266    command.target = selenium.preprocessParameter(command.target);267    command.value = selenium.preprocessParameter(command.value);268    LOG.debug("Command found, going to execute " + command.command);269    updateStats(command.command);270    //ImplicitWaitExt, Yu-Xian Chen, SELAB, CSIE, NCKU, 2016/11/07271    if (executeUsingWebDriver) {272      this.result = handler.execute(selenium, command);273      this.waitForCondition = this.result.terminationCondition;274      this.continueTestWhenConditionIsTrue();275    } else {276      this.showNotFoundLog = false;277      this.implicitTime = "";278      var implicitWait = function() {279        try {280          this.elementNotFound = false;281          this.result = handler.execute(selenium, command);282        } catch(e) { 283          var err = e.toString();284          var match_not_found = err.match(/(not found)$/);285          var failed_locator = err.match(/(LOCATOR_DETECTION_FAILED)/);286          this.elementNotFound = match_not_found && !failed_locator;287          // check timed out or not288          if (this.implicitTime && (Date.now() - this.implicitTime) > 30000) {289            this.implicitTimedout = true;290            this.elementNotFound = false; 291            LOG.warn("Sideex: Implicit wait timed out with 30000ms");292            // this.result = {failed: true, failureMessage: extractExceptionMessage(e)};293          }294        } finally {295          if (this.elementNotFound) {296            if (!this.showNotFoundLog) {297              this.showNotFoundLog = true;298              this.implicitTime = Date.now();299              LOG.info("Sideex: Wait until the element is found");300            }301            setTimeout(implicitWait, 100);302          } else {303            if (failed_locator) {304              // need to print error message305              this.result = handler.execute(selenium, command);306              this.waitForCondition = this.result.terminationCondition;307              this.continueTestWhenConditionIsTrue();308            } else if (this.implicitTimedout) {309              this.implicitTimedout = false;310              // print error message and stop testcase311              try {312                this.result = handler.execute(selenium, command);313              } catch (e) {314                if (!this._handleCommandError(e)) {315                    this.testComplete();316                } else {317                    this.continueTest();318                }319              }320            } else {321              this.waitForCondition = this.result.terminationCondition;322              this.continueTestWhenConditionIsTrue();323            }324          }325        }326      }.bind(this);327      implicitWait();328    }329  },330  pause: function() {331    // editor.setState("paused");332    setState(Debugger.PAUSED);333  },334  _checkExpectedFailure: HtmlRunnerTestLoop.prototype._checkExpectedFailure335});336function Logger() {337  var self = this;338  var levels = ["log","debug","info","warn","error"];339  this.maxEntries = 2000;340  this.entries = [];341  levels.forEach(function(level) {342    self[level] = function(message) {343      self.log(message, level);344    }345  });346  this.observers = [];347  this.exception = function(exception) {348    var msg = "Unexpected Exception: " + exception + ". " + describe(exception, ', ');349    this.error(msg);350  }351  this.log = function(message, level) {352    var entry = {353      message: message,354      level: level,355      line: function() {356        return '[' + this.level + '] ' + message + "\n";357      }358    };359    this.entries.push(entry);360    if (this.entries.length > this.maxEntries) this.entries.shift();361    this.observers.forEach(function(o) {362      o.onAppendEntry(entry)363    });364  }365  this.clear = function() {366    this.entries.splice(0, this.entries.length);367    this.observers.forEach(function(o) {368      o.onClear()369    });370  }371}372var LOG = new Logger();373//374// runner functions375//376this.currentTest = null;377this.stopping = false;378function resetCurrentTest() {379  currentTest = null;380  testCase.debugContext.reset();381  for (var i = 0; i < testCase.commands.length; i++) {382    delete testCase.commands[i].result;383    editor.view.rowUpdated(i);384  }385}386function createSelenium(baseURL, useLastWindow) {387  var window;388  if (useLastWindow) {389    window = this.lastWindow;390  }391  if (!window) {392    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);393    window = wm.getMostRecentWindow('navigator:browser');394  }395  this.lastWindow = window;396  var contentWindow = window.getBrowser().selectedBrowser.contentWindow;397  var selenium = Selenium.createForWindow(contentWindow);398  selenium.browserbot.getCurrentPage();399  selenium.browserbot.baseUrl = baseURL;400  return selenium;401}402function start(baseURL, handler, useLastWindow) {403  //if (!stopAndDo("start", baseURL)) return;404  resetCurrentTest();405  //Samit: use the web driver backed selenium406  if (this.executeUsingWebDriver) {407    var webDriverBrowserString = this.editor.getOptions().webDriverBrowserString;408    selenium = new WebdriverBackedSelenium(baseURL, webDriverBrowserString);409  } else {410    selenium = createSelenium(baseURL, useLastWindow);411    selenium.browserbot.selectWindow(null);412  }413  commandFactory = new CommandHandlerFactory();414  commandFactory.registerAll(selenium);415  currentTest = new IDETestLoop(commandFactory, handler);416  currentTest.getCommandInterval = function() {417    return getInterval();418  };419  testCase.debugContext.reset();420  currentTest.start();421  //setState(Debugger.PLAYING);422}423function executeCommand(baseURL, command) {424  //if (!stopAndDo("executeCommand", baseURL, command)) return;425  resetCurrentTest();426  //Samit: use the web driver backed selenium427  if (this.executeUsingWebDriver) {428    var webDriverBrowserString = this.editor.getOptions().webDriverBrowserString;429    selenium = new WebdriverBackedSelenium(baseURL, webDriverBrowserString);430  } else {431    selenium = createSelenium(baseURL);432  }433  commandFactory = new CommandHandlerFactory();434  commandFactory.registerAll(selenium);435  currentTest = new IDETestLoop(commandFactory);436  currentTest.getCommandInterval = function() {437    return 0;438  };439  var first = true;440  currentTest.nextCommand = function() {441    if (first) {442      first = false;443      testCase.debugContext.debugIndex = testCase.commands.indexOf(command);444      return new SeleniumCommand(command.command, command.target, command.value);445    } else {446      return null;447    }448  }449  currentTest.firstCommand = currentTest.nextCommand; // Selenium <= 0.6 only450  currentTest.commandStarted = function() {451    editor.view.rowUpdated(testCase.commands.indexOf(command));452  }453  currentTest.commandComplete = function(result) {454    if (result.failed) {455      command.result = 'failed';456    } else if (result.passed) {457      command.result = 'passed';458    } else {459      command.result = 'done';460    }461    editor.view.rowUpdated(testCase.commands.indexOf(command));462  }463  currentTest.commandError = function() {464    command.result = 'failed';465    editor.view.rowUpdated(testCase.commands.indexOf(command));466  }467  currentTest.start();468}469function continueCurrentTest() {470  if (currentTest != null) {471    if (currentTest.resume) {472      // Selenium 0.7?473      currentTest.resume();474    } else {475      // Selenium 0.6476      currentTest.finishCommandExecution();477    }478  } else {479    LOG.error("currentTest is null");480  }481}482//Samit: Enh: Determine is we are running under Firefox 4 or under mac, so we can fallback on the Selenium Core to do the show483var useHighlightFromCore_ = (function() {484  try {485    var appInfo = Components.classes['@mozilla.org/xre/app-info;1'].486        getService(Components.interfaces.nsIXULAppInfo);487    var versionChecker = Components.classes['@mozilla.org/xpcom/version-comparator;1'].488        getService(Components.interfaces.nsIVersionComparator);489    return (versionChecker.compare(appInfo.version, '4.0') >= 0);490  } catch(e) {491    return false;492  }493})() || (navigator.appVersion.indexOf("Mac") != -1);494function showElement(locator) {495  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);496  var contentWindow = wm.getMostRecentWindow('navigator:browser').getBrowser().contentWindow;497	var selenium = Selenium.createForWindow(contentWindow);498	locator = selenium.preprocessParameter(locator);499  //var pageBot = contentWindow._test_pageBot;500  //if (pageBot == null) {501  var pageBot = new MozillaBrowserBot(contentWindow);502  pageBot.getCurrentWindow = function() {503    return contentWindow;504  }505  //contentWindow._test_pageBot = pageBot;506  //}507  try {508    try {509      var e = pageBot.findElement(locator);510    } catch (error) {   // Samit: Fix: Table locators in the form "tableName.row.column" fail511      // Retry if the locator matches "tableName.row.column", e.g. "mytable.3.4"512      var pattern = /(.*)\.(\d+)\.(\d+)/;513      if (pattern.test(locator)) {514        var pieces = locator.match(pattern);515        // if there is an exception the outer try will catch it516        var table = pageBot.findElement(pieces[1]);517        e = table.rows[pieces[2]].cells[pieces[3]];518      }519    }520    if (e) {521      /* Samit: Since Firefox 4 broke the flasher, simply use the now enhanced version of the highlight from Selenium Core */522      if (useHighlightFromCore_) {523        //Samit: Enh: Provide this functionality on Macs by using the builtin highlight function since flasher component is not supported on Mac524        // see the dom inspector bug for more info - https://bugzilla.mozilla.org/show_bug.cgi?id=368608525        e.scrollIntoView();526        highlight(e);527      } else {528        var flasher = Components.classes["@mozilla.org/inspector/flasher;1"].createInstance()529            .QueryInterface(Components.interfaces.inIFlasher);530        flasher.color = "#88ff88";531        flasher.thickness = 2;532        flasher.invert = false;533        flasher.scrollElementIntoView(e);534        flasher.drawElementOutline(e);535        var flashIndex = 0;536        function animateFlasher() {537          var timeout = 0;538          if (flashIndex % 2 == 0) {539            flasher.repaintElement(e);540            timeout = 300;541          } else {542            flasher.drawElementOutline(e);543            timeout = 300;544          }545          flashIndex++;546          if (flashIndex < 3) {547            setTimeout(animateFlasher, timeout);548          }549        }550        setTimeout(animateFlasher, 300);551      }552    } else {553      LOG.error("locator not found: " + locator);554    }555  } catch (error) {556    LOG.error("locator not found: " + locator + ", error = " + error);557  }...

Full Screen

Full Screen

Session.js

Source:Session.js Github

copy

Full Screen

1var By = require("./By").By;2var Errors = require("./Errors").Errors;3var WebElement = require("./WebElement").WebElement;4var Future = require('fibers/future'), wait = Future.wait;5var http = require("http");6function Request(options, data) {7    var future = new Future();8    var content = "";9    if (data) {10        options.headers['content-length'] = (data) ? JSON.stringify(data).length : 0;11    }12    var request = http.request(options, function(response) {13        response.setEncoding('utf8');14        response.on('data', function (chunk) {15            content += chunk;16        });17        response.on('end', function() {18            future.return({19                data: content,20                status: response.statusCode,21                headers: response.headers22            });23        });24    });25    request.on('error', function(e) {26        console.log('problem with request: ' + e.message);27    });28    if (data) {29        request.write(JSON.stringify(data));30    }31    request.end();32    return future;33}34/**35 Create a new Web Driver session36 @class Session37 @async38 @param {Object} [options]39    Options for WebDriver session40    @param {String} [options.hostname=localhost]41    @param {Number} [options.port=4444] Selenium server port42    @param {String} [options.path="/wd/hub"] Path to Selenium server REST hub43    @param {String} [options.username] Username for Basic authentication44    @param {String} [options.password] Password for Basic authentication45 @param {Function} callback Function context where to run WebDriver commands46 @example47        new WebDriver.Session(function() {48           this.go("http://google.com");49           if (this.title.indexOf("Google") !== -1) {50                console.log("Success!");51           }52        });53 @example54        new WebDriver.Session({55           hostname: "ondemand.saucelabs.com",56           port: 80,57           username: "<username>",58           password: "<password>"59        }, function() {60           this.url = "http://facebook.com";61        });62 @constructor63 **/64var Session = function(options, callback) {65    if (typeof(options) === "function") {66        callback = options;67        options = {};68    }69    options = options || {};70    this.hostname = options.hostname || "localhost";71    this.port = options.port || 4444;72    this.path = options.path || "/wd/hub";73    this.sessionId = null;74    this.username = options.username;75    this.password = options.password;76    this.implicitWait = 0;77    this.desiredCapabilities = options.desiredCapabilities || {78        browserName: "firefox"79    };80    var future = function() {81        this.setup();82        try {83            callback.call(this);84        } catch(e) {85            this.close();86            throw e;87        }88        this.close();89    }.bind(this).future();90    future().resolve(function(err) {91        if (err) {92            throw err;93        }94    });95};96Session.prototype.setup = function() {97    var response = this.POST("/session", {98        desiredCapabilities: this.desiredCapabilities99    }, (this.username && this.password) ? this.username + ":" + this.password : null);100    if (response.status === 302 || response.status === 303) {101        this.sessionId = response.headers.location.substring(response.headers.location.lastIndexOf("/")+1);102    }103};104Session.prototype.close = function() {105    if (this.sessionId) {106        this.DELETE('/session/:sessionId');107    }108    this.sessionId = null;109    return this;110};111Session.prototype.log = function(message, color) {112    console.log(message);113};114Session.prototype.requestOptions = function(path, auth) {115    var options = {116        hostname: this.hostname,117        port: this.port,118        path: this.path + path.replace(':sessionId', this.sessionId),119        method: 'GET',120        headers: {121            'content-type': 'application/json',122            'Accept': 'application/json',123            'charset': 'charset=UTF-8'124        }125    };126    if (auth) {127        options.headers.Authorization = 'Basic ' + (new Buffer(auth)).toString('base64');128    }129    return options;130};131Session.prototype.GET = function(path, auth) {132    this.log("GET " + path);133    return Request(this.requestOptions(path, auth)).wait();134};135Session.prototype.POST = function(path, data, auth) {136    var options = this.requestOptions(path, auth);137    options.method = 'POST';138    this.log("POST " + path);139    return Request(options, data).wait();140};141Session.prototype.DELETE = function(path, auth) {142    var options = this.requestOptions(path, auth);143    options.method = 'DELETE';144    delete options.headers;145    this.log("DELETE " + path);146    return Request(options).wait();147};148Session.prototype.parseResponse = function(data) {149    var response = JSON.parse(data.data);150    if (response.status !== 0) {151        switch (response.status) {152            case 6:153                throw new Errors.NoSuchDriver();154                break;155            case 7:156                throw new Errors.NoSuchElement();157                break;158            case 8:159                throw new Errors.NoSuchFrame();160                break;161            default:162                throw new Error("Error code " + response.status);163        }164    }165    return response.value;166};167Session.prototype.parseElement = function(response) {168    if (response && typeof(response) === "object" && typeof(response.ELEMENT) === "string") {169        return new WebElement(this, response);170    }171    return response;172};173/**174 Navigate forwards in the browser history, if possible.175 @method forward176 @chainable177 */178Session.prototype.forward = function() {179    this.POST("/session/:sessionId/forward");180    return this;181};182/**183 Navigate backwards in the browser history, if possible.184 @method back185 @chainable186 */187Session.prototype.back = function() {188    this.POST("/session/:sessionId/back");189    return this;190};191/**192 Refresh the current page.193 @method refresh194 @chainable195 */196Session.prototype.refresh = function() {197    this.POST("/session/:sessionId/refresh");198    return this;199};200/**201 Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.202 The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.203 Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a WebElement reference will be converted to the corresponding DOM element.204 Likewise, any WebElements in the script result will be returned to the client as WebElement JSON objects.205 @method execute206 @param {Function} func The function to execute207 @param {Array} [args] The function arguments208 @example209        var hiddenElement = this.element("#hidden");210        this.execute(function(element) {211            element.style.display = "block";212        }, hiddenElement);213 @example214        var body = this.execute(function() {215            return document.body;216        });217        this.element("body").equals(body) // true;218 @return The script result.219 */220Session.prototype.execute = function(func, args) {221    args = (Array.isArray(args) ? args : (args ? [args] : [])).map(function(arg){222        return (arg instanceof WebElement) ? arg.element : arg;223    });224    return this.parseElement(this.parseResponse(this.POST("/session/:sessionId/execute", {225        script: "return (" + func.toString() + ").apply(null, arguments);",226        args: args227    })));228};229/**230 Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.231 The executed script is assumed to be asynchronous and must signal that is done by invoking the provided callback, which is always provided as the final argument to the function.232 The value to this callback will be returned to the client.233 Asynchronous script commands may not span page loads. If an unload event is fired while waiting for a script result, an error should be returned to the client.234 The script argument defines the script to execute in the form of a function. The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.235 The final argument will always be a callback function that must be invoked to signal that the script has finished.236 Arguments may be any JSON-primitive, array, or JSON object. WebElement references will be converted to the corresponding DOM element.237 Likewise, any WebElements in the script result will be returned to the client as WebElement objects.238 @method executeAsync239 @param {Function} func The function to execute240 @param {Number} timeout=1000 Set the amount of time, in milliseconds, that asynchronous script permitted to run before they are aborted and a Timeout error is returned to the client.241 @param {Array} [args] The function arguments242 @example243         var input2 = this.executeAsync(function(done) {244           window.setTimeout(function() {245               done(document.getElementById("input2"));246           }, 200);247        }, 1000);248 @example249        var asyncCalculation = this.executeAsync(function(a, b, done) {250           window.setTimeout(function() {251               done(a*b);252           }, 100);253        }, 2000, [5, 10]);254        if (asyncCalculation === 50) {255            console.log("Success! Running asynchronous code synchronously!");256        }257 @return The script result.258 */259Session.prototype.executeAsync = function(func, timeout, args) {260    this.POST("/session/:sessionId/timeouts/async_script", {261        ms: timeout262    });263    args = (Array.isArray(args) ? args : (args ? [args] : [])).map(function(arg){264        return (arg instanceof WebElement) ? arg.element : arg;265    });266    return this.parseElement(this.parseResponse(this.POST("/session/:sessionId/execute_async", {267        script: "return (" + func.toString() + ").apply(null, arguments);",268        args: args269    })));270};271/**272 Take a screenshot of the current page.273 @method screenshot274 @return {String} The screenshot as a base64 encoded PNG.275 */276Session.prototype.screenshot = function() {277    return this.parseResponse(this.GET("/session/:sessionId/screenshot"));278};279/**280 Search for an element on the page, starting from the document root.281 The located element will be returned as a WebElement object.282 Each locator must return the first matching element located in the DOM.283 @method element284 @param {String} value The search target285 @param {Number} [wait=0] Timeout for waiting to appear in milliseconds. 0 for no wait.286 @param {By} [using=By.cssSelector] The locator strategy to use.287 @return {WebElement} A WebElement object for the located element.288 */289Session.prototype.element = function(value, wait, using) {290    wait = wait || 0;291    if (wait !== this.implicitWait) {292        this.implicitWait = wait;293        this.POST("/session/:sessionId/timeouts/implicit_wait", {294            ms: wait295        });296    }297    using = using || By.cssSelector;298    var response = this.POST("/session/:sessionId/element", {299        using: using,300        value: value301    });302    return new WebElement(this, this.parseResponse(response));303};304/**305 Search for multiple elements on the page, starting from the document root.306 The located elements will be returned as an array of WebElement objects.307 Elements should be returned in the order located in the DOM.308 @method elements309 @param {String} value The search target310 @param {Number} [wait=0] Timeout for waiting to appear in milliseconds. 0 for no wait.311 @param {By} [using=By.cssSelector] The locator strategy to use.312 @return {WebElement[]} A list of WebElements for the located elements.313 */314Session.prototype.elements = function(value, wait, using) {315    wait = wait || 0;316    if (wait !== this.implicitWait) {317        this.implicitWait = wait;318        this.POST("/session/:sessionId/timeouts/implicit_wait", {319            ms: wait320        });321    }322    using = using || By.cssSelector;323    var response = this.POST("/session/:sessionId/elements", {324        using: using,325        value: value326    });327    var self = this;328    return this.parseResponse(response).map(function(element) {329        return new WebElement(self, element);330    });331};332/**333 Send a sequence of key strokes to the active element. This command is similar to the send keys command in every aspect except the implicit termination:334 The modifiers are not released at the end of the call. Rather, the state of the modifier keys is kept between calls, so mouse interactions can be335 performed while modifier keys are depressed.336 @method keys337 @param {String|String[]} value The keys sequence to be sent.338 @chainable339 */340Session.prototype.keys = function(value) {341    this.POST("/session/:sessionId/keys", {342        value: Array.isArray(value) ? value : value.split('')343    });344    return this;345};346/**347 Navigate to a new URL.348 @method go349 @param {String} value The URL to navigate to.350 @example351 this.go("http://google.com");352 @chainable353 */354Session.prototype.go = function(url) {355    this.POST("/session/:sessionId/url", {url: url});356    return this;357};358/**359 Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.360 @method acceptAlert361 @chainable362 */363Session.prototype.acceptAlert = function() {364    this.POST("/session/:sessionId/accept_alert");365    return this;366};367/**368 Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.369 For alert() dialogs, this is equivalent to clicking the 'OK' button.370 @method dismissAlert371 @chainable372 */373Session.prototype.dismissAlert = function() {374    this.POST("/session/:sessionId/dismiss_alert");375    return this;376};377/**378 Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor.379 If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.380 For alert() dialogs, this is equivalent to clicking the 'OK' button.381 @method moveMouse382 @param {number} xoffset X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.383 @param {number} yoffset Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.384 @param {WebElement} [element=null] WebElement to use for offset. If not specified or is null, the offset is relative to current position of the mouse.385 @chainable386 */387Session.prototype.moveMouse = function(x, y, element) {388    if (element) {389        element = element.element.ELEMENT;390    }391    this.POST("/session/:sessionId/moveto", {392        element: element,393        xoffset: x || 0,394        yoffset: y || 0395    });396    return this;397};398/**399 Click any mouse button (at the coordinates set by the last moveto command).400 Note that calling this command after calling buttondown and before calling button up (or any out-of-order interactions sequence) will yield undefined behaviour).401 @method click402 @param {MouseButtons} [button=MouseButtons.LEFT]  Which button, enum: {LEFT = 0, MIDDLE = 1 , RIGHT = 2}. Defaults to the left mouse button if not specified.403 @chainable404 */405Session.prototype.click = function(button) {406    this.POST("/session/:sessionId/click", {button: button});407    return this;408};409/**410 Click and hold the left mouse button (at the coordinates set by the last moveto command).411 Note that the next mouse-related command that should follow is buttonup . Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.412 @method buttonDown413 @param {MouseButtons} [button=MouseButtons.LEFT]  Which button, enum: {LEFT = 0, MIDDLE = 1 , RIGHT = 2}. Defaults to the left mouse button if not specified.414 @chainable415 */416Session.prototype.buttonDown = function(button) {417    this.POST("/session/:sessionId/buttondown", {button: button});418    return this;419};420/**421 Releases the mouse button previously held (where the mouse is currently at).422 Must be called once for every buttondown command issued. See the note in click and buttondown about implications of out-of-order commands.423 @method buttonUp424 @param {MouseButtons} [button=MouseButtons.LEFT]  Which button, enum: {LEFT = 0, MIDDLE = 1 , RIGHT = 2}. Defaults to the left mouse button if not specified.425 @chainable426 */427Session.prototype.buttonUp = function(button) {428    this.POST("/session/:sessionId/buttonup", {button: button});429    return this;430};431/**432 Double-clicks at the current mouse coordinates (set by moveto).433 @method doubleClick434 @chainable435 */436Session.prototype.doubleClick = function() {437    this.POST("/session/:sessionId/doubleclick");438    return this;439};440Object.defineProperties(Session.prototype, {441    /**442     Get or set the text of the currently displayed JavaScript `alert()`, `confirm()`, or `prompt()` dialog.443     @attribute alertText444     @type String445     **/446    alertText: {447        set: function(value) {448            this.POST("/session/:sessionId/alert_text", {text: value});449            return this;450        },451        get: function() {452            return this.parseResponse(this.GET("/session/:sessionId/alert_text"));453        }454    },455    /**456     Get the current page title.457     @attribute title458     @readOnly459     @type String460     **/461    title: {462        get: function() {463            return this.parseResponse(this.GET("/session/:sessionId/title"));464        }465    },466    /**467     Get or set the url for the current window.468     @attribute url469     @type String470     **/471    url: {472        set: function(url) {473            return this.go(url);474        },475        get: function() {476            return this.parseResponse(this.GET("/session/:sessionId/url"));477        }478    },479    /**480     Get or set the current browser orientation. The orientation should be specified as defined as `LANDSCAPE` or `PORTRAIT`.481     @attribute orientation482     @type String483     **/484    orientation: {485        set: function(orientation) {486            this.POST("/session/:sessionId/orientation", {orientation: orientation});487            return this;488        },489        get: function() {490            return this.parseResponse(this.GET("/session/:sessionId/orientation"));491        }492    }493});...

Full Screen

Full Screen

implicit-wait-ext.js

Source:implicit-wait-ext.js Github

copy

Full Screen

1/*2 * Copyright 2014 Florent Breheret3 * http://code.google.com/p/selenium-implicit-wait/4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 *      http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16/**17 * Specifies the amount of time it should wait when searching for an element if it is not immediately present.18 * @param {Integer} timeout Timeout in millisecond, set 0 to disable it19 * @exemple20     setImplicitWait | 021     setImplicitWait | 100022 */23Selenium.prototype.doSetImplicitWait = function(timeout){   24    this.browserbot.implicitwait.waitElement_timeout = +timeout || 0;25};26/**27 * Specifies the amount of time it should wait for a condition to be true before executing the command.28 * @param {Integer} timeout Timeout in millisecond, set 0 to disable it29 * @param {String} condition_js Javascript logical expression that need to be true to execute each command.30 * @exemple31     setImplicitWaitCondition |  0  |  32     setImplicitWaitCondition |  1000  | !window.Sys || !window.Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack();33     setImplicitWaitCondition |  1000  | !window.dojo || !window.dojo.io.XMLHTTPTransport.inFlight.length;34     setImplicitWaitCondition |  1000  | !window.Ajax || !window.Ajax.activeRequestCount;35     setImplicitWaitCondition |  1000  | !window.tapestry || !window.tapestry.isServingRequests();36     setImplicitWaitCondition |  1000  | !window.jQuery || !window.jQuery.active;37 */38Selenium.prototype.doSetImplicitWaitCondition = function(timeout, condition_js) {39    var implicitwait = this.browserbot.implicitwait;40    if((implicitwait.preCondition_timeout = +timeout || 0)){41        implicitwait.preCondition = new Function('return ' + condition_js);42        implicitwait.preCondition.__source__ = condition_js;43    }else{44        implicitwait.preCondition = null;45    }46};47if(this.TestLoop){48    49    this.ImplicitWait = function(){50        this.waitElement_timeout = (window.editor && window.editor.implicitwait.timeout) || 0;51        this.preCondition_timeout = 0;52        this.preCondition = null;53    };54    55    /**56     * Overrides BrowserBot.prototype.findElement: function(locator, win) in selenium-browserbot.js line 152457     */58    this.MozillaBrowserBot.prototype.findElementOrNull = function(locator, win){59        var loc = this.locator_cache || (this.locator_cache = parse_locator(locator));    //cache the parsing result of the locator. Clearing is done by resume.60        if(!win)61            win = this.getCurrentWindow();62        try{63            var element = this.findElementRecursive(loc.type, loc.string, win.document, win);64            if(element)65                return core.firefox.unwrap(element);66        }catch(e){67            if(e.isSeleniumError)68                throw e;69        }70        this.is_element_missing = true; //boolean used by "resume" to identify that the command failed to find an element71        return null;72    };73    74    /**75     * Overrides TestLoop.prototype.resume: function() in selenium-executionloop.js line 7176     */77    this.TestLoop.prototype.resume = function(){78        var selDebugger = this.selDebugger = window.editor.selDebugger,79            runner = selDebugger.runner,80            selenium = this.selenium = runner.selenium,81            browserbot = this.browserbot = selenium.browserbot,82            implicitwait = browserbot.implicitwait || (browserbot.implicitwait = new runner.ImplicitWait()),83            LOG = runner.LOG;84        85        LOG.debug("currentTest.resume() - actually execute modified");86        browserbot.runScheduledPollers();87        88        var command = this.currentCommand;89        LOG.info("Executing: |" + command.command + " | " + command.target + " | " + command.value);90        if((this.commandHandler = this.commandFactory.getCommandHandler(command.command)) === null)91            throw new SeleniumError("Unknown command: '" + command.command + "'");92            93        command.target = selenium.preprocessParameter(command.target);94        command.value = selenium.preprocessParameter(command.value);95        LOG.debug("Command found, going to execute " + command.command);96        97        runner.updateStats(command.command);98        browserbot.locator_cache = null;     //Clears the locator cache set by findElementOrNull99        100        this.waitElement_timeout = implicitwait.waitElement_timeout;101        this.preCondition = implicitwait.preCondition;        //defined by doSetImplicitWaitCondition102        this.preCondition_endtime = implicitwait.preCondition && new Date().getTime() + implicitwait.preCondition_timeout;103        return this.resume_pre_condition();104    };105    106    /**107     * Waits for the condition defined by doSetImplicitWaitCondition to be true or throws an error if the timeout is reached108     */109    this.TestLoop.prototype.resume_pre_condition = function(){110        var failureMessage;111        try{112            if(!this.preCondition || this.preCondition.call(this.selenium)){113                this.waitElement_endtime = this.waitElement_timeout && new Date().getTime() + this.waitElement_timeout;114                return this.resume_command();115            }116            if(new Date().getTime() < this.preCondition_endtime)117                return this.retry(this.resume_pre_condition, 20);118            failureMessage = 'Implicit condition timeout: ' + this.preCondition.__source__;119        }catch(e){120            failureMessage = 'Exception on implicit condition: ' + extractExceptionMessage(e);121        }122        LOG.error(failureMessage);123        if(this.commandError(failureMessage))124            return this.continueTest();125        return this.testComplete();126    };127    128    /**129     * Executes the current command until there is no failing locator or until the time-out is reached130     */131    this.TestLoop.prototype.resume_command = function(){132        this.browserbot.is_element_missing = false;     //boolean set to true by findElementOrNull when a locator is not found133        try{134            this.result = this.commandHandler.execute(this.selenium, this.currentCommand);135            if(this.browserbot.is_element_missing && this.waitElement_endtime && this.result.failed && new Date().getTime() < this.waitElement_endtime)136                return this.retry(this.resume_command, 20);    //Retry for the verify and assert commands with a failing locator137            return this.resume_term_condition();138        }catch(e){139            if(this.browserbot.is_element_missing && this.waitElement_endtime && new Date().getTime() < this.waitElement_endtime)    //Retry for actions with a failing locator140                return this.retry(this.resume_command, 20);141            var failureMessage = e.isSeleniumError ? e.message : extractExceptionMessage(e);142            if (e.isSeleniumError)143                LOG.error(failureMessage);144            else145                LOG.exception(e);146            if(this.commandError(failureMessage))147                return this.continueTest();148            return this.testComplete();149        }150    };151    152    /**153     * Waits for the termination condition to be true or throws an error if the time-out is reached154     */155    this.TestLoop.prototype.resume_term_condition = function(){156        try{157            this.browserbot.runScheduledPollers();158            if(this.result.terminationCondition && !this.result.terminationCondition())159                return this.retry(this.resume_term_condition, 20);160        }catch(e){161            this.result = {failed: true, failureMessage: extractExceptionMessage(e)};162        }163        this.commandComplete(this.result);164        return this.continueTest();165    };166    167    /**168     * Registers a callback method that will be called after the given delay on the current scope if the editor is not paused.169     */170    this.TestLoop.prototype.retry = function(callback, delay){171        var self = this;172        if(this.selDebugger.state !== 2) // if not PAUSE_REQUESTED173            window.setTimeout(function(){callback.call(self);}, delay);174    };...

Full Screen

Full Screen

timeout.js

Source:timeout.js Github

copy

Full Screen

...45  };46};47// implicit48commands.implicitWaitW3C = async function implicitWaitW3C (ms) {49  await this.implicitWait(ms);50};51commands.implicitWaitMJSONWP = async function implicitWaitMJSONWP (ms) {52  await this.implicitWait(ms);53};54commands.implicitWait = async function implicitWait (ms) {55  await this.setImplicitWait(this.parseTimeoutArgument(ms));56};57helpers.setImplicitWait = function setImplicitWait (ms) { // eslint-disable-line require-await58  this.implicitWaitMs = ms;59  log.debug(`Set implicit wait to ${ms}ms`);60  if (this.managedDrivers && this.managedDrivers.length) {61    log.debug('Setting implicit wait on managed drivers');62    for (let driver of this.managedDrivers) {63      if (_.isFunction(driver.setImplicitWait)) {64        driver.setImplicitWait(ms);65      }66    }...

Full Screen

Full Screen

commands.js

Source:commands.js Github

copy

Full Screen

...17  let oldSessionId = this.sessionId;18  await this.deleteSession();19  log.debug('Restarting app');20  await this.startSelendroidSession();21  this.implicitWait(oldImpWait);22  this.timeouts('command', oldCommandTimeoutMs);23  this.sessionId = oldSessionId;24};25commands.performMultiAction = async function performMultiAction (elId, actions) {26  if (elId) {27    throw new Error('Selendroid actions do not support element id');28  }29  return await this.selendroid.jwproxy.command('/action', 'POST', {payload: actions});30};31function encodeString (value, unicode) {32  for (let i = 0; i < value.length; i++) {33    let c = value.charCodeAt(i);34    // if we're using the unicode keyboard, and this is unicode, maybe encode35    if (unicode && (c > 127 || c === 38)) {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { remote } = require('webdriverio');2(async () => {3    const browser = await remote({4        capabilities: {5        }6    })7    await browser.implicitWait(5000)8    await browser.deleteSession()9})().catch(async (e) => {10    console.error(e)11    await browser.deleteSession()12})

Full Screen

Using AI Code Generation

copy

Full Screen

1var wd = require('wd');2var driver = wd.promiseChainRemote("localhost", 4723);3driver.init({4}).then(function() {5        .setImplicitWaitTimeout(10000)6        .elementByAccessibilityId('Login')7        .click()8        .elementByAccessibilityId('Logi

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Test', function() {2    it('should do something', function() {3        driver.init({4        });5        driver.implicitWait(10000);6        driver.quit();7    });8});

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Base Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful