I'm running a series of automated GUI tests using Selenium in Java. These tests regularely takes screenshots using:
public static void takeScreenshot(String screenshotPathAndName, WebDriver driver) {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(screenshotPathAndName));
} catch(Exception e) {
e.printStackTrace();
}
}
This works excellently in Chrome and IE, however in firefox I keep getting large pieces of whitespace under the screenshots. I suspect that the whitespace is actually a part of the page itself, but normally hidden from view in the browser(the scrollbar stops before the whitespace). I did a quick test with
driver.get("http://stackoverflow.com/");
takeScreenshot("D:\\TestRuns\\stackoverflow.png", driver);
and found that when using the Firefox driver the entire page in captured in the screenshot, while with the Chrome driver only what's shown in the browser is captured.
Is there any way to force the Firefox driver to take a screenshot containing ONLY what can actually be seen in the browser (what an actual user would see)?
Based on answers from this question I was able to add 4 lines of code to just crop the image down to the browser size. This does solve my problem, although it would have been nicer if it could be solved through the driver instead of cropping after the screenshot has been taken.
public static void takeScreenshot(String screenshotPathAndName, WebDriver driver) {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
int height = driver.manage().window().getSize().getHeight();
BufferedImage img = ImageIO.read(scrFile);
BufferedImage dest = img.getSubimage(0, 0, img.getWidth(), height);
ImageIO.write(dest, "png", scrFile);
FileUtils.copyFile(scrFile, new File(screenshotPathAndName));
} catch(Exception e) {
e.printStackTrace();
}
}
Try this :
private static void snapshotBrowser(TakesScreenshot driver, String screenSnapshotName, File browserFile) {
try {
File scrFile = driver.getScreenshotAs(OutputType.FILE);
log.info("PNG browser snapshot file name: \"{}\"", browserFile.toURI().toString());
FileUtils.deleteQuietly(browserFile);
FileUtils.moveFile(scrFile, browserFile);
} catch (Exception e) {
log.error("Could not create browser snapshot: " + screenSnapshotName, e);
}
}
Related
I'm trying to move to a different page (click 'my account'), and a floating advertisement appears:
advertisement
I tried to click on it, and can't find the "Close" element.
Found that it might related to frames, but still not works.
My Code:
public void clickMyAccount() {
driver.findElement(myAccountBtn).click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void clickCloseAd(){
driver.switchTo().frame(driver.findElement(By.id("google_esf")));
driver.switchTo().frame(driver.findElement(By.id("aswift_9")));
driver.switchTo().frame(driver.findElement(By.id("ad_iframe")));
driver.findElement(By.id("dismiss-button")).click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
driver.switchTo().defaultContent();
}
Site:
https://practice.automationtesting.in/
Any idea how can I click the floating advertisement?
Tried: move between frames until able to find the Close element
Actual: still can't find this element
It is hard to handle advertisement popUp. So we can handle it in 2 ways:
downloading ad-blocker extension to your chrome and using the chrome option code.
download ad-bocker- https://chrome.google.com/webstore/detail/adblock-%E2%80%94-best-ad-blocker/gighmmpiobklfepjocnamgkkbiglidom
use chromeoption driver code:
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("disable-infobars");
Notice that popUp gets disabled is do back. so we can is click on myaccount go back and then click back:
WebElement MyAccount = driver.findElement(By.xpath("//[#href='https://practice.automationtesting.in/my-account/']"));
MyAccount.click();
driver.navigate().back();
MyAccount.click();
Found the issue:
My 'wait' not always working, so the driver tries to close the ad when not displayed - still searching for a way to correct this
It's working without frame1: "google_esf", only frame2 and frame3 needed
Updated code:
public void clickMyAccount() {
System.out.println("Click My Account");
if(driver.findElement(myAccountBtn).isDisplayed()){
driver.findElement(myAccountBtn).click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
} else {
System.out.println("My account button not displayed");
}
}
public void clickCloseAd(){
System.out.println("Click Close Ad");
if(driver.findElement(By.id("aswift_9")).isDisplayed()){
// driver.switchTo().frame(driver.findElement(By.id("google_esf"))); //Not in use but also a frame
driver.switchTo().frame(driver.findElement(By.id("aswift_9")));
driver.switchTo().frame(driver.findElement(By.id("ad_iframe")));
driver.findElement(By.id("dismiss-button")).click();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
driver.switchTo().defaultContent();
} else {
System.out.println("Ad not displayed");
}
}
Thanks all!
The screen shot is taken and stored in the folder. but its not displaying for the failed test.
displayed as corrupted image.
Java Code:
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail(MarkupHelper.createLabel(result.getName()+ " - Test failed due to below issue/error: ", ExtentColor.RED));
test.get().fail(result.getThrowable());
//Take screenshot and allow automatic saving of media files relative to the report
//Extentreports log and screenshot operations for failed tests.
try {
File src=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// String base64Screenshot = "data:image/png;base64,"+((TakesScreenshot)driver).getScreenshotAs(OutputType.BASE64);
String path=prop.getProperty("Screenshot_Folder")+System.currentTimeMillis()+".png";
File destination=new File(path);
FileUtils.copyFile(src, destination);
test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromPath(path).build());
//test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromBase64String(base64Screenshot).build());
} catch (Exception e) {
e.printStackTrace();
System.out.println("Screen-capture has been taken but not attached to Extent report");
}
}
below is the property file.
AutomationReport_Folder = D://Shared//V1core_automation
ExtentReport_Folder = D://Shared//V1core_automation//ExtentReports//
Screenshot_Folder = D://Shared//V1core_automation//ExtentReports//Screenshots//
Method for screen shot
public static String getScreenshot(WebDriver driver)
{
TakesScreenshot ts=(TakesScreenshot) driver;
File src=ts.getScreenshotAs(OutputType.FILE);
String path=System.getProperty("user.dir")+"/Screenshots/"+System.currentTimeMillis()+".png";
File destination=new File(path);
try
{
FileUtils.copyFile(src, destination);
} catch (IOException e)
{
System.out.println("Capture Failed "+e.getMessage());
}
return path;
}
Replace this line in your code:
test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromPath(path).build());
With
MediaEntityBuilder.addScreenCaptureFromPath(path, result.getMethod().getMethodName());
and see it works.
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());
}
I'm trying to take a screenshot of specific Element using Ashot.
unfortunately, I'm not getting the element screenshot.
When I sent my code to someone else who ran it the element screenshot was taken correctly.
I don't understand why it is not working on my computer.
The code is:
public class ScreenShot
{
WebDriver driver;
#BeforeClass
public void StartSession()
{
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com/");
}
#Test
public void VerifyScreenShot()
{
TakeScreenShot();
//CompareScreenShot();
}
#Step("take element screen shot")
public void TakeScreenShot()
{
try
{
//find the element you want to picture
WebElement imageElement = driver.findElement(By.id("hplogo"));
//take the element screenshot
Screenshot imageScreenShot = new AShot().coordsProvider(new WebDriverCoordsProvider()).takeScreenshot(driver,imageElement);
//save the element picture in the project folder under img folder
ImageIO.write(imageScreenShot.getImage(),"png",new File("./img/glogo.png"));
}
catch (Exception e)
{
System.out.println("Error writing image file: "+ e);
}
}
#AfterClass
public void EndSession()
{
driver.quit();
}
}
i found the solution.
i was needed to change my computer resolution to 100% and than take the element screenshot.
than the element image was as i expected.
I must check downloaded PDF and open it using Selenium. For that, I am using Robot class. This is not the permanent or we can say general solution of this.
Question : Can anyone please help and provide more reliable solution for the same ?
Please find below code:
public boolean CommonEvents(WebDriver driver) throws InterruptedException {
try {
Thread.sleep(2000);
Robot robot = new Robot();
robot.mouseMove(100, 700);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(10000);
} catch(Exception e) {
BaseTest.reportPass(driver, null, "Should click on PDF to open", "Failed to click on PDF to open");
}
}
Just in case you really need to open every downloaded PDF then I would simply add this line to your preferences (e.g. for Firefox):
ffprofile.setPreference("browser.helperApps.neverAsk.openFile", "application/pdf");
Then it will automatically open the downloaded file after finishing the download.
You can use something similar to this if you have a fixed directory where you are saving the downloaded pdf files .
public static void main(String[] args) {
try {
File pdfFile = new File("c:\\Hello.pdf");
if (pdfFile.exists()) {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().open(pdfFile);
} else {
System.out.println("Awt Desktop is not supported.");
}
} else {
System.out.println("File doesn't exists.");
}
System.out.println("File opened.");
} catch (Exception ex) {
ex.printStackTrace();
}
}
Reference : https://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html
We use below logic:
First set preference for a download location, so that the file will be downloaded to your desired location.
chromePrefs.put("download.default_directory", downloadFilepath);
Set Preference so that it won't ask the pop to download.
chromePrefs.put("profile.default_content_settings.popups", 0);
As #Mudit_ has answered check for the *.pdf with regex pattern, if you want to make it dynamic.
My purpose is post with a Featured Image.
This program can post Featured Image.
But dialog doesn't close!
So I can't publish.
public void uploadThumbnail(String imgPath) {
//parent current window
String currentWindow = driver.getWindowHandle();
System.out.println(imgPath);
try {
driver.findElement(By.id("set-post-thumbnail")).click();
sleep(2000);
click(By.linkText("Upload Files"));
//Select Files
sleep(1000);
driver.findElement(By.id("__wp-uploader-id-1")).click();
//upload
driver.findElement(By.xpath("//div[7]/input")).sendKeys(imgPath);
sleep(2000);
driver.findElement(By.xpath("//div[#id='__wp-uploader-id-0']/div[5]/div/div[2]/button")).click();
} catch (Exception e) {
e.printStackTrace();
uploadThumbnail(imgPath);
}
sleep(1000);
}
How to close the dialog or how to ignore the dialog and publish?
I stacked on the page.Finally I find plugin which is "Nelio External Featured Image".
it is can set picture by URL.So I don't need upload window and dialog.
Now I can set a picture on Featured Image on WordPress by Selenium from java!!!
Thank you Nelio External Featured Image developers!!