How to use this.executeAtom method in Appium Xcuitest Driver

Best JavaScript code snippet using appium-xcuitest-driver

ios-controller.js

Source:ios-controller.js Github

copy

Full Screen

...291iOSController.findWebElementOrElements = function (strategy, selector, ctx, many, cb) {292 var ext = many ? 's' : '';293 var atomsElement = this.getAtomsElement(ctx);294 var doFind = function (findCb) {295 this.executeAtom('find_element' + ext, [strategy, selector, atomsElement], function (err, res) {296 this.handleFindCb(err, res, many, findCb);297 }.bind(this));298 }.bind(this);299 this.implicitWaitForCondition(doFind, cb);300};301iOSController.findElementOrElements = function (strategy, selector, ctx, many, cb) {302 if (deviceCommon.checkValidLocStrat(strategy, this.curContext, cb)) {303 if (this.curContext) {304 this.findWebElementOrElements(strategy, selector, ctx, many, cb);305 } else {306 this.findUIElementOrElements(strategy, selector, ctx, many, cb);307 }308 }309};310iOSController.findElement = function (strategy, selector, cb) {311 this.findElementOrElements(strategy, selector, null, false, cb);312};313iOSController.findElements = function (strategy, selector, cb) {314 this.findElementOrElements(strategy, selector, null, true, cb);315};316iOSController.findElementFromElement = function (element, strategy, selector, cb) {317 this.findElementOrElements(strategy, selector, element, false, cb);318};319iOSController.findElementsFromElement = function (element, strategy, selector, cb) {320 this.findElementOrElements(strategy, selector, element, true, cb);321};322iOSController.setValueImmediate = function (elementId, value, cb) {323 value = escapeSpecialChars(value, "'");324 var command = ["au.getElement('", elementId, "').setValue('", value, "')"].join('');325 this.proxy(command, cb);326};327iOSController.setValue = function (elementId, value, cb) {328 if (this.isWebContext()) {329 this.useAtomsElement(elementId, cb, function (atomsElement) {330 this.executeAtom('click', [atomsElement], function (err, res) {331 if (err) {332 cb(err, res);333 } else {334 this.executeAtom('type', [atomsElement, value], cb);335 }336 }.bind(this));337 }.bind(this));338 } else {339 value = escapeSpecialChars(value, "'");340 // de-escape \n so it can be used specially341 value = value.replace(/\\\\n/g, "\\n");342 if (this.useRobot) {343 var keysUrl = this.args.robotUrl + "/sendKeys";344 request.post({url: keysUrl, form: {keys: value}}, cb);345 } else {346 var command = ["au.getElement('", elementId, "').setValueByType('", value, "')"].join('');347 this.proxy(command, cb);348 }349 }350};351iOSController.replaceValue = function (elementId, value, cb) {352 logger.debug("Not implemented for iOS, please use setValue as you would normally.");353 return cb(new NotYetImplementedError(), null);354};355iOSController.useAtomsElement = deviceCommon.useAtomsElement;356iOSController.click = function (elementId, cb) {357 if (this.isWebContext()) {358 this.useAtomsElement(elementId, cb, function (atomsElement) {359 this.executeAtom('click', [atomsElement], cb);360 }.bind(this));361 } else {362 if (this.useRobot) {363 var locCmd = "au.getElement('" + elementId + "').rect()";364 this.proxy(locCmd, function (err, res) {365 if (err) return cb(err, res);366 var rect = res.value;367 var pos = {x: rect.origin.x, y: rect.origin.y};368 var size = {w: rect.size.width, h: rect.size.height};369 var tapPoint = { x: pos.x + (size.w / 2), y: pos.y + (size.h / 2) };370 var tapUrl = this.args.robotUrl + "/tap";371 request.post({url:tapUrl, form: {x:tapPoint.x, y:tapPoint.y}}, cb);372 }.bind(this));373 } else {374 this.nativeTap(elementId, cb);375 }376 }377};378iOSController.nativeTap = function (elementId, cb) {379 var command = ["au.tapById('", elementId, "')"].join('');380 this.proxy(command, cb);381};382iOSController.nativeWebTap = function (elementId, cb) {383 this.useAtomsElement(elementId, cb, function (atomsElement) {384 this.executeAtom('get_top_left_coordinates', [atomsElement], function (err, res) {385 if (err || res.status !== 0) return cb(err, res);386 var x = res.value.x, y = res.value.y;387 this.executeAtom('get_size', [atomsElement], function (err, res) {388 if (err || res.status !== 0) return cb(err, res);389 var w = res.value.width, h = res.value.height;390 var clickX = x + (w / 2);391 var clickY = y + (h / 2);392 this.curWebCoords = {x: clickX, y: clickY};393 this.clickWebCoords(function (err, res) {394 // make sure real tap actually has time to register395 setTimeout(function () {396 cb(err, res);397 }, 500);398 });399 }.bind(this));400 }.bind(this));401 }.bind(this));402};403iOSController.pushFile = function (base64Data, remotePath, cb) {404 if (this.realDevice) {405 logger.debug("Unsupported: cannot write files to physical device");406 return cb(new NotYetImplementedError(), null);407 }408 logger.debug("Pushing " + remotePath + " to iOS simulator");409 var writeFile = function (err, fullPath) {410 if (err) return cb(err);411 logger.debug("Attempting to write " + fullPath + "...");412 async.series([413 function (cb) {414 try {415 if (fs.existsSync(fullPath)) {416 logger.debug(fullPath + " already exists, deleting...");417 fs.unlinkSync(fullPath);418 }419 mkdirp.sync(path.dirname(fullPath));420 var content = new Buffer(base64Data, 'base64');421 var fd = fs.openSync(fullPath, 'w');422 fs.writeSync(fd, content, 0, content.length, 0);423 fs.closeSync(fd);424 logger.debug("Wrote " + content.length + "bytes to " + fullPath);425 cb(null);426 } catch (e) {427 cb(e);428 }429 }.bind(this)430 ], function (err) {431 logger.debug("Returning response");432 if (err) return cb(err);433 cb(null, {434 status: status.codes.Success.code435 });436 });437 };438 this._getFullPath(remotePath, writeFile);439};440/*441 * Get the full path to an iOS simulator file.442 * Calls cb(err, fullFilePath)443 * /Some/Path fetches a file relative to the root of the device's filesystem.444 * /Applications/AppName.app/Some/Path fetches a file relative to the root of that Application's .app directory, adding in the GUID.445 * So it looks something like: /Applications/GUID-GUID-GUID-GUID/Some/Path446 */447iOSController._getFullPath = function (remotePath, cb) {448 var fullPath = "";449 var v = (this.args.platformVersion || this.iOSSDKVersion);450 var simRoots = this.sim.getDirs();451 if (simRoots.length < 1) {452 return cb(new Error("Could not find simulator root for SDK version " +453 v + "; have you launched this sim before?"));454 } else if (simRoots.length > 1) {455 logger.warn("There were multiple simulator roots for version " + v + ". " +456 "We may be pulling the file from the one you're not using!");457 }458 if (simRoots.length > 1) {459 var filteredSimRoots = simRoots.filter(function (root) {460 return fs.existsSync(root + "/Applications") || // ios7461 fs.existsSync(root + "/Containers/Data/Application"); // ios8462 });463 if (filteredSimRoots.length > 0) {464 simRoots = filteredSimRoots;465 }466 }467 var basePath = simRoots[0];468 var appName = null;469 if (this.args.app) {470 var appNameRegex = new RegExp("\\" + path.sep + "(\\w+\\.app)");471 var appNameMatches = appNameRegex.exec(this.args.app);472 if (appNameMatches) {473 appName = appNameMatches[1];474 }475 }476 // de-absolutize the path477 if (isWindows()) {478 if (remotePath.indexof("://") === 1) {479 remotePath = remotePath.slice(4);480 }481 } else {482 if (remotePath.indexOf("/") === 0) {483 remotePath = remotePath.slice(1);484 }485 }486 if (remotePath.indexOf(appName) === 0) {487 logger.debug("We want an app-relative file");488 var findPath = basePath;489 if (this.args.platformVersion >= 8) {490 // the .app file appears in /Containers/Data and /Containers/Bundle both. We only want /Bundle491 findPath = path.resolve(basePath, "Containers", "Bundle");492 }493 findPath = findPath.replace(/\s/g, '\\ ');494 var findCmd = 'find ' + findPath + ' -name "' + appName + '"';495 exec(findCmd, function (err, stdout) {496 if (err) return cb(err);497 var appRoot = stdout.replace(/\n$/, '');498 var subPath = remotePath.substring(appName.length + 1);499 fullPath = path.resolve(appRoot, subPath);500 cb(null, fullPath);501 }.bind(this));502 } else {503 logger.debug("We want a sim-relative file");504 fullPath = path.resolve(basePath, remotePath);505 cb(null, fullPath);506 }507};508iOSController.pullFile = function (remotePath, cb) {509 logger.debug("Pulling " + remotePath + " from sim");510 if (this.realDevice) {511 return cb(new NotYetImplementedError(), null);512 }513 var readAndReturnFile = function (err, fullPath) {514 if (err) return cb(err);515 logger.debug("Attempting to read " + fullPath);516 fs.readFile(fullPath, {encoding: 'base64'}, function (err, data) {517 if (err) return cb(err);518 cb(null, {status: status.codes.Success.code, value: data});519 });520 };521 this._getFullPath(remotePath, readAndReturnFile);522};523iOSController.pullFolder = function (remotePath, cb) {524 logger.debug("Pulling " + remotePath + " from sim");525 if (this.realDevice) {526 return cb(new NotYetImplementedError(), null);527 }528 var bufferOnSuccess = function (buffer) {529 logger.debug("Converting in-memory zip file to base64 encoded string");530 var data = buffer.toString('base64');531 logger.debug("Returning in-memory zip file as base54 encoded string");532 cb(null, {status: status.codes.Success.code, value: data});533 };534 var bufferOnFail = function (err) {535 cb(new Error(err));536 };537 var zipAndReturnFolder = function (err, fullPath) {538 if (err) return cb(err);539 logger.debug("Adding " + fullPath + " to an in-memory zip archive");540 var zip = new AdmZip();541 zip.addLocalFolder(fullPath);542 zip.toBuffer(bufferOnSuccess, bufferOnFail);543 };544 this._getFullPath(remotePath, zipAndReturnFolder);545};546iOSController.touchLongClick = function (elementId, cb) {547 cb(new NotYetImplementedError(), null);548};549iOSController.touchDown = function (elId, x, y, cb) {550 cb(new NotYetImplementedError(), null);551};552iOSController.touchUp = function (elementId, cb) {553 cb(new NotYetImplementedError(), null);554};555iOSController.touchMove = function (elId, startX, startY, cb) {556 cb(new NotYetImplementedError(), null);557};558iOSController.toggleData = function (cb) {559 cb(new NotYetImplementedError(), null);560};561iOSController.toggleFlightMode = function (cb) {562 cb(new NotYetImplementedError(), null);563};564iOSController.toggleWiFi = function (cb) {565 cb(new NotYetImplementedError(), null);566};567iOSController.toggleLocationServices = function (cb) {568 cb(new NotYetImplementedError(), null);569};570iOSController.getStrings = function (language, stringFile, cb) {571 this.parseLocalizableStrings(language, stringFile, function () {572 var strings = this.localizableStrings;573 if (strings && strings.length >= 1) strings = strings[0];574 cb(null, {575 status: status.codes.Success.code576 , value: strings577 });578 }.bind(this));579};580iOSController.executeAtom = function (atom, args, cb, alwaysDefaultFrame) {581 var counter = this.executedAtomsCounter++;582 var frames = alwaysDefaultFrame === true ? [] : this.curWebFrames;583 this.returnedFromExecuteAtom[counter] = false;584 this.processingRemoteCmd = true;585 this.remote.executeAtom(atom, args, frames, function (err, res) {586 this.processingRemoteCmd = false;587 if (!this.returnedFromExecuteAtom[counter]) {588 this.returnedFromExecuteAtom[counter] = true;589 res = this.parseExecuteResponse(res);590 cb(err, res);591 }592 }.bind(this));593 this.lookForAlert(cb, counter, 0, 5000);594};595iOSController.executeAtomAsync = function (atom, args, responseUrl, cb) {596 var counter = this.executedAtomsCounter++;597 this.returnedFromExecuteAtom[counter] = false;598 this.processingRemoteCmd = true;599 this.asyncResponseCb = cb;600 this.remote.executeAtomAsync(atom, args, this.curWebFrames, responseUrl, function (err, res) {601 this.processingRemoteCmd = false;602 if (!this.returnedFromExecuteAtom[counter]) {603 this.returnedFromExecuteAtom[counter] = true;604 res = this.parseExecuteResponse(res);605 cb(err, res);606 }607 }.bind(this));608 this.lookForAlert(cb, counter, 0, 5000);609};610iOSController.receiveAsyncResponse = function (asyncResponse) {611 var asyncCb = this.asyncResponseCb;612 //mark returned as true to stop looking for alerts; the js is done.613 this.returnedFromExecuteAtom = true;614 if (asyncCb !== null) {615 this.parseExecuteResponse(asyncResponse, asyncCb);616 asyncCb(null, asyncResponse);617 this.asyncResponseCb = null;618 } else {619 logger.warn("Received async response when we weren't expecting one! " +620 "Response was: " + JSON.stringify(asyncResponse));621 }622};623iOSController.parseExecuteResponse = deviceCommon.parseExecuteResponse;624iOSController.parseElementResponse = deviceCommon.parseElementResponse;625iOSController.lookForAlert = function (cb, counter, looks, timeout) {626 setTimeout(function () {627 if (typeof looks === 'undefined') {628 looks = 0;629 }630 if (this.instruments !== null) {631 if (!this.returnedFromExecuteAtom[counter] && looks < 11 && !this.selectingNewPage) {632 logger.debug("atom did not return yet, checking to see if " +633 "we are blocked by an alert");634 // temporarily act like we're not processing a remote command635 // so we can proxy the alert detection functionality636 this.alertCounter++;637 this.proxy("au.alertIsPresent()", function (err, res) {638 if (res !== null) {639 if (res.value === true) {640 logger.debug("Found an alert, returning control to client");641 this.returnedFromExecuteAtom[counter] = true;642 cb(null, {643 status: status.codes.Success.code644 , value: ''645 });646 } else {647 // say we're processing remote cmd again648 looks++;649 setTimeout(this.lookForAlert(cb, counter, looks), 1000);650 }651 }652 }.bind(this));653 }654 }655 }.bind(this), timeout);656};657iOSController.clickCurrent = function (button, cb) {658 var noMoveToErr = {659 status: status.codes.UnknownError.code660 , value: "Cannot call click() before calling moveTo() to set coords"661 };662 if (this.isWebContext()) {663 if (this.curWebCoords === null) {664 return cb(null, noMoveToErr);665 }666 this.clickWebCoords(cb);667 } else {668 if (this.curCoords === null) {669 return cb(null, noMoveToErr);670 }671 this.clickCoords(this.curCoords, cb);672 }673};674iOSController.clickCoords = function (coords, cb) {675 if (this.useRobot) {676 var tapUrl = this.args.robotUrl + "/tap";677 request.post({url:tapUrl, form: {x:coords.x, y:coords.y}}, cb);678 } else {679 var opts = coords;680 opts.tapCount = 1;681 opts.duration = 0.3;682 opts.touchCount = 1;683 var command = ["au.complexTap(" + JSON.stringify(opts) + ")"].join('');684 this.proxy(command, cb);685 }686};687iOSController.translateWebCoords = function (coords, cb) {688 var wvCmd = "au.getElementsByType('webview')"689 , webviewIndex = this.webContextIndex();690 // add static offset for safari in landscape mode691 var yOffset = this.curOrientation === "LANDSCAPE" ?692 this.landscapeWebCoordsOffset :693 0;694 // absolutize web coords695 this.proxy(wvCmd, function (err, res) {696 if (err) return cb(err, res);697 if (res.value.length < 1) {698 return cb(null, {699 status: status.codes.UnknownError.code700 , value: "Could not find any webviews to click inside!"701 });702 }703 if (typeof res.value[webviewIndex] === "undefined") {704 logger.warn("Could not find webview at index " + webviewIndex + ", " +705 "taking last available one for clicking purposes");706 webviewIndex = res.value.length - 1;707 }708 var realDims, wvDims, wvPos;709 var step1 = function () {710 var wvId = res.value[webviewIndex].ELEMENT;711 var locCmd = "au.getElement('" + wvId + "').rect()";712 this.proxy(locCmd, function (err, res) {713 if (err) return cb(err, res);714 var rect = res.value;715 wvPos = {x: rect.origin.x, y: rect.origin.y};716 realDims = {w: rect.size.width, h: rect.size.height};717 next();718 });719 }.bind(this);720 var step2 = function () {721 var cmd = "(function () { return {w: document.width, h: document.height}; })()";722 this.remote.execute(cmd, function (err, res) {723 wvDims = {w: res.result.value.w, h: res.result.value.h};724 next();725 });726 }.bind(this);727 var next = function () {728 if (wvDims && realDims && wvPos) {729 var xRatio = realDims.w / wvDims.w;730 var yRatio = realDims.h / wvDims.h;731 var serviceBarHeight = 20;732 if (parseFloat(this.args.platformVersion) >= 8) {733 // ios8 includes the service bar height in the app734 serviceBarHeight = 0;735 }736 var newCoords = {737 x: wvPos.x + Math.round(xRatio * coords.x)738 , y: wvPos.y + yOffset + Math.round(yRatio * coords.y) - serviceBarHeight739 };740 logger.debug("Converted web coords " + JSON.stringify(coords) +741 "into real coords " + JSON.stringify(newCoords));742 cb(newCoords);743 }744 }.bind(this);745 step1();746 step2();747 }.bind(this));748};749iOSController.clickWebCoords = function (cb) {750 this.translateWebCoords(this.curWebCoords, function (coords) {751 this.clickCoords(coords, cb);752 }.bind(this));753};754iOSController.submit = function (elementId, cb) {755 if (this.isWebContext()) {756 this.useAtomsElement(elementId, cb, function (atomsElement) {757 this.executeAtom('submit', [atomsElement], cb);758 }.bind(this));759 } else {760 cb(new NotImplementedError(), null);761 }762};763iOSController.pressKeyCode = function (keycode, metastate, cb) {764 cb(new NotImplementedError(), null);765};766iOSController.longPressKeyCode = function (keycode, metastate, cb) {767 cb(new NotImplementedError(), null);768};769iOSController.keyevent = function (keycode, metastate, cb) {770 cb(new NotImplementedError(), null);771};772iOSController.complexTap = function (tapCount, touchCount, duration, x, y, elementId, cb) {773 var command;774 var options = {775 tapCount: tapCount776 , touchCount: touchCount777 , duration: duration778 , x: x779 , y: y780 };781 var JSONOpts = JSON.stringify(options);782 if (elementId !== null) {783 command = ["au.getElement('", elementId, "').complexTap(", JSONOpts, ')'].join('');784 } else {785 command = ["au.complexTap(", JSONOpts, ")"].join('');786 }787 this.proxy(command, cb);788};789iOSController.clear = function (elementId, cb) {790 if (this.isWebContext()) {791 this.useAtomsElement(elementId, cb, function (atomsElement) {792 this.executeAtom('clear', [atomsElement], cb);793 }.bind(this));794 } else {795 var command = ["au.getElement('", elementId, "').setValue('')"].join('');796 this.proxy(command, cb);797 }798};799iOSController.getText = function (elementId, cb) {800 if (this.isWebContext()) {801 this.useAtomsElement(elementId, cb, function (atomsElement) {802 this.executeAtom('get_text', [atomsElement], cb);803 }.bind(this));804 } else {805 var command = ["au.getElement('", elementId, "').text()"].join('');806 this.proxy(command, function (err, res) {807 // in some cases instruments returns in integer. we only want a string808 res.value = res.value ? res.value.toString() : '';809 cb(err, res);810 });811 }812};813iOSController.getName = function (elementId, cb) {814 if (this.isWebContext()) {815 this.useAtomsElement(elementId, cb, function (atomsElement) {816 var script = "return arguments[0].tagName.toLowerCase()";817 this.executeAtom('execute_script', [script, [atomsElement]], cb);818 }.bind(this));819 } else {820 var command = ["au.getElement('", elementId, "').type()"].join('');821 this.proxy(command, cb);822 }823};824iOSController.getAttribute = function (elementId, attributeName, cb) {825 if (this.isWebContext()) {826 var atomsElement = this.getAtomsElement(elementId);827 if (atomsElement === null) {828 cb(null, {829 status: status.codes.UnknownError.code830 , value: "Error converting element ID for using in WD atoms: " + elementId831 });832 } else {833 this.executeAtom('get_attribute_value', [atomsElement, attributeName], cb);834 }835 } else {836 if (_.contains(['label', 'name', 'value', 'values', 'hint'], attributeName)) {837 var command = ["au.getElement('", elementId, "').", attributeName, "()"].join('');838 this.proxy(command, cb);839 } else {840 cb(null, {841 status: status.codes.UnknownCommand.code842 , value: "UIAElements don't have the attribute '" + attributeName + "'"843 });844 }845 }846};847iOSController.getLocation = function (elementId, cb) {848 if (this.isWebContext()) {849 this.useAtomsElement(elementId, cb, function (atomsElement) {850 this.executeAtom('get_top_left_coordinates', [atomsElement], cb);851 }.bind(this));852 } else {853 var command = ["au.getElement('", elementId,854 "').getElementLocation()"].join('');855 this.proxy(command, cb);856 }857};858iOSController.getSize = function (elementId, cb) {859 if (this.isWebContext()) {860 var atomsElement = this.getAtomsElement(elementId);861 if (atomsElement === null) {862 cb(null, {863 status: status.codes.UnknownError.code864 , value: "Error converting element ID for using in WD atoms: " + elementId865 });866 } else {867 this.executeAtom('get_size', [atomsElement], cb);868 }869 } else {870 var command = ["au.getElement('", elementId, "').getElementSize()"].join('');871 this.proxy(command, cb);872 }873};874iOSController.getWindowSize = function (windowHandle, cb) {875 if (windowHandle !== "current") {876 cb(null, {877 status: status.codes.NoSuchWindow.code878 , value: "Currently only getting current window size is supported."879 });880 }881 if (this.isWebContext()) {882 this.executeAtom('get_window_size', [], function (err, res) {883 cb(null, {884 status: status.codes.Success.code885 , value: res886 });887 });888 } else {889 this.proxy("au.getWindowSize()", cb);890 }891};892iOSController.mobileWebNav = function (navType, cb) {893 this.remote.willNavigateWithoutReload = true;894 this.executeAtom('execute_script', ['history.' + navType + '();', null], cb);895};896iOSController.back = function (cb) {897 if (this.isWebContext()) {898 this.mobileWebNav("back", cb);899 } else {900 var command = "au.back();";901 this.proxy(command, cb);902 }903};904iOSController.forward = function (cb) {905 if (this.isWebContext()) {906 this.mobileWebNav("forward", cb);907 } else {908 cb(new NotImplementedError(), null);909 }910};911iOSController.refresh = function (cb) {912 if (this.isWebContext()) {913 this.executeAtom('refresh', [], cb);914 } else {915 cb(new NotImplementedError(), null);916 }917};918iOSController.getPageIndex = function (elementId, cb) {919 if (this.isWebContext()) {920 cb(new NotImplementedError(), null);921 } else {922 var command = ["au.getElement('", elementId, "').pageIndex()"].join('');923 this.proxy(command, cb);924 }925};926iOSController.keys = function (keys, cb) {927 keys = escapeSpecialChars(keys, "'");928 if (this.isWebContext()) {929 this.active(function (err, res) {930 if (err || typeof res.value.ELEMENT === "undefined") {931 return cb(err, res);932 }933 this.setValue(res.value.ELEMENT, keys, cb);934 }.bind(this));935 } else {936 var command = ["au.sendKeysToActiveElement('", keys, "')"].join('');937 this.proxy(command, cb);938 }939};940iOSController.frame = function (frame, cb) {941 if (this.isWebContext()) {942 var atom;943 if (frame === null) {944 this.curWebFrames = [];945 logger.debug("Leaving web frame and going back to default content");946 cb(null, {947 status: status.codes.Success.code948 , value: ''949 });950 } else {951 if (typeof frame.ELEMENT !== "undefined") {952 this.useAtomsElement(frame.ELEMENT, cb, function (atomsElement) {953 this.executeAtom('get_frame_window', [atomsElement], function (err, res) {954 if (this.checkSuccess(err, res, cb)) {955 logger.debug("Entering new web frame: " + res.value.WINDOW);956 this.curWebFrames.unshift(res.value.WINDOW);957 cb(err, res);958 }959 }.bind(this));960 }.bind(this));961 } else {962 atom = "frame_by_id_or_name";963 if (typeof frame === "number") {964 atom = "frame_by_index";965 }966 this.executeAtom(atom, [frame], function (err, res) {967 if (this.checkSuccess(err, res, cb)) {968 if (res.value === null || typeof res.value.WINDOW === "undefined") {969 cb(null, {970 status: status.codes.NoSuchFrame.code971 , value: ''972 });973 } else {974 logger.debug("Entering new web frame: " + res.value.WINDOW);975 this.curWebFrames.unshift(res.value.WINDOW);976 cb(err, res);977 }978 }979 }.bind(this));980 }981 }982 } else {983 frame = frame ? frame : 'target.frontMostApp()';984 var command = ["wd_frame = ", frame].join('');985 this.proxy(command, cb);986 }987};988iOSController.implicitWait = function (ms, cb) {989 this.implicitWaitMs = parseInt(ms, 10);990 logger.debug("Set iOS implicit wait to " + ms + "ms");991 cb(null, {992 status: status.codes.Success.code993 , value: null994 });995};996iOSController.asyncScriptTimeout = function (ms, cb) {997 this.asyncWaitMs = parseInt(ms, 10);998 logger.debug("Set iOS async script timeout to " + ms + "ms");999 cb(null, {1000 status: status.codes.Success.code1001 , value: null1002 });1003};1004iOSController.pageLoadTimeout = function (ms, cb) {1005 this.pageLoadMs = parseInt(ms, 10);1006 if (this.remote) this.remote.pageLoadMs = this.pageLoadMs;1007 logger.debug("Set iOS page load timeout to " + ms + "ms");1008 cb(null, {1009 status: status.codes.Success.code1010 , value: null1011 });1012};1013iOSController.elementDisplayed = function (elementId, cb) {1014 if (this.isWebContext()) {1015 this.useAtomsElement(elementId, cb, function (atomsElement) {1016 this.executeAtom('is_displayed', [atomsElement], cb);1017 }.bind(this));1018 } else {1019 var command = ["au.getElement('", elementId, "').isDisplayed()"].join('');1020 this.proxy(command, cb);1021 }1022};1023iOSController.elementEnabled = function (elementId, cb) {1024 if (this.isWebContext()) {1025 this.useAtomsElement(elementId, cb, function (atomsElement) {1026 this.executeAtom('is_enabled', [atomsElement], cb);1027 }.bind(this));1028 } else {1029 var command = ["au.getElement('", elementId, "').isEnabled() === 1"].join('');1030 this.proxy(command, cb);1031 }1032};1033iOSController.elementSelected = function (elementId, cb) {1034 if (this.isWebContext()) {1035 this.useAtomsElement(elementId, cb, function (atomsElement) {1036 this.executeAtom('is_selected', [atomsElement], cb);1037 }.bind(this));1038 } else {1039 var command = ["au.getElement('", elementId, "').isSelected()"].join('');1040 this.proxy(command, cb);1041 }1042};1043iOSController.getCssProperty = function (elementId, propertyName, cb) {1044 if (this.isWebContext()) {1045 this.useAtomsElement(elementId, cb, function (atomsElement) {1046 this.executeAtom('get_value_of_css_property', [atomsElement,1047 propertyName], cb);1048 }.bind(this));1049 } else {1050 cb(new NotImplementedError(), null);1051 }1052};1053iOSController.getPageSource = function (cb) {1054 if (this.isWebContext()) {1055 this.processingRemoteCmd = true;1056 var cmd = 'document.getElementsByTagName("html")[0].outerHTML';1057 this.remote.execute(cmd, function (err, res) {1058 if (err) {1059 cb("Remote debugger error", {1060 status: status.codes.UnknownError.code1061 , value: res1062 });1063 } else {1064 cb(null, {1065 status: status.codes.Success.code1066 , value: res.result.value1067 });1068 }1069 this.processingRemoteCmd = false;1070 }.bind(this));1071 } else {1072 this.getSourceForElementForXML(null, function (err, res) {1073 var xmlSource;1074 if (err || res.status !== 0) return cb(err, res);1075 try {1076 xmlSource = _xmlSourceFromJson(res.value);1077 } catch (e) {1078 return cb(e);1079 }1080 return cb(null, {1081 status: status.codes.Success.code1082 , value: xmlSource1083 });1084 }.bind(this));1085 }1086};1087iOSController.getAlertText = function (cb) {1088 this.proxy("au.getAlertText()", cb);1089};1090iOSController.setAlertText = function (text, cb) {1091 text = escapeSpecialChars(text, "'");1092 this.proxy("au.setAlertText('" + text + "')", cb);1093};1094iOSController.postAcceptAlert = function (cb) {1095 this.proxy("au.acceptAlert()", cb);1096};1097iOSController.postDismissAlert = function (cb) {1098 this.proxy("au.dismissAlert()", cb);1099};1100iOSController.lock = function (secs, cb) {1101 this.proxy(["au.lock(", secs, ")"].join(''), cb);1102};1103iOSController.isLocked = function (cb) {1104 cb(new NotYetImplementedError(), null);1105};1106iOSController.background = function (secs, cb) {1107 this.proxy(["au.background(", secs, ")"].join(''), cb);1108};1109iOSController.getOrientation = function (cb) {1110 this.proxy("au.getScreenOrientation()", function (err, res) {1111 if (res && res.status === status.codes.Success.code) {1112 // keep track of orientation for our own purposes1113 logger.debug("Setting internal orientation to " + res.value);1114 this.curOrientation = res.value;1115 }1116 cb(err, res);1117 });1118};1119iOSController.setOrientation = function (orientation, cb) {1120 var command = ["au.setScreenOrientation('", orientation, "')"].join('');1121 this.proxy(command, function (err, res) {1122 if (res && res.status === 0) {1123 this.curOrientation = orientation;1124 }1125 cb(err, res);1126 }.bind(this));1127};1128iOSController.getScreenshot = function (cb) {1129 var guid = uuid.create();1130 var command = ["au.capture('screenshot", guid, "')"].join('');1131 var shotFolder = path.resolve(this.args.tmpDir,1132 "appium-instruments/Run 1/");1133 if (!fs.existsSync(shotFolder)) {1134 mkdirp.sync(shotFolder);1135 }1136 var shotPath = path.resolve(shotFolder, 'screenshot' + guid + '.png');1137 // Retrying the whole screenshot process for three times.1138 async.retry(3,1139 function (cb) {1140 async.waterfall([1141 function (cb) { this.getOrientation(function () { cb(); }); }.bind(this),1142 function (cb) { this.proxy(command, cb); }.bind(this),1143 function (response, cb) {1144 var data;1145 var screenshotWaitTimeout = (this.args.screenshotWaitTimeout || 10) * 1000;1146 logger.debug('Waiting ' + screenshotWaitTimeout + ' ms for screenshot to ge generated.');1147 var startMs = Date.now();1148 var lastErr;1149 async.until(1150 function () { return data || Date.now() - startMs > screenshotWaitTimeout; },1151 function (cb) {1152 setTimeout(function () {1153 fs.readFile(shotPath, function (err, _data) {1154 lastErr = err;1155 if (!err) { data = _data; }1156 cb();1157 });1158 }, 300);1159 },1160 function (err) {1161 if (!data) {1162 return cb(new Error("Timed out waiting for screenshot file. " + (lastErr || '').toString()));1163 }1164 cb(err, response, data);1165 }1166 );1167 }.bind(this),1168 function (response, data, cb) {1169 // rotate if necessary1170 if (this.curOrientation === "LANDSCAPE") {1171 // need to rotate 90 deg CC1172 logger.debug("Rotating landscape screenshot");1173 rotateImage(shotPath, -90, function (err) {1174 if (err) return cb(new Error("Could not rotate screenshot appropriately"), null);1175 fs.readFile(shotPath, function read(err, _data) {1176 if (err) return cb(new Error("Could not retrieve screenshot file following rotate. " + err.toString()));1177 cb(null, response, _data);1178 });1179 });1180 } else cb(null, response, data);1181 }.bind(this),1182 function (response, data, cb) {1183 var b64data = new Buffer(data).toString('base64');1184 response.value = b64data;1185 cb(null, response);1186 }1187 ], cb);1188 }.bind(this), cb);1189};1190iOSController.fakeFlick = function (xSpeed, ySpeed, swipe, cb) {1191 var command = "";1192 if (swipe) {1193 command = ["au.touchSwipeFromSpeed(", xSpeed, ",", ySpeed, ")"].join('');1194 this.proxy(command, cb);1195 } else {1196 command = ["au.touchFlickFromSpeed(", xSpeed, ",", ySpeed, ")"].join('');1197 this.proxyWithMinTime(command, FLICK_MS, cb);1198 }1199};1200iOSController.fakeFlickElement = function (elementId, xoffset, yoffset, speed, cb) {1201 var command = "";1202 if (this.isWebContext()) {1203 this.useAtomsElement(elementId, cb, function (atomsElement) {1204 this.executeAtom('get_top_left_coordinates', [atomsElement], function (err, res) {1205 if (err || res.status !== 0) return cb(err, res);1206 var x = res.value.x, y = res.value.y;1207 this.executeAtom('get_size', [atomsElement], function (err, res) {1208 if (err || res.status !== 0) return cb(err, res);1209 var w = res.value.width, h = res.value.height;1210 var clickX = x + (w / 2);1211 var clickY = y + (h / 2);1212 this.translateWebCoords({x: clickX, y: clickY}, function (from) {1213 this.translateWebCoords({x: clickX + xoffset, y: clickY + yoffset}, function (to) {1214 // speed is not used because underlying UIATarget.flickFromTo doesn't support it1215 command = ["au.flick(", JSON.stringify({from: from, to: to}), ")"].join('');1216 this.proxy(command, cb);1217 }.bind(this));1218 }.bind(this));1219 }.bind(this));1220 }.bind(this));1221 }.bind(this));1222 } else {1223 command = ["au.getElement('", elementId, "').touchFlick(", xoffset, ",",1224 yoffset, ",", speed, ")"].join('');1225 this.proxyWithMinTime(command, FLICK_MS, cb);1226 }1227};1228iOSController.drag = function (startX, startY, endX, endY, duration, touchCount, elId, destElId, cb) {1229 var command;1230 if (elId) {1231 if (this.isWebContext()) {1232 return cb(new NotYetImplementedError(), null);1233 }1234 command = ["au.getElement('", elId, "').drag(", startX, ',', startY, ',',1235 endX, ',', endY, ',', duration, ',', touchCount, ")"].join('');1236 } else {1237 command = ["au.dragApp(", startX, ',', startY, ',', endX, ',', endY, ',',1238 duration, ")"].join('');1239 }1240 // wait for device to complete swipe1241 this.proxy(command, function (err, res) {1242 setTimeout(function () {1243 cb(err, res);1244 }, duration * 1000);1245 });1246};1247iOSController.swipe = function (startX, startY, endX, endY, duration, touchCount, elId, cb) {1248 this.drag(startX, startY, endX, endY, duration, touchCount, elId, null, cb);1249};1250iOSController.rotate = function (x, y, radius, rotation, duration, touchCount, elId, cb) {1251 var command;1252 var location = {'x' : x, 'y' : y};1253 var options = {'duration' : duration, 'radius' : radius, 'rotation' : rotation, 'touchCount' : touchCount};1254 if (elId) {1255 if (this.isWebContext()) {1256 return cb(new NotYetImplementedError(), null);1257 }1258 command = "au.getElement('" + elId + "').rotateWithOptions(" + JSON.stringify(location) +1259 "," + JSON.stringify(options) + ")";1260 this.proxy(command, cb);1261 } else {1262 this.proxy("target.rotateWithOptions(" + JSON.stringify(location) + "," + JSON.stringify(options) + ")", cb);1263 }1264};1265iOSController.pinchClose = function (startX, startY, endX, endY, duration,1266 percent, steps, elId, cb) {1267 var command;1268 var fromPointObject = {'x' : startX, 'y' : startY};1269 var toPointObject = {'x' : endX, 'y' : endY};1270 if (elId) {1271 command = ["au.getElement('", elId, "').pinchCloseFromToForDuration(",1272 JSON.stringify(fromPointObject), ",", JSON.stringify(toPointObject),1273 ",", duration, ")"].join('');1274 this.proxy(command, cb);1275 } else {1276 this.proxy("target.pinchCloseFromToForDuration(" + JSON.stringify(fromPointObject) +1277 "," + JSON.stringify(toPointObject) + "," + duration + ")", cb);1278 }1279};1280iOSController.pinchOpen = function (startX, startY, endX, endY, duration,1281 percent, steps, elId, cb) {1282 var command;1283 var fromPointObject = {'x' : startX, 'y' : startY};1284 var toPointObject = {'x' : endX, 'y' : endY};1285 if (elId) {1286 if (this.isWebContext()) {1287 return cb(new NotYetImplementedError(), null);1288 }1289 command = ["au.getElement('", elId, "').pinchOpenFromToForDuration(",1290 JSON.stringify(fromPointObject), ",", JSON.stringify(toPointObject), ",",1291 duration + ")"].join('');1292 this.proxy(command, cb);1293 } else {1294 this.proxy("target.pinchOpenFromToForDuration(" + JSON.stringify(fromPointObject) +1295 "," + JSON.stringify(toPointObject) + "," + duration + ")", cb);1296 }1297};1298iOSController.flick = function (startX, startY, endX, endY, touchCount, elId,1299 cb) {1300 var command;1301 if (elId) {1302 if (this.isWebContext()) {1303 return cb(new NotYetImplementedError(), null);1304 }1305 command = ["au.getElement('", elId, "').flick(", startX, ',', startY, ',',1306 endX, ',', endY, ',', touchCount, ")"].join('');1307 } else {1308 command = ["au.flickApp(", startX, ',', startY, ',', endX, ',', endY,1309 ")"].join('');1310 }1311 this.proxyWithMinTime(command, FLICK_MS, cb);1312};1313iOSController.scrollTo = function (elementId, text, direction, cb) {1314 if (this.isWebContext()) {1315 return cb(new NotYetImplementedError(), null);1316 }1317 // we ignore text for iOS, as the element is the one being scrolled too1318 var command = ["au.getElement('", elementId, "').scrollToVisible()"].join('');1319 this.proxy(command, cb);1320};1321iOSController.scroll = function (elementId, direction, cb) {1322 direction = direction.charAt(0).toUpperCase() + direction.slice(1);1323 // By default, scroll the first scrollview.1324 var command = "au.scrollFirstView('" + direction + "')";1325 if (elementId) {1326 if (this.isWebContext()) {1327 return cb(new NotYetImplementedError(), null);1328 }1329 // if elementId is defined, call scrollLeft, scrollRight, scrollUp, and scrollDown on the element.1330 command = ["au.getElement('", elementId, "').scroll", direction, "()"].join('');1331 }1332 this.proxy(command, cb);1333};1334iOSController.shake = function (cb) {1335 this.proxy("au.shake()", cb);1336};1337iOSController.setLocation = function (latitude, longitude, altitude, horizontalAccuracy, verticalAccuracy, course, speed, cb) {1338 var coordinates = {'latitude' : latitude, 'longitude' : longitude};1339 var hasOptions = altitude !== null || horizontalAccuracy !== null || verticalAccuracy !== null || course !== null || speed !== null;1340 if (hasOptions) {1341 var options = {};1342 if (altitude !== null) {1343 options.altitude = altitude;1344 }1345 if (horizontalAccuracy !== null) {1346 options.horizontalAccuracy = horizontalAccuracy;1347 }1348 if (verticalAccuracy !== null) {1349 options.verticalAccuracy = verticalAccuracy;1350 }1351 if (course !== null) {1352 options.course = course;1353 }1354 if (speed !== null) {1355 options.speed = speed;1356 }1357 this.proxy("target.setLocationWithOptions(" + JSON.stringify(coordinates) + "," +1358 JSON.stringify(options) + ")", cb);1359 } else {1360 this.proxy("target.setLocation(" + JSON.stringify(coordinates) + ")", cb);1361 }1362};1363iOSController.hideKeyboard = function (strategy, key, cb) {1364 this.proxy("au.hideKeyboard(" +1365 "'" + strategy + "'" +1366 (key ? ",'" + key + "'" : "") +1367 ")",1368 cb);1369};1370iOSController.url = function (url, cb) {1371 if (this.isWebContext()) {1372 // make sure to clear out any leftover web frames1373 this.curWebFrames = [];1374 this.processingRemoteCmd = true;1375 this.remote.navToUrl(url, function () {1376 cb(null, {1377 status: status.codes.Success.code1378 , value: ''1379 });1380 this.processingRemoteCmd = false;1381 }.bind(this));1382 } else {1383 // in the future, detect whether we have a UIWebView that we can use to1384 // make sense of this command. For now, and otherwise, it's a no-op1385 cb(null, {status: status.codes.Success.code, value: ''});1386 }1387};1388iOSController.getUrl = function (cb) {1389 if (this.isWebContext()) {1390 this.processingRemoteCmd = true;1391 this.remote.execute('window.location.href', function (err, res) {1392 if (err) {1393 cb("Remote debugger error", {1394 status: status.codes.JavaScriptError.code1395 , value: res1396 });1397 } else {1398 cb(null, {1399 status: status.codes.Success.code1400 , value: res.result.value1401 });1402 }1403 this.processingRemoteCmd = false;1404 }.bind(this));1405 } else {1406 cb(new NotImplementedError(), null);1407 }1408};1409iOSController.active = function (cb) {1410 if (this.isWebContext()) {1411 this.executeAtom('active_element', [], function (err, res) {1412 cb(err, res);1413 });1414 } else {1415 this.proxy("au.getActiveElement()", cb);1416 }1417};1418iOSController.isWebContext = function () {1419 return this.curContext !== null && this.curContext !== NATIVE_WIN;1420};1421iOSController.webContextIndex = function () {1422 return this.curContext.replace(WEBVIEW_BASE, "") - 1;1423};1424iOSController.getCurrentContext = function (cb) {1425 var err = null, response = null;1426 if (this.curContext) {1427 response = {1428 status: status.codes.Success.code1429 , value: WEBVIEW_BASE + this.curContext1430 };1431 } else {1432 response = {1433 status: status.codes.Success.code1434 , value: 'NATIVE_APP'1435 };1436 }1437 cb(err, response);1438};1439iOSController.getContexts = function (cb) {1440 this.getContextsAndViews(function (err, richCtxs) {1441 if (err) return cb(err);1442 var ctxs = _(richCtxs).map(function (richCtx) {1443 return richCtx.id;1444 });1445 cb(null, {1446 status: status.codes.Success.code1447 , value: ctxs1448 });1449 });1450};1451iOSController.setContext = function (name, callback, skipReadyCheck) {1452 var cb = function (err, res) {1453 if (!err && res.status === status.codes.Success.code && this.perfLogEnabled) {1454 logger.debug('Starting performance log on ' + this.curContext);1455 this.logs.performance = new IOSPerfLog(this.remote);1456 this.logs.performance.startCapture(function () {1457 callback(err, res);1458 });1459 } else {1460 callback(err, res);1461 }1462 }.bind(this);1463 logger.debug("Attempting to set context to '" + name + "'");1464 if (name === this.curContext) {1465 cb(null, {1466 status: status.codes.Success.code1467 , value: ""1468 });1469 } else if (name === NATIVE_WIN || name === null) {1470 if (this.curContext === null || this.curContext === NATIVE_WIN) {1471 cb(null, {1472 status: status.codes.Success.code1473 , value: ""1474 });1475 } else {1476 this.curContext = null;1477 //TODO: this condition should be changed to check if the webkit protocol is being used.1478 if (this.args.udid) {1479 this.remote.disconnect();1480 this.remote = null;1481 }1482 cb(null, {1483 status: status.codes.Success.code1484 , value: ''1485 });1486 }1487 } else {1488 var idx = name.replace(WEBVIEW_BASE, '');1489 if (idx === WEBVIEW_WIN) {1490 // allow user to pass in "WEBVIEW" without an index1491 idx = '1';1492 }1493 var pickContext = function () {1494 if (_.contains(this.contexts, idx)) {1495 var pageIdKey = parseInt(idx, 10);1496 var next = function () {1497 this.processingRemoteCmd = true;1498 if (this.args.udid === null) {1499 this.remote.selectPage(pageIdKey, function () {1500 this.curContext = idx;1501 this.processingRemoteCmd = false;1502 cb(null, {1503 status: status.codes.Success.code1504 , value: ''1505 });1506 }.bind(this), skipReadyCheck);1507 } else {1508 if (name === this.curContext) {1509 logger.debug("Remote debugger is already connected to window [" + name + "]");1510 this.processingRemoteCmd = false;1511 cb(null, {1512 status: status.codes.Success.code1513 , value: name1514 });1515 } else {1516 this.remote.disconnect(function () {1517 this.curContext = idx;1518 this.remote.connect(idx, function () {1519 this.processingRemoteCmd = false;1520 cb(null, {1521 status: status.codes.Success.code1522 , value: name1523 });1524 }.bind(this));1525 }.bind(this));1526 }1527 }1528 }.bind(this);1529 next();1530 } else {1531 cb(null, {1532 status: status.codes.NoSuchContext.code1533 , value: "Context '" + name + "' does not exist"1534 });1535 }1536 }.bind(this);1537 // only get contexts if they haven't already been gotten1538 if (typeof this.contexts === 'undefined') {1539 this.getContexts(function () {1540 pickContext();1541 }.bind(this));1542 } else {1543 pickContext();1544 }1545 }1546};1547iOSController.getWindowHandle = function (cb) {1548 if (this.isWebContext()) {1549 var windowHandle = this.curContext;1550 var response = {1551 status: status.codes.Success.code1552 , value: windowHandle1553 };1554 cb(null, response);1555 } else {1556 cb(new NotImplementedError(), null);1557 }1558};1559iOSController.massagePage = function (page) {1560 page.id = page.id.toString();1561 return page;1562};1563iOSController.getWindowHandles = function (cb) {1564 if (!this.isWebContext()) {1565 return cb(new NotImplementedError(), null);1566 }1567 this.listWebFrames(function (err, pageArray) {1568 if (err) {1569 return cb(err);1570 }1571 this.windowHandleCache = _.map(pageArray, this.massagePage);1572 var idArray = _.pluck(this.windowHandleCache, 'id');1573 // since we use this.contexts to manage selecting debugger pages, make1574 // sure it gets populated even if someone did not use the1575 // getContexts method1576 if (!this.contexts) {1577 this.contexts = idArray;1578 }1579 cb(null, {1580 status: status.codes.Success.code1581 , value: idArray1582 });1583 }.bind(this));1584};1585iOSController.setWindow = function (name, cb, skipReadyCheck) {1586 if (!this.isWebContext()) {1587 return cb(new NotImplementedError(), null);1588 }1589 if (_.contains(_.pluck(this.windowHandleCache, 'id'), name)) {1590 var pageIdKey = parseInt(name, 10);1591 var next = function () {1592 this.processingRemoteCmd = true;1593 if (this.args.udid === null) {1594 this.remote.selectPage(pageIdKey, function () {1595 this.curContext = pageIdKey.toString();1596 this.curWindowHandle = pageIdKey.toString();1597 cb(null, {1598 status: status.codes.Success.code1599 , value: ''1600 });1601 this.processingRemoteCmd = false;1602 }.bind(this), skipReadyCheck);1603 } else {1604 if (name === this.curWindowHandle) {1605 logger.debug("Remote debugger is already connected to window [" + name + "]");1606 cb(null, {1607 status: status.codes.Success.code1608 , value: name1609 });1610 } else if (_.contains(_.pluck(this.windowHandleCache, 'id'), name)) {1611 this.remote.disconnect(function () {1612 this.curContext = name;1613 this.curWindowHandle = name;1614 this.remote.connect(name, function () {1615 cb(null, {1616 status: status.codes.Success.code1617 , value: name1618 });1619 });1620 }.bind(this));1621 } else {1622 cb(null, {1623 status: status.codes.NoSuchWindow.code1624 , value: null1625 });1626 }1627 }1628 }.bind(this);1629 next();1630 } else {1631 cb(null, {1632 status: status.codes.NoSuchWindow.code1633 , value: null1634 });1635 }1636};1637iOSController.closeWindow = function (cb) {1638 if (this.isWebContext()) {1639 var script = "return window.open('','_self').close();";1640 this.executeAtom('execute_script', [script, []], function (err, res) {1641 setTimeout(function () {1642 cb(err, res);1643 }, 500);1644 }, true);1645 } else {1646 cb(new NotImplementedError(), null);1647 }1648};1649iOSController.setSafariWindow = function (windowId, cb) {1650 var checkPages = function (_cb) {1651 this.findElement('name', 'Pages', function (err, res) {1652 if (this.checkSuccess(err, res, _cb)) {1653 this.getAttribute(res.value.ELEMENT, 'value', function (err, res) {1654 if (this.checkSuccess(err, res, _cb)) {1655 if (res.value === "") {1656 _cb(err, res);1657 } else {1658 _cb();1659 }1660 }1661 }.bind(this));1662 }1663 }.bind(this));1664 }.bind(this);1665 var tapPages = function (_cb) {1666 this.findElement('name', 'Pages', function (err, res) {1667 if (this.checkSuccess(err, res, _cb)) {1668 this.nativeTap(res.value.ELEMENT, function (err, res) {1669 if (this.checkSuccess(err, res, _cb)) {1670 _cb();1671 }1672 }.bind(this));1673 }1674 }.bind(this));1675 }.bind(this);1676 var selectPage = function (_cb) {1677 this.findElement('class name', 'UIAPageIndicator', function (err, res) {1678 if (this.checkSuccess(err, res, _cb)) {1679 this.setValue(res.value.ELEMENT, windowId, function (err, res) {1680 if (this.checkSuccess(err, res, _cb)) {1681 _cb();1682 }1683 }.bind(this));1684 }1685 }.bind(this));1686 }.bind(this);1687 var doneWithPages = function (_cb) {1688 this.findElement('name', 'Done', function (err, res) {1689 if (this.checkSuccess(err, res, _cb)) {1690 this.nativeTap(res.value.ELEMENT, function (err, res) {1691 if (this.checkSuccess(err, res, _cb)) {1692 _cb();1693 }1694 }.bind(this));1695 }1696 }.bind(this));1697 }.bind(this);1698 async.series([checkPages, tapPages, selectPage, doneWithPages],1699 function (err) { cb(err); });1700};1701iOSController.checkSuccess = function (err, res, cb) {1702 if (typeof res === "undefined") {1703 cb(err, {1704 status: status.codes.UnknownError.code1705 , value: "Did not get valid response from execution. Expected res to " +1706 "be an object and was " + JSON.stringify(res)1707 });1708 return false;1709 } else if (err || res.status !== status.codes.Success.code) {1710 cb(err, res);1711 return false;1712 }1713 return true;1714};1715iOSController.execute = function (script, args, cb) {1716 if (this.isWebContext()) {1717 this.convertElementForAtoms(args, function (err, res) {1718 if (err) {1719 cb(null, res);1720 } else {1721 this.executeAtom('execute_script', [script, res], cb);1722 }1723 }.bind(this));1724 } else {1725 this.proxy(script, cb);1726 }1727};1728iOSController.executeAsync = function (script, args, responseUrl, cb) {1729 if (this.isWebContext()) {1730 if (this.args.udid) {1731 var defaultHost = getDefaultCallbackAddress();1732 var urlObject = url.parse(responseUrl);1733 if (urlObject.hostname === defaultHost) {1734 logger.debug('Real device safari test and no custom ' +1735 'callback address set, ' +1736 'changing callback address to local ip.');1737 urlObject.hostname = localIp();1738 urlObject.host = null; // set to null, otherwise hostname is ignored1739 responseUrl = url.format(urlObject);1740 } else {1741 logger.debug('Custom callback address set, leaving as is.');1742 }1743 }1744 logger.debug("Response url for executeAsync is " + responseUrl);1745 this.convertElementForAtoms(args, function (err, res) {1746 if (err) {1747 cb(null, res);1748 } else {1749 this.executeAtomAsync('execute_async_script', [script, args, this.asyncWaitMs], responseUrl, cb);1750 }1751 }.bind(this));1752 } else {1753 this.proxy(script, cb);1754 }1755};1756iOSController.convertElementForAtoms = deviceCommon.convertElementForAtoms;1757iOSController.title = function (cb) {1758 if (this.isWebContext()) {1759 this.executeAtom('title', [], cb, true);1760 } else {1761 cb(new NotImplementedError(), null);1762 }1763};1764iOSController.moveTo = function (element, xoffset, yoffset, cb) {1765 this.getLocation(element, function (err, res) {1766 if (err) return cb(err, res);1767 var coords = {1768 x: res.value.x + xoffset1769 , y: res.value.y + yoffset1770 };1771 if (this.isWebContext()) {1772 this.curWebCoords = coords;1773 this.useAtomsElement(element, cb, function (atomsElement) {1774 var relCoords = {x: xoffset, y: yoffset};1775 this.executeAtom('move_mouse', [atomsElement, relCoords], cb);1776 }.bind(this));1777 } else {1778 this.curCoords = coords;1779 cb(null, {1780 status: status.codes.Success.code1781 , value: null1782 });1783 }1784 }.bind(this));1785};1786iOSController.equalsWebElement = function (element, other, cb) {1787 var ctxElem = this.getAtomsElement(element);1788 var otherElem = this.getAtomsElement(other);1789 var retStatus = status.codes.Success.code1790 , retValue = false;1791 // We assume if it's referencing the same element id, then it's equal1792 if (ctxElem.ELEMENT === otherElem.ELEMENT) {1793 retValue = true;1794 cb(null, {1795 status: retStatus1796 , value: retValue1797 });1798 } else {1799 // ...otherwise let the browser tell us.1800 this.executeAtom('element_equals_element', [ctxElem.ELEMENT, otherElem.ELEMENT], cb);1801 }1802};1803iOSController.getCookies = function (cb) {1804 if (!this.isWebContext()) {1805 return cb(new NotImplementedError(), null);1806 }1807 var script = "return document.cookie";1808 this.executeAtom('execute_script', [script, []], function (err, res) {1809 if (this.checkSuccess(err, res, cb)) {1810 var cookieMan = new CookieMan(res.value);1811 var cookies = [];1812 try {1813 cookies = _(cookieMan.cookies()).map(function (v,k) {1814 return {name: k, value: v};1815 });1816 } catch (e) {1817 return cb(null, {1818 status: status.codes.UnknownError.code1819 , value: "Error parsing cookies from result, which was " + res.value1820 });1821 }1822 cb(null, {1823 status: status.codes.Success.code1824 , value: cookies1825 });1826 }1827 }.bind(this), true);1828};1829iOSController.setCookie = function (cookie, cb) {1830 if (!this.isWebContext()) {1831 return cb(new NotImplementedError(), null);1832 }1833 cookie = _.clone(cookie);1834 // if 'Path' field is not specified, Safari will not update cookies as expected; eg issue #17081835 if (!cookie.path) {1836 cookie.path = "/";1837 }1838 var webCookie = (new CookieMan()).cookie(cookie.name, cookie.value, {1839 expires: _.isNumber(cookie.expiry) ? (new Date(cookie.expiry * 1000)).toUTCString() :1840 cookie.expiry, path: cookie.path, domain: cookie.domain,1841 httpOnly: cookie.httpOnly, secure: cookie.secure});1842 var script = "document.cookie = " + JSON.stringify(webCookie);1843 this.executeAtom('execute_script', [script, []], function (err, res) {1844 if (this.checkSuccess(err, res, cb)) {1845 cb(null, {1846 status: status.codes.Success.code1847 , value: true1848 });1849 }1850 }.bind(this), true);1851};1852iOSController._deleteCookie = function (cookieName, cb) {1853 var webCookie = (new CookieMan()).removeCookie(cookieName , {path: "/"});1854 var script = "document.cookie = " + JSON.stringify(webCookie);1855 this.executeAtom('execute_script', [script, []], function (err, res) {1856 if (this.checkSuccess(err, res, cb)) {1857 cb(null, {1858 status: status.codes.Success.code1859 , value: true1860 });1861 }1862 }.bind(this), true);1863};1864iOSController.deleteCookie = function (cookieName, cb) {1865 if (!this.isWebContext()) {1866 return cb(new NotImplementedError(), null);1867 }1868 // check cookie existence1869 var script = "return document.cookie";1870 this.executeAtom('execute_script', [script, []], function (err, res) {1871 if (this.checkSuccess(err, res, cb)) {1872 var cookieMan = new CookieMan(res.value);1873 if (_.isUndefined(cookieMan.cookie(cookieName))) {1874 // nothing to delete1875 return cb(null, {1876 status: status.codes.Success.code1877 , value: true1878 });1879 }1880 // delete cookie1881 this._deleteCookie(cookieName, cb);1882 }1883 }.bind(this), true);1884};...

Full Screen

Full Screen

web.js

Source:web.js Github

copy

Full Screen

...18 return;19 }20 if (!_.isUndefined(frame.ELEMENT)) {21 let atomsElement = this.useAtomsElement(frame.ELEMENT);22 let value = await this.executeAtom('get_frame_window', [atomsElement]);23 logger.debug(`Entering new web frame: '${value.WINDOW}'`);24 this.curWebFrames.unshift(value.WINDOW);25 } else {26 atom = _.isNumber(frame) ? 'frame_by_index' : 'frame_by_id_or_name';27 let value = await this.executeAtom(atom, [frame]);28 if (_.isNull(value) || _.isUndefined(value.WINDOW)) {29 throw new errors.NoSuchFrameError();30 }31 logger.debug(`Entering new web frame: '${value.WINDOW}'`);32 this.curWebFrames.unshift(value.WINDOW);33 }34};35commands.getCssProperty = async function (propertyName, el) {36 let atomsElement = this.useAtomsElement(el);37 return await this.executeAtom('get_value_of_css_property', [atomsElement, propertyName]);38};39commands.submit = async function (el) {40 if (this.isWebContext()) {41 let atomsElement = this.useAtomsElement(el);42 await this.executeAtom('submit', [atomsElement]);43 } else {44 throw new errors.NotImplementedError();45 }46};47commands.refresh = async function () {48 if (this.isWebContext()) {49 await this.executeAtom('refresh', []);50 } else {51 throw new errors.NotImplementedError();52 }53};54commands.setUrl = async function (url) {55 logger.debug(`Attempting to set url '${url}'`);56 if (!this.isWebContext()) {57 // in the future, detect whether we have a UIWebView that we can use to58 // make sense of this command. For now, and otherwise, it's a no-op59 throw new errors.NotImplementedError();60 }61 // make sure to clear out any leftover web frames62 this.curWebFrames = [];63 await this.remote.navToUrl(url);64};65commands.getUrl = async function () {66 if (!this.isWebContext()) {67 throw new errors.NotImplementedError();68 }69 return await this.remote.execute('window.location.href');70};71commands.title = async function () {72 if (!this.isWebContext()) {73 throw new errors.NotImplementedError();74 }75 return await this.executeAtom('title', [], true);76};77commands.getCookies = async function () {78 if (!this.isWebContext()) {79 throw new errors.NotImplementedError();80 }81 logger.debug('Retrieving all cookies');82 let script = 'return document.cookie';83 let jsCookies = await this.executeAtom('execute_script', [script, []]);84 let cookies = [];85 try {86 for (let [name, value] of _.pairs(cookieUtils.createJWPCookie(undefined, jsCookies))) {87 cookies.push({name, value});88 }89 return cookies;90 } catch (err) {91 logger.error(err);92 throw new errors.UnknownError(`Error parsing cookies from result: '${jsCookies}'`);93 }94};95commands.setCookie = async function (cookie) {96 if (!this.isWebContext()) {97 throw new errors.NotImplementedError();98 }99 cookie = _.clone(cookie);100 // if `path` field is not specified, Safari will not update cookies as expected; eg issue #1708101 if (!cookie.path) {102 cookie.path = "/";103 }104 let jsCookie = cookieUtils.createJSCookie(cookie.name, cookie.value, {105 expires: _.isNumber(cookie.expiry) ? (new Date(cookie.expiry * 1000)).toUTCString() :106 cookie.expiry,107 path: cookie.path,108 domain: cookie.domain,109 httpOnly: cookie.httpOnly,110 secure: cookie.secure111 });112 let script = `document.cookie = ${JSON.stringify(jsCookie)}`;113 await this.executeAtom('execute_script', [script, []]);114};115commands.deleteCookie = async function (cookieName) {116 if (!this.isWebContext()) {117 throw new errors.NotImplementedError();118 }119 // check cookie existence120 let cookies = await this.getCookies();121 if (_.indexOf(_.pluck(cookies, 'name'), cookieName) === -1) {122 logger.debug(`Cookie '${cookieName}' not found. Ignoring.`);123 return true;124 }125 return await this._deleteCookie(cookieName);126};127commands.deleteCookies = async function () {128 if (!this.isWebContext()) {129 throw new errors.NotImplementedError();130 }131 let cookies = await this.getCookies();132 if (cookies.length) {133 for (let cookie of cookies) {134 await this._deleteCookie(cookie.name);135 }136 }137 return true;138};139helpers._deleteCookie = async function (cookieName) {140 logger.debug(`Deleting cookie '${cookieName}'`);141 let webCookie = cookieUtils.expireCookie(cookieName , {path: "/"});142 let script = `document.cookie = ${JSON.stringify(webCookie)}`;143 await this.executeAtom('execute_script', [script, []]);144};145extensions.findWebElementOrElements = async function (strategy, selector, many, ctx) {146 let atomsElement = this.getAtomsElement(ctx);147 let element;148 let doFind = async () => {149 element = await this.executeAtom(`find_element${many ? 's' : ''}`, [strategy, selector, atomsElement], true);150 return !_.isNull(element);151 };152 try {153 await this.implicitWaitForCondition(doFind);154 } catch (err) {155 if (err.message && err.message.match(/Condition unmet/)){156 // condition was not met setting res to empty array157 element = [];158 } else {159 throw err;160 }161 }162 if (many) {163 return element;164 } else {165 if (!element || _.size(element) === 0) {166 throw new errors.NoSuchElementError();167 }168 return element;169 }170};171extensions.webFlickElement = async function (el, xoffset, yoffset) {172 let atomsElement = await this.useAtomsElement(el);173 let {x, y} = await this.executeAtom('get_top_left_coordinates', [atomsElement]);174 let {width, height} = await this.executeAtom('get_size', [atomsElement]);175 // translate to proper coordinates176 x = x + (width / 2);177 y = y + (height / 2);178 let from = await this.translateWebCoords({x, y});179 let to = await this.translateWebCoords({x: x + xoffset, y: y + yoffset});180 let args = {from, to};181 let command = `au.flick(${JSON.stringify(args)})`;182 await this.uiAutoClient.sendCommand(command);183};184extensions.mobileWebNav = async function (navType) {185 this.remote.allowNavigationWithoutReload();186 await this.executeAtom('execute_script', [`history.${navType}();`, null]);187};188extensions.nativeWebTap = async function (el) {189 let atomsElement = this.useAtomsElement(el);190 let {x, y} = await this.executeAtom('get_top_left_coordinates', [atomsElement]);191 let {width, height} = await this.executeAtom('get_size', [atomsElement]);192 x = x + (width / 2);193 y = y + (height / 2);194 this.curWebCoords = {x, y};195 await this.clickWebCoords();196 // make sure real tap actually has time to register197 await B.delay(500);198};199extensions.clickWebCoords = async function () {200 let coords = await this.translateWebCoords(this.curWebCoords);201 await this.clickCoords(coords);202};203extensions.translateWebCoords = async function (coords) {204 logger.debug(`Translating coordinates (${JSON.stringify(coords)}) to web coordinates`);205 let wvCmd = 'au.getElementsByType(\'webview\')';...

Full Screen

Full Screen

element.js

Source:element.js Github

copy

Full Screen

...9 let atomsElement = this.getAtomsElement(el);10 if (_.isNull(atomsElement)) {11 throw new errors.UnknownError(`Error converting element ID for using in WD atoms: '${el}`);12 } else {13 return await this.executeAtom('get_attribute_value', [atomsElement, attribute]);14 }15 } else {16 if (_.contains(['label', 'name', 'value', 'values', 'hint'], attribute)) {17 let command = `au.getElement('${el}').${attribute}()`;18 return await this.uiAutoClient.sendCommand(command);19 } else {20 throw new errors.UnknownCommandError(`UIAElements don't have the attribute '${attribute}'`);21 }22 }23};24commands.clear = async function (el) {25 el = unwrapEl(el);26 if (this.isWebContext()) {27 let atomsElement = this.useAtomsElement(el);28 await this.executeAtom('clear', [atomsElement]);29 } else {30 let command = `au.getElement('${el}').setValue('')`;31 await this.uiAutoClient.sendCommand(command);32 }33};34commands.setValueImmediate = async function (value, el) {35 el = unwrapEl(el);36 value = util.escapeSpecialChars(value, "'");37 let command = `au.getElement('${el}').setValue('${value}')`;38 await this.uiAutoClient.sendCommand(command);39};40commands.setValue = async function (value, el) {41 el = unwrapEl(el);42 if (this.isWebContext()) {43 let atomsElement = this.useAtomsElement(el);44 await this.executeAtom('click', [atomsElement]);45 await this.executeAtom('type', [atomsElement, value]);46 } else {47 if (value instanceof Array) {48 value = value.join("");49 }50 if(typeof value !== 'string') {51 value = `${value}`;52 }53 value = util.escapeSpecialChars(value, "'");54 // de-escape \n so it can be used specially55 value = value.replace(/\\\\n/g, "\\n");56 if (this.opts.useRobot) {57 /* TODO */throw new errors.NotYetImplementedError();58 } else {59 let command = `au.getElement('${el}').setValueByType('${value}')`;60 await this.uiAutoClient.sendCommand(command);61 }62 }63};64commands.getText = async function (el) {65 el = unwrapEl(el);66 if (this.isWebContext()) {67 let atomsElement = this.useAtomsElement(el);68 return await this.executeAtom('get_text', [atomsElement]);69 } else {70 let command = `au.getElement('${el}').text()`;71 let res = await this.uiAutoClient.sendCommand(command);72 // in some cases instruments returns in integer. we only want a string73 res = res ? res.toString() : '';74 return res;75 }76};77commands.elementDisplayed = async function (el) {78 el = unwrapEl(el);79 if (this.isWebContext()) {80 let atomsElement = this.useAtomsElement(el);81 return await this.executeAtom('is_displayed', [atomsElement]);82 } else {83 let command = `au.getElement('${el}').isDisplayed()`;84 return await this.uiAutoClient.sendCommand(command);85 }86};87commands.elementEnabled = async function (el) {88 el = unwrapEl(el);89 if (this.isWebContext()) {90 let atomsElement = this.useAtomsElement(el);91 return await this.executeAtom('is_enabled', [atomsElement]);92 } else {93 let command = `au.getElement('${el}').isEnabled() === 1`;94 return await this.uiAutoClient.sendCommand(command);95 }96};97commands.elementSelected = async function (el) {98 el = unwrapEl(el);99 if (this.isWebContext()) {100 let atomsElement = this.useAtomsElement(el);101 return await this.executeAtom('is_selected', [atomsElement]);102 } else {103 let command = `au.getElement('${el}').isSelected()`;104 return await this.uiAutoClient.sendCommand(command);105 }106};107commands.getName = async function (el) {108 el = unwrapEl(el);109 if (this.isWebContext()) {110 let atomsElement = this.useAtomsElement(el);111 let script = 'return arguments[0].tagName.toLowerCase()';112 return await this.executeAtom('execute_script', [script, [atomsElement]]);113 } else {114 let command = `au.getElement('${el}').type()`;115 return await this.uiAutoClient.sendCommand(command);116 }117};118commands.getLocation = async function (el) {119 el = unwrapEl(el);120 if (this.isWebContext()) {121 let atomsElement = await this.useAtomsElement(el);122 return await this.executeAtom('get_top_left_coordinates', [atomsElement]);123 } else {124 let command = `au.getElement('${el}').getElementLocation()`;125 return await this.uiAutoClient.sendCommand(command);126 }127};128commands.getSize = async function (el) {129 el = unwrapEl(el);130 if (this.isWebContext()) {131 let atomsElement = this.getAtomsElement(el);132 if (atomsElement === null) {133 throw new errors.UnknownError(`Error converting element ID for using in WD atoms: '${el}'`);134 } else {135 return await this.executeAtom('get_size', [atomsElement]);136 }137 } else {138 let command = `au.getElement('${el}').getElementSize()`;139 return await this.uiAutoClient.sendCommand(command);140 }141};142Object.assign(extensions, commands, helpers);143export { commands, helpers };...

Full Screen

Full Screen

general.js

Source:general.js Github

copy

Full Screen

...6commands.active = async function () {7 if (!this.isWebContext()) {8 throw new errors.UnknownError('Command should be proxied to WDA');9 }10 return await this.executeAtom('active_element', []);11};12/**13 * Close app (simulate device home button). If a duration is given, app will14 * re-open after that many seconds15 */16commands.background = async function (seconds) {17 let params = {};18 if (seconds) {19 params.duration = seconds;20 }21 return await this.proxyCommand('/deactivateApp', 'POST', params);22};23/*24 * Simulate Touch ID with either valid (match === true) or invalid (match === false)25 * fingerprint26 */27commands.touchId = async function (match = true) {28 let params = {29 match30 };31 return await this.proxyCommand('/simulator/touch_id', 'POST', params);32};33commands.getWindowSize = async function (windowHandle = 'current') {34 if (windowHandle !== "current") {35 throw new errors.NotYetImplementedError('Currently only getting current window size is supported.');36 }37 if (!this.isWebContext()) {38 return await this.proxyCommand(`/window/${windowHandle}/size`, 'GET');39 } else {40 return await this.executeAtom('get_window_size', []);41 }42};43commands.hideKeyboard = async function (strategy, ...possibleKeys) {44 let keyboard;45 try {46 keyboard = await this.findNativeElementOrElements('class name', 'XCUIElementTypeKeyboard', false);47 } catch (err) {48 // no keyboard found49 log.debug('No keyboard found. Unable to hide.');50 return;51 }52 possibleKeys.pop(); // last parameter is the session id53 possibleKeys = possibleKeys.filter((element) => !!element); // get rid of undefined elements54 if (possibleKeys.length) {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { exec } = require('child_process');2const { promisify } = require('util');3const execAsync = promisify(exec);4const fs = require('fs');5async function executeAtom (atom, args, frames) {6 const jsArgs = JSON.stringify([atom, args, frames]);7 const js = `var args = JSON.parse(arguments[0]);` +8 `return UIAutomation.getUIAutomation().executeAtom.apply(null, args);`;9 const script = `UIATarget.localTarget().frontMostApp().delegate().` +10 `atmBridge().runSerializedScript('${js}', '${jsArgs}')`;11 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);12 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);13 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);14 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);15 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);16 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);17 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);18 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);19 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);20 const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to keystroke "a" using {command down}'`);21 const { stdout } = await execAsync(`osascript -e 'tell application "System Events"

Full Screen

Using AI Code Generation

copy

Full Screen

1const { execSync } = require('child_process');2const { join } = require('path');3const { XCUITestDriver } = require('../../node_modules/appium-xcuitest-driver/lib/driver');4const port = 4723;5const host = 'localhost';6const driver = new XCUITestDriver();7driver.executeAtom('execute_script', ['mobile: scroll', {direction: 'down'}], {});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { exec } = require('child_process');2const { promisify } = require('util');3const execAsync = promisify(exec);4describe('My First Test', function() {5 it('Verify that the test works', async function() {6 const { stdout, stderr } = await execAsync('node test.js');7 console.log(stdout);8 console.log(stderr);9 });10});11const { exec } = require('child_process');12const { promisify } = require('util');13const execAsync = promisify(exec);14describe('My First Test', function() {15 it('Verify that the test works', async function() {16 const { stdout, stderr } = await execAsync('node test.js');17 console.log(stdout);18 console.log(stderr);19 });20});21const { exec } = require('child_process');22const { promisify } = require('util');23const execAsync = promisify(exec);24describe('My First Test', function() {25 it('Verify that the test works', async function() {26 const { stdout, stderr } = await execAsync('node test.js');27 console.log(stdout);28 console.log(stderr);29 });30});31const { exec } = require('child_process');32const { promisify } = require('util');33const execAsync = promisify(exec);34describe('My First Test', function() {35 it('Verify that the test works', async function() {36 const { stdout, stderr } = await execAsync('node test.js');37 console.log(stdout);38 console.log(stderr);39 });40});41const { exec } = require('child_process');42const { promisify } = require('util');43const execAsync = promisify(exec);44describe('My First Test', function() {45 it('Verify that the test works', async function() {46 const { stdout, stderr } = await execAsync('node test.js');47 console.log(stdout);48 console.log(stderr);49 });50});51const { exec } = require('child_process');52const { promisify } = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1var driver = new iosDriver();2driver.executeAtom('execute_script', [jsCode, []], function(err, res) {3 console.log('Result', res);4});5capabilities.setCapability("platformName", "iOS");6capabilities.setCapability("platformVersion", "10.3.1");7capabilities.setCapability("deviceName", "iPhone 6s");8capabilities.setCapability("automationName", "XCUITest");9capabilities.setCapability("app", "/Users/xxxx/Documents/xxxx.app");10capabilities.setCapability("udid", "xxxx");11capabilities.setCapability("bundleId", "xxxx");12capabilities.setCapability("xcodeOrgId", "xxxx");13capabilities.setCapability("xcodeSigningId", "iPhone Developer");14capabilities.setCapability("updatedWDABundleId", "xxxx");15capabilities.setCapability("useNewWDA", true);16capabilities.setCapability("noReset", true);

Full Screen

Using AI Code Generation

copy

Full Screen

1this.executeAtom('execute_script', [script, args], context, function(err, res) {2 console.log('res', res);3 callback(err, res);4});5this.executeAtom('execute_script', [script, args], context, function(err, res) {6 console.log('res', res);7 callback(err, res);8});9this.executeAtom('execute_script', [script, args], context, function(err, res) {10 console.log('res', res);11 callback(err, res);12});13this.executeAtom('execute_script', [script, args], context, function(err, res) {14 console.log('res', res);15 callback(err, res);16});

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 Xcuitest Driver automation tests on LambdaTest cloud grid

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

Sign up Free
_

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful