others - Selenium WebDriver C# 完整网站截图,ChromeDriver和 FirefoxDriver

当我用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

...