'How to write a generic base64 screenshot method using selenium 4 with java and attach it to extent report on test failure?

method used currently

public static String getScreenshot(String screenshotName) throws IOException {
        String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
        TakesScreenshot ts = (TakesScreenshot) Base.getDriver();
        File source = ts.getScreenshotAs(OutputType.FILE);
        String destination = System.getProperty("user.dir") + "/FailedTestsScreenshots/" + screenshotName + dateName
                + ".png";
        File finalDestination = new File(destination);
        FileUtils.copyFile(source, finalDestination);
        return destination;
    }

TestListener.java

@Override
    public synchronized void onTestFailure(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " failed!"));
        test.get().fail(result.getThrowable());
        if (result.getStatus() == ITestResult.FAILURE) {
            try {

                String imgPath = Utilities.getScreenshot(result.getName());
                test.get().addScreenCaptureFromPath(imgPath);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

I want to get the screenshot in base 64 format so that it cab be shared to anyone easily. I am using selenium version 4.0.0 and extent report version 3.1.5



Solution 1:[1]

Here's some methods I use for this (Base64 encoding from Joe Walnes: https://github.com/jenkinsci/xstream/blob/master/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java ) :

 File full_scrn = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
     full_scrn.deleteOnExit();

Later on I use these methods...

private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

 public String FileToBase64(String ThisScreenshotPath)
     {
        String Base64String = "";
        Path screen_path = Paths.get(ThisScreenshotPath);
        byte[] screenshot_in_bytes = null;
         try
          {
          screenshot_in_bytes = Files.readAllBytes(screen_path);
          }
          catch (Exception ex)
          {
         System.out.println("Exception reading screenshot file: " + ex.toString()); 
          }
     Base64String = encode(screenshot_in_bytes);   
     return Base64String;
     }

public String encode(byte[] input) {
    StringBuffer result = new StringBuffer();
    int outputCharCount = 0;
    for (int i = 0; i < input.length; i += 3) {
        int remaining = Math.min(3, input.length - i);
        int oneBigNumber = (input[i] & 0xff) << 16 | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | (remaining <= 2 ? 0 : input[i + 2] & 0xff);
        for (int j = 0; j < 4; j++) result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '=');
        if ((outputCharCount += 4) % 76 == 0) result.append('\n');
    }
    return result.toString();
}

For HTML output:

"<img src=\"data:image/png;base64," + ThisScreenshotBase64String + "\"...

I do not use Extent reports, so can't help on that end.

Solution 2:[2]

I had a similar requirement to store screenshots in base64 as reports will be shared with multiple stakeholders across my team. The following solution worked well for me.

Screenshot.java

public static String getScreenshot(WebDriver driver) {
        String screenshotBase64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);
        return screenshotBase64;
    }

TestListener.java

@Override
    public void onTestFailure(ITestResult result) {
        test.fail("Test case Failed");
        test.fail("Failed step: ",MediaEntityBuilder.createScreenCaptureFromBase64String("data:image/png;base64,"+Screenshot.getScreenshot(driver)).build());
        test.fail(result.getThrowable());
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pcalkins
Solution 2 vijay atm