问题描述

在测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.     public static void killProcess(String processName) {  
  17.         try {  
  18.             String cmd = isWindows() ? "tskill " + processName : "killall \"" + processName + "\"";  
  19.             cmdInvoke(cmd);  
  20.         } catch (Exception e) {  
  21.             Log.logInfo(e.getMessage());  
  22.         }  
  23.     }  

  24.     public static String cmdInvoke(String cmd) {  
  25.         String cmdOut = "";  
  26.         BufferedReader br = null;  

  27.         try {  
  28.             Process p = Runtime.getRuntime().exec(cmd);  
  29.             br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
  30.             String line = null;  
  31.             while ((line = br.readLine()) != null) {  
  32.                 cmdOut = line;  
  33.             }  
  34.         } catch (Exception e) {  
  35.             e.printStackTrace();  
  36.         } finally {  
  37.             if (br != null) {  
  38.                 try {  
  39.                     br.close();  
  40.                 } catch (Exception e) {  
  41.                     e.printStackTrace();  
  42.                 }  
  43.             }  
  44.         }  
  45.         return cmdOut;  
  46.     }