使用 Extent Reports 将 java 机器人屏幕截图保存到 testng 侦听器中

问题描述

我在下面有一个测试方法来检查空密码:

@Test(priority = 4,description = "Empty password validation")
public void emptyPassword(Method method,ITestContext context) {
        ExcelData ex = new ExcelData();
        try {
            ISuite suite = context.getSuite();
            String env = (String)suite.getAttribute("Env");

            String [] envLinks = ex.getEnvLinks(env);
            homePage.loadLMSLoginPage(envLinks[0]);
            ExtentTestManager.startTest(method.getName(),"Empty Password Validation");
            loginPage
                    .verifyEmptyPassword("USERNAME","",context);
        }catch(Exception e){
            e.printstacktrace();
        }
    }

这是密码验证的方法,因为当密码为空时系统会弹出警告,selenium webdriver无法截图,因此我使用robot框架。我正在尝试通过下面的 ITestContext 将此屏幕截图传递到我的 Listener 类中:

public LoginPage verifyEmptyPassword(String id,String pswd,ITestContext context) throws AWTException {

        try {

            writeText(userId,id);
            writeText(userPwd,pswd);
            click(logInButtonId);
            Alert passworDalert = driver.switchTo().alert();
            String passtext = passworDalert.getText();

            Robot robot = new Robot();
            Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
            BufferedImage image = robot.createScreenCapture(screenRect);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            context.setAttribute("PassworDalert",passtext);
            ImageIO.write(image,"PNG",out);
            out.flush();
            byte[] encodeBase64 = Base64.encodeBase64(out.toByteArray());
            context.setAttribute("AlertScreenshot",encodeBase64);

            passworDalert.accept();

            Assert.assertTrue(passtext.contains("Enter Password !"));
        }catch (IOException e){
            e.printstacktrace();;
        }
        return this;
    }

在我的侦听器类中,在我的 onTestSuccess 方法中,如果根据测试名称检测到该方法为“emptyPassword”,它将在我的 Listener 类正在扩展的另一个类中的另一个方法 getpassworDalert() 中以不同方式保存屏幕截图:

public void onTestSuccess(ITestResult iTestResult) {
        System.out.println("Test" + getTestMethodName(iTestResult) + " passed");
        //ExtentReports log operation for passed tests.
        Object testClass = iTestResult.getInstance();
        ITestContext context = iTestResult.getTestContext();
        ExtentTest extent = ExtentTestManager.gettest();
        WebDriver webDriver = ((BaseTest) testClass).getDriver();
        String base64Screenshot = "data:image/png;base64," + ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BASE64);
          if (getTestMethodName(iTestResult).equals("emptyPassword")) {
            getpassworDalert(context,extent);
        } else {
            ExtentTestManager.gettest().log(LogStatus.PASS,"Test passed",ExtentTestManager.gettest().addBase64ScreenShot(base64Screenshot));
        }
    }

这是我尝试从上下文中获取屏幕截图并保存的地方,但它在 ExtentReports 中显示为空白,如下所示,一直在尝试对此进行调试,但找不到答案。有人可以帮忙吗?

public void getpassworDalert(ITestContext context,ExtentTest extent) {
        String message = (String) context.getAttribute("PassworDalert");
        byte [] imgByte = (byte[]) context.getAttribute("AlertScreenshot");
        String img = new String(imgByte);
        extent.log(LogStatus.PASS,"Test passed,alert message:" + message,extent.addBase64ScreenShot(img));

    }

enter image description here

解决方法

使用“captureScreenshot”方法创建一个新类(屏幕截图)以截取屏幕截图

 try{
            projectPath = System.getProperty("user.dir");
            TakesScreenshot ts=(TakesScreenshot)driver;
            File source=ts.getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(source,new File("./screenshots/"+ screenshotName+".png"));
            System.out.println("Screenshot taken successfully");
            }
            catch (Exception e){
                System.out.println("Exception while taking screenshot "+e.getMessage());
            }
} 

然后在您的测试用例中调用该类

screenshot.captureScreenshot();
test1.log(Status.FAIL,"Test failed.",MediaEntityBuilder.createScreenCaptureFromPath(projectPath+ "/screenshots/imagename.png").build());

希望这会有所帮助。