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



我使用Java Selenium在android上运行脚本(通过Appium服务器)。我发现用selenium的

来定位toast是不可能的。
driver.findElement(By.LinkText("User not logged in")
在Appium

但是可以在selendoid中用于捕获吐司消息。

我有一种方法,我可以使用selendoid和Appium在同一脚本?

最后,我们能够在不需要截图和执行OCR的情况下读取toast消息。我已经在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);

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

toast = driver.find_element(:xpath, "//android.widget.Toast[1]")
if toast.text == "Hello" 

但我不建议这样做,因为uiautomator2还不稳定。

方法2:

  1. 触发屏幕文本信息
  2. 捕捉截图
  3. 将图像转换为文本文件

    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
    
  4. 检查文本文件中是否有toast message

    def get_string_from_file(word, filename)
      File.readlines(filename).each do |line|
      return true if line.include?(word)
      end
    end
    

看起来您不能在同一会话中切换驱动程序类型。如果你想切换到Selendroid只是为了吐司验证-你可以使用OSR图像识别引擎。

检查这个答案w/Ruby bindings

想法很简单:

  • 使祝酒词出现
  • 少截图
  • 遍历截图并寻找所需的文本
下面是OCR在Java中使用的一个很好的简单示例:tess4j示例(确保安装了Tesseract引擎)
Step 1:
File scrFile=null;
String path1 = null;
BufferedImage originalImage=null;
BufferedImage resizedImage=null;
System.out.println("Startingnnnn");
scrFile = ((TakesScreenshot) appiumDriver).getScreenshotAs(OutputType.FILE);
System.out.println("after scrfilennnn");
originalImage = ImageIO.read(scrFile);
System.out.println("after originalFilennn");
BufferedImage.TYPE_INT_ARGB : originalImage.getType();
resizedImage = CommonUtilities.resizeImage(originalImage, IMG_HEIGHT, IMG_WIDTH);
ImageIO.write(resizedImage, "jpg", new File(path + "/"+ testCaseId + "/img/" + index + ".jpg"));
Image jpeg = Image.getInstance(path + "/" + testCaseId + "/img/"+ index + ".jpg");
Step 2: 
BufferedImage pathforToast= original image;
Step 3:
System.setProperty("jna.library.path","C:/Users/Dell/workspace/MOBILEFRAMEWORK/dlls/x64/");
Tesseract instance = Tesseract.getInstance();
`enter code here`ImageIO.scanForPlugins();
String result=null;
result = instance.doOCR(pathforToast);`enter code here`
System.out.println(result);`enter code here`

Appium 1.6.4@beta最新版本支持toast消息

截取Toast Message页面的屏幕截图,尝试将图像文件转换为文本,并使用下面的代码验证文本

  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消息,我们需要使用tess4j jar来完成它。首先,我们需要截取屏幕截图,然后我们需要使用tess4j API从屏幕截图中读取文本。

 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;
 }

欲了解更多详细信息,请参阅此视频- https://www.youtube.com/watch?v=lM6-ZFXiSls

我找到了捕获Toast消息并验证它们的三种方法。

  1. 获取页面源并从中验证toast消息。

public void verifyToastMessageUsingPageSource(String toastmsg) throws InterruptedException { boolean found = false; for(int i =0 ; i <8; i++){ if(getDriver().getPageSource().contains("class="android.widget.Toast" text=""+toastmsg+""")){ found = true; break; } Thread.sleep(300); } Assert.assertTrue(found,"toast message "+toastmsg+" is present"); }

Similar can be found using Xpath: //android.widget.Toast[1]

  1. Using the grep command, wait for a toast message in uiautomator events. run the command before clicking and toast message will be varified.

    adb shell uiautomator events | grep "ToastMessgae"

  2. This is tricky and needs more code to run.

    • start capturing screenshots thread.
    • perform click action
    • stop screen capturing thread.
    • extract text from the captured images using OCR and verify the toast message is present in the captured images.

I prefer the 1st and 2nd option, it provides validation in less time with less code.

comment if you need code for 2nd and 3rd point.

Appium with version number>=1.6.4 supports toast notification with UiAutomator2. In Javascript with webdriver you can do like this

let toast=await driver1.elements("xpath","/hierarchy/android.widget.Toast");
let data=await toast[0].text();
console.log(data)

Appium + Javascript解决方案

在helper类中创建一个函数,并在测试文件中使用实际文本参数

调用它
Helperclass.js
-----------------------------
    async isToastMessageDisplayed(toastText) {
            const numberOfAttempts = 2; // Adjust the number of attempts as needed
                  const waitTime = 200; // Adjust the wait time between attempts in milliseconds
            
                  for (let i = 0; i < numberOfAttempts; i++) {
                      await driver.pause(waitTime);
                      const pageSource = await driver.getPageSource();
                      if (pageSource.includes(toastText)) {
                          console.log(`Toast message displayed ${i + 1}: ${toastText}`);
                          return true;
                      }
                  }
                  return false; }
Test.js
----------------------------------------------------------
    const toastText = "Wrong OTP entered. Please enter the correct OTP";
            const isToastDisplayed = await HelperClass.isToastMessageDisplayed(toastText);
            expect(isToastDisplayed).to.be.true;

相关内容

  • 没有找到相关文章

最新更新