【问题标题】:Is it possible to capture a screen shot for a webelement directly by using WebDriver?是否可以使用 WebDriver 直接捕获 web 元素的屏幕截图?
【发布时间】:2011-12-27 08:01:23
【问题描述】:

Interface TakesScreenshot 页面我发现了这个:

截取屏幕截图并将其存储在指定位置。为了 WebDriver 扩展 TakesScreenshot,这是尽最大努力 根据浏览器按顺序返回以下内容 首选项: - 整个页面 - 当前窗口 - 可见部分 当前帧 - 包含 浏览器

对于扩展 TakesScreenshot 的 WebElement,这是尽最大努力 根据浏览器按顺序返回以下内容 首选项: - HTML 元素的全部内容 - 可见的 HTML 元素的一部分。

所以我想知道它应该支持捕获 web 元素的屏幕截图,但现在找不到任何与此支持相关的文档。不确定它是否真的支持。

有人知道这方面的更多细节吗?谢谢。

【问题讨论】:

    标签: selenium webdriver


    【解决方案1】:

    文档表明它支持,但在实践中,它不起作用(至少不适用于 .Net 绑定):

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

    有一个对我有用的解决方法 - 在页面上执行 javascript 以获取元素的位置:

    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()));
    

    这将为您提供元素在视口中的位置,此时您可以截取整个页面的屏幕截图并将其裁剪到元素的边界。

    希望对您有所帮助...

    【讨论】:

    • WebElement 类本身就没有top、left、width 和height 的方法吗?似乎 Java 绑定确实如此:element.getLocation().getX()、element.getSize().getWidth() 等。但最好提供此代码 sn-p。它对于本机没有该信息的语言绑定可能很有用。
    【解决方案2】:

    遵循@Anders 的想法,在 Java 中 - 不需要 javascript(使用 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);
    

    【讨论】:

    • 对于这种类型的实现,我有时会遇到“RasterFormatException: (x + width) is outside Raster”之类的异常。但它不会一直发生。我只是使用元素坐标和大小,所以这不可能是错误的。有趣的是,使用 javaxt.com/javaxt-core/javaxt.io.Image 等其他库没有问题
    【解决方案3】:
    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);
    }
    

    此代码将截取页面的完整屏幕截图,然后它将查找_element 位置,并将使用元素的矩形大小将图像保存到磁盘。

    【讨论】:

      【解决方案4】:

      试试这个

      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);
      

      然后,在您验证此操作后,将 webElement 替换为您自己的元素。首先运行此代码只是为了确保您的 webdriver 具有屏幕截图功能并且您的文件 io 按预期工作(即您将发现文件的保存位置)。

      它的作用是截取屏幕截图,将其保存到文件中。然后,将该文件作为图像读取并根据元素的位置抓取子图像。然后,它将该子图像保存到文件中。这需要两次文件写入和一次文件读取(因此可能会对此进行很好的优化)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 1970-01-01
        • 2012-10-26
        • 2023-01-23
        • 2018-03-30
        相关资源
        最近更新 更多