Selenium- screenshot of visible part of page - selenium

Is there a way to get Selenium WebDriver to take screenshot only of the visible part of the page for PhantomJS? I've browsed the source and there is no API AFAICT. So is there a trick to do that somehow?
EDIT: Chrome already snaps only visible part, so removed it as part of question.

According to the JavaDoc API for TakesScreenshot a WebDriver extending TakesScreenshot will make a best effort to return the following in order of preference:
Entire page
Current window
Visible portion of the current frame
The screenshot of the entire display containing the browser
As PhantomJS is a headless browser it probably doesn't have menus/tabs and other similar browser chrome. So all you can control is the Dimension of the browser window.
// Portrait iPhone 6 browser dimensions
Dimension dim = new Dimension(375, 627);
driver.manage().window().setSize(dim);
Taking a screenshot will most likely capture the entire page. If you want to restrict your resulting file to the dimensions you requested you could always
crop it to your required dimensions (not ideal but PhantomJS is not a real browser).
private static void capture(String url, WebDriver driver, Dimension dim, String filename) throws IOException{
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().window().setSize(dim);
driver.get(url);
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
int w = dim.getWidth();
int h = dim.getHeight();
Image orig = ImageIO.read(scrFile);
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
bi.getGraphics().drawImage(orig, 0, 0, w, h, 0, 0, w, h, null);
ImageIO.write(bi, "png", new File(filename));
}

You can use robot class for this as belows
Robot rb=new Robot();
rb.keyPress(KeyEvent.VK_ALT);
rb.keyPress(KeyEvent.VK_PRINTSCREEN);
rb.keyRelease(KeyEvent.VK_PRINTSCREEN);
rb.keyRelease(KeyEvent.VK_ALT);
Once you have copied the screenshot on clipboard then u can save it to file.

WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

Related

Selenium to click Images link on Google and click first image

I have the below code. When I execute this,
Firefox opens - Expected
Go to Google.com - Expected
Keys in Pluralsight logo on searchbox - expected
I do not know what happens then I see the Google.com page with no text in searchbox.
However, when I put breakpoint and step in line by line I see it clicks Images. So, what is wrong when I execute it without breakpoints?
Another question I have is, once I am on the Images screen, how do I make my script click on the 1st image? I see the class name is rg_ic rg_i but I cannot use this as it has spaces. The ID keeps changing everytime. So, how can I click the 1st image? I commented it for now because I cannot get it to work.
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new FirefoxDriver();
driver.Url = "http://google.com";
var searchBox = driver.FindElement(By.Name("q"));
searchBox.SendKeys("Pluralsight logo");
searchBox.Submit();
var imageLink = driver.FindElement(By.LinkText("Images"));
imageLink.Click();
//var firstImage = driver.FindElements(By.ClassName("rg_ic"))[0];
//firstImage.Click();
}
}
}
the image id's are constant, and I ran a successful test using this (granted I'm using python, but the syntax is similar):
driver.get("http://google.com")
search_box = driver.find_element_by_name("q")
search_box.send_keys("Pluralsight logo")
search_box.submit()
time.sleep(4)
first_img = driver.find_element_by_id("dimg_1").click()
You have to provide time for the image to load. You could do this with an expected condition or just an explicit wait. Hope this helps.

Not able to draw on canvas using selenium webdriver version 2.53.1 in Internet Explorer browser

I have a GIS-based application to test, I want to draw certain shapes on a canvas in Internet Explorer browser, but the control is not clicking on the web canvas element. my code is working fine in Chrome and Mozilla browsers but I need to make it work in IE also(IE11 to be precise).
My Code Is:
WebElement image = driver.findElement(By.xpath(".//*[#id='map']/div/canvas"));
Actions builder = new Actions(driver);
WebElement canvasElement = null;
org.openqa.selenium.Point point = image.getLocation();
int xcord = point.getX();
System.out.println("Element's Position from left side Is "+xcord +" pixels.");
int ycord = point.getY();
System.out.println("Element's Position from top side Is "+ycord +" pixels.");
builder.clickAndHold(canvasElement).moveByOffset(150, 100).
moveByOffset(180,100).click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
builder.clickAndHold(canvasElement).moveByOffset(-100,-150).doubleClick().moveByOffset(180,200).moveByOffset(-220,-170).doubleClick().click()
.build().perform();

JAVA Selenium Webdriver Capturing wrong region in the screenshot

I am using selenium Web Driver(Java) to automate our web application.
I need to capture and compare the each icon of the application in all browsers.
For that first I've opened the application in Firefox and captured icons images with its xpath and then saving them at a particular path.
Later comparing the saved images when the application opened in another browser.
For this I have used the below code to capture the images, but the element image is not capturing, some unknown region in the screen is saving.
Please help, how to get the correct image of the element.
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
Point point = x.getLocation();
//Get width and height of the element
int eleWidth = x.getSize().getWidth();
int eleHeight = x.getSize().getHeight();
Rectangle rect = new Rectangle(point.getX(),point.getY(),eleWidth, eleHeight);
//Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(), rect.width, rect.height);
ImageIO.write(eleScreenshot, "png", screenshot);
//Copy the element screenshot to disk
FileUtils.copyFile(screenshot, new File("E:\\ICONS\\Icon1.jpg"));
driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(By.xpath("//*[#id='CWinBtn']")));
WebElement ele =driver.findElement(By.xpath("//*[#id='CCDLinkedformToolbar_cmdPrint']"));
try{
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
Point point = ele.getLocation();
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX()+30, 95, eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);
FileUtils.copyFile(screenshot, new File("E:\\ ICONS\\Icon1.png"));
}
catch(Exception e){
e.printStackTrace();
}
Changes that i have made to my previous code are, added value to X coordinate and passed static value to Y coordinate, as per my application resolution.

InternetExplorerDriver Zoom Level Error

I'm trying to run tests against IE8 but I've encountered a strange issue:
When creating the webdriver instance (driver = Selenium::WebDriver.for :ie), IE starts up and an exception is thrown by WebDriver:
"Unexpected error launching Internet Explorer. Browser zoom level was set to 0%"
IE seems to show a failure to connect to the IE Driver Server but if I refresh the browser manually, it connects just fine.
I have checked online and only two other people seem to have reported this. One possible solution was to ensure that all zones have the same "protected mode" settings, which they do.
My environment is Windows 7 and IE8 with IE Driver Server v2.25.3 and I'm using the Ruby bindings.
Any ideas?
According to the answer given by Jim Evans (one of Selenium developers) in this thread at WebDriver User Group the code below should fix your problem.
DesiredCapabilities caps = DesiredCapabilities.internetExplorer();
caps.setCapability("ignoreZoomSetting", true);
driver = new InternetExplorerDriver(caps);
Since the question isn't tagged with a specific language, and since JacekM's answer didn't work for me in C# (given the casing, I assume his is for Java...). I'll put the corresponding solution for C# here:
var service = InternetExplorerDriverService.CreateDefaultService(#"Path\To\Driver");
// properties on the service can be used to e.g. hide the command prompt
var options = new InternetExplorerOptions
{
IgnoreZoomLevel = true
};
var ie = new InternetExplorerDriver(service, options);
To quickly fix it adjust your browser zoom to 100%.
The most robust approach
Before you start with Internet Explorer and Selenium Webdriver Consider these two important rules.
The zoom level :Should be set to default (100%) and
The security zone settings : Should be same for all. The security settings should be set according to your organisation permissions.
How to set this?
Simply go to Internet explorer, do both the stuffs manually. Thats it. No secret.
Do it through your code.
Method 1:
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver","D:\\IEDriverServer_Win32_2.33.0\\IEDriverServer.exe");
WebDriver driver= new InternetExplorerDriver(capabilities);
driver.get(baseURl);
//Identify your elements and go ahead testing...
This will definetly not show any error and browser will open and also will navigate to the URL.
BUT This will not identify any element and hence you can not proceed.
Why? Because we have simly suppressed the error and asked IE to open and get that URL. However Selenium will identify elements only if the browser zoom is 100% ie. default. So the final code would be
Method 2 The robust and full proof way:
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver","D:\\IEDriverServer_Win32_2.33.0\\IEDriverServer.exe");
WebDriver driver= new InternetExplorerDriver(capabilities);
driver.get(baseURl);
driver.findElement(By.tagName("html")).sendKeys(Keys.chord(Keys.CONTROL,"0"));
//This is to set the zoom to default value
//Identify your elements and go ahead testing...
Hope this helps. Do let me know if further information is required.
While setting the IgnoreZoomLevel property allows you to open the browser without error, the test will find no elements at a zoom level other than 100%.
Sending Ctrl+0 will also not always have the expected result, depending on your systems DPI setting. If you have selected Medium (120 dpi) or Larger (144 dpi) (Windows 7 settings) Ctrl+0 will set the zoom to 125% or 150%.
A workaround I found is to set the zoom level according to the DPI settings by editing the setting, before opening IE, in the registry. This does not require administrator rights since everything is located under HKEY_CURRENT_USER.
This is my little helper class I came up with. (C#)
using Microsoft.Win32;
namespace WebAutomation.Helper
{
public static class InternetExplorerHelper
{
private static int m_PreviousZoomFactor = 0;
public static void SetZoom100()
{
// Get DPI setting.
RegistryKey dpiRegistryKey = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop\\WindowMetrics");
int dpi = (int)dpiRegistryKey.GetValue("AppliedDPI");
// 96 DPI / Smaller / 100%
int zoomFactor100Percent = 100000;
switch (dpi)
{
case 120: // Medium / 125%
zoomFactor100Percent = 80000;
break;
case 144: // Larger / 150%
zoomFactor100Percent = 66667;
break;
}
// Get IE zoom.
RegistryKey zoomRegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Internet Explorer\\Zoom", true);
int currentZoomFactor = (int)zoomRegistryKey.GetValue("ZoomFactor");
if (currentZoomFactor != zoomFactor100Percent)
{
// Set IE zoom and remember the previous value.
zoomRegistryKey.SetValue("ZoomFactor", zoomFactor100Percent, RegistryValueKind.DWord);
m_PreviousZoomFactor = currentZoomFactor;
}
}
public static void ResetZoom()
{
if (m_PreviousZoomFactor > 0)
{
// Reapply the previous value.
RegistryKey zoomRegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Internet Explorer\\Zoom", true);
zoomRegistryKey.SetValue("ZoomFactor", m_PreviousZoomFactor, RegistryValueKind.DWord);
}
}
}
}
I came up with the values comparing the ZoomFactor value in the registry at different system DPI settings with IE zoom set to 100%. There are more than 3 DPI settings in newer Windows versions, so you need to extend the class if you need those.
You could also modify this to calculate any zoom level you want but that was just not relevant for me.
I just call InternetExplorerHelper.SetZoom100(); before opening IE and InternetExplorerHelper.ResetZoom() after closing it.
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings() ;
driver = new RemoteWebDriver(new URL("http://localhost:8888/wd/hub"),options);
This basically happens when your browser is set to some zoom level other than 100%(Happens when you scroll mouse on a web page while pressing the Ctrl key.). You can fix this by specifying the code mentioned above to let selenium to ignore the browser zoom level or you can simply open the browser and reset the zoom level to 100% either by going to settings or using a shortcut Ctrl+0(This worked for IE11 and chrome)
Thanks for the post, this really worked for me.
For fixing the zoom level exception:
InternetExplorerOptions options = new InternetExplorerOptions { IgnoreZoomLevel= true };
driver = new InternetExplorerDriver(#"C:\seleniumreferences\IEDriverServer32", options);
Or Goto Internet Explorer Options > Advanced
Check the box for “Reset zoom level for new windows and tabs”.
Click Link to see the image --->
Internet Explorer Options > Advanced
InternetExplorerOptions ieOptions = new InternetExplorerOptions();
ieOptions.IgnoreZoomLevel = true;
driver = new InternetExplorerDriver(driverFilePath, ieOptions);
Set the IgnoreZoomLevel property to true and pass it as InternetExplorerOptions to the driver.
InternetExplorerOptions options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
IWebDriver driver = new InternetExplorerDriver(IEDriverLocation,options);
As Tomas Lycken's answer said, there is no language specified, so I will share my solution in Python:
capabilities = DesiredCapabilities.INTERNETEXPLORER
capabilities['ignoreZoomSetting'] = True
driver = webdriver.Ie(capabilities=capabilities)
Working Code using Java
InternetExplorerOptions capabilities= new InternetExplorerOptions();
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
System.setProperty("webdriver.ie.driver", Constant.drivers + "\\IEDriverServer.exe");
driver = new InternetExplorerDriver(capabilities);
driver.manage().window().maximize();

How can I programmatically create a screen shot of a given Web site?

I want to be able to create a screen shot of a given Web site, but the Web site may be larger than can be viewed on the screen. Is there a way I can do this?
Goal is to do this with .NET in C# in a WinForms application.
There are a few tools.
The thing is, you need to render it in some given program, and take a snapshot of it.
I don't know about .NET but here are some tools to look at.
KHTML2PNG
imagegrabwindow() (Windows PHP Only)
Create screenshots of a web page using Python and QtWebKit
Website Thumbnails Service
Taking automated webpage screenshots with embedded Mozilla
I just found out about the website browsershots.org which generates screenshots for a whole bunch of different browsers. To a certain degree you can even specify the resolution.
I wrote a program in VB.NET that did what you specified, except for the screen size issue.
I embedded a web control(look at the very bottom of all controls) onto my form, and tweaked it's settings(Hide scroll). I used a timer to wait on dynamic content, and then I used "copyFromScreen" to get the image.
My program had dynamic dimensions(settable via command line). I found that if I made my program larger than the screen, the image would just return black pixels for the off screen area. I did not research farther since my job was complete at that time.
Hope that gives you a good start. Sorry for any wrong wordings. I log onto windows to develop only once every couple of months.
Doing at as a screen shot is likely to get ugly. It's easy enough to capture the entire content of the page with wget, but the image means capturing the rendering.
Here's some tools that purport to do it.
You can render it on WebBrowser control and then take snapshot if page size bigger than screen size you have to scroll control take one or more snapshots and then merge all pictures :)
This is the code for creating screenshot programatically:
using System.Drawing.Imaging;
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
bmpScreenShot.Save("test.jpg", ImageFormat.Jpeg);
Java ScreenShots of WebSite
Combine Screens together for Final Entire WebPage Screenshot.
public static void main(String[] args) throws FileNotFoundException, IOException {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
ChromeDriver browser = new ChromeDriver();
WebDriver driver = browser;
driver.get("https://news.google.co.in/");
driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);
JavascriptExecutor jse = (JavascriptExecutor) driver;
Long clientHeight = (Long) jse.executeScript("return document.documentElement.clientHeight");
Long scrollHeight = (Long) jse.executeScript("return document.documentElement.scrollHeight");
int screens = 0, xAxis = 0, yAxis = clientHeight.intValue();
String screenNames = "D:\\Screenshots\\Yash";
for (screens = 0; ; screens++) {
if (scrollHeight.intValue() - xAxis < clientHeight) {
File crop = new File(screenNames + screens+".jpg");
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), crop);
BufferedImage image = ImageIO.read(new FileInputStream(crop));
int y_Axixs = scrollHeight.intValue() - xAxis;
BufferedImage croppedImage = image.getSubimage(0, image.getHeight()-y_Axixs, image.getWidth(), y_Axixs);
ImageIO.write(croppedImage, "jpg", crop);
break;
}
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), new File(screenNames + screens+".jpg"));
jse.executeScript("window.scrollBy("+ xAxis +", "+yAxis+")");
jse.executeScript("var elems = window.document.getElementsByTagName('*');"
+ " for(i = 0; i < elems.length; i++) { "
+ " var elemStyle = window.getComputedStyle(elems[i], null);"
+ " if(elemStyle.getPropertyValue('position') == 'fixed' && elems[i].innerHTML.length != 0 ){"
+ " elems[i].parentNode.removeChild(elems[i]); "
+ "}}"); // Sticky Content Removes
xAxis += yAxis;
}
driver.quit();
}