代码改变世界

解决 hybird 应用中重复获取 WebView,导致页面元素无法识别的问题

2017-11-13 01:18  清风软件测试开发  阅读(498)  评论(0编辑  收藏  举报

转载地址:http://blog.csdn.net/testman930/article/details/50799532

问题描述

在测APP的业务流,WebView和Native模式耦合在一起。例如:WebView >> Native >> WebView >> 。。。。。。 
Appium貌似有个问题,从WebView切换到NATIVE后,chromedriver可能会把第一个WebView的缓存驻留在内存中,即便用driver.close()方法关闭当前上下文,也无法清除。 
这样会导致进入其他的WebView,读取的还是第一个WebView的内容,导致页面元素无法识别。 
下面是发现问题到解决问题的一个过程,希望能帮助到遇到过同样问题的同行。

第一版代码:可能大多数人开始都会这么写,这样可能导致无法识别到其他窗口WebView的内容。

[java] view plain copy
  1. public void testDemo() {  
  2.         try {  
  3.             Log.logInfo("开始切换到WebView模式");  
  4.             ((AppiumDriver) driver).context("WEBVIEW_com.xx.xx.xx.xx");  
  5.             Log.logInfo("成功切换到WebView模式,开始查找WebView元素");  
  6.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.second > span")).click();  
  7.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.last > span")).click();  
  8.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > div")).click();  
  9.             Log.logInfo("开始切换到NATIVE模式");  
  10.             ((AppiumDriver) driver).context("NATIVE_APP");  
  11.         } catch (Exception e) {  
  12.             // anything  
  13.         }  
  14.     }  

 

第二版代码:我的思路是想通过正常途径解决问题,把当前WebView的实例赋给临时对象,用完后调用close()方法(quit()会把整个Seesion关闭),还是以失败告终,有点发吼了。

[java] view plain copy
  1. public void testDemo() {  
  2.         try {  
  3.             Log.logInfo("开始切换到WebView模式");  
  4.             AppiumDriver chromeDriver = (AppiumDriver) ((AppiumDriver) driver).context("WEBVIEW_com.xx.xx.xx.xx");  
  5.             Log.logInfo("成功切换到WebView模式,开始查找WebView元素");  
  6.             chromeDriver .findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.second > span")).click();  
  7.             chromeDriver .findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.last > span")).click();  
  8.             chromeDriver .findElement(By.cssSelector("#myWeidian > div.tpl_part > div")).click();  
  9.             chromeDriver.close();  
  10.             Log.logInfo("开始切换到NATIVE模式");  
  11.             ((AppiumDriver) driver).context("NATIVE_APP");  
  12.         } catch (Exception e) {  
  13.              // anything  
  14.         }  
  15.     }  

 

第三版代码:软的不行来硬的,放了个绝招,杀chromedriver的进程,还真的成功了,有时候真的需要暴力。。

[java] view plain copy
  1. public void testDemo() {  
  2.         try {  
  3.             Log.logInfo("开始切换到WebView模式");  
  4.             ((AppiumDriver) driver).context("WEBVIEW_com.xx.xx.xx.xx");  
  5.             Log.logInfo("成功切换到WebView模式,开始查找WebView元素");  
  6.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.second > span")).click();  
  7.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > ul > li.last > span")).click();  
  8.             driver.findElement(By.cssSelector("#myWeidian > div.tpl_part > div")).click();  
  9.             Log.logInfo("开始切换到NATIVE模式");  
  10.             ((AppiumDriver) driver).context("NATIVE_APP");  
  11.             Tools.killProcess("chromedriver");  
  12.         } catch (Exception e) {  
  13.             Tools.killProcess("chromedriver");  
  14.         }  
  15.     }  
  16.   
  17.     public static void killProcess(String processName) {  
  18.         try {  
  19.             String cmd = isWindows() ? "tskill " + processName : "killall \"" + processName + "\"";  
  20.             cmdInvoke(cmd);  
  21.         } catch (Exception e) {  
  22.             Log.logInfo(e.getMessage());  
  23.         }  
  24.     }  
  25.   
  26.     public static String cmdInvoke(String cmd) {  
  27.         String cmdOut = "";  
  28.         BufferedReader br = null;  
  29.   
  30.         try {  
  31.             Process p = Runtime.getRuntime().exec(cmd);  
  32.             br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
  33.             String line = null;  
  34.             while ((line = br.readLine()) != null) {  
  35.                 cmdOut = line;  
  36.             }  
  37.         } catch (Exception e) {  
  38.             e.printStackTrace();  
  39.         } finally {  
  40.             if (br != null) {  
  41.                 try {  
  42.                     br.close();  
  43.                 } catch (Exception e) {  
  44.                     e.printStackTrace();  
  45.                 }  
  46.             }  
  47.         }  
  48.         return cmdOut;  
  49.     }