简体   繁体   English

如何使用Appium在移动应用程序中获取烤面包机消息的文本

[英]How to get text of a toaster message in mobile app using Appium

I am trying to verify a toaster message in Android Mobile app but not able to get text of toaster message as it doesn't show in uiautomatorviewer. 我正在尝试在Android Mobile应用中验证烤面包机消息 ,但由于uiautomatorviewer中未显示该消息,因此无法获取烤面包机消息的文本。 Got some information that by the help of OCR it can be done taking screenshots and fetching the text from that screenshots Can anyone help me out how to do this step by step using java in Appium project? 得到了一些信息,这些信息可以通过OCR进行截屏并从该截屏中获取文本来完成。有人可以帮助我逐步使用Appium项目中的Java来完成此操作吗?

You can follow the information on the below links to install the Tesseract on your machine: 您可以按照以下链接上的信息在计算机上安装Tesseract:

For Mac: http://emop.tamu.edu/Installing-Tesseract-Mac 对于Mac: http//emop.tamu.edu/Installing-Tesseract-Mac

For Windows: http://emop.tamu.edu/Installing-Tesseract-Windows8 对于Windows: http//emop.tamu.edu/Installing-Tesseract-Windows8

After installing the TessEract on your machine you need to add the dependency of TessEract Java library in your project. 在计算机上安装TessEract之后,您需要在项目中添加TessEract Java库的依赖项。 If you are using Maven for it, adding below dependency will work: 如果您正在使用Maven,则添加以下依赖项将起作用:

    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>tesseract</artifactId>
        <version>3.04-1.1</version>
    </dependency>

Also the 'Step 3' which is mentioned by Ivan need not to be followed. 同样,也不必遵循Ivan提到的“步骤3”。

If you are using 'TestNG' the TessEract API needs to be initialised only once so instead of initialising it every time, as per your framework you can initialise it either in the 'BeforeTest' or 'BeforeSuite' or 'BeforeClass' method and accordingly close the API either in 'AfterTest' or 'AfterSuite' or 'AfterClass' method. 如果您使用的是'TestNG',则只需要初始化一次TessEract API,而不是每次都初始化,根据您的框架,您可以在'BeforeTest'或'BeforeSuite'或'BeforeClass'方法中对其进行初始化,然后关闭可以使用“ AfterTest”,“ AfterSuite”或“ AfterClass”方法中的API。

Below is the code that I have written to achieve it. 以下是我为实现此目的而编写的代码。

import static org.bytedeco.javacpp.lept.pixDestroy;
import static org.bytedeco.javacpp.lept.pixRead;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.bytedeco.javacpp.lept.PIX;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

    public class BaseTest {

    static TessBaseAPI api = new TessBaseAPI();

    @BeforeSuite
        public void beforeSuit() throws IOException {

            File screenshotsDirec = new File("target/screenshots");

            if (screenshotsDirec.exists())
                FileUtils.forceDelete(screenshotsDirec);

            FileUtils.forceMkdir(screenshotsDirec);

            System.out.println("Initializing TessEract library");

            if (api.Init("/opt/local/share", "eng") != 0) {
                System.err.println("Could not initialize tesseract.");
            }

        }

    public synchronized boolean verifyToastMessage(String msg)
                throws IOException {
            TakesScreenshot takeScreenshot = ((TakesScreenshot) driver);

            File[] screenshots = new File[5];

            for (int i = 0; i < screenshots.length; i++) {
                screenshots[i] = takeScreenshot.getScreenshotAs(OutputType.FILE);
            }

            String outText;

            Boolean isMsgContains = false;

            for (int i = 0; i < screenshots.length; i++) {
                PIX image = pixRead(screenshots[i].getAbsolutePath());
                api.SetImage(image);
                outText = api.GetUTF8Text().getString().replaceAll("\\s", "");
                System.out.println(outText);
                isMsgContains = outText.contains(msg);
                pixDestroy(image);
                if (isMsgContains) {
                    break;
                }
            }

            return isMsgContains;

        }

    @AfterSuite()
        public void afterTest() {

            try {
                api.close();
            } catch (Exception e) {
                api.End();
                e.printStackTrace();
            }

        }
    }

I would also like to add that writing tests to read and verify the Toast messages is this way is not very much reliable as in one of my tests this code successfully captures the Toast message while in another test it fails to capture the toast message because the capturing of the screenshots starts when the toast message disappears. 我还想补充一点,就是编写测试来读取和验证Toast消息是否可靠,因为在我的一个测试中,此代码成功捕获了Toast消息,而在另一个测试中,该代码未能捕获Toast消息,因为当敬酒消息消失时,开始捕获屏幕截图。 That was the reason I tried to write this code very much efficiently. 这就是我试图非常高效地编写此代码的原因。 However that also does not serve the purpose. 但是,这也没有达到目的。

Follow this discussion on Appium forum: https://discuss.appium.io/t/verifying-toast/3676 . 在Appium论坛上关注此讨论: https ://discuss.appium.io/t/verifying-toast/3676。

Basic steps to verify a Toaster are: 验证烤面包机的基本步骤是:

  1. Perform action to trigger the toast message to appear on screen 执行操作以触发Toast消息出现在屏幕上
  2. Take x number of screenshots 拍摄x张截图
  3. Increase resolutions of all screenshots 提高所有屏幕截图的分辨率
  4. Use tessearct OCR to detect the toast message. 使用tessearct OCR检测烤面包消息。

Refer this repo to use Java OCR library (see at the bottom): 请参考此仓库以使用Java OCR库(请参阅底部):

import org.bytedeco.javacpp.*;
import static org.bytedeco.javacpp.lept.*;
import static org.bytedeco.javacpp.tesseract.*;

public class BasicExample {
    public static void main(String[] args) {
        BytePointer outText;

        TessBaseAPI api = new TessBaseAPI();
        // Initialize tesseract-ocr with English, without specifying tessdata path
        if (api.Init(null, "eng") != 0) {
            System.err.println("Could not initialize tesseract.");
            System.exit(1);
        }

        // Open input image with leptonica library
        PIX image = pixRead(args.length > 0 ? args[0] : "/usr/src/tesseract/testing/phototest.tif");
        api.SetImage(image);
        // Get OCR result
        outText = api.GetUTF8Text();
        System.out.println("OCR output:\n" + outText.getString());

        // Destroy used object and release memory
        api.End();
        outText.deallocate();
        pixDestroy(image);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM