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