-- Start application log ----------------------------------------------------- [INFO] : TiApplication: (main) [0,0] checkpoint, app created. [INFO] : TiApplication: (main) [44,44] Titanium 6.0.2 (2017/01/23 06:30 undefined) [INFO] : MultiDex: VM with version 2.1.0 has multidex support [INFO] : MultiDex: install [INFO] : MultiDex: VM has multidex support, MultiDex support library is disabled. [WARN] : V8Object: (main) [210,254] Runtime disposed, cannot set property 'userAgent' [INFO] : TiApplication: (main) [26,280] Titanium Javascript runtime: v8 [DEBUG] : TouchtestmoduleModule: (main) [7,287] inside onAppCreate [DEBUG] : CrittercismAndroidModule: (main) [0,287] App context is defined. [INFO] : I/System.out: ActivityRecorder: before com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [INFO] : TiRootActivity: (main) [0,0] checkpoint, on root activity create, savedInstanceState: null [INFO] : I/System.out: ActivityRecorder: before com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [INFO] : I/System.out: ActivityRecorder: before com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [DEBUG] : NetworkSecurityConfig: No Network Security Config specified, using platform default [INFO] : I/System.out: ActivityRecorder: after com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [INFO] : I/System.out: ActivityRecorder: after com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [INFO] : I/System.out: ActivityRecorder: after com.appc.weballoy.WeballoyActivity@2837a23_onCreate(), launchUrl = null [INFO] : TiRootActivity: (main) [0,0] checkpoint, on root activity resume. activity = com.appc.weballoy.WeballoyActivity@2837a23 [TRACE] : updating tiapp metadata with Appcelerator Platform... [INFO] : I/System.out: ActivityRecorder: before org.appcelerator.titanium.TiActivity@9f98e36_onCreate(), launchUrl = null [INFO] : I/System.out: ActivityRecorder: before org.appcelerator.titanium.TiActivity@9f98e36_onCreate(), launchUrl = null [DEBUG] : ApplicationLoaders: ignored Vulkan layer search path /data/app/com.android.chrome-2/lib/arm:/data/app/com.android.chrome-2/base.apk!/lib/armeabi-v7a for namespace 0xf000b090 [INFO] : WebViewFactory: Loading com.android.chrome version 54.0.2840.85 (code 284008552) [TRACE] : Uploaded tiapp metadata with Appcelerator Platform! [INFO] : cr_LibraryLoader: Time to load native libraries: 5 ms (timestamps 8225-8230) [INFO] : cr_LibraryLoader: Expected native library version number "54.0.2840.85", actual native library version number "54.0.2840.85" [INFO] : cr_LibraryLoader: Expected native library version number "54.0.2840.85", actual native library version number "54.0.2840.85" [INFO] : chromium: [INFO:library_loader_hooks.cc(151)] Chromium logging enabled: level = 0, default verbosity = 0 [INFO] : cr_BrowserStartup: Initializing chromium process, singleProcess=true [INFO] : Adreno: QUALCOMM build : a5b4970, If5818605d9 [INFO] : Adreno: Build Date : 10/12/16 [INFO] : Adreno: OpenGL ES Shader Compiler Version: XE031.09.00.04 [INFO] : Adreno: Local Branch : N24D [INFO] : Adreno: Remote Branch : [INFO] : Adreno: Remote Branch : [INFO] : Adreno: Reconstruct Branch : [DEBUG] : TouchTestDriver: 11:27:59,596 [main][25] TTWebViewClientWrapper.injectIfRequired from ajbefore WebView_loadDataWithBaseURL with attached = ti.modules.titanium.ui.widget.webview.TiWebViewClient@cf3f00b of class ti.modules.titanium.ui.widget.webview.TiWebViewClient [DEBUG] : TouchTestDriver: 11:27:59,596 [main][25] ti.modules.titanium.ui.widget.webview.TiWebViewClient is not cached. Processing... [DEBUG] : TouchTestDriver: 11:27:59,596 [main][25] Current class (ti.modules.titanium.ui.widget.webview.TiWebViewClient) can handle onPageFinished [DEBUG] : TouchTestDriver: 11:27:59,597 [main][25] Current class (ti.modules.titanium.ui.widget.webview.TiWebViewClient) can handle shouldOverrideUrlLoading [DEBUG] : TouchTestDriver: 11:27:59,597 [main][25] Caching ti.modules.titanium.ui.widget.webview.TiWebViewClient with class being point-cut able set to true [DEBUG] : TouchTestDriver: 11:27:59,597 [main][25] Adding TTD Javascript interfaces [DEBUG] : TouchTestDriver: 11:27:59,597 [main][25] ti.modules.titanium.ui.widget.webview.TiWebViewClient does not need TTW Client wrapping. [INFO] : cr_Ime: ImeThread is enabled. [DEBUG] : Window: Checkpoint: postWindowCreated() [INFO] : I/System.out: ActivityRecorder: after org.appcelerator.titanium.TiActivity@9f98e36_onCreate(), launchUrl = null [INFO] : I/System.out: ActivityRecorder: after org.appcelerator.titanium.TiActivity@9f98e36_onCreate(), launchUrl = null [ERROR] : libEGL: validate_display:99 error 3008 (EGL_BAD_DISPLAY) [WARN] : VideoCapabilities: Unrecognized profile 2130706433 for video/avc [INFO] : Choreographer: Skipped 30 frames! The application may be doing too much work on its main thread. [INFO] : VideoCapabilities: Unsupported profile 4 for video/mp4v-es [INFO] : OpenGLRenderer: Initialized EGL, version 1.4 [DEBUG] : OpenGLRenderer: Swap behavior 1 [DEBUG] : TouchTestDriver: 11:27:59,754 [main][25] onPageStarted [WARN] : cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 20315 [ERROR] : chromium: [ERROR:interface_registry.cc(99)] Failed to locate a binder for interface: autofill::mojom::AutofillDriver [DEBUG] : TouchTestDriver: 11:28:00,520 [main][25] The anchor reference for file:///android_asset/Resources/ is null and the query string is null [DEBUG] : TouchTestDriver: 11:28:00,521 [main][25] onPageFinished ti.modules.titanium.ui.widget.webview.TiUIWebView$NonHTCWebView{80273da VFEDHVCL. .F....I. 0,0-1440,2112 #3}, file:///android_asset/Resources/ : injecting as it is file/http protocol. Reload JS? false Page started loading? true [DEBUG] : TouchTestDriver: 11:28:00,521 [main][25] Loading and evaluating all TTW scripts [DEBUG] : TouchTestDriver: 11:28:00,540 [main][25] Base64 : LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiAg [DEBUG] : TouchTestDriver: Q29weXJpZ2h0IDIwMTMtMjAxNCBTT0FTVEEsIEluYy4KKiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4K [DEBUG] : TouchTestDriver: KiAgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbC4KKgoqICBGaWxlOiAgVFRXLmpzCioKKioq [DEBUG] : TouchTestDriver: KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp3aW5kb3cu [DEBUG] : TouchTestDriver: dHRyX2luaXRpYWxpemVkID0gZmFsc2U7CmlmICghd2luZG93LlRUV19PcHRpb25zKQp7CiAgVFRX [DEBUG] : TouchTestDriver: X09wdGlvbnMgPSB7fTsKfQpUVFcgPSB7fTsKClRUVy5sb2cgPSBmdW5jdGlvbihtc2cpCnsKICB3 [DEBUG] : TouchTestDriver: aW5kb3cudG9wLmRvY3VtZW50LmxvY2F0aW9uLmhyZWYgPSAidHRsb2c6Ly8iICsgZW5jb2RlVVJJ [DEBUG] : TouchTestDriver: Q29tcG9uZW50KG1zZyk7Cn0KLy8gV2UncmUgZ29pbmcgdG8gbmVlZCBKU09OLnN0cmluaWZ5LCBz [DEBUG] : TouchTestDriver: byBtYWtlIHN1cmUgbm8gb25lIGhhcyB0YW1wZXJlZCB3aXRoIGl0Lgp0dEpTT04gPSB3aW5kb3cu [DEBUG] : TouchTestDriver: SlNPTjsKaWYgKHR0SlNPTi5zdHJpbmdpZnkudG9TdHJpbmcoKS5pbmRleE9mKCJuYXRpdmUgY29k [DEBUG] : TouchTestDriver: ZSIpID09IC0xKSAgICAgIAp7CiAgLy8gU29tZW9uZSBoYXMgb3ZlcndyaXR0ZW4gd2luZG93LkpT [DEBUG] : TouchTestDriver: T04uc3RyaW5pZnkgKHd3dy5jbm4uY29tISkuICBDcmVhdGUgYW4gaWZyYW1lIHRvCiAgLy8gZ2V0 [DEBUG] : TouchTestDriver: IHRoZSBuYXRpdmUgSlNPTiBvYmplY3QgYmFjay4KICB2YXIgaWZyYW1lID0gZG9jdW1lbnQuY3Jl [DEBUG] : TouchTestDriver: YXRlRWxlbWVudCgiaWZyYW1lIik7CiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUp [DEBUG] : TouchTestDriver: OwogIGlmcmFtZS5zdHlsZS52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgaWZyYW1lLnN0eWxlLnBv [DEBUG] : TouchTestDriver: c2l0aW9uID0gImFic29sdXRlIjsKICBpZnJhbWUuc3R5bGUud2lkdGg9IjFweCI7CglpZnJhbWUu [DEBUG] : TouchTestDriver: c3R5bGUuaGVpZ2ggPSAiMXB4IjsKICB0dEpTT04gPSBpZnJhbWUuY29udGVudFdpbmRvdy5KU09O [DEBUG] : TouchTestDriver: OyAgICAgICAKfQoKZnVuY3Rpb24gdHRfb25sb2FkKGUpCnsKIC8vIFdoZW4gdGhlIGlmcmFtZSBp [DEBUG] : TouchTestDriver: cyByZS1sb2FkZWQsIHdlIHJlbW92ZSB0aGUgaGFzVEREIGF0dHJpYnV0ZSBzbyB0aGF0IHRoZSBz [DEBUG] : TouchTestDriver: Y3JpcHQgd2lsbCBhZ2FpbgogLy8gYmUgaW5qZWN0ZWQuCiBlLnRhcmdldC5yZW1vdmVBdHRyaWJ1 [DEBUG] : TouchTestDriver: dGUoImhhc1RURCIpOwp9CgovL1RoaXMgaXMgdGhlIGZ1bmN0aW9uIHRoYXQgVFRXIHdpbGwgY2Fs [DEBUG] : TouchTestDriver: bCBkdXJpbmcgd2ViVmlld0RpZEZpbmlzaExvYWQgd2hlbiB0aGUgVUlXZWJWaWV3IGFscmVhZHkg [DEBUG] : TouchTestDriver: aGFzIFRUVyBzY3JpcHRzIGluIGl0LgovL1dlIGRvbid0IGtub3cgd2hpY2ggZnJhbWUgaXQgaXMg [DEBUG] : TouchTestDriver: dGhhdCBsb2FkZWQsIGJ1dCB0aGVyZSBoYXMgdG8gYmUgYSBmcmFtZSBzb21ld2hlcmUgdGhhdCBo [DEBUG] : TouchTestDriver: YXMganVzdCBsb2FkZWQgYW5kIGRvZXNuJ3QKLy95ZXQgaGF2ZSBUVEQgaW4gaXQuICBXZSBhbHNv [DEBUG] : TouchTestDriver: IGNhbGwgdGhpcyBmdW5jdGlvbiBhdCB0aGUgZW5kIG9mIFRUV0F1dG9tYXRpb24uc2NyaXB0IGlu [DEBUG] : TouchTestDriver: IGNhc2UgdGhlIGZyYW1lIGxvYWQgYmVmb3JlCi8vdGhlIG1haW4gZG9jdW1lbnQgaGFzIFRURCBp [DEBUG] : TouchTestDriver: bmplY3RlZC4KZnVuY3Rpb24gdHRfaW5qZWN0SW5TdWJmcmFtZXMoKQp7ICAKICB2YXIgaWZyYW1l [DEBUG] : TouchTestDriver: cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJpZnJhbWUiKTsKICBmb3IgKHZhciBp [DEBUG] : TouchTestDriver: PTA7IGk8aWZyYW1lcy5sZW5ndGg7ICsraSkKICB7CiAgICB2YXIgaWZyYW1lID0gaWZyYW1lc1tp [DEBUG] : TouchTestDriver: XTsKICAgIHR0X2luamVjdEluRnJhbWUoaWZyYW1lKTsKICB9Cn0KCmZ1bmN0aW9uIHR0X2luamVj [DEBUG] : TouchTestDriver: dEluRnJhbWUoaWZyYW1lKQp7ICAKICAvL1RoaXMgaXMgIHRoZSBzY3JpcHQgdGhhdCBpcyBldmFs [DEBUG] : TouchTestDriver: J2QgaW4gdGhlIHRvcCBBVVQgZG9jdW1lbnQncyBpZnJhbWVzLgogIHZhciBzY3JpcHQgPSAidHJ5 [DEBUG] : TouchTestDriver: IiArIAogICAgICAgICAgICAgICAieyIgKyAKICAgICAgICAgICAgICAgICAgInZhciBzayA9IGRv [DEBUG] : TouchTestDriver: Y3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOyIgKyAKICAgICAgICAgICAgICAgICAgInNr [DEBUG] : TouchTestDriver: LnNyYyA9ICd0dHc6Ly9Ub3VjaFRlc3RXZWJJbm5lckZyYW1lU2NyaXB0c19fQ29tYmluZWQuanMn [DEBUG] : TouchTestDriver: OyIgKyAKICAgICAgICAgICAgICAgICAgInNrLnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0JzsiICsg [DEBUG] : TouchTestDriver: CiAgICAgICAgICAgICAgICAgICJkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNrKTsiICsgCiAg [DEBUG] : TouchTestDriver: ICAgICAgICAgICAgICAifSIgKyAKICAgICAgICAgICAgICAgICJjYXRjaChlKSIgKyAKICAgICAg [DEBUG] : TouchTestDriver: ICAgICAgICAgICJ7IiArIAogICAgICAgICAgICAgICAgICAvLyJhbGVydChcIlRUVyBpbmplY3Qg [DEBUG] : TouchTestDriver: ZmFpbGVkIGJlY2F1c2U6IFwiICsgZS5tZXNzYWdlKSIgKyAKICAgICAgICAgICAgICAgICJ9OyI7 [DEBUG] : TouchTestDriver: CiAgdHJ5CiAgewogICAgaWYgKGlmcmFtZS5nZXRBdHRyaWJ1dGUoImhhc1RURCIpID09IG51bGwp [DEBUG] : TouchTestDriver: CiAgICB7CiAgICAgIGlmIChpZnJhbWUuY29udGVudFdpbmRvdykKICAgICAgewogICAgICAgIGlm [DEBUG] : TouchTestDriver: IChpZnJhbWUuY29udGVudFdpbmRvdy5ldmFsICE9IG51bGwpCiAgICAgICAgewogICAgICAgICAg [DEBUG] : TouchTestDriver: aWZyYW1lLmNvbnRlbnRXaW5kb3cuZXZhbChzY3JpcHQpOyAKICAgICAgICAgIGlmcmFtZS5zZXRB [DEBUG] : TouchTestDriver: dHRyaWJ1dGUoImhhc1RURCIsICJ0cnVlIik7CiAgICAgICAgICBpZnJhbWUuYWRkRXZlbnRMaXN0 [DEBUG] : TouchTestDriver: ZW5lcigibG9hZCIsIHR0X29ubG9hZCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAg [DEBUG] : TouchTestDriver: ICAgICB7CiAgICAgICAgICAvL2FsZXJ0KCJub24tdGVzdGFibGUgZnJhbWUgZGV0ZWN0ZWQiKTsK [DEBUG] : TouchTestDriver: ICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgLy9hbGVydCgibm8g [DEBUG] : TouchTestDriver: Y29udGVudFdpbmRvdyIpICAKICAgICAgfQogICAgfQogIH0KICBjYXRjaCAoZSkgCiAgewogICAg [DEBUG] : TouchTestDriver: Ly9hbGVydCgiZXhjZXB0aW9uIGluIGlmcmFtZS5ldmFsOiAiICsgZSArICIgY29udGVudFdpbmRv [DEBUG] : TouchTestDriver: dzogIiArIGlmcmFtZS5jb250ZW50V2luZG93ICsgIiAgZXZhbDogIiArIGlmcmFtZS5jb250ZW50 [DEBUG] : TouchTestDriver: V2luZG93LmV2Y [DEBUG] : TouchTestDriver: 11:28:00,541 [main][25] Decoded from base64 : 13 scripts [DEBUG] : TouchTestDriver: 11:28:00,541 [main][25] /**************************************************** Copyright 2013-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: TTW.js****************************************************/window.ttr_initialized = false;if (!window.TTW_Options){ TTW_Options = {};}TTW = {};TTW.log = function(msg){ window.top.document.location.href = "ttlog://" + encodeURIComponent(msg);}// We're going to need JSON.strinify, so make sure no one has tampered with it.ttJSON = window.JSON;if (ttJSON.stringify.toString().indexOf("native code") == -1) { // Someone has overwritten window.JSON.strinify (www.cnn.com!). Create an iframe to // get the native JSON object back. var iframe = document.createElement("iframe"); document.body.appendChild(iframe); iframe.style.visibility = "hidden"; iframe.style.position = "absolute"; iframe.style.width="1px"; iframe.style.heigh = "1px"; ttJSON = iframe.contentWindow.JSON; }function tt_onload(e){ // When the iframe is re-loaded, we remove the hasTDD attribute so that the script will again // be injected. e.target.removeAttribute("hasTTD");}//This is the function that TTW will call during webViewDidFinishLoad when the UIWebView already has TTW scripts in it.//We don't know which frame it is that loaded, but there has to be a frame somewhere that has just loaded and doesn't//yet have TTD in it. We also call this function at the end of TTWAutomation.script in case the frame load before//the main document has TTD injected.function tt_injectInSubframes(){ var iframes = document.getElementsByTagName("iframe"); for (var i=0; i 0) { return elements[0]; } return null; } this.finders["text"] = function(locator, doc, win, bReturnFirst) { var elem = this.finders["xpath"].call(this,"//*[starts-with(text(), \"" + locator + "\")]", doc, win, false); var textProperty = "textContent"; if (!elem) { elem = this.finders["xpath"].call(this,"//input[starts-with(@value, \"" + locator + "\")]", doc, win, false); textProperty = "value"; } if (Array [DEBUG] : TouchTestDriver: 11:28:00,542 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: findElement.js****************************************************/TTW.findAllElements = function(locator) { return TTW.findElement(locator, true);}TTW.findElement = function(locator, bReturnArray) { this.findElementRecursive = function(strategy, locator, index, inDocument, inWindow, bReturnFirst) { // Try finding the element in the given window var element = null; try { if (index > 0) { var elems = TTW.ElementFinders.findElementBy(strategy, locator, inDocument, inWindow, false); element = elems && elems.length > index ? elems[index] : null; } else { element = TTW.ElementFinders.findElementBy(strategy, locator, inDocument, inWindow, bReturnFirst); } } catch (e) { tt_log("Exception in findElementRecursive: " + e, "info"); } if (element != null) { return element; } // Continue looking in frames var frames = null; try { frames = inWindow.frames; } catch (e) { tt_log("findElementRecursive exception getting inWindow.frames: " + e, "info"); } for (var i = 0; i < frames.length; i++) { var doc = null; try { doc = frames[i].document; } catch (e) { tt_log("findElementRecursive exception getting frames[i].document: " + e, "info"); } if (doc && frames[i] && doc != null && frames[i] != null) { element = this.findElementRecursive(strategy, locator, index, doc, frames[i], bReturnFirst); if (element != null) { return element; } } } return null; } this.strategyCanHaveIndex = function(strategy) { return strategy == "tagname"; } this.stringStartsWith = function(string, prefix) { // If string is something like "name=Mukul\nAte\nA\nBagel", then checks to see if prefix (i.e. // name, text, link) will match the first n characters of "string", where n is the prefix length. return string.slice(0, prefix.length) == prefix; } this.locatorHasStrategy = function(string) { var builders = TTW.getLocatorBuilders(); for (var i=0; i= 0 || string.indexOf('*') >= 0)) return "exact:" + string; else return string; } this.addLocator = function(locator, finderName) { if (this.selected == eLocStrategies.DEFAULT) this.selected = finderName; if (this.isXpathStrategy(finderName)) this.xpathLocators[finderName] = locator; else this.locators[finderName] = locator; } this.buildAll = function(e, bReturnFirst) { [DEBUG] : TouchTestDriver: 11:28:00,543 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: locatorBuilders.js****************************************************/function TTW_locatorBuilders() { this.idAttrs = ["data-test-id","datatestid"]; this.builders = {}; this.builders["id"] = function(e) { return this.getLocatorId(e); }; this.getLocatorId = function(e) { for (var i=0; i 0 ? e.value.substring(0, max_substring_length) : null; if (e.textContent) return this.trim(e.textContent).length > 0 ? e.textContent.substring(0, max_substring_length) : null; return null; }; this.builders["link"] = function(e) { if (e.nodeName.toLowerCase() == 'a') { var text = e.textContent; if (!text.match(/^\s*$/)) { return text.replace(/\xA0/g, " ").replace(/^\s*(.*?)\s*$/, "$1"); } } return null; }; this.builders["name"] = function(e) { if (e.name) { return e.name; } return null; }; this.builders["xpath_id"] = function(e) { if (e.nodeType != 1) return null; // handle the case of an element with the same id as another element. var idLocator = this.getLocatorId(e); if (idLocator != null && TTW.findElement(idLocator) != e) { return "//*[@" + this.getIdAttribute(e) + "=" + this.attributeValue(this.getLocatorId(e)) + "][2]"; } var path = ''; var current = e.parentNode; var pXPath = null; var parentWithId = null; while (pXPath == null && current != null && current.nodeType == 1 && this.QName(current).indexOf("#") != 0) { //alert("while: " + current + " : " + this.getLocatorId(current)); // find the nearest parent with an id or name if (this.getLocatorId(current) != null) { pXPath = "/" + "/" + this.QName(current) + "[@" + this.getIdAttribute(current) + "=" + this.attributeValue(this.getLocatorId(current)) + "]"; } else { if (current.hasAttribute("name") && current.getAttribute("name") != "") pXPath = "/" + "/" + this.QName(current) + "[@name=" + this.attributeValue(current.getAttribute("name")) + "]"; } if (pXPath != null) parentWithId = current; current = current.parentNode; } if (pXPath != null) { current = e; while ((current != null) && (current != parentWithId) && (current.nodeType == 1) && this.QName(current).indexOf("#") != 0) { var currentPath = '/' + this.QName(current); if (current.parentNode != null) { var childNodes = current.parentNode.childNodes; var total = 0; var index = -1; for (var i = 0; i < childNodes.length; i++) { var child = childNodes[i]; if (child.nodeName == current.nodeName) { if (child == current) index = total; total++; } } if (total > 1 && index >= 0) { currentPath += '[' + (index + 1) + ']'; } } path = currentPath + path; var locator = '/' + path; current = current.parentNode; } if (current != null) [DEBUG] : TouchTestDriver: 11:28:00,543 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: cookieUtils.js****************************************************/function tt_getCookie() { return document.cookie;}function tt_isCookiePresent(name) { /** * Returns true if a cookie with the specified name is present, or false otherwise. * @param name the name of the cookie * @return boolean true if a cookie with the specified name is present, or false otherwise. */ var v = tt_getCookieByName(name); var absent = (v === null); return !absent;} function tt_doCreateCookie(nameValuePair, optionsString) { /** * Create a new cookie whose path and domain are same with those of current page * under test, unless you specified a path for this cookie explicitly. * * @param nameValuePair name and value of the cookie in a format "name=value" * @param optionsString options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'. * the optionsString's format is "path=/path/, max_age=60, domain=.foo.com". The order of options are irrelevant, the unit * of the value of 'max_age' is second. Note that specifying a domain that isn't a subset of the current domain will * usually fail. */ var results = /[^\s=\[\]\(\),"\/\?@:;]+=[^\s=\[\]\(\),"\/\?@:;]*/.test(nameValuePair); if (!results) { // invalid parameter return; } var cookie = nameValuePair.trim(); results = /max_age=(\d+)/.exec(optionsString); if (results) { var expireDateInMilliseconds = (new Date()).getTime() + results[1] * 1000; cookie += "; expires=" + new Date(expireDateInMilliseconds).toGMTString(); } results = /path=([^\s,]+)[,]?/.exec(optionsString); if (results) { var path = results[1]; if ("/" != path) { path = path.replace(/\/$/, ""); } cookie += "; path=" + path; } results = /domain=([^\s,]+)[,]?/.exec(optionsString); if (results) { var domain = results[1]; cookie += "; domain=" + domain; } document.cookie = cookie;}function tt_doDeleteCookie(name, optionsString){ /** * Delete a named cookie with specified path and domain. Be careful; to delete a cookie, you * need to delete it using the exact same path and domain that were used to create the cookie. * If the path is wrong, or the domain is wrong, the cookie simply won't be deleted. Also * note that specifying a domain that isn't a subset of the current domain will usually fail. * * Since there's no way to discover at runtime the original path and domain of a given cookie, * we've added an option called 'recurse' to try all sub-domains of the current domain with * all paths that are a subset of the current path. Beware; this option can be slow. In * big-O notation, it operates in O(n*m) time, where n is the number of dots in the domain * name and m is the number of slashes in the path. * * @param name the name of the cookie to be deleted * @param optionsString options for the cookie. Currently supported options include 'path', 'domain' * and 'recurse.' The optionsString's format is "path=/path/, domain=.foo.com, recurse=true". * The order of options are irrelevant. Note that specifying a domain that isn't a subset of * the current domain will usually fail. */ // set the expire time of the cookie to be deleted to one minute before now. var path = ""; var domain = ""; var recurse = false; var matched = false; results = /path=([^\s,]+)[,]?/.exec(optionsString); if (results) { matched = true; path = results[1]; } results = /domain=([^\s,]+)[,]?/.exec(optionsString); if (results) { matched = true; domain = results[1]; } results = /recurse=([^\s,]+)[,]?/.exec(optionsString); if (results) { matched = true; recurse = results[1]; if ("false" == recurse) { recurse = false; } } // Treat the entire optionsString as a path (for backwards compatibility) if (optionsString & [DEBUG] : TouchTestDriver: 11:28:00,544 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: getOutput.js****************************************************//** * handleTask * continueTask * * This is the javascript version of TTAutomationTaskHandler.m handleTask * * -(NSDictionary*) handleTask:(NSString*)taskName task:(NSDictionary*)task */function tta_getOutput(output){ /** * getOutput * * This is the javascript version of TTAutomationTaskHandler.m getOutput * * -(id) getOutput:(NSDictionary *)output error:(NSError **)error */ this.getOutput = function(output) { // output // // command // params { arg1, arg2 } var params = output.params; var arg1 = null; var arg2 = null; if (params != null) { arg1 = params.arg1; arg2 = params.arg2; if (arg1 != null && arg1 != "" && output.command != "output-textPresent" && output.command != "output-eval") { var loc = new TTLocator(); loc.initWithJsonString(arg1); arg1 = loc.serializeShort(); } } switch (output.command) { case "output-isElementChecked": case "output-elementChecked": { return tta_isElementChecked(arg1);; } case "output-isElementPresent": case "output-elementPresent": { return tta_isElementPresent(arg1); } case "output-isElementVisible": case "output-elementVisible": { return tta_isElementVisible(arg1); } case "output-inputValue": case "output-getElementValue": { return tta_getElementValue(arg1); } case "output-elementText": { return tta_getElementText(arg1); } case "output-allAttributeValue": { return tta_getAllAttributeValue(arg1); } case "output-allElementText": { return tta_getAllElementText(arg1); } case "output-htmlSource": { return tta_getHtmlSource(); } case "output-alert": { return tta_getAlertValue(); } case "output-confirmation": { return tta_getConfirmationValue(); } case "output-prompt": { return tta_getPromptValue(); } case "output-bodyText": { return tta_getBodyText(); } case "output-textPresent": { return tta_isTextPresent(arg1); } case "output-eval": { return tta_getEval(arg1); } case "output-innerHTML": { return tta_getInnerHTML(arg1); } case "output-location": { return tta_getLocation(); } case "output-title": { return tta_getTitle(); } case "output-xpathCount": { return tta_getXpathCount(arg1); } case "output-attributeValue": { return tta_getAttributeValue(arg1); } case "output-cookie": { return tt_getCookie(); } case "output-cookieByName": { return tt_getCookieByName(arg1); } case "output-allDropDownOptionLabels": { return tt_getAllDropDownOptionLabels(arg1); } case "output-allDropDownOptionValues": { return tt_getAllDropDownOptionValues(arg1); } // This is an implicit wait used by hybrid, but not exposed as an accessor case "output-elementReadyForAction": { return tta_readyForAction(arg1); } default: return "Unrecognized output: " + output.command; } } // The AUT no longer does the task handling... try { var value = this.getOutput(output); return ttJSON.stringify({value:value}); } catch (exception) { var msg = null; if (typeof exception == "object") { msg = exception.message; } else { msg = exception; } return ttJSON.stringify({value:null,error:{fatal:true,message:msg}}); }} [DEBUG] : TouchTestDriver: 11:28:00,544 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: performAction.js****************************************************//** * handleTask * continueTask * * This is the javascript version of TTAutomationTaskHandler.m handleTask * * -(NSDictionary*) handleTask:(NSString*)taskName task:(NSDictionary*)task */function tta_performAction(task){ this.performAction = function(task) { //tt_log("perform " + task.name, "debug"); var params = task.data.params; var locator = params.arg1; var param2 = params.arg2; var elem = null; var loc = new TTLocator(); loc.initWithJsonString(locator); locator = loc.serializeShort(); switch (task.name) { case "click": case "clickAt": case "doubleClick": case "webClick": case "touchUp": case "type": case "typePassword": case "webType": case "dragAndDrop": case "dragAndDropToObject": case "scroll": case "select": case "addSelection": case "removeSelection": case "assignId": case "check": case "uncheck": case "contextMenu": case "scroll": { // This action type requires an element. // We try to find it using the locator, // but allow up to a minute of "implicit // wait" for it to appear, if it is not // immediately available. //elem = [self findElementWithWait:locator error:&error]; elem = TTW.findElement(locator); if (elem == null) { var msg = "The locator, " + locator + ", did not match any elements."; return ttJSON.stringify({error:{fatal:true,message:msg}}); } break; } } var elem2 = null; switch (task.name) { case "dragAndDropToObject": { // This action type requires an element as the second parameter. // We try to find it using the locator, // but allow up to a minute of "implicit // wait" for it to appear, if it is not // immediately available. //elem = [self findElementWithWait:locator error:&error]; elem2 = TTW.findElement(param2); if (elem2 == null) { // Implicit errors are always fatal.. var msg = "The locator, " + locator + ", did not match any elements."; return ttJSON.stringify({error:{fatal:true,message:msg}}); } break; } } switch (task.name) { case "click": case "webClick": { tta_click(elem, locator); break; } case "doubleClick": { tta_doubleClick(elem); break; } case "clickAt": { tta_clickAt(elem, param2); break; } case "dragAndDrop": { tta_dragAndDrop(elem, param2); break; } case "dragAndDropToObject": { tta_dragAndDropToObject(elem, elem2); break; } case "touchUp": { tta_touchUp(elem); break; } case "type": case "webType": case "typePassword": // passwords have already been decrypted, so we can do a normal type here. { if (param2 != null) { tta_type(elem, param2); } break; } case "contextMenu": { tta_contextMenu(elem); break; } case "select": { tta_select(elem, param2); break; } case "addSelection": { tta_addSelection(elem, param2); break; } case "removeSelection": { tta_removeSelection(elem, param2); break; } case "assignId": { tta_assignId(elem, param2); break; } case "goBack": case "back": { tta_goBack(); break; } case "createCookie": { tt_doCreateCookie(locator, param2); break; } case "deleteCookie": { tt_doDeleteCookie(locator, param2); break; } [DEBUG] : TouchTestDriver: 11:28:00,544 [main][25] /**************************************************** Copyright 2012-2015 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: TTWAutomation.js****************************************************///Scripts for TTWfunction TTWAutomation(){}TTWAutomation.prototype.doBlur = function(elem) { if (elem.blur) { elem.blur(); } else { this.triggerEvent(elem, "blur"); }}function tta_doChange(elem) { if (elem.onchange) { elem.onchange(); } else { tta_dispatchEvent(elem, "change"); }}TTWAutomation.prototype.triggerEvent = function(elem, event){ tta_dispatchEvent(elem, event); }function tta_dispatchEvent(element, eventType){ var evt = document.createEvent('HTMLEvents'); if (evt.initEvent) { evt.initEvent(eventType, true, true); element.dispatchEvent(evt); }}//Automation functions to be injected in the AUTfunction tt_log(msg, level){ switch (level) { case "error": alert(msg); break; case "info": //alert(msg); break; case "debug": //alert(msg); break; default: alert(msg); }}function tta_scroll(elem, top, left){ // Perhaps it's a bug in the browser, but I have found that for body only, // this needs to be a number. For other elements, string would work. Also, // for body only, setting left to 0 when it's already 0 causes top to not work. if (elem.scrollTop != Number(top)) elem.scrollTop = Number(top); if (elem.scrollLeft != Number(left)) elem.scrollLeft = Number(left);}function tta_select(elem, optionLocator){ if (elem.type != "date") tta_selectOption(elem, optionLocator) else elem.value = optionLocator;}function tta_findOptionIndex(elem, optionLocator){ if (optionLocator.indexOf("value=") == 0) { var value = optionLocator.substring(6); for (var ndx = 0; ndx < elem.options.length; ndx++) { if (elem.options[ndx].value == value) { return ndx; } } } else if (optionLocator.indexOf("id=") == 0) { var id = optionLocator.substring(3); for (var ndx = 0; ndx < elem.options.length; ndx++) { if (id == elem.options[ndx].getAttribute("id")) { return ndx; } } } else if (optionLocator.indexOf("index=") == 0) { var index = optionLocator.substring(6); return Number(index); } else if (optionLocator.indexOf("text=") == 0) { var text = optionLocator.substring(5); for (var ndx = 0; ndx < elem.options.length; ndx++) { if (elem.options[ndx].text == text) { return ndx; } } } else if (optionLocator.indexOf("label=") == 0) { var label = optionLocator.substring(6); for (var ndx = 0; ndx < elem.options.length; ndx++) { if (elem.options[ndx].text == label) { return ndx; } } }}function tta_goBack(){ window.history.back();}function tta_check(elem){ elem.checked = true;}function tta_uncheck(elem){ elem.checked = false;}function tta_assignId(elem, newID){ elem.setAttribute("id", newID);}function tta_type(elem, value){ var ttw = new TTWAutomation(); elem.value = value; this.doBlur(elem); if (elem.change) { elem.change(); } this.triggerEvent(elem, "change"); //ttw.doType(elem,value);}function tta_isElementChecked(loc){ var element = TTW.findElement(loc); if (element != null) { if (element.checked) { return true; } } return false;}function tta_isElementPresent(loc){ return TTW.findElement(loc) != null;}function tta_isElementVisible(loc){ var element = TTW.findElement(loc); if (element != null) { if (element.offsetWidth > 0 && element.offsetHeight > 0) { if (element.style.display == "none") { return false; } var elementRect = element.getBoundingClientRect(); if (elementRect.top >= 0 && elementRect.left >= 0 && elementRect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && elementRect.right <= (window.innerWidth || document.documentElement.clientWidth)) { [DEBUG] : TouchTestDriver: 11:28:00,544 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: TTWRecorder.js****************************************************/var TTWRecorder = { keydownElem : null, locator : null, isPassword : false, keyboardTab : false, keyboardReturn : false};function tt_onKeyDown(e){ if (e.target != window.top.TTWRecorder.keydownElem) { window.top.TTWRecorder.locator = window.top.TTW.getLocator(e.target, 'all'); window.top.TTWRecorder.keydownElem = e.target; } var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; if (key == 9) { window.top.TTWRecorder.keyboardTab = true; window.top.document.location.href='ttwr://keyboardTab'; } else if (key == 13) { window.top.TTWRecorder.keyboardReturn = true; window.top.document.location.href='ttwr://keyboardReturn' + '?value=' + encodeURIComponent(e.target.value) + '&locator=' + encodeURIComponent(window.top.TTWRecorder.locator) + pwdParam; } else { window.top.TTWRecorder.isPassword = e.target.getAttribute("type") == "password"; var pwdParam = window.top.TTWRecorder.isPassword ? "&isPassword=true" : ""; window.top.document.location.href='ttwr://pendingType' + '?value=' + encodeURIComponent(e.target.value) + '&locator=' + encodeURIComponent(window.top.TTWRecorder.locator) + pwdParam; }}// Called by nativefunction tt_getScrollPos(elem){ if (!elem) elem = document.body; return ttJSON.stringify({top: elem.scrollTop, left: elem.scrollLeft})}function TTW_addListeners(){ if (window.top.TTW_Options != null && window.top.TTW_Options.os == "iOS") { // In iOS, this can't be done on a timeout or it won't happen in cases where the page is going away (eBay search) document.addEventListener('keydown', function(e){tt_onKeyDown(e)}, true); } else { document.addEventListener('keydown', function(e){setTimeout(function() {tt_onKeyDown(e);}, 10)}, true); }}//This function is called by the TouchTest Web appTTWRecorder.evaluateJavaScript = function(view, script){ var result = eval("(" + script + ")"); if (result != undefined) autJavascriptEvaluator.didFinishEvaluation(view, script, result.toString());}//console.log("JS: TTWRecorder END"); [DEBUG] : TouchTestDriver: 11:28:00,545 [main][25] /**************************************************** Copyright 2012-2014 SOASTA, Inc.* All rights reserved.* Proprietary and confidential.** File: TouchTestLocator.js****************************************************//** * TouchTestLocator */function TouchTestLocator(){}// Mobile web allows a tolerance of 15px when tapping on small items like// checkboxes and radios.TouchTestLocator.touchTolerance = 15;/** * This function is used by TTD for Touch Locator on Hybrid app */TouchTestLocator.inspectWithLocator = function(locator, bPositionOnly){ try { locator = unescape(locator); var target = TTW.findElement(locator); var position = target.getBoundingClientRect(); var output; if (bPositionOnly) { output = ttJSON.stringify({ "x" : "" + position.left, "y" : "" + position.top, "w" : "" + position.width, "h" : "" + position.height, "type" : "" + target.getAttribute("type") }); } else { output = ttJSON.stringify({ "locators" : TTW.getLocator(target, 'all'), "tagName" : "" + target.tagName, "x" : "" + position.left, "y" : "" + position.top, "w" : "" + position.width, "h" : "" + position.height, "type" : "" + target.getAttribute("type") }); } if (window.top.touchLocatorJavascriptOutputEvaluator) window.top.touchLocatorJavascriptOutputEvaluator.didFinishOutputEvaluation("inspectWithLocator", output); else return output; } catch (e) { return "Exception in inspectWithLocator: " + e.message + "\n" + e.stack; } }// This will return a message as a locator from inspectWithPoint. Used only for debugging!!TouchTestLocator.inspectWithPointLogging = function(msg){// var metas = document.getElementsByTagName('meta');// for (i=0; i