Отчет об экстенте 3 Добавить снимок экрана

Я пытаюсь создать селен с отчетом о степени, но мне не удалось заставить работать функцию сохранения снимка экрана, потому что я не могу ссылаться на объект WebDriver в классе ITestListener. Ниже приведен мой пример кода:

Test Runner.java:

@Listeners({com.peterwkc.Listener.TestListener.class})
public class ChromeTestManager {

    private WebDriverManager webDriverManager = new WebDriverManager();
    private WebDriver driver;

    private LoginPages loginPages;
    private AdminPages adminPages;

    @BeforeClass
    //@Parameters({"browser"})
    public void setupTest(/*String browser*/) throws MalformedURLException {
        System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
        // Set & Get ThreadLocal Driver with Browser

        webDriverManager.createDriver("chrome");
        driver = webDriverManager.getDriver();

        // Pages Object Initialization
        loginPages = PageFactory.initElements(driver, LoginPages.class);
        logoutPages = PageFactory.initElements(driver, LogoutPages.class);
        adminPages = PageFactory.initElements(driver, AdminPages.class);
    }

    @DataProvider(name = "loginCredentials")
    public static Object[][] getLoginCredentials() {
        return new Object [][] {{ "Admin123", "admin123"  }, {"testUser", "test"}, {"test", "test"}};
    }

    @Test(groups= {"Login"}, description="Invalid Login", priority = 0, dataProvider = "loginCredentials", invocationCount = 3) 
    public void login_invalid(String username, String password) {
        loginPages.login_invalid(driver, username, password);
    }
}

Открытый класс TestListener.java TestListener реализует ITestListener {

    //Extent Report Declarations
    private static ExtentReports extent = ExtentManager.createInstance();
    private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();

    public TestListener() {
    }

@Override
    public synchronized void onTestFailure(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " failed!"));
        test.get().fail("Exception Error : \n" + result.getThrowable());

        /*String feature = getClass().getName();
        String screenShot;
        try {
            screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
            test.get().addScreenCaptureFromPath(screenShot);
            test.get().log(Status.FAIL, screenShot);
        } catch (IOException ex) {    
            LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
        }*/

    }
}

Вопросов:

  • Как передать объект WebDriver из TestRunner.java в класс TestListener?

  • Как сохранить снимок экрана в отчете экстента 3?

  • Что-то не так с моим кодом?

пожалуйста, помогите, заранее спасибо!


person nicholas    schedule 19.06.2018    source источник


Ответы (2)


Ниже приведены шаги для этого:

1. Передача объекта WebDriver в класс Listener

Сначала создайте метод ниже в классе ChromeTestManager или в любом другом месте, откуда вы можете его вызвать, здесь предположим, что он присутствует в классе ChromeTestManager:

public static ITestContext setContext(ITestContext iTestContext, WebDriver driver) {
        iTestContext.setAttribute("driver", driver);

        return iTestContext;
    }

Он установит объект драйвера в TestContext.

Теперь измените метод setUp @BeforeClass, чтобы он принимал параметр ITestContext, код ниже:

public class ChromeTestManager {

        private WebDriverManager webDriverManager = new WebDriverManager();
        private WebDriver driver;

        private LoginPages loginPages;
        private AdminPages adminPages;

        private static ITestContext context;  // creating a ITestContext variable

        @BeforeClass
        //@Parameters({"browser"})
        public void setupTest(ITestContext iTestContext) throws MalformedURLException {
            System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
            // Set & Get ThreadLocal Driver with Browser

            webDriverManager.createDriver("chrome");
            driver = webDriverManager.getDriver(); 

            this.context = setContext(iTestContext, driver);  // setting the driver into context

            // Pages Object Initialization
            loginPages = PageFactory.initElements(driver, LoginPages.class);
            logoutPages = PageFactory.initElements(driver, LogoutPages.class);
            adminPages = PageFactory.initElements(driver, AdminPages.class);
        }

Когда вы запустите это, он будет работать плавно и не вызовет ошибок (если вы думаете, что то, как я передам контекст ITestcontext, это обрабатывается внутри)

Теперь драйвер добавлен как объект в ITestcontext;

Теперь доступ к драйверу в прослушивателе:

@Override
    public synchronized void onTestFailure(ITestResult result) {
        WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver");  // here we are accessing the driver object that we added in Test class  

}

2. Сохранение ScreenShot в отчете о экстенте 3 (я использую зависимость 3.1.5 в maven)

@Override
    public synchronized void onTestFailure(ITestResult result) {
        System.out.println("!!!!!!!!!!!!!!!!!!!! Test Failed !!!!!!!!!!!!!!!!!!!!");

        WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // accessing driver here
        String feature = getClass().getName();
        String screenShot;
        try {
            screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
            test.addScreenCaptureFromPath(screenShotPath);  // I am assuming that the "screenShot" is fully qualified path with extension e.g "C:\Users\12345\Desktop\sfgfdh.PNG"
        } catch (IOException ex) {    
            LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
        }

    }

3. Что-то не так с вашим кодом?

Нет

Вам просто нужен драйвер в классе Listener, и при добавлении снимка экрана в отчет экстента убедитесь, что путь к снимку экрана правильный и является полным путем с расширением.

Пожалуйста, дайте мне знать, если вы столкнетесь с проблемой в этом.

person dangi13    schedule 20.06.2018
comment
Привет @ dangi12, пожалуйста, рассмотрите эту проблему stackoverflow.com/questions/61080059/ - person ; 07.04.2020

Прежде всего, не создавайте экземпляр вашего webDriver в @BeforeClass, потому что он вызывается только один раз, как говорится в аннотации перед классом, попробуйте использовать interface ITestListener и использовать реализацию beforeInvocation для инициализации WebDriver.

Во-вторых, вы не можете вызвать PageFactory для всех PageObject одновременно, как вы думаете, все 3 страницы инициализируются одновременно, это должно быть достигнуто в конструкторе для каждого объекта страницы, и когда вы инициализируете объект страницы (новый вход в систему), элементы также инициализируются, так что это не нормально:

    // Pages Object Initialization
    loginPages = PageFactory.initElements(driver, LoginPages.class);
    logoutPages = PageFactory.initElements(driver, LogoutPages.class);
    adminPages = PageFactory.initElements(driver, AdminPages.class);

В-третьих, я не вижу инициализации теста ExtentReport. Это должно выглядеть примерно так:

ExtentTest extentTest = ExtentTestManager.startTest(method.getName(), "");

Вот пример фрагмента кода из моей реализации вызова снимка экрана, я вызываю его из afterInvocation, потому что я использую параллельную инициализацию драйвера, и поэтому он должен быть отсюда, но также может быть получен с помощью реализации onTestFailure:

       public synchronized void afterInvocation(IInvokedMethod method, ITestResult testResult){
        if (method.isTestMethod() && testResult.getStatus()==2) {

                File scrFile = (dataMethod.getAndroidDriver()).getScreenshotAs(OutputType.FILE);
                String dest = System.getProperty("user.dir") + "/resources/screenshots/" + dataMethod.getDriver().getSessionId() + ".png";

                File destination = new File(dest);
                try {
                    FileUtils.copyFile(scrFile, destination);
                    dataMethod.setScreenshotPath(destination.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.err.println("Path:" + dataMethod.getScreenshotPath());

        }

Вы должны больше думать о структуре,

Надеюсь это поможет...

person Kovacic    schedule 19.06.2018
comment
Класс называется ChromeTestManager и FirefoxTestManager. Я хотел бы разработать все тесты, вызываемые из этих двух классов, где я запускаю их параллельно. Какой шаблон проектирования реализовать в этом случае? Во-первых, как это решить в таком случае? Во-вторых, как это решить? В-третьих, я использую Extent 3, где я получаю образец кода из github. - person nicholas; 19.06.2018
comment
Как вы разрабатываете тест в Selenium Grid? Я просто хочу, чтобы два драйвера создали экземпляр: ChromeDriver и FirefoxDriver? Вы создаете много драйверов? - person nicholas; 19.06.2018
comment
Возможно, вы сможете предложить мне лучшее решение, поскольку у меня меньше опыта, чем у вас. Вы можете получить мой код на странице bitbucket.org/peterwkc/selenium_opensource/src/master - person nicholas; 19.06.2018