Selenium webdriver 如何在Appium(selenium Java)中测试Android toast消息

Selenium webdriver 如何在Appium(selenium Java)中测试Android toast消息,selenium-webdriver,appium,android-testing,selendroid,Selenium Webdriver,Appium,Android Testing,Selendroid,我正在使用Selenium和Java在android上运行脚本(通过Appium服务器)。 我发现用硒来定位吐司是不可能的 driver.findElement(By.LinkText("User not logged in") 在阿皮姆 但可以在Selendroid中用于捕获toast消息 有没有一种方法可以在同一个脚本中同时使用Selendroid和Appium?看起来无法在同一个会话中切换驱动程序类型。 如果您试图切换到Selendroid仅用于toast验证,则可以使用OSR图像识别引

我正在使用Selenium和Java在android上运行脚本(通过Appium服务器)。 我发现用硒来定位吐司是不可能的

driver.findElement(By.LinkText("User not logged in")
在阿皮姆

但可以在Selendroid中用于捕获toast消息


有没有一种方法可以在同一个脚本中同时使用Selendroid和Appium?

看起来无法在同一个会话中切换驱动程序类型。 如果您试图切换到Selendroid仅用于toast验证,则可以使用OSR图像识别引擎

检查这个答案

想法很简单:

  • 使toast消息出现
  • 截图
  • 迭代截图并查找所需文本

下面是一个在Java中使用OCR的简单示例:(确保安装了引擎)

Appium 1.6。4@beta最新版本支持toast消息

拍摄toast消息页面的屏幕截图,尝试将图像文件转换为文本,并使用以下代码验证文本。

  public void imageconversion(String filePath) throws IOException,          
    {    
                ITesseract instance = new Tesseract();
    //file path is the image which you need to convert to text
                File imageFile = new File(filePath);  
                BufferedImage img = null;
                img = ImageIO.read(imageFile);
                BufferedImage blackNWhite = new BufferedImage(img.getWidth(),img.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
                Graphics2D graphics = blackNWhite.createGraphics();
                graphics.drawImage(img, 0, 0, null);
                //path where your downloaded tessdata exists
                instance.setDatapath("E://ocr//data"); 
              //What language you required to convert,( e.g. English)
                instance.setLanguage("eng");        
                String result = instance.doOCR(blackNWhite);


                System.out.println(result);

            }

Appium直接不提供任何API来读取toast消息,我们需要使用Tess4JJAR来读取。首先我们需要拍摄屏幕截图,然后我们需要使用TESS4JAPI读取屏幕截图中的文本

 static String scrShotDir = "screenshots";
  File scrFile;
  static File scrShotDirPath = new java.io.File("./"+ scrShotDir+ "//");
  String destFile;
  static AndroidDriver driver = null;

 public String readToastMessage() throws TesseractException {
String imgName = takeScreenShot();
  String result = null;
  File imageFile = new File(scrShotDirPath, imgName);
  System.out.println("Image name is :" + imageFile.toString());
  ITesseract instance = new Tesseract();

  File tessDataFolder = LoadLibs.extractTessResources("tessdata"); // Extracts
                   // Tessdata
                   // folder
                   // from
                   // referenced
                   // tess4j
                   // jar
                   // for
                   // language
                   // support
  instance.setDatapath(tessDataFolder.getAbsolutePath()); // sets tessData
                // path

  result = instance.doOCR(imageFile);
  System.out.println(result);
  return result;
 }

 /**
  * Takes screenshot of active screen
  * 
  * @return ImageFileName
  */
 public String takeScreenShot() {
  File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 

  SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy__hh_mm_ssaa");
  new File(scrShotDir).mkdirs(); // Create folder under project with name
          // "screenshots" if doesn't exist
  destFile = dateFormat.format(new Date()) + ".png"; // Set file name
               // using current
               // date time.
  try {
   FileUtils.copyFile(scrFile, new File(scrShotDir + "/" + destFile)); // Copy
                    // paste
                    // file
                    // at
                    // destination
                    // folder
                    // location
  } catch (IOException e) {
   System.out.println("Image not transfered to screenshot folder");
   e.printStackTrace();
  }
  return destFile;
 }

有关更多详细信息,请参阅此视频-

方法1:来自Appium 1.6.4版的支持toast消息,为此您需要使用
自动名称:'uiautomator2'

toast = driver.find_element(:xpath, "//android.widget.Toast[1]")
if toast.text == "Hello" 
但我不建议这样做,因为uiautomator2还不稳定

方法2:

  • 在屏幕上触发文本消息
  • 截图
  • 将图像转换为文本文件

    def assettoast(string)
      sname = (0...8).map { (65 + rand(26)).chr }.join
      $driver.driver.save_screenshot("#{sname}")
    
      # Make sure tesseract is installed in the system. If not you can install using "brew install tesseract" in mac
      system ("tesseract #{sname} #{sname}")
    
      text_file="#{sname}.txt"
      var= get_string_from_file(string, text_file)
      raise if var != true
    end
    
    def get_string_from_file(word, filename)
      File.readlines(filename).each do |line|
      return true if line.include?(word)
      end
    end
    
  • 检查文本文件中是否有toast消息

    def assettoast(string)
      sname = (0...8).map { (65 + rand(26)).chr }.join
      $driver.driver.save_screenshot("#{sname}")
    
      # Make sure tesseract is installed in the system. If not you can install using "brew install tesseract" in mac
      system ("tesseract #{sname} #{sname}")
    
      text_file="#{sname}.txt"
      var= get_string_from_file(string, text_file)
      raise if var != true
    end
    
    def get_string_from_file(word, filename)
      File.readlines(filename).each do |line|
      return true if line.include?(word)
      end
    end
    

  • 最后,我们能够阅读toast消息,而无需截图和执行OCR。 我已经在Appium 1.15.1上进行了测试

    Toast消息位于com.package.system下

    通常情况下,用于此的Xpath将是“/hierarchy/android.widget.Toast”。 类名为“android.widget.settings”

    当显示toast消息时,您可以通过刷新元素检查器屏幕来确认这一点

    WebDriverWait waitForToast = new WebDriverWait(driver.25);
    
    waitForToast.until(ExpectedConditions.presenceOfElementLoacted(By.xpath("/hierarchy/android.widget.Toast")));
    
    String toastMessage = driver.findElement((By.xpath("/hierarchy/android.widget.Toast")).getText();
    
    System.out.println(toastMessage);
    

    我找到了三种捕获Toast消息并进行验证的方法

  • 获取页面源并验证其中的toast消息
  • public void verifyToastMessageUsingPageSource(字符串toastmsg)引发InterruptedException{ 布尔值=false;
    对于(int i=0;我感谢!!因此我从下载了Tess4J 2.0,我在eclipse中将所有jar文件添加到我的项目中,我还发出了以下命令,以包含dll文件gsdll32、libtesseract303和liblept170,这些文件存储在code System.setProperty(“jna.library.path”、“C:\\Tess4J\\dllfiles”)的dllfiles文件夹中;在运行示例代码时。它在线程“main”java.lang.UnsatisfiedLinkError中引发错误“Exception”:找不到指定的模块"我能够解决错误。代码使用了doOCR函数,但该函数不起作用。是Microsoft VC++造成了此错误。我安装了VC++2013,代码运行了,但现在的问题是tesseract没有正确转换图像。它缺少很多文本,并且它识别的一些文本不正确。是否有其他好的OCR我能用它吗?@RJX实际上你应该先玩图像,让它“可读”
    img.contrast.normalize.negate.posterize(3).adaptive_resize(3)
    如您所见,我使用ImageMagick对其进行对比、规格化、否定、后期验证和调整x3大小。这就是我在项目中发现的效果。是的,我认为这是最简单的解决方案。使用Appium 1.17.1进行了尝试。但是,
    元素定位的可见性
    不适用于toast通知。必须使用
    呈现ElementLoacted
    如上例所示。是的,与OCR方法(屏幕截图方法)相比,此方法节省了大量时间。这不适用于appium inspector,但对吗?。我无法使用1.20版本的inspector选择android toast消息。请尝试扩展xml层次结构,然后查看。toast消息将正常显示,并且是层次结构的结尾。我尚未使用1.20。1.15 inspector可以正常工作。