Selenium WebDriver drag and drop to scrollbar - java

I have issue with Selenium WebDriver drag-and-drop. It didn't want drop to webelement in scroll-bar.
I tried this:
new Actions(SeleniumDriver.getDriver())).dragAndDrop(element, target).build().perform();
also tried by using offsets:
(new Actions(SeleniumDriver.getDriver()))
.dragAndDropBy(element, xoffset, yoffset).build().perform();
and try use:
Actions builder = new Actions(SeleniumDriver.getDriver());
builder.clickAndHold(element).build().perform();
builder.moveToElement(target).build().perform();
builder.release(target).build().perform();
Any body know working solutions for scroll-bars? Thank's for any help.

I found solution by using Java Robot class.
Switch chrome to full screen:
DesiredCapabilities dc = new DesiredCapabilities();
ChromeOptions options = new ChromeOptions();
options.addArguments("--kiosk", "test-type");
dc.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(dc);
Get coordinates of start and destination element:
// start coordinates
int startX = new Integer(element.getLocation().x);
int startY = new Integer(element.getLocation().y);
// destination dimensions
int startWidth = new Integer(element.getSize().width);
int startHeight = new Integer(element.getSize().height);
// destination coordinates
int destinationX = new Integer(target.getLocation().x);
int destinationY = new Integer(target.getLocation().y);
// destination dimensions
int destinationWidth = new Integer(target.getSize().width);
int destinationHeight = new Integer(target.getSize().height);
// work out destination coordinates
int endX = Math.round(destinationX + (destinationWidth / 2));
int endY = Math.round(destinationY + (destinationHeight / 2));
int sX = Math.round(startX + (startWidth / 2));
int sY = Math.round(startY + (startHeight / 2));
Use Java Robot class for drag and drop:
Thread.sleep(1000);
Robot robot = new Robot();
robot.mouseMove(sX, sY);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseMove(endX, endY);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

Make sure you are trying to drag the right element.
Maybe that element is not dragable, it could be an inner element that is dragable.

A few ideas;
A small sleep is required after the click and hold. I have tested applications which required 100ms of hold until the drag and drop us initialized.
It could be using HTML 5 drag and drop which last I tried wasn't supported by Selenium
wrong element as suggested by user3723314

Related

Remove PdfName.Rotate value without rotation

I have to combine multiple pages from several files into new one PDF. The page orientation of all the pages must be portrait.
After this work is done, I am using a couple of programs to reset the rotation to zero without really rotate the page.
I want to use itext to remove the rotation value.
Taked from itext examples, I've tried something like this:
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
int n = pdfDoc.getNumberOfPages();
PdfPage page;
PdfNumber rotate;
for (int p = 1; p <= n; p++) {
page = pdfDoc.getPage(p);
rotate = page.getPdfObject().getAsNumber(PdfName.Rotate);
page.setRotation(0);
pdfDoc.close();
}
}
This:
PdfDictionary diccionario = page.getPdfObject();
diccionario.Remove(iText.Kernel.Pdf.PdfName.Rotate);
And the function CopyPagesTo with the same result: The pages orientation has been altered.
Here there is an example file with 0, 90, 180 y 270 degrees.
The goal is set rotate value of all pages to zero keeping portrait mode:
https://filebin.ca/4vep0uuU1p2s/1.pdf
Any advice would be greatly appreciated.
I have found a solution using the SetIgnorePageRotationForContent function.
VB.NET example:
Dim srcPdf As iText.Kernel.Pdf.PdfDocument = New iText.Kernel.Pdf.PdfDocument(New iText.Kernel.Pdf.PdfReader(srcFile))
Dim destPDF As New iText.Kernel.Pdf.PdfDocument(New iText.Kernel.Pdf.PdfWriter(destFile))
For contador = 1 To srcPdf.GetNumberOfPages
Dim srcPage = srcPdf.GetPage(contador)
Dim rotacion As iText.Kernel.Pdf.PdfNumber = srcPage.GetPdfObject().GetAsNumber(iText.Kernel.Pdf.PdfName.Rotate)
If IsNothing(rotacion) OrElse rotacion.IntValue = 0 Then
srcPdf.CopyPagesTo(contador, contador, destPDF)
Continue For
End If
Dim destPage As iText.Kernel.Pdf.PdfPage = destPDF.AddNewPage(New iText.Kernel.Geom.PageSize(srcPage.GetPageSizeWithRotation))
If rotacion.IntValue = 180 Then
destPage.GetPdfObject().Put(iText.Kernel.Pdf.PdfName.Rotate, New iText.Kernel.Pdf.PdfNumber(180))
Else
destPage.GetPdfObject().Put(iText.Kernel.Pdf.PdfName.Rotate, New iText.Kernel.Pdf.PdfNumber(rotacion.IntValue + 180))
End If
destPage.SetIgnorePageRotationForContent(True)
Dim canvas As New iText.Kernel.Pdf.Canvas.PdfCanvas(destPage)
Dim pageCopy As iText.Kernel.Pdf.Xobject.PdfFormXObject = srcPage.CopyAsFormXObject(destPDF)
canvas.AddXObject(pageCopy, 0, 0)
destPage.GetPdfObject().Remove(iText.Kernel.Pdf.PdfName.Rotate)
Next
destPDF.Close()
srcPdf.Close()

Take screenshot element in selenium on ubuntu wrong position

When I change the environment from Windows 10 to Ubuntu and some function is not working good. Like that function take a screenshot
Please help me find the solution take a screenshot on Ubuntu. When take a screenshot on Ubuntu the picture I think is the wrong position of the element. Thank you
Working for Windows 10
public void captureElementScreenshot(WebElement element, String fileName) {
//Capture entire page screenshot as buffer.
//Used TakesScreenshot, OutputType Interface of selenium and File class of java to capture screenshot of entire page.
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
//Used selenium getSize() method to get height and width of element.
//Retrieve width of element.
int ImageWidth = element.getSize().getWidth();
//Retrieve height of element.
int ImageHeight = element.getSize().getHeight();
//Used selenium Point class to get x y coordinates of Image element.
//get location(x y coordinates) of the element.
Point point = element.getLocation();
int xcord = point.getX();
int ycord = point.getY();
//Reading full image screenshot.
BufferedImage img = null;
try {
img = ImageIO.read(screen);
BufferedImage dest = img.getSubimage(xcord, ycord, ImageWidth, ImageHeight);
ImageIO.write(dest, "png", screen);
//Used FileUtils class of apache.commons.io.
//save Image screenshot In D: drive.
FileUtils.copyFile(screen, new File(System.getProperty("user.dir") + "//src//test//screenshot//" + fileName + ".png"));
System.out.println("Success save file " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
//cut Image using height, width and x y coordinates parameters.
}
And this config browser
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "//src//test//browser//chromedriver");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
ChromeOptions options = new ChromeOptions();
options.addArguments("force-device-scale-factor=0.75");
options.addArguments("high-dpi-support=0.75");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(capabilities);
driver.manage().window().maximize();
It's about two line code. I have commented and It's working
options.addArguments("force-device-scale-factor=0.75");
options.addArguments("high-dpi-support=0.75");

Apply FFT on BufferedImage give me an ArrayIndexOutOfBoundsException

I create a BufferedImage with Robot and try to apply FFT algorithm from rosetta code on the DataBufferInt generated by the Robot but it's fail in the fft method and I don't know why.
Robot r = new Robot();
Rectangle rect = new Rectangle(10,10,200,200);
BufferedImage capture = r.createScreenCapture(rect);
// All data in getDataBuffer() seems to be negative
int[] pixels = ((DataBufferInt)buffer.getRaster().getDataBuffer()).getData();
Complex[] cinput = new Complex[pixels.length];
for (int i = 0; i < pixels.length; i++) {
cinput[i] = new Complex(pixels[i], 0.0);
}
// Fail (method from rosetta code)
FastFourierTransform.fft(cinput);
Give me:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 40000
at engine.FastFourierTransform.fft(FastFourierTransform.java:42)
at engine.ImageProcessing.FFT(ImageProcessing.java:30)
at test.Testor.main(Testor.java:24)
I'm doing something wrong ?
You can use the Catalano Framework, you can easily perform the fast fourier transform. Also works for MxN-sized images.
Robot r = new Robot();
Rectangle rect = new Rectangle(10,10,200,200);
BufferedImage capture = r.createScreenCapture(rect);
FastBitmap fb = new FastBitmap(capture);
fb.toGrayscale();
FourierTransform ft = new FourierTransform(fb);
ft.Forward();
fb = ft.toFastBitmap();
//Display the image
JOptionPane.showMessageDialog(null, fb.toIcon());

How to download recaptcha in Selenium? [duplicate]

Currently I'm trying to capture a screenshot using the Selenium WebDriver. But I can only obtain the whole page screen shot. However, what I wanted is just to capture a part of the page or perhaps just on specific element based on ID or any specific element locator. (For example, I wish to capture the picture with image id = "Butterfly")
Is there any way to capture a screenshot by selected item or element?
We can get the element screenshot by cropping entire page screenshot as below:
driver.get("http://www.google.com");
WebElement ele = driver.findElement(By.id("hplogo"));
// Get entire page screenshot
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
// Get the location of element on the page
Point point = ele.getLocation();
// Get width and height of the element
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();
// Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(),
eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);
// Copy the element screenshot to disk
File screenshotLocation = new File("C:\\images\\GoogleLogo_screenshot.png");
FileUtils.copyFile(screenshot, screenshotLocation);
Here is a Python 3 version using Selenium webdriver and Pillow.
This program captures the screenshot of the whole page and crop the element based on its location. The element image will be available as image.png. Firefox supports saving element image directly using element.screenshot_as_png('image_name').
from selenium import webdriver
from PIL import Image
driver = webdriver.Chrome()
driver.get('https://www.google.co.in')
element = driver.find_element_by_id("lst-ib")
location = element.location
size = element.size
driver.save_screenshot("shot.png")
x = location['x']
y = location['y']
w = size['width']
h = size['height']
width = x + w
height = y + h
im = Image.open('shot.png')
im = im.crop((int(x), int(y), int(width), int(height)))
im.save('image.png')
Update
Now chrome also supports individual element screenshots. So you may directly capture the screenshot of the web element as given below.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.google.co.in')
image = driver.find_element_by_id("lst-ib").screenshot_as_png
# or
# element = driver.find_element_by_id("lst-ib")
# element.screenshot_as_png("image.png")
The AShot framework from Yandex can be used for taking screenshots in Selenium WebDriver scripts for
full web pages
web elements
This framework can be found on https://github.com/yandex-qatools/ashot.
The code for taking the screenshots is very straightforward:
ENTIRE PAGE
Screenshot screenshot = new AShot()
.shootingStrategy(new ViewportPastingStrategy(1000))
.takeScreenshot(driver);
ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\results.png"));
SPECIFIC WEB ELEMENT
Screenshot screenshot = new AShot()
.takeScreenshot(driver, driver.findElement(By.xpath("(//div[#id='ct_search'])[1]")));
ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\div_element.png"));
See more details and more code samples on this article.
In Node.js, I wrote the following code which works but it is not based on selenium's official WebDriverJS, but based on SauceLabs's WebDriver: WD.js and a very compact image library called EasyImage.
I just wanna emphasize that you cannot really take the screenshot of an element but what you should do is to first, take the screenshot of the whole page, then select the part of the page you like and crop that specific part:
browser.get(URL_TO_VISIT)
.waitForElementById(dependentElementId, webdriver.asserters.isDisplayed, 3000)
.elementById(elementID)
.getSize().then(function(size) {
browser.elementById(elementID)
.getLocation().then(function(location) {
browser.takeScreenshot().then(function(data) {
var base64Data = data.replace(/^data:image\/png;base64,/, "");
fs.writeFile(filePath, base64Data, 'base64', function(err) {
if (err) {
console.log(err);
}
else {
cropInFile(size, location, filePath);
}
doneCallback();
});
});
});
});
And the cropInFileFunction, goes like this:
var cropInFile = function(size, location, srcFile) {
easyimg.crop({
src: srcFile,
dst: srcFile,
cropwidth: size.width,
cropheight: size.height,
x: location.x,
y: location.y,
gravity: 'North-West'
},
function(err, stdout, stderr) {
if (err) throw err;
});
};
For everyone asking for code in C#, below is a simplified version of my implementation.
public static void TakeScreenshot(IWebDriver driver, IWebElement element)
{
try
{
string fileName = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".jpg";
Byte[] byteArray = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray;
System.Drawing.Bitmap screenshot = new System.Drawing.Bitmap(new System.IO.MemoryStream(byteArray));
System.Drawing.Rectangle croppedImage = new System.Drawing.Rectangle(element.Location.X, element.Location.Y, element.Size.Width, element.Size.Height);
screenshot = screenshot.Clone(croppedImage, screenshot.PixelFormat);
screenshot.Save(String.Format(#"C:\SeleniumScreenshots\" + fileName, System.Drawing.Imaging.ImageFormat.Jpeg));
}
catch (Exception e)
{
logger.Error(e.StackTrace + ' ' + e.Message);
}
}
I wasted a lot of time on taking screenshot and I want to save yours.
I have used chrome + selenium + c# the result was totally horrible. Finally i wrote a function :
driver.Manage().Window.Maximize();
RemoteWebElement remElement = (RemoteWebElement)driver.FindElement(By.Id("submit-button"));
Point location = remElement.LocationOnScreenOnceScrolledIntoView;
int viewportWidth = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientWidth"));
int viewportHeight = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientHeight"));
driver.SwitchTo();
int elementLocation_X = location.X;
int elementLocation_Y = location.Y;
IWebElement img = driver.FindElement(By.Id("submit-button"));
int elementSize_Width = img.Size.Width;
int elementSize_Height = img.Size.Height;
Size s = new Size();
s.Width = driver.Manage().Window.Size.Width;
s.Height = driver.Manage().Window.Size.Height;
Bitmap bitmap = new Bitmap(s.Width, s.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, s);
bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
RectangleF part = new RectangleF(elementLocation_X, elementLocation_Y + (s.Height - viewportHeight), elementSize_Width, elementSize_Height);
Bitmap bmpobj = (Bitmap)Image.FromFile(filePath);
Bitmap bn = bmpobj.Clone(part, bmpobj.PixelFormat);
bn.Save(finalPictureFilePath, System.Drawing.Imaging.ImageFormat.Png);
Surya's answer works great if you don't mind involving disk IO. If you'd rather not, then this method may be better for you
private Image getScreenshot(final WebDriver d, final WebElement e) throws IOException {
final BufferedImage img;
final Point topleft;
final Point bottomright;
final byte[] screengrab;
screengrab = ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES);
img = ImageIO.read(new ByteArrayInputStream(screengrab));
//crop the image to focus on e
//get dimensions (crop points)
topleft = e.getLocation();
bottomright = new Point(e.getSize().getWidth(),
e.getSize().getHeight());
return img.getSubimage(topleft.getX(),
topleft.getY(),
bottomright.getX(),
bottomright.getY());
}
If you prefer you can skip declaring screengrab and instead doing
img = ImageIO.read(
new ByteArrayInputStream(
((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES)));
which is cleaner, but I left it in for clarity. You can then save it as a file or put it in a JPanel to your heart's content.
I think most of the answers here are over-engineered. The way i did it is through 2 helper methods, the first to wait for an element based on any selector; and the second to take a screenshot of it.
Note: We cast the WebElement to a TakesScreenshot instance, so we only capture that element in the image specifically. If you want the full page/window, you should cast driver instead.
Edit: I forgot to say that i'm using Java and Selenium v3 (but should be the same for v4)
WebDriver driver = new FirefoxDriver(); // define this somewhere (or chrome etc)
public <T> T screenshotOf(By by, long timeout, OutputType<T> type) {
return ((TakesScreenshot) waitForElement(by, timeout))
.getScreenshotAs(type);
}
public WebElement waitForElement(By by, long timeout) {
return new WebDriverWait(driver, timeout)
.until(driver -> driver.findElement(by));
}
And then just screenshot whatever u want like this :
long timeout = 5; // in seconds
/* Screenshot (to file) based on first occurence of tag */
File sc = screenshotOf(By.tagName("body"), timeout, OutputType.FILE);
/* Screenshot (in memory) based on CSS selector (e.g. first image in body
who's "src" attribute starts with "https") */
byte[] sc = screenshotOf(By.cssSelector("body > img[href^='https']"), timeout, OutputType.BYTES);
Python 3
Tried with Selenium 3.141.0 and chromedriver 73.0.3683.68, this works,
from selenium import webdriver
chromedriver = '/usr/local/bin/chromedriver'
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument('window-size=1366x768')
chromeOptions.add_argument('disable-extensions')
cdriver = webdriver.Chrome(options=chromeOptions, executable_path=chromedriver)
cdriver.get('url')
element = cdriver.find_element_by_css_selector('.some-css.selector')
element.screenshot_as_png('elemenent.png')
No need to get a full image and get a section of a fullscreen image.
This might not have been available when Rohit's answer was created.
public void GenerateSnapshot(string url, string selector, string filePath)
{
using (IWebDriver driver = new ChromeDriver())
{
driver.Navigate().GoToUrl(url);
var remElement = driver.FindElement(By.CssSelector(selector));
Point location = remElement.Location;
var screenshot = (driver as ChromeDriver).GetScreenshot();
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
{
using (Bitmap bitmap = new Bitmap(stream))
{
RectangleF part = new RectangleF(location.X, location.Y, remElement.Size.Width, remElement.Size.Height);
using (Bitmap bn = bitmap.Clone(part, bitmap.PixelFormat))
{
bn.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
}
}
}
driver.Close();
}
}
If you are looking for a JavaScript solution, here's my gist:
https://gist.github.com/sillicon/4abcd9079a7d29cbb53ebee547b55fba
The basic idea is the same, take the screen shot first, then crop it.
However, my solution will not require other libraries, just pure WebDriver API code. However, the side effect is that it may increase the load of your testing browser.
Here is an extension function for C#:
public static BitmapImage GetElementImage(this IWebDriver webDriver, By by)
{
var elements = webDriver.FindElements(by);
if (elements.Count == 0)
return null;
var element = elements[0];
var screenShot = (webDriver as ITakesScreenshot).GetScreenshot();
using (var ms = new MemoryStream(screenShot.AsByteArray))
{
Bitmap screenBitmap;
screenBitmap = new Bitmap(ms);
return screenBitmap.Clone(
new Rectangle(
element.Location.X,
element.Location.Y,
element.Size.Width,
element.Size.Height
),
screenBitmap.PixelFormat
).ToBitmapImage();
}
}
Now you can use it to take the image of any element like this:
var image = webDriver.GetElementImage(By.Id("someId"));
Consider using needle - tool for automated visual comparison
https://github.com/bfirsh/needle ,
which has built-in functionality that allows to take screenshots of specific elements (selected by CSS selector). The tool works on Selenium's WebDriver and it's written in Python.
Below the function for taking snapshot a specific element in Selenium. Here the driver is a type of WebDriver.
private static void getScreenshot(final WebElement e, String fileName) throws IOException {
final BufferedImage img;
final Point topleft;
final Point bottomright;
final byte[] screengrab;
screengrab = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
img = ImageIO.read(new ByteArrayInputStream(screengrab));
topleft = e.getLocation();
bottomright = new Point(e.getSize().getWidth(), e.getSize().getHeight());
BufferedImage imgScreenshot=
(BufferedImage)img.getSubimage(topleft.getX(), topleft.getY(), bottomright.getX(), bottomright.getY());
File screenshotLocation = new File("Images/"+fileName +".png");
ImageIO.write(imgScreenshot, "png", screenshotLocation);
}
c# code:
public Bitmap MakeElemScreenshot( IWebDriver driver, WebElement elem)
{
Screenshot myScreenShot = ((ITakesScreenshot)driver).GetScreenshot();
Bitmap screen = new Bitmap(new MemoryStream(myScreenShot.AsByteArray));
Bitmap elemScreenshot = screen.Clone(new Rectangle(elem.Location, elem.Size), screen.PixelFormat);
screen.Dispose();
return elemScreenshot;
}
using System.Drawing;
using System.Drawing.Imaging;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
public void ScreenshotByElement()
{
IWebDriver driver = new FirefoxDriver();
String baseURL = "www.google.com/"; //url link
String filePath = #"c:\\img1.png";
driver.Navigate().GoToUrl(baseURL);
var remElement = driver.FindElement(By.Id("Butterfly"));
Point location = remElement.Location;
var screenshot = (driver as FirefoxDriver).GetScreenshot();
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
{
using (Bitmap bitmap = new Bitmap(stream))
{
RectangleF part = new RectangleF(location.X, location.Y, remElement.Size.Width, remElement.Size.Height);
using (Bitmap bn = bitmap.Clone(part, bitmap.PixelFormat))
{
bn.Save(filePath, ImageFormat.Png);
}
}
}
}
If you get an exception java.awt.image.RasterFormatException in chrome, or you want to scroll a element into view then capture a screenshot.
Here is a solution from #Surya answer.
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
Long offsetTop = (Long) jsExecutor.executeScript("window.scroll(0, document.querySelector(\""+cssSelector+"\").offsetTop - 0); return document.querySelector(\""+cssSelector+"\").getBoundingClientRect().top;");
WebElement ele = driver.findElement(By.cssSelector(cssSelector));
// Get entire page screenshot
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
// Get the location of element on the page
Point point = ele.getLocation();
// Get width and height of the element
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();
// Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), Math.toIntExact(offsetTop),
eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);
// Copy the element screenshot to disk
File screenshotLocation = new File("c:\\temp\\div_element_1.png");
FileUtils.copyFile(screenshot, screenshotLocation);
This is my version, in C#, I was basically get most part from Brook's answer and modified it to fit my purpose
public static byte[] GetElementImage(this IWebElement element)
{
var screenShot = MobileDriver.Driver.GetScreenshot();
using (var stream = new MemoryStream(screenShot.AsByteArray))
{
var screenBitmap = new Bitmap(stream);
var elementBitmap = screenBitmap.Clone(
new Rectangle(
element.Location.X,
element.Location.Y,
element.Size.Width,
element.Size.Height
),
screenBitmap.PixelFormat
);
var converter = new ImageConverter();
return (byte[]) converter.ConvertTo(elementBitmap, typeof(byte[]));
}
}
To take a screenshot for a specific element you can now just use this:
public void takeCanvasScreenshot(WebElement element, String imageName) {
File screenshot = element.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(screenshot, new File("src/main/resources/screenshots/" + imageName + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
}
For C#, below code can work .
try
{
IWebElement transactions = driver.FindElement(By.XPath(".//*[#id='some element']"));
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
string title = "some title";
screenshot.SaveAsFile(title, ScreenshotImageFormat.Jpeg);
}
catch (Exception)
{
// handle if element not found
}
I'm using a modified version of #Brook's answer and is working fine even for elements that needs the page to be scrolled.
public void TakeScreenshot(string fileNameWithoutExtension, IWebElement element)
{
// Scroll to the element if necessary
var actions = new Actions(_driver);
actions.MoveToElement(element);
actions.Perform();
// Get the element position (scroll-aware)
var locationWhenScrolled = ((RemoteWebElement) element).LocationOnScreenOnceScrolledIntoView;
var fileName = fileNameWithoutExtension + ".png";
var byteArray = ((ITakesScreenshot) _driver).GetScreenshot().AsByteArray;
using (var screenshot = new System.Drawing.Bitmap(new System.IO.MemoryStream(byteArray)))
{
var location = locationWhenScrolled;
// Fix location if necessary to avoid OutOfMemory Exception
if (location.X + element.Size.Width > screenshot.Width)
{
location.X = screenshot.Width - element.Size.Width;
}
if (location.Y + element.Size.Height > screenshot.Height)
{
location.Y = screenshot.Height - element.Size.Height;
}
// Crop the screenshot
var croppedImage = new System.Drawing.Rectangle(location.X, location.Y, element.Size.Width, element.Size.Height);
using (var clone = screenshot.Clone(croppedImage, screenshot.PixelFormat))
{
clone.Save(fileName, ImageFormat.Png);
}
}
}
The two ifs were necessary (at least for the chrome driver) because the size of the crop exceeded in 1 pixel the screenshot size, when scrolling was needed.
I believe this isn't going to work for you as you use C# and my solution includes a Java library, however maybe others will find it helpful.
For capturing custom screenshots you can use the Shutterbug library. The specific call for this purpose would be:
Shutterbug.shootElement(driver, element).save();
I followed the sample code from #codeslord, but for some reason I had to access my screenshot data differently:
# Open the Firefox webdriver
driver = webdriver.Firefox()
# Find the element that you're interested in
imagepanel = driver.find_element_by_class_name("panel-height-helper")
# Access the data bytes for the web element
datatowrite = imagepanel.screenshot_as_png
# Write the byte data to a file
outfile = open("imagepanel.png", "wb")
outfile.write(datatowrite)
outfile.close()
(using Python 3.7, Selenium 3.141.0 and Mozilla Geckodriver 71.0.0.7222)

Selenium WebDriver and Java Robot Class

I want to use the Java Robot class in order to move the mouse over a link to dynamically create more content. For the web interactions I use the Selenium WebDriver.
Point coordinates = driver.findElement(By.xpath("//li[#id='1234']/a")).getLocation();
Robot robot;
try {
robot = new Robot();
robot.mouseMove(coordinates.getX(),coordinates.getY()+120);
} catch (AWTException e1) {
e1.printStackTrace();
}
Selenium throws an error for the getLocation function:
Exception in thread "main" org.openqa.selenium.WebDriverException: Cannot determine size of element
Does anybody know what am I doing wrong?
mouseover action you can achieve (Actions class) without using Robot also.
new Actions(driver).moveToElement(driver.findElement(By.xpath("//li[#id='1234']/a"))).perform();
include below import statement in your file.
import org.openqa.selenium.interactions.Actions;
If you just want to make a mouse movement on the page, Selenium interactions can help you do the same.
Here is the sample code for you
WebElement myLink = driver.findElement(By.xpath("//li[#id='1234']/a"));
Actions act = new Actions(driver);
act.moveToElement(myLink).build().perform();
// if you want to click on the link :
act.click(myLink).build().perform();
// if you want to move to the element and then click onthe link :
act.moveToElement(myLink).click(myLink).build().perform();
// or can be done in two different steps like this :
act = act.moveToElement(myLink);
act.click(myLink).build().perform()
For doing this we should import org.openqa.selenium.interactions.Actions;
Hope this solves your problem.
I tried this and it seems to work for me. Please check
Point p = webele.getLocation();
int x = p.getX();
int y = p.getY();
Dimension d = webele.getSize();
int h = d.getHeight();
int w = d.getWidth();
Robot r = new Robot();
r.mouseMove(x + (w/2), y+(h/2) +80);

Categories