ExtentReports - screenshot not in the report - broken image - java

I'm trying to add a screenshot to my ExtentReport HTML file, but for some reason, the image is not there even though it DOES exist and the console shows that it's looking at the correct place (href is correct).
This is the latest trial code:
Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
String destination = getScreenshotPath();
ImageIO.write(screenshot.getImage(), "IMG", new File(destination));
test.fail("Details: " + test.addScreenCaptureFromPath(destination));
The screenshot gets saved in the destination.
When I try the debugging mode, or look at the report, it's printed as:
Details: com.aventstack.extentreports.ExtentTest#62041567
and there's a broken image under it:

As suggested - the absolute path could be a solution, but I didn't want to go that way.
I've figured out that a solution is to store the images in the same directory where the report gets generated, give the image name to .addScreenCaptureFromPath(screenshotName.PNG) and it works perfectly.

I used the absolute path
Note: inspects the broken image from the browser to validate the absolute path of the image
Take ScreenShot:
public static String TakesScreenshot(IWebDriver driver, string FileName)
{
string pathProject = AppDomain.CurrentDomain.BaseDirectory;
string pathScreen = pathProject.Replace("\\bin\\Debug", "");
string path = pathScreen + "project/Test-output/Images/";
StringBuilder TimeAndDate = new StringBuilder(DateTime.Now.ToString());
TimeAndDate.Replace("/", "_");
TimeAndDate.Replace(":", "_");
TimeAndDate.Replace(" ", "_");
string imageName = FileName + TimeAndDate.ToString();
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(path + "_" + imageName + "." + System.Drawing.Imaging.ImageFormat.Jpeg);
return path + "_" + imageName + "." + "jpeg";
}
Attach image to the report with path of the preview method:
In the specific step:
ExtentTest.Fail("message", MediaEntityBuilder.CreateScreenCaptureFromPath(TakeScreenShot.TakesScreenshot(driver, "Fatal")).Build());
With the method "TakesScreenshot" Take the screenshot
Version ExtentReport: 3,
C#,
NUnit 3
USING JAVA:
<dependency>
<groupId>com.relevantcodes</groupId>
<artifactId>extentreports</artifactId>
<version>2.41.2</version>
</dependency>
Is:
ExtentTestManager.getTest().log(LogStatus.ERROR, ExtentTestManager.getTest().addScreenCapture("//ABOLUTE/PATH/IMAGE.PNG"));
regards.

In order to get screenshot in the extent report just add a extra dot in the extent report screenshot path. Refer code below:
test.log(Status.INFO, "FAQs button clicked",
MediaEntityBuilder.createScreenCaptureFromPath("." + screenshot()).build());
Hope this helps!

You can add screenshot for absolute path as below:
File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
//for file copy, absolute path starts from your project directory
FileUtils.copyFile(src, new File("../resources/reports/screenshots/screen2.png"));
String img = logger.addScreenCapture("./screenshots/screen2.png");
logger.log(LogStatus.PASS, "Title verified...", img);
Please note that here in addScreenCapture() method path started from screenshots folder and not resources as in copyFile() method. Its because ExtentReports is initialized as :
ExtentReports report = new ExtentReports("../resources/reports/extentreports_v2.html", true);
so for extentreports_v2.html to find screenshot's absolute path, it should start from "reports" directory

This is will work for you as its works me as well.
public void afterScenario(Scenario scenario) throws IOException {
if (scenario.isFailed()) {
String screenshotName = scenario.getName().replaceAll(" ", "_");
//This takes a screenshot from the driver at save it to the specified location
File sourcePath = ((TakesScreenshot) testContext.getWebDriverManager().getDriver()).getScreenshotAs(OutputType.FILE);
//Building up the destination path for the screenshot to save
//Also make sure to create a folder 'screenshots' with in the cucumber-report folder
File destinationPath = new File("./src/test/resources/"+screenshotName + ".png");
//Copy taken screenshot from source location to destination location
Files.copy(sourcePath, destinationPath);
//This attach the specified screenshot to the test
Reporter.addScreenCaptureFromPath(screenshotName+".png");
System.out.println("Cant take screenshot in grid.");
}
}

I tried various sites and blogs for this issue, but couldn't get a solution anywhere. I got below solution after trying various approaches. Try the below solution and it worked perfectly for me.
public static synchronized String addScreenshots(){
WebDriver webDriver = Browser.getDriver();
Long l = Calendar.getInstance().getTimeInMillis();
String screenshotId = l.toString();
String Path = System.getProperty("user.dir")+"/ExtentReports/";
File screenshot = ((TakeScreenshot)WebDriver).getScreenshotAs(OutputType.FILE);
String imgPath = Path+screenshotId+".png";
File dest = new File(imgPath);
try {
FileUtils.copyFile(screenShot, dest);
} catch (IOException e) {
e.printStackTrace();
}
String ImagePath = "../ExtentReports/"+screenshotId+".png";
return ImagePath;
}

I tried the following code, and it resulted in a screenshot being recorded in the report.
File file = new File("./Screenshots/" + result.getName() + ".png");
String absolutePath = file.getAbsolutePath();
logger.fail("details", MediaEntityBuilder.createScreenCaptureFromPath(absolutePath).build());

The below piece of code can solve your problem:
public void reportStatus(ITestResult result){
if(result.getStatus()==ITestResult.FAILURE){
String screenshotFilePath=takeScreenshotMethod(driver, result.getName());
extentTest.log(Status.FAIL, "Screenshot", MediaEntityBuilder.createScreenCaptureFromPath(screenshotFilePath).build());
}
}

public static void TakeScreenshot(Status status, string stepDetail)
{
string path = #"C:\ExtentReports\" + "TestExecLog_" + DateTime.Now.ToString("yyyyMMddHHmmss");
Screenshot image = ((ITakesScreenshot)driver).GetScreenshot();
image.SaveAsFile(path + ".png", ScreenshotImageFormat.Png);
ExtentReport.exChildTest.Log(status, stepDetail, MediaEntityBuilder.CreateScreenCaptureFromPath(path + ".png").Build());
}
public static void ReadJsonObject(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jobject = JObject.Parse(myJsonString);
}
public static void ReadJsonArray(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jarray = JArray.Parse(myJsonString);
}

Related

Resize File Please

I've tried numerous forms but I'm not getting the size of my photos at all, they're coming out with more than 3mb and I need them to upload numerous pictures via FTP. Follow code for someone could demonstrate a functional gradient
File createImageFile() throws IOException {
Logger.getAnonymousLogger().info("Generating the image - method started");
// New Image
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
String imageFileName = os_id+ "_"+ txtCheckList_id.getText().toString() + "_" + txtCheckListItens_id.getText().toString() + "_1A_" + timeStamp;
File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "GRP");
Logger.getAnonymousLogger().info("Storage directory set");
if (!storageDirectory.exists()) storageDirectory.mkdir();
File image = new File(storageDirectory, imageFileName + ".png");
Logger.getAnonymousLogger().info("File name and path set");
mImageFileLocation = image.getAbsolutePath();
return image;
}
You can simply use file.length() to get the size of the file, please check the mentioned example,
int file_size = Integer.parseInt(String.valueOf(file.length()/1024));

How to move folder and files?

My program uses a file database and I was wondering how to move a folder without deleting the files from within the folder. I am using java. When I press a button I would like them to move to a specified location. The code on the button looks like this:
private void uploadButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
ProjectInfo.documentTitle = fileName.getText();
ProjectInfo.moveFileLocation = fileSpecificLocation.getText();
String name = userNameText.getText();
Signup.fileToMoveTo = "C:\\CloudAurora\\" + name + "\\";
String docTtl = ProjectInfo.documentTitle;
// docTtl.renameTo(new File(Signup.fileToMoveTo));
ProjectInfo.documentTitle = fileName.getText();
ProjectInfo.moveFileLocation = fileSpecificLocation.getText();
String name = userNameText.getText();
Signup.fileToMoveTo = "C:\\CloudAurora\\" + name + "\\";
String docTtl = ProjectInfo.documentTitle;
System.out.println(ProjectInfo.documentTitle);
System.out.println(Signup.fileToMoveTo);
}
If Someone could help that would be awesome. I have looked for a way to do it but couldn't figure out how
I hope as per your case, I have mentioned the source file and destination file correctly. Below code should move the folders along with the file.
File srcFile = new File(docTtl);
File destFile = new File(Signup.fileToMoveTo);
/* Handle IOException for the below line */
Files.move(Paths.get(srcFile.getPath()), Paths.get(destFile.getPath()), StandardCopyOption.REPLACE_EXISTING);

Java - code to convert string to post script file using Ghostscript

I never worked with postscript before... And I need to replace a tool that:
Converts a string to postscript
Generates a pdf file based on a postscript file (done)
My issue is: I have no idea how to achieve step 1. By the way, I would preferably do in a similar way to the one I did on step (2).
I was wondering if I can just replace the parameters, but how? Could you please assist me?
The code to item (2) is below:
public byte[] convertPostScriptToPDF() throws IOException {
//get Ghostscript instance
Ghostscript gs = Ghostscript.getInstance();
File file= new File (this.getClass().getResource( "/resources/employer_report_last_page2.ps").getFile());//(Config.EMP_REPORT.REPORT_LAST_PAGE_STORE_PATH);
File pdfGenerated = File.createTempFile("output", "pdf");
System.out.println("Path for temp file -> " + pdfGenerated.getAbsolutePath());
//prepare Ghostscript interpreter parameters
//refer to Ghostscript documentation for parameter usage
String[] gsArgs = new String[10];
gsArgs[0] = "-ps2pdf";
gsArgs[1] = "-dNOPAUSE";
gsArgs[2] = "-dBATCH";
gsArgs[3] = "-dSAFER";
gsArgs[4] = "-sDEVICE=pdfwrite";
// gsArgs[5] = "-sOutputFile=output2.pdf";//output file name
gsArgs[5] = "-sOutputFile=" + pdfGenerated.getAbsolutePath();
// gsArgs[5] = "-sOutputFile=" + file.getAbsolutePath();
gsArgs[6] = "-c";
gsArgs[7] = ".setpdfwrite";
gsArgs[8] = "-f";
// gsArgs[9] = "input.ps";//input file name
gsArgs[9] = file.getAbsolutePath();//input file name
//execute and exit interpreter
try {
gs.initialize(gsArgs);
gs.exit();
} catch (GhostscriptException e) {
System.out.println("ERROR: " + e.getMessage());
}
FileInputStream fis = new FileInputStream(pdfGenerated);
return IOUtils.toByteArray(fis);
}
Thank you in advance!
I got no solution, so I realized I could try a workaround...
I changed the application logic. At the end it would convert everything to pdf, so instead of :
convert string to ps
add ps content other ps
convert ps to string
I did:
onvertd string to pdf
convert ps to pdf
merged both using the PDFMergerUtility

file path from \ to /

I have this problem: I am choosing a file from JFileChooser and if i take a system print i get this path: C:\Users\Joakim\Desktop\dude.txt and when i want to use this link to copy this file to another location i need to have the path like this: C://Users/Joakim/Desktop/dude.txt
How can i do this?
public void upload(String username) throws RemoteException, NullPointerException{
JFileChooser chooser = new JFileChooser(getProperty + "/desktop/");
int returnVal = chooser.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " + chooser.getSelectedFile().getName());
} try {
String fileName = chooser.getSelectedFile().getName();
System.out.println(fileName); //name of the file
File selectedFile = chooser.getSelectedFile();
System.out.println(selectedFile); //path of the file
//File path= selectedFile.replaceAll('/','/');
String serverDirectory = ("C://Users/Joakim/Dropbox/Project RMI/SERVER/");
byte[] filedata = cf.downloadFile(selectedFile);
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(serverDirectory + fileName));
output.write(filedata, 0, filedata.length);
output.flush();
output.close();
} catch (Exception e) {
System.err.println("FileServer exception: " + e.getMessage());
e.printStackTrace();
}
}
Thanks in Advance :)
Edit: So this did not work out as i planed. I wanted to change the path to C://Users/Joakim/Desktop/dude.txt but thats not enough. I need to have //C://Users/Joakim/Desktop/dude.txt. The problem i have now is to get that and still use it as a File. I did test out
File newFil = new File("//" + selectedFile);
byte[] filedata = cf.downloadFile(nyFil);
This do not work for me. I still get out C://Users/Joakim/Desktop/dude.txt
Do someone have a tip or two? :)
You should really be using the system properties file.separator:
Character that separates components of a file path. This is "/" on
UNIX and "\" on Windows.
String fileSeparator = System.getProperty("file.separator");
You can also access the file separator as File.separator
Consider breaking up your path to incorporate the use of this property in lieu of forward or backward slashes.
It's simple, try this :
String first = "C:\\Mine\\Java";
String second = first.replace("\\", "/");
second = second.replaceFirst("/", "//");
System.out.println(second);
OUTPUT :
Hope this might help in some way.
Regards
This should work: C:\Users use double \
Try with this
/**
* Prepare dropbox path from the path.
*
* #param path
* that is to be formated.
* #return
* Return dropbox formated path.
*/
public static String createDropboxPathFormat(String path) {
// Replaced all \ with / of the path.
String dropboxPath = path.replaceAll("[\\\\]", "/");
// Finally replaced all // with /
dropboxPath = dropboxPath.replaceAll("[//]", "/");
return dropboxPath;
}

My working directory, files, and urls

I have a convergence of needs revolving around where my data files are. The current application has all class and data files in a JAR (building using Eclipse IDE).
I've noticed there seem to be a variety of ways in which people get this information. I need the path for where my image files are (graphics). I also need it as a URL o use the toolkit call.
Toolkit tk = frame.getToolkit();
image = tk.getImage(url.toFile());
But I am having trouble with creating the URL or something. I have tried a few different methods. At this point, I keep data files next to class files in the file system. I am adding another function to what I do - strip the /bin directory off when running in debug.
// in class BwServices at init:
try {
rootDataPath = BwServices.class.getProtectionDomain()
.getCodeSource().getLocation().getPath();
rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
fileSystemAccess = true;
}
if(rootDataPath.endsWith("/bin/"))
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);
Later on... I go to get images, and some calls don't work, I don't know why
I've tried two things....
// 1
String s = "file://" + rootDataPath + d.toString() + fileName;
url = frame.getClass().getResource(s);
// 2
try {
url = new URL(s);
} catch (MalformedURLException e) {
trace("getImage - can't get url: " + s);
e.printStackTrace();
}
Either of which has problems.
I have calls to get images from different places. The 'frame' is the parent frame throughout the execution, in class BwFrame.
My path comes out like this in any attempts...
rootDataPath: /C:/Users/Markgm/Documents/DEV/workspace/bwp/
So, I'm looking for ways to open either FileInputStream or URLs for the toolkit, for files relative to where the class file is (and with some trick for when in debug). For a client-side app this is what this is. Someday, I might want to run this as an Applet, but I don't know where the image files will have to be. (50x75 playing cards and a few button images) Any help or advice is appreciated!
TIA,
Mark
Toolkit tk = frame.getToolkit();
Don't use Toolkit to load images, since Java 1.4. Use ImageIO.read(String/File/URL) instead, which is a blocking method that ensures the entire image is loaded before returning.
image = tk.getImage(url.toString());
And there is an actual problem. Once you have an URL (or File) object, don't toss it away and use the String representation. Even more importantly, don't provide a String that is supposed to represent a File, but actually represents an URL!
I didn't read the rest of that mess of code snippets (in the question or follow-up 'answer'), you might look to post an SSCCE in future.
I got rid of using URLs at all, which started with the use of pasted code. The behavior of URLs changed, as did everything, when running from a class file versus running from a JAR file. So I have code here that shows some of what I ended up doing, and comments to what happens (class file or jar file), and I also got the adjustment for debug time to work (snipping off bin/ from the end).
// root path - starts with jar file or pathspec
try {
rootDataPath = BwServices.class.getProtectionDomain()
.getCodeSource().getLocation().getPath();
rootDataPath = URLDecoder.decode(rootDataPath, "UTF-8");
if(rootDataPath.endsWith("BwPlayer.jar"))
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 12);
fileSystemAccess = true;
} catch(SecurityException e) {
trace("No file system access: " + e.getMessage());
messageBox(frame, "BwServices", "Cannot access file system");
rootDataPath = "";
} catch (UnsupportedEncodingException e) {
trace("Jar URL decode exception: "+ e.getMessage());
}
if(rootDataPath.endsWith("/bin/")) // remove bin/ portion if in debug
rootDataPath = rootDataPath.substring(0, rootDataPath.length() - 4);
trace("rootDataPath: "+rootDataPath);
Above: from init() time. Below, a getImage() function, including extra debug-related lines. Note: url.getFile() doesn't directly work for 2 reasons - one is it has the file:/ when out of a jar, and the other because it won't take a full pathspec beneath its pre-stated root /.
static public Image getImage(Directory d, String fileName) {
Image image = null;
String s = d.toString() + fileName;
/*
// Note: Start with / required for this url call (w/o full pathsepc)
URL url = parentFrame.getClass().getResource("/" + s);
if(url == null) {
trace(s + " - null url ");
return null;
}
*/
String file = rootDataPath + s; // url.getFile();
// end note
String t = s = "getImage(" + file + ") ";
Toolkit tk = parentFrame.getToolkit();
if(tk == null)
s = s + "NULL tk ";
else {
try {
// full pathspec needed here
// url.getFile() returns with file:/ when running from the .jar file
// but not when running from .class file (so don't use it)
s = t = "getImage(" + file + ") ";
image = tk.getImage(file); //url.getFile());
MediaTracker media = new MediaTracker(parentFrame);
media.addImage(image, 0);
try {
media.waitForID(0);
} catch(InterruptedException e) {
s = s + e.getMessage();
}
if(image == null) {
// image = null;
s = s + "NULL image ";
} else if(image.getHeight(parentFrame) < 1) {
s = s + "invalid height";
}
} catch (SecurityException e) {
s = s + e.getMessage();
}
}
if(! s.equals(t)) {
s = "file=" + file + "\n" + s;
s = "rootDataPath=" + rootDataPath + "\n" + s;
messageBox(parentFrame, "getImage()", s);
}
return image;
}

Categories