隐藏

Selenium WebDriver C# 完整網站截圖,ChromeDriver和 FirefoxDriver

发布:2021/2/19 17:50:09作者:管理员 来源:本站 浏览次数:968

當我用ChromeDriver拍攝屏幕截圖時,屏幕上顯示的是我的viewport ,
當我用FirefoxDriver拍照時,是全屏網站,得到了我想要的。

ChromeDriver的聲明方式如下:

 IWebDriver driver = new ChromeDriver(); 

FirefoxDriver的聲明方式如下:

 IWebDriver driver = new FirefoxDriver(); 

兩個驅動程序執行相同的代碼:

driver.Manage().Window.Maximize();

driver.Navigate().GoToUrl(url);//url is a string variable

ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;

Screenshot screenshot = screenshotDriver.GetScreenshot();

screenshot.SaveAsFile("c:/test.png", ImageFormat.Png);

ChromeDriver的test png解析度為1920x1099,僅包含瀏覽器viewport ,

FirefoxDriver的test png解析度為1903x16559,包含整個頁面。

因為GetScreenshot()方法在IEDriver,FirefoxDriver,OperaDriver,ChromeDriver和中的實現略有不同,所以我知道方法不返回相同的解析度。

我的問題是:

  1. 為什麼FirefoxDriver方法的ChromeDriver .GetScreenshot()之間存在這樣的差別,即使它們使用了相同的介面(ITakesScreenshot )?

  2. 有沒有方法使ChromeDriver方法的GetScreenshot()返回整個網頁屏幕而不是只返回viewport?

时间:

無法使用ChromeDriver2來獲取整個頁面的屏幕截圖,我們需要進行手動實施,我修改了一種方法,該方法可在博客中找到,該方法可與ChromeDriver很好地配合使用。

如下所示使用此方法:

private IWebDriver _driver = new ChromeDriver(CHROME_DRIVER_PATH);

screenshot.SaveAsFile(saveFileName, ImageFormat.Jpeg);


public Bitmap GetEntereScreenshot()

{


Bitmap stitchedImage = null;

try

{

long totalwidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.offsetWidth");//documentElement.scrollWidth");


long totalHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.parentNode.scrollHeight");


int totalWidth = (int)totalwidth1;

int totalHeight = (int)totalHeight1;


// Get the Size of the Viewport

long viewportWidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.clientWidth");//documentElement.scrollWidth");

long viewportHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return window.innerHeight");//documentElement.scrollWidth");


int viewportWidth = (int)viewportWidth1;

int viewportHeight = (int)viewportHeight1;



// Split the Screen in multiple Rectangles

List<Rectangle> rectangles = new List<Rectangle>();

// Loop until the Total Height is reached

for (int i = 0; i < totalHeight; i += viewportHeight)

{

int newHeight = viewportHeight;

// Fix if the Height of the Element is too big

if (i + viewportHeight > totalHeight)

{

newHeight = totalHeight - i;

}

// Loop until the Total Width is reached

for (int ii = 0; ii < totalWidth; ii += viewportWidth)

{

int newWidth = viewportWidth;

// Fix if the Width of the Element is too big

if (ii + viewportWidth > totalWidth)

{

newWidth = totalWidth - ii;

}


// Create and add the Rectangle

Rectangle currRect = new Rectangle(ii, i, newWidth, newHeight);

rectangles.Add(currRect);

}

}


// Build the Image

stitchedImage = new Bitmap(totalWidth, totalHeight);

// Get all Screenshots and stitch them together

Rectangle previous = Rectangle.Empty;

foreach (var rectangle in rectangles)

{

// Calculate the Scrolling (if needed)

if (previous != Rectangle.Empty)

{

int xDiff = rectangle.Right - previous.Right;

int yDiff = rectangle.Bottom - previous.Bottom;

// Scroll

//selenium.RunScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));

((IJavaScriptExecutor)_driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));

System.Threading.Thread.Sleep(200);

}


// Take Screenshot

var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();


// Build an Image out of the Screenshot

Image screenshotImage;

using (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))

{

screenshotImage = Image.FromStream(memStream);

}


// Calculate the Source Rectangle

Rectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);


// Copy the Image

using (Graphics g = Graphics.FromImage(stitchedImage))

{

g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);

}


// Set the Previous Rectangle

previous = rectangle;

}

}

catch (Exception ex)

{

// handle

}

return stitchedImage;

}


我最近編寫了一個基於selenium的應用程序來測試IE用戶界面,並發現:

  1. 用selenium截圖並不像使用.NET那樣快
  2. 當對話框出現時,selenium無法拍攝屏幕截圖,

在System.Drawing中使用Graphics.CopyFromScreen方法作為替代解決方案,直到該特性在Chrome中實現。 一旦你嘗試過Net方法,我認為你不會回頭用它。

我偶然發現了同樣的問題,ChromeDriver2不支持它。

所以我創建了一個小腳本,通過頁面滾動,拍攝和縫合一切。

你可以在我的博客帖子中找到該腳本: http://dev.flauschig.ch/wordpress/?p=341