robotium原理之获取WebElement元素
public ArrayList<WebElement> getWebElements(boolean onlySufficientlyVisible){ boolean javaScriptWasExecuted = executeJavaScriptFunction("allWebElements();"); return getWebElements(javaScriptWasExecuted, onlySufficientlyVisible); }
private boolean executeJavaScriptFunction(final String function){ final WebView webView = viewFetcher.getFreshestView(viewFetcher.getCurrentViews(WebView.class, true)); if(webView == null){ return false; } //做一些JS注入执行前的准备工作,例如将WebView设为可允许执行JS等,并将RobotiumWeb.js中的脚本以String形式返回 final String javaScript = prepareForStartOfJavascriptExecution(); activityUtils.getCurrentActivity(false).runOnUiThread(new Runnable() { public void run() { if(webView != null){ webView.loadUrl("javascript:" + javaScript + function); } } }); return true; }
javascript: function allWebElements() { for (var key in document.all){ try{ promptElement(document.all[key]); //调用promptElement(element)函数 }catch(ignored){} } finished(); //执行完后,调用finished()函数 } function promptElement(element) { var id = element.id; var text = element.innerText; if(text.trim().length == 0){ text = element.value; } var name = element.getAttribute('name'); var className = element.className; var tagName = element.tagName; var attributes = ""; var htmlAttributes = element.attributes; for (var i = 0, htmlAttribute; htmlAttribute = htmlAttributes[i]; i++){ attributes += htmlAttribute.name + "::" + htmlAttribute.value; if (i + 1 < htmlAttributes.length) { attributes += "#$"; } } var rect = element.getBoundingClientRect(); if(rect.width > 0 && rect.height > 0 && rect.left >= 0 && rect.top >= 0){ prompt(id + ';,' + text + ';,' + name + ";," + className + ";," + tagName + ";," + rect.left + ';,' + rect.top + ';,' + rect.width + ';,' + rect.height + ';,' + attributes); //弹出包含id、text、name等字段的提示框 } } function finished(){ prompt('robotium-finished'); //弹出包含robotium-finished字符串的提示框,用于标识脚本注入执行结束 }
onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) |
@Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult r) { if(message != null && (message.contains(";,") || message.contains("robotium-finished"))){ //如果提示框中包含robotium-finished字符串,即表示那段JS注入脚本执行完毕了 if(message.equals("robotium-finished")){ webElementCreator.setFinished(true); } else{ webElementCreator.createWebElementAndAddInList(message, view);//有人提示框中的内容,那么就可以对提示框中的内容进行处理了 } r.confirm(); return true; } else { if(originalWebChromeClient != null) { return originalWebChromeClient.onJsPrompt(view, url, message, defaultValue, r); } return true; } }
public void enableJavascriptAndSetRobotiumWebClient(List<WebView> webViews, WebChromeClient originalWebChromeClient){ this.originalWebChromeClient = originalWebChromeClient; for(final WebView webView : webViews){ if(webView != null){ inst.runOnMainSync(new Runnable() { public void run() { webView.getSettings().setJavaScriptEnabled(true); webView.setWebChromeClient(robotiumWebClient); } }); } } }
private WebElement createWebElementAndSetLocation(String information, WebView webView){ String[] data = information.split(";,"); //将消息按;,符号分割,其中;,符号是在前面执行JS时加入的 String[] elements = null; int x = 0; int y = 0; int width = 0; int height = 0; Hashtable<String, String> attributes = new Hashtable<String, String>(); try{ x = Math.round(Float.valueOf(data[5])); y = Math.round(Float.valueOf(data[6])); width = Math.round(Float.valueOf(data[7])); height = Math.round(Float.valueOf(data[8])); elements = data[9].split("\\#\\$"); }catch(Exception ignored){} if(elements != null) { for (int index = 0; index < elements.length; index++){ String[] element = elements[index].split("::"); if (element.length > 1) { attributes.put(element[0], element[1]); } else { attributes.put(element[0], element[0]); } } } WebElement webElement = null; try{ webElement = new WebElement(data[0], data[1], data[2], data[3], data[4], attributes);//将id、text、name等字段存入 setLocation(webElement, webView, x, y, width, height); }catch(Exception ignored) {} return webElement; }
/** * Sets the location of a {@code WebElement} * * @param webElement the {@code TextView} object to set location * @param webView the {@code WebView} the text is shown in * @param x the x location to set * @param y the y location to set * @param width the width to set * @param height the height to set */ private void setLocation(WebElement webElement, WebView webView, int x, int y, int width, int height ){ float scale = webView.getScale(); int[] locationOfWebViewXY = new int[2]; webView.getLocationOnScreen(locationOfWebViewXY); int locationX = (int) (locationOfWebViewXY[0] + (x + (Math.floor(width / 2))) * scale); int locationY = (int) (locationOfWebViewXY[1] + (y + (Math.floor(height / 2))) * scale); webElement.setLocationX(locationX); webElement.setLocationY(locationY); }至此,WebElement对象中包含了id、text、name等字段,还包含了x、y坐标,知道了坐标后就可以像其它Android中的原生View一样根据坐标发送点击事件。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。