2011-12-27 88 views
5

Interface TakesScreenshot頁,我發現這一點:是否可以直接使用WebDriver捕獲webelement的屏幕截圖?

捕獲截圖並將其存儲在指定的位置。對於 webdriver的延伸TakesScreenshot,這使得盡力而爲 根據瀏覽器返回以下中 優選順序: - 整個頁 - 當前窗口 - 當前幀的可見部分 - 包含 整個顯示器的屏幕截圖瀏覽器

延長TakesScreenshot WebElement,這使得盡力而爲 根據瀏覽器返回以下的 優先順序: - HTML元素的全部內容 - HTML元素的visisble 部分。

所以我想知道它應該支持捕捉webelement的截圖,但是現在找不到與此支持相關的任何文檔。不知道它是否真的支持。

有人知道關於這方面的更多細節嗎?謝謝。

回答

1

該文件將表明它是支持,但在實踐中,它不會(與淨綁定至少不會)工作:

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

這會給你的元素的位置的視窗內,此時你可以把整個頁面的截圖和裁剪道n只是元素的邊界。

希望幫助...

+1

WebElement類本身不具有top,left,width和height的方法嗎?看起來像Java綁定一樣:元素。getLocation()。getX(),element.getSize()。getWidth()等等,但是你提供這段代碼片段是很好的。對於原生沒有這些信息的語言綁定可能很有用。 – David 2013-01-24 01:50:23

1

繼@Anders的想法,在Java中 - (使用javaPng)不需要的javascript:

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

對於這種類型的實現,我有時會遇到類似「RasterFormatException:(x + width)在Raster之外」的異常。但它不會一直髮生。我只是使用元素座標和大小,所以沒有辦法可能是錯誤的。有趣的是,使用其他庫如http://www.javaxt.com/javaxt-core/javaxt.io.Image/沒有問題 – David 2014-04-14 20:15:14

0

試試這個

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按預期工作(即您將發現保存文件的位置)。

這是做什麼捕獲截圖,將其保存到文件。然後,將該文件作爲圖像讀取,並根據元素的位置抓取子圖像。然後,它將該子圖像保存到文件中。這需要兩個文件寫入和一個文件讀取(所以這可能會有一個很好的優化)。

1
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位置和圖像將使用元素的矩形大小被保存到磁盤。

相關問題