Is it possible to capture a screen shot for a webelement directly by using WebDriver?

前端 未结 4 914
执笔经年
执笔经年 2021-01-13 07:46

At Interface TakesScreenshot page I found this:

Capture the screenshot and store it in the specified location. For WebDriver extending TakesScreens

相关标签:
4条回答
  • 2021-01-13 08:26
    public static Bitmap FullScreen { get; set; }
    public static Bitmap Image { get; set; }
    
    public static void TakeScreenShot(ChromeDriver driver, IWebElement element)
    {
        Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
    
        screenshot.SaveAsFile(Environment.CurrentDirectory + @"\screens\file.bmp", ImageFormat.Bmp);
    
        FullScreen = new Bitmap(Environment.CurrentDirectory + @"\screens\file.bmp");
    
        Size element_size = element.Size;
        Point element_location = element.Location;
    
        Rectangle rect = new Rectangle(element_location, element_size);
    
        Image = FullScreen.Clone(rect, PixelFormat.Format24bppRgb);
    
        Image.Save(Environment.CurrentDirectory + @"\screens\file2.bmp", ImageFormat.Bmp);
    
    }
    
    void Main()
    {
        ChromeDriver driver = new ChromeDriver();
    
        driver.Navigate().GoToUrl("http://domain.com");
    
        Thread.Sleep(1500);
        IWebElement _element = driver.findElementById("ElementIdGoesHere");
        TakeScreenShot(driver, _element);
    }
    

    This code will take full screenshot of the page, then it will look for the _element location and the image will be saved to the disk using the rectangle size of the element.

    0 讨论(0)
  • 2021-01-13 08:28

    Try this

    WebDriver driver = new FirefoxDriver();
    WebElement webElement = driver.findElements(By.xpath("//html")).get(0);
    
    File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    BufferedImage img = ImageIO.read(screen);
    
    File f = new File('element.png');
    
    Point p = webElement.getLocation();
    int width = webElement.getSize().getWidth();
    int height = webElement.getSize().getHeight();
    BufferedImage dest = img.getSubimage(p.getX(), p.getY(), width, height);
    ImageIO.write(dest, "png", f);
    

    Then, after you verify this works, replace the webElement with your own element. Run this code first just to make sure your webdriver has the screen shot capability and that your file io works as expected (ie you will discover where the files are saved).

    What this does is capture a screenshot, saves it to file. Then, reads that file as an image and grabs a subimage based on the position of the element. Then, it saves that sub image to file. This requires two file writes and a file read (so there would probably be a good optimization for this).

    0 讨论(0)
  • 2021-01-13 08:31

    Following the idea of @Anders, in Java - no javascript required (using javaPng):

    byte[] imageBytes = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.BYTES);
    BufferedImage img = new PngImage().read(new ByteArrayInputStream(imageBytes), true);
    
    //set element to the required webElement
    BufferedImage crop = img.getSubimage(element.getLocation().x, 
        element.getLocation().y, element.getSize().width, element.getSize().height);
    
    0 讨论(0)
  • 2021-01-13 08:42

    The documentation would indicate that it is supported, but in practice, it does not work (at least not with the .Net bindings):

    var screenshotTaker = element as ITakesScreenshot;
    var image = screenshotTaker.GetScreenshot();
    image.SaveAsFile(fileName, ImageFormat.Jpeg); // << null exception thrown here
    

    There is a workaround that has worked for me - execute javascript on the page to get the location of the element:

    const string javascript = "return arguments[0].getBoundingClientRect()";
    var obj = (Dictionary<string, object>)((IJavaScriptExecutor)_core.Driver).ExecuteScript(javascript, element);
    var rect = new Rectangle((int)double.Parse(obj["left"].ToString()),
                             (int)double.Parse(obj["top"].ToString()),
                             (int)double.Parse(obj["width"].ToString()),
                             (int)double.Parse(obj["height"].ToString()));
    

    That will give you the location of the element within the viewport, at which point you can take a screenshot of the entire page and crop it down to just the bounds of the element.

    Hopefully that helps...

    0 讨论(0)
提交回复
热议问题