13

I'd like to capture the screenshot of the options that are displayed in the dropdown using selenium c# just like the image that is displayed below.

enter image description here

I've tried multiple ways to take the screenshot. Basically I've to expand the dropdown of the element to capture the screenshot. Here is what I've done

//#1
var element = Driver.FindElement(By.Id("carsId"));
Actions builder = new Actions(Driver);
builder.SendKeys(element, Keys.LeftAlt + Keys.Down).Build().Perform();

//#2
Actions act = new Actions(Driver);
act.MoveToElement(element).Build().Perform();

The first implementation to press Alt + Down keys worked manually when I've done on the site but didn't work through selenium. The second implementation didn't work either. I've also tried builder.ClickAndHold() method as well.

And I've another question over here. Is it really possible for selenium to click and expand for a while until to grab the screen?

Any help would be greatly appreciated.

Karthik Chintala
  • 5,465
  • 5
  • 30
  • 60
  • Is there some reason you don't want to just pull the text of the options and write that to a log instead of the screenshot? – JeffC Nov 21 '15 at 06:27
  • @JeffC I'm able to pull the options for the dropdown and write it to the log, but my client needs a screenshot of the list of options – Karthik Chintala Nov 23 '15 at 09:02
  • @KarthikChintala Have you taken the screenshot already? what is the issue there? – Manu Nov 23 '15 at 10:48
  • @Manu I didn't. I want to. The issue is with taking the screenshot with the dropdown options. I don't need the list of options, but a screenshot of those options just as shown in the image. – Karthik Chintala Nov 23 '15 at 10:50
  • 1
    @KarthikChintala Can u pls add how the screen look like and the DOM structure of the options? Also, I understand that u only need the web element screenshot, right? – Manu Nov 23 '15 at 10:56
  • @Manu I need the screenshot with options as attached in the question, not the web element. No big DOM structure. You can assume a dom with html tag and a dropdown with id as `carsId` – Karthik Chintala Nov 23 '15 at 11:29
  • @Manu I'm not bothered about the web element screenshot or the entire page screenshot at the moment. But what I need is to take screenshot when the dropdown menu expands when clicked (which shows list of items) – Karthik Chintala Nov 23 '15 at 11:37

3 Answers3

3

I don't think it'll be possible for normal drop downs. Since the overlay with the options you can choose from are displayed inside a native control and outside of the context of what selenium can work with. For this, you'll need some separate process or tool that can capture the screenshot of the desktop or application it self.

Link

Now, to capture the screenshot of desktop/application, we use Robot objects in Java.

For C#, you can use methods suggested in Capture screenshot of active window?.

Robot Sample Code:

try {

    //Get the size of the screen stored in toolkit object
    Toolkit tk = Toolkit.getDefaultToolkit();
    Dimension d = tk.getScreenSize();

    //Create Rectangle object using height and width of screen
    //Here entire screen is captured, change it if you need particular area
    Rectangle rect = new Rectangle(0, 0, d.width, d.height);  

    //Creates an image containing pixels read from the screen 
    Robot r = new Robot();
    BufferedImage img = r.createScreenCapture(rect);

    //Write the above generated buffered image to a file
    File f = new File("myimage.jpg");

    //Convert BufferedImage to a png/jpg image
    ImageIO.write(img, "jpg", f);

} catch (Exception e) {
    System.out.println(e.getMessage());
}

This will take the screenshot of the entire screen and save it into the file on given file location.

Selenium can only take screenshot of options in custom dropdowns made using Javascript/CSS and not in select dropdown.

Let me know if above code works or you need more help.

Community
  • 1
  • 1
Manu
  • 2,251
  • 19
  • 30
  • Thanks for your answer Manu. I know taking a screenshot for the entire page and for a particular element. I've read the Quote that you've addressed in the answer. I thought if there is any other way to click the dropdown so that it expands and then take screenshot of the page. – Karthik Chintala Nov 23 '15 at 12:59
  • The thing is you cannot take screenshot with expanded select dropdown using selenium. That's the limitation. – Manu Nov 23 '15 at 13:21
  • Thanks you for your effort. I did manage to get the options in the dropdown clicked, but selenium is unable to grab the screenshot of the page with the options expanded. And yeah, looks like selenium can't grab those screenshots. – Karthik Chintala Nov 30 '15 at 09:06
2

Its really easy to do WITHOUT ANY ADDITIONAL TOOLS, believe me.

All you need is to do the following steps after click on Select element:

  1. Make page screenshot
  2. Get your Select element position (its coordinates on the page)
  3. Get last Option element position
  4. Get last Option element size
  5. Create new Rectangle with position the same as have select and

    var screenshotSize = lastOption.Position - Select.Position;

    screenShotSize.height += lastOption.Size.Height;

  6. Cut-off all except this Rectangle from the screenshot

In case of c# you can use for #6 the following code

Bitmap ScreenshotOfSelect = browserScreenshot.Clone(new Rectangle(point, size), screen.PixelFormat);

And as result you will receive bitmap that contains exactly only expanded Select =)

so as you see, its really-really easy to do =) And you don't need any tools except selenium. And also browser window can be invisible at the moment (as exmample in case of using phantomJS)

Andrew_STOP_RU_WAR_IN_UA
  • 9,318
  • 5
  • 65
  • 101
1

To open the dropdown you just have to .Click() the element. So in your case,

IWebElement element = Driver.FindElement(By.Id("carsId"));
element.Click();

will expand the dropdown. The problem is that Selenium's screenshot functionality does not capture the open dropdown. You can get around that by using .NET to just take a screenshot of the active window. Working example code below.

static void Main(string[] args)
{
    IWebDriver Driver = new FirefoxDriver();
    Driver.Navigate().GoToUrl("http://www.tutorialspoint.com/html/html_select_tag.htm");
    Driver.Manage().Window.Maximize();
    IWebElement element = Driver.FindElement(By.Name("dropdown"));
    element.Click();
    TakeScreenShotOfWindow(@"C:\sshot.png");
}

// from http://stackoverflow.com/a/363008/2386774
public static void TakeScreenShotOfWindow(string filePath)
{
    // Create a new bitmap.
    var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

    // Create a graphics object from the bitmap.
    var gfxScreenshot = Graphics.FromImage(bmpScreenshot);

    // Take the screenshot from the upper left corner to the right bottom corner.
    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

    // Save the screenshot to the specified path that the user has chosen.
    bmpScreenshot.Save(filePath, ImageFormat.Png);
}
JeffC
  • 22,180
  • 5
  • 32
  • 55
  • Let's be picky :-) This is a screenshot of the screen, not the browser window, plus the browser window could be on another screen (secondary monitor, ...). – Simon Mourier Nov 24 '15 at 20:00
  • OK... if the browser is on the screen, then it's a screenshot of the browser. :) Yes, it's possible that the browser might run on a different screen. My guess is it's run on a lab machine and probably only has one monitor. You could also control which screen the browser comes up on. The straightforward way doesn't work but this does satisfy as an answer to the question and is extremely simple to implement. – JeffC Nov 24 '15 at 23:56
  • Old post but this is actually the best solution I've seen for C#. Using the commonly quoted Screenshot.Clone method often results in an out of memory exception whereas this approach does not. You can also use it to take a screenshot of a particular element instead of the whole screen using the element's X & Y values etc – Phonesis Mar 07 '17 at 11:33