How to add screenshot using selenum in docker or linux env - selenium

I am tring to add screenshot, whenever my testcases are getting failed. However i have succeeded doing this in Windows env, but i am unable to achieve it in docker/linux env.
code for screenshot:
public void testFailure(Failure failure) throws java.lang.Exception
{
Random rand = new Random();
//Scenario scenario;
System.out.println("Execution Failure : ");
try {
//String screenshotName = failure.getTestHeader().toString();
int num = rand.nextInt(10000000);
String screenshotName = "Screenshot"+num;
/*File sourcePath = ((TakesScreenshot)Homepage.driver).getScreenshotAs(OutputType.FILE);
File destinationPath = new File(System.getProperty("user.dir") + "/target/CucumberExtentReport/Screenshots/" + screenshotName +".jpeg");
Files.copy(sourcePath, destinationPath);
Reporter.addScreenCaptureFromPath(destinationPath.toString());
*/
final byte[] screenshot = ((TakesScreenshot)Homepage.driver).getScreenshotAs(OutputType.BYTES);
File destinationPath = new File(System.getProperty("user.dir") + "/target/CucumberExtentReport/Screenshots/" + screenshotName +".jpeg");
FileUtils.writeByteArrayToFile(destinationPath, screenshot);
//Files.copy(sourcePath, destinationPath);
Reporter.addScreenCaptureFromPath(destinationPath.toString());
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
Note: I have used extent reports for adding screenshot on failed testcases...

Related

Why base64 screenshot is coming as blank in emailable extent report?

When I execute from local machine, I could see screenshot properly within extent report for the failed scenario. When I execute it from Jenkins and have the extent report emailed, it's coming as blank. I am trying to use base64 in my case. Code as specified below:
public static String getBase64Screenshot() throws IOException {
WebDriver driver1 = BaseConfig.setDriver();
Date oDate = new Date();
SimpleDateFormat oSDF = new SimpleDateFormat("yyyyMMddHHmmss");
String sDate = oSDF.format(oDate);
String encodedBase64 = null;
FileInputStream fileInputStream = null;
File source = ((TakesScreenshot) driver1).getScreenshotAs(OutputType.FILE);
String destination =System.getProperty("user.dir")+"/target/cucumber-reports/"+"Screenshot_" + sDate + ".png";
File finalDestination = new File(destination);
FileUtils.copyFile(source, finalDestination);
try {
fileInputStream =new FileInputStream(finalDestination);
byte[] bytes =new byte[(int)finalDestination.length()];
fileInputStream.read(bytes);
encodedBase64 = new String(Base64.getEncoder().encode(bytes));
}catch (FileNotFoundException e){
e.printStackTrace();
}
return "data:image/png;base64,"+encodedBase64;
}
#After(order = 1)
public void afterScenario(Scenario scenario) {
WebDriver driver1 = BaseConfig.setDriver();
if (scenario.isFailed()) {
String screenshotName = scenario.getName().replaceAll(" ", "_");
System.out.println(screenshotName);
try {
Reporter.addScreenCaptureFromPath(getBase64Screenshot());
}catch (IOException e)
}
}
blank screenshot

Null pointer exception while taking screenshot in selenium POM with extent report

A null pointer exception is thrown While trying to take screenshot when the scenario fails. I have an actions class in which i have defiled the capture screenshot method.
public static String capture(WebDriver driver) throws NullPointerException, IOException {
File scrFile;
scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File Dest = new File("D:\\Dinu\\SeleniumReports\\Test" + System.currentTimeMillis() + ".jpeg");
String filepath = Dest.getAbsolutePath();
org.openqa.selenium.io.FileHandler.copy(scrFile, Dest);
return filepath;
}
Extent reports are implemented using Itestlisterner interface. Below given code for which implements the screenshot method given:
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail(result.getThrowable());
try {
String screenshotPath = actions.capture(driver);
test.get().addScreenCaptureFromPath(screenshotPath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And am getting the below error: Please help in resolving the same.
public static String getScreenhot(WebDriver driver, String screenshotName) throws Exception {
String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
//after execution, you could see a folder "FailedTestsScreenshots" under src folder
String destination = System.getProperty("user.dir") + "/FailedTestsScreenshots/"+screenshotName+dateName+".png";
File finalDestination = new File(destination);
FileUtils.copyFile(source, finalDestination);
return destination;
}
#AfterMethod
public void getResult(ITestResult result) throws IOException{
if(result.getStatus() == ITestResult.FAILURE){
logger.log(LogStatus.FAIL, "Test Case Failed is "+result.getName());
logger.log(LogStatus.FAIL, "Test Case Failed is "+result.getThrowable());
//To capture screenshot path and store the path of the screenshot in the string "screenshotPath"
//We do pass the path captured by this mehtod in to the extent reports using "logger.addScreenCapture" method.
String screenshotPath = ExtentReportsClass.getScreenshot(driver, result.getName());
//To add it in the extent report
logger.log(LogStatus.FAIL, logger.addScreenCapture(screenshotPath));
}else if(result.getStatus() == ITestResult.SKIP){
logger.log(LogStatus.SKIP, "Test Case Skipped is "+result.getName());
}
// ending test
//endTest(logger) : It ends the current test and prepares to create HTML report
extent.endTest(logger);
}

I need to add all the screenshots of steps performed in One word file using selenium webdriver

Please help me out.
I want to add all the steps screenshot in one document(word) file using selenium webdriver with java for that particular test case and that file should get stored with a that particular test case name.
public static void main(String[] args) {
try {
XWPFDocument docx = new XWPFDocument();
XWPFRun run = docx.createParagraph().createRun();
FileOutputStream out = new FileOutputStream(System.getProperty("user.dir")+"\\Result\\Screenshot");
for (int counter = 1; counter <= 5; counter++) {
captureScreenShot(docx, run, out);
TimeUnit.SECONDS.sleep(1);
}
docx.write(out);
out.flush();
out.close();
docx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void captureScreenShot(XWPFDocument docx, XWPFRun run, FileOutputStream out) throws Exception {
String screenshot_name = System.currentTimeMillis() + ".png";
BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
File file = new File(System.getProperty("user.dir")+"\\Result\\Screenshot" + screenshot_name);
ImageIO.write(image, "png", file);
InputStream pic = new FileInputStream(System.getProperty("user.dir")+"\\Result\\Screenshot" + screenshot_name);
run.addBreak();
run.addPicture(pic, XWPFDocument.PICTURE_TYPE_PNG, screenshot_name, Units.toEMU(350), Units.toEMU(350));
pic.close();
file.delete();
}

Getting sscreenshot attached for failed test to allure report in format: datetime-classsname-testname selenium, testng, allure

I am using testng, maven, allure in my framework. Currently my screenshots for failed test are saved in surefire-reports/screenshots as :
datetime-classname-methodname
eg: 09-22-2017_01.13.23_ClassName_Methodname.png
Here is code for this :
#AfterMethod
protected void screenShotIfFail(ITestResult result) throws IOException {
if (!result.isSuccess()) {
takeScreenShot(result.getMethod());
}
}
private void takeScreenShot(String name) throws IOException {
String path = getRelativePath(name);
File screenShot = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenShot, new File(path));
String filename = makeScreenShotFileName(name);
System.out.println("Taking Screenshot! " + filename);
Reporter.log("<a href=" + path + " target='_blank' >" + filename
+ "</a>");
}
private void takeScreenShot(ITestNGMethod testMethod) throws IOException {
String nameScreenShot = testMethod.getTestClass().getRealClass()
.getSimpleName()
+ "_" + testMethod.getMethodName();
takeScreenShot(nameScreenShot);
}
private String makeScreenShotFileName(String name) {
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy_hh.mm.ss");
Date date = new Date();
return dateFormat.format(date) + "_" + name + ".png";
}
private String getRelativePath(String name) throws IOException {
Path path = Paths.get(".", "target", "surefire-reports", "screenShots",
makeScreenShotFileName(name));
File directory = new File(path.toString());
return directory.getCanonicalPath();
}
For getting attached to allure reports, i tried #Attachment like this :
#Attachment(value = "filename", type = "image/png")
private byte[] takeScreenShot(String name) throws IOException {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
Screenshot is getting attached to allure report, but how can i get it in same format as in surefire reports.
Thanks !!
You can pass a custom name directly into method annotated with #Attachment:
#Attachment(value = "{name}", type = "image/png")
private byte[] takeScreenShot(String name) throws IOException {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
The only difference between Allure 1 and Allure 2 is in value parameter. For Allure 1 use the following syntax:
value = "{0}"
Where {0} is reference to the first method's parameter (its index).
For Allure 2, use the following:
value = "{name}"
In this case {name} is the name of a method's parameter.

Powermock: ProcessBuilder redirectErrorStream giving nullPointerException

I am using powermock to mock some native command invocation using process builder. the strange thing is these test pass sometimes and fail sometimes giving a NPE. Is this a powermock issue or some gotcha in the program.
Here is a snippet of the class I am testing:
public void method1(String jsonString, String filename) {
try {
JSONObject jObj = new JSONObject(jsonString);
JSONArray jArr = jObj.getJSONArray("something");
String cmd = "/home/y/bin/perl <perlscript>.pl<someConstant>" + " -k " + <someConstant> + " -t " + <someConstant>;
cmd += vmArr.getJSONObject(i).getString("jsonKey");
ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
pb.redirectErrorStream(false);
Process shell = pb.start();
shell.waitFor();
if (shell.exitValue() != 0) {
throw new RuntimeException("Error in Collecting the logs. cmd="+cmd);
}
StringBuilder error = new StringBuilder();
InputStream iError = shell.getErrorStream();
BufferedReader bfr =
new BufferedReader(
new InputStreamReader(iError));
String line = null;
while ((line = bfr.readLine()) != null) {
error.append(line + "\n");
}
if (!error.toString().isEmpty()) {
LOGGER.error(error`enter code here`);
}
iError.close();
bfr.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
and the unit test case is:
#PrepareForTest( {<Classtobetested>.class, ProcessBuilder.class,Process.class, InputStream.class,InputStreamReader.class, BufferedReader.class} )
#Test(sequential=true)
public class TestClass {
#Test(groups = {"unit"})
public void testMethod() {
try {
ProcessBuilder prBuilderMock = createMock(ProcessBuilder.class);
Process processMock = createMock(Process.class);
InputStream iStreamMock = createMock(InputStream.class);
InputStreamReader iStrRdrMock = createMock(InputStreamReader.class);
BufferedReader bRdrMock = createMock(BufferedReader.class);
String errorStr =" Error occured";
String json = <jsonStringInput>;
String cmd = "/home/y/bin/perl <perlscript>.pl -k "+<someConstant>+" -t "+<someConstant>+" "+<jsonValue>;
expectNew(ProcessBuilder.class, "bash", "-c", cmd).andReturn(prBuilderMock);
expect(prBuilderMock.redirectErrorStream(false)).andReturn(prBuilderMock);
expect(prBuilderMock.start()).andReturn(processMock);
expect(processMock.waitFor()).andReturn(0);
expect(processMock.exitValue()).andReturn(0);
expect(processMock.getErrorStream()).andReturn(iStreamMock);
expectNew(InputStreamReader.class, iStreamMock)
.andReturn(iStrRdrMock);
expectNew(BufferedReader.class, iStrRdrMock)
.andReturn(bRdrMock);
expect(bRdrMock.readLine()).andReturn(errorStr);
expect(bRdrMock.readLine()).andReturn(null);
iStreamMock.close();
bRdrMock.close();
expectLastCall().once();
replayAll();
<ClassToBeTested> instance = new <ClassToBeTested>();
instance.method1(json, fileName);
verifyAll();
} catch (Exception e) {
Assert.fail("failed while collecting log.", e);
}
}
I get an error on execution and the test case fails..
Caused by: java.lang.NullPointerException
at java.lang.ProcessBuilder.start(ProcessBuilder.java:438)
Note: I do not get this error on all executions. Sometimes it passes and sometimes it fails. I am not able to understand this behavior. Also, I have camouflaged some variable names because of the copyright issues.
Since your are mocking the constructor call you have to prepare your code as wall. This is because the constructor invocation is part of your code. Read more in the PowerMock documentation:
http://code.google.com/p/powermock/wiki/MockConstructor