I have browse button to browse for the file. After browsing there is a import button which will actually import the file.
I'm able to browse the path using the following code:
public static void uploadFiles(String object, String data) {
try {
String filemode="";
Capabilities cap = ((RemoteWebDriver) driver).getCapabilities();
String browsername = cap.getBrowserName();
//System.out.println(browsername);
if (browsername.contains("chrome")){
filemode= "Open";
}
else if (browsername.contains("firefox")){
filemode= "File Upload";
}
else if (browsername.contains("explorer")){
filemode = "Choose File to Upload";
}
String EXE_FILE=DriverScript.EXE_FILENAME;
String[] command={EXE_FILE,filemode,data};
Runtime.getRuntime().exec(command);
Thread.sleep(5000);
} catch (Exception e) {
}
}
But when I click on the import button after that "JavaScript error (WARNING: The server did not provide any stacktrace information)" exception is thrown. EXE_FILE is the path to Fileload.exe which is used for browsing
Uploading a file using Selenium:
WebElement upload = driver.findElement(By.id("identifier of input tag"));
upload.sendKeys("path to file");
Remove capability INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS if you're using it in your test code and manually set your IE protected mode settings to be the same for all zones.
It should fix the problem.
Related
I am using onTestFailure method to display error screenshot in TestNG results. I am using Jenkins to run my test but image is not getting displayed in TestNG results however it is showing it as a link and nothing is happening on clicking this scattered image link. When I copy image link using mouse and trying open it in a browser then image is getting displayed correctly which means path to image is correct.
public class ScreenshotListener extends TestListenerAdapter {
#Override
public void onTestFailure(ITestResult result) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
String methodName = result.getName();
//String pathToScreen;
if(!result.isSuccess()){
File scrFile = ((TakesScreenshot)GlobalVar.wDriver).getScreenshotAs(OutputType.FILE);
try {
String reportDirectory = new File(System.getProperty("user.dir")).getAbsolutePath() + "/target/surefire-reports";
File destFile = new File((String) reportDirectory+"/failure_screenshots/"+methodName+"_"+formater.format(calendar.getTime())+".png");
FileUtils.copyFile(scrFile, destFile);
Reporter.log("<a href='"+ destFile.getAbsolutePath() + "'> <img src='"+ destFile.getAbsolutePath() + "' height='100' width='100'/> </a><br />");
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
I expect image link should display proper screenshot of error but it is showing blank screenshot. I have attached the screenshot of TestNGResults
FURTHER INVESTIGATION RESULT:
I investigated it further and found the reason of not displaying the screenshot. Actually screenshot path is coming as **C:\SelWrokspaceLuna 18 May\RDTest\target\surefire-reports\failure_screenshots\ but jenkin workspace path is **http://localhost:8080/job/firstjob/ws/target/surefire-reports/failure_screenshots/
Can anyone suggest how to get path of Jenkin workspace in selenium script? so that i can give jenkin workspace path in my HTML. Basically how to know this path http://localhost:8080/job/firstjob/ws in selenium script
How do i identify download is not completed /in progress ? because i want to close web driver after download finished.
WebDriver: Chrome
sample code like this ,assume chrome driver setup is ready.
#Test
public void testDownloadPdf(){
// here is the selenium java code to download pdf.
// when do i perform driver.close();
}
In general, better close the driver in #AfterClass.
If you know the exact file name and expected location, you can use Paths
String file_path_full = "C:\\users\\username\\downloads\\yourpdffile.pdf";
while(Files.notExists(Paths.get(file_path_full))) {Thread.sleep(10000);}
I found this... it work in my case
here i'm using FileUtils.sizeOfDirectory(downloadfolder) it will return size of directory and will check after every 5 sec is the size is equal or not.if file size is equal then download is completed .
private void waitForDownloadFinished() throws Exception {
try {
String path = "/Download/path/";
if (path != null) {
File folder = new File(path);
long size, reSize;
do {
size = FileUtils.sizeOfDirectory(folder);
Thread.sleep(5000);
reSize = FileUtils.sizeOfDirectory(folder);
} while (size != reSize);
System.out.println("Download completed");
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
getWebBrowser().quit();
}
}
To generate PDF from a HTML file, I want to use selenium Chrome driver.
I tried it with command line :
chrome.exe --headless --disable-gpu --print-to-pdf file:///C:invoiceTemplate2.html
and it works perfectly, So I wanted to do that with JAVA and here's my code :
System.setProperty("webdriver.chrome.driver", "C:/work/chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu", "--print-to-pdf",
"file:///C:/invoiceTemplate2.html");
WebDriver driver = new ChromeDriver(options);
driver.quit();
The server is started with no problem, but chrome is opened with multiple tabs with the arguments I specified in Options.
Any solution to this ? thx.
This can indeed be done with Selenium and ChromeDriver (tested with Chrome version 85), but using the "print-to-pdf" option when starting Chrome from the webdriver is not the solution.
The thing to do is to use the command execution functionality of ChromeDriver:
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/remote/RemoteWebDriver.html#execute-java.lang.String-java.util.Map-
There is a command called Page.printToPDF that provides PDF output functionality. A dictionary containing the item "data", with the resulting PDF in base-64-encoded format, is returned.
Unfortunately, I do not have a full Java example, but in this answer, there is a C# example (Selenium methods are named differently in C# compared to Java, but the principle should be the same):
https://stackoverflow.com/a/63970792/2416627
The Page.printToPDF command in Chrome is documented here:
https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
UPDATE:
we noticed that the original workaround was not always working properly, and we went for a Selenium + ChromeDriver:
public void generatePdf(Path inputPath, Path outputPath) throws Exception
{
try
{
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu", "--run-all-compositor-stages-before-draw");
ChromeDriver chromeDriver = new ChromeDriver(options);
chromeDriver.get(inputPath.toString());
Map<String, Object> params = new HashMap();
String command = "Page.printToPDF";
Map<String, Object> output = chromeDriver.executeCdpCommand(command, params);
try
{
FileOutputStream fileOutputStream = new FileOutputStream(outputPath.toString());
byte[] byteArray = java.util.Base64.getDecoder().decode((String) output.get("data"));
fileOutputStream.write(byteArray);
fileOutputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (Exception e)
{
e.printStackTrace(System.err);
throw e;
}
}
If this will be called frequently I suggest reusing the driver object because it takes a while to initialize.
Remember to close or quit the driver to avoid leaving Zombie chrome processes behind and also remember to install ChromeDriver in your machine.
Original Solution:
Not being able to get the desired outcome using ChromeDriver my workaround was to call the headless chrome in the command-line from my Java program.
This is working on Windows but just changing the contents of the paths used in the command variable should make it work in Linux too.
public void generatePdf(Path inputPath, Path outputPath) throws Exception {
try {
String chromePath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe";
String command = chromePath + " --headless --disable-gpu --run-all-compositor-stages-before-draw --print-to-pdf=" + outputPath.toString() + " " + inputPath.toString();
// Runs "chrome" Windows command
Process process = Runtime.getRuntime().exec(command);
process.waitFor(); // Waits for the command's execution to finish
}catch (Exception e){
e.printStackTrace(System.err);
throw e;
}finally{
// Deletes files on exit
input.toFile().deleteOnExit();
output.toFile().deleteOnExit();
}
}
Note: both input and output paths are temporary files created with NIO.
The code will help you save the page in PDF format on Selenium c#
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
protected void PDFconversion(ChromeDriver driver, string root, string rootTemp)
{
//Grid.Rows.Add(TxtBxName.Text, TxtBxAddress.Text);
try
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
Thread.Sleep(500);
js.ExecuteScript("setTimeout(function() { window.print(); }, 0);");
Thread.Sleep(500);
driver.SwitchTo().Window(driver.WindowHandles.Last());
Thread.Sleep(500);
string JSPath = "document.querySelector('body>print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('#destinationSettings').shadowRoot.querySelector('#destinationSelect').shadowRoot.querySelector('print-preview-settings-section:nth-child(9)>div>select>option:nth-child(3)')";
Thread.Sleep(500);
IWebElement PrintBtn = (IWebElement)js.ExecuteScript($"return {JSPath}");
Thread.Sleep(500);
PrintBtn.Click();
string JSPath1 = "document.querySelector('body>print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('cr-button.action-button')";
Thread.Sleep(1000);
IWebElement PrintBtn1 = (IWebElement)js.ExecuteScript($"return {JSPath1}");
PrintBtn1.Click();
Thread.Sleep(1000);
SendKeys.Send("{HOME}");
SendKeys.Send(rootTemp + "\\" + "result.pdf"); // Path
SendKeys.Send("{TAB}");
SendKeys.Send("{TAB}");
SendKeys.Send("{TAB}");
SendKeys.Send("{ENTER}");
Thread.Sleep(1000);
}
catch (Exception ex){}
}
You have to do two things.
First: Make a screenshot using selenium.
Second: Convert that screenshot using any pdf tool, like itext. Here I am showing a complete example of how to do this.
Step 1: Download the jar of itext from here and add the jar file to your build path.
Step 2: Add this code to your project.
ChromeOptions options = new ChromeOptions();
options.addArguments("disable-infobars");
options.addArguments("--print-to-pdf");
WebDriver driver = new ChromeDriver(options);
driver.get("file:///C:/invoiceTemplate2.html");
try {
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("screenshot.png"));
Document document = new Document(PageSize.A4, 20, 20, 20, 20);
PdfWriter.getInstance(document, new FileOutputStream("webaspdf.pdf"));
document.open();
Image image = Image.getInstance("screenshot.png");
document.add(image);
document.close();
}
catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
Note: To use the mentioned itext package, add the required imports to your code.
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
I am looking for a way to attach a screenshot to Results section of TestNG Report for the failed methods.
So far I was able to attache my screenshots to Reporter Output by implementing this:
Reporter.log("<br> <img src=.\\screenshots\\" + fileName + " /> <br>");
but still struggling with adding them to Test Results section of failed methods.
I was able to implement Listener and intercept onTestFailure actions which was originally suggested here:
How can I include a failure screenshot to the testNG report
Here is an example of that:
#Override
public void onTestFailure(ITestResult result) {
Reporter.setCurrentTestResult(result);
Reporter.log("<br> <img src=.\\screenshots\\Untitled.png /> <br>");
Reporter.setCurrentTestResult(null);
}
But Reporter.log function still pushes my information in the Reporter output log but not in the Results->Failed methods->Failed method log.
Update (03/14/14): I've attached screenshot to clarify my question. The problem is not in capturing screenshot and attaching it to Report. That part works fine. The problem is that screenshot is attached to Test Output part of the report but I want to see it in Results -> Failed Methods.
I have also implemented the same extending Testng TestListenerAdapter. By capturing the screenshot then attach it to the Testng Report with the image of size height=100 and width=100 with onTestFailure. Please see below if this helps solve your problem
File scrFile = ((TakesScreenshot) WebdriverManager.globalDriverInstance).getScreenshotAs(OutputType.FILE);
//Needs Commons IO library
try {
FileUtils.copyFile(scrFile, new File(file.getAbsolutePath()+ "/selenium-reports/html/" + result.getName() + ".jpg"));
Reporter.log("<a href='"+ file.getAbsolutePath()+"/selenium-reports/html/" + result.getName() + ".jpg'> <img src='"+ file.getAbsolutePath()+"/selenium-reports/html/"+ result.getName() + ".jpg' height='100' width='100'/> </a>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Reporter.setCurrentTestResult(null);
In addition to above don't forget to add following lines to your testng suite xml
<listeners>
<listener class-name="com.tests.DotTestListener" />
</listeners>
OR
passing as listner parameter if you are executing it from command line
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -listener com.tests.DotTestListener test\testng.xml
Reference : http://testng.org/doc/documentation-main.html#logging-listeners
I've had same problem but it solved. By implementing SuitePanel you will be able to add screenshot as you want
https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/reporters/jq/SuitePanel.java
I almost don't change the original code except
...
// Description?
String description = tr.getMethod().getDescription();
if (! Strings.isNullOrEmpty(description)) {
xsb.push("em");
xsb.addString("(" + description + ")");
xsb.pop("em");
}
// Add screen shot here
xsb.push(“img”,”src”,imagePath);
xsb.pop(“img”);
xsb.pop(D);
xsb.pop(D);
If you want to show the screen shot on the failed method then you will have to capture the exception and modify its message content and add img html to that and then it will appear. Let me know if you need example
I had same issue but its fixed now. I made a method to catcher screenshot in base class. this method return full path of screenshot.
public String getScreenshot (String screenshotName, WebDriver driver) throws IOException{
DateFormat dateformate = new SimpleDateFormat("dd-mm-yy-hh-mm-ss");
Date date = new Date();
String currentdate = dateformate.format(date);
String imageName =screenshotName+currentdate;
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
String location =System.getProperty("user.dir")+"\\testOutput\\screenshot\\"+imageName+".png";
File screenshotLocation =new File (location);
FileUtils.copyFile(source, screenshotLocation);
return location;
}
Add use this path to add screenshot in testng report as well as report log by updating testng TestNgListener-
public void onTestFailure(ITestResult arg0) {
Object currentClass = arg0.getInstance();
WebDriver driver = ((BrowserSetup) currentClass).getDriver();
String name = arg0.getName();
System.out.println(name);
try {
String screenshotPath =getScreenshot(name, driver);
System.out.println("Screenshot taken");
String path = "<img src=\"file://" + screenshotPath + "\" alt=\"\"/>";
System.out.println(screenshotPath+" and path - "+path);
Reporter.log("Capcher screenshot path is "+path);
} catch (Exception e) {
System.out.println("Exception while takescreenshot "+e.getMessage());
}
printTestResults(arg0);
}
I suggest you to use ReportNG instead of the primitive TestNG reports.
If the problem only with getting screenshots, you can try to get it like this:
private static byte[] GetCropImg(IWebDriver targetChrome, IWebElement targetElement)
{
var screenshot = ((ITakesScreenshot)targetChrome).GetScreenshot();
var location = targetElement.Location;
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
{
var rect = new Rectangle(location.X, location.Y, targetElement.Size.Width, targetElement.Size.Height);
using (Bitmap bmpImage = new Bitmap(stream))
{
using (Bitmap cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat))
{
using (MemoryStream ms = new MemoryStream())
{
cropedImag.Save(ms, ImageFormat.Jpeg);
byte[] byteImage = ms.ToArray();
return byteImage;
}
}
}
}
}
and then you can save file or save sting64
var imgString64 = Convert.ToBase64String(byteImage); //Get Base64
PS: on JAVA it should be almost the same)
you can get failed test cases screen shots with name of failed test class by using #After method.
Use below code segment
I'm creating a Java application using Netbeans. From the 'Help' Menu item, I'm required to open a PDF file. When I run the application via Netbeans, the document opens, but on opening via the jar file, it isn't opening. Is there anything that can be done?
m_aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Runtime rt = Runtime.getRuntime();
URL link2=getClass().getResource("/newpkg/Documentation.pdf");
String link=link2.toString();
link=link.substring(6);
System.out.println(link);
System.out.println(link2);
String link3="E:/new/build/classes/newpkg/Documentation.pdf";
try {
Process proc = rt.exec("rundll32.exe url.dll,FileProtocolHandler " + link3);
} catch (IOException ex) {
Logger.getLogger(Menubar1.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
The two outputs are as follows:
E:/new/build/classes/newpkg/Documentation.pdf
file:/E:/new/build/classes/newpkg/Documentation.pdf
Consider the above code snippet. On printing 'link',we can see that it is exactly same as the hard coded 'link3'. On using the hard coded 'link3' , the PDF file gets opened from jar application. But when we use link, though it is exactly same as 'link3', the PDF doesn't open.
This is most likely related to the incorrect PDF resource loading. In the IDE you have the PDF file either as part of the project structure or with a directly specified relative path. When a packaged application is running it does not see the resource.
EDIT:
Your code reveals the problem as I have described. The following method could be used to properly identify resource path.
public static URL getURL(final String pathAndFileName) {
return Thread.currentThread().getContextClassLoader().getResource(pathAndFileName);
}
Pls refer to this question, which might provide additional information.
Try out this:
m_aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
URL link2=Menubar1.class.getResource("/newpkg/Documentation.pdf");
String link=link2.toString();
link=link.substring(6);
System.out.println(link);
File file=new File(link);
System.out.println(file);
try {
desktop.open(file);
} catch (IOException ex) {
Logger.getLogger(Menubar1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});