2013-05-28 4 views
15

Когда я делаю скриншоты с ChromeDriver, я получаю экраны с размером моего окна просмотра.
Когда я делаю скриншоты с FirefoxDriver, я получаю то, что хочу, это полноэкранный отпечаток веб-сайта.Selenium WebDriver C# Полный скриншоты сайта с ChromeDriver и 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); 

test.png ChromeDriver является в 1920x1099 и содержит только окно просмотра обозревателя.
Скачайте приложение FirefoxDriver's test.png с разрешением 1903x16559 и см. Всю страницу.

Я знаю, что метод GetScreenshot() не возвращает одинаковые размеры разрешения, поскольку он имеет несколько разные реализации в IEDriver, FirefoxDriver, OperaDriver, ChromeDriver.

Мои вопросы:

  1. Почему существует такая разница между ChromeDriver и метод FirefoxDriver в .GetScreenshot(), даже то они используют одинаковый интерфейс (ITakesScreenshot)?

  2. Есть ли способ заставить метод ChromeDriver GetScreenshot() вернуть весь экран веб-страницы, а не только окно просмотра?

ответ

4

Похоже, что полноэкранные скриншоты еще не реализованы в ChromeDriver из-за некоторых неточностей в его предыдущей реализации.

Источник: https://code.google.com/p/chromedriver/issues/detail?id=294

Я недавно написал заявление Selenium основы для тестирования Internet Explorer UI и обнаружил, что:

  1. Принимая скриншоты с селеном не так быстро, как с использованием .NET, и
  2. Selenium не может делать скриншоты при наличии диалоговых окон. Это был главный недостаток, так как мне нужно было идентифицировать неожиданные диалоги во время взаимодействия со страницами.

Изучите использование метода Graphics.CopyFromScreen в System.Drawing как альтернативное решение, пока эта функция не будет реализована в Chrome. Однако, если вы попытались использовать Net-подход, я не думаю, что вы оглядитесь назад =]

1

Я наткнулся на эту же проблему, и ChromeDriver2 просто не поддерживает ее.

Итак, я создал небольшой скрипт, который прокручивается через страницу, снимает скриншоты и сшивает все вместе.

Вы можете найти сценарий в моем блоге здесь: http://dev.flauschig.ch/wordpress/?p=341

+2

Обратите внимание, что [ссылка только ответы] (http://meta.stackoverflow.com/tags/link-only-answers/info) не рекомендуется, SO ответы должны быть в конечной точке в поиске решение (по сравнению с еще одной остановкой ссылок, которые со временем становятся устаревшими). Пожалуйста, подумайте о добавлении отдельного резюме здесь, сохранив ссылку в качестве ссылки. – kleopatra

9

мы не можем получить скриншот всей страницы с ChromeDriver2, мы должны пойти для ручного implementation.I модифицировал метод с доступно в блог, который отлично работает с 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; 
    } 
+1

Это отлично работало, должно быть ответом. – Sire

+0

При запуске этого скрипта возникает небольшая проблема, так как он управляет браузером при прокрутке веб-страницы, потому что это javascript-инъекция. В любом случае спасибо Roemer :) –

+1

у него также есть проблема с facebook .. или yahoo эти страницы показывают абсолютный div сверху, когда вы прокручиваете вниз, и этот div повторяется. любой, как отлично работает большинство веб-страниц. –

6

я вымыл ответ @Selvantharajah Roshanth и добавил чек, так что он не будет пытаться склеивать снимки экрана, которые уже подходят в окне просмотра.

public Image GetEntireScreenshot() 
{ 
    // Get the total size of the page 
    var totalWidth = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return document.body.offsetWidth"); //documentElement.scrollWidth"); 
    var totalHeight = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return document.body.parentNode.scrollHeight"); 
    // Get the size of the viewport 
    var viewportWidth = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return document.body.clientWidth"); //documentElement.scrollWidth"); 
    var viewportHeight = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return window.innerHeight"); //documentElement.scrollWidth"); 

    // We only care about taking multiple images together if it doesn't already fit 
    if (totalWidth <= viewportWidth && totalHeight <= viewportHeight) 
    { 
     var screenshot = driver.TakeScreenshot(); 
     return ScreenshotToImage(screenshot); 
    } 
    // Split the screen in multiple Rectangles 
    var rectangles = new List<Rectangle>(); 
    // Loop until the totalHeight is reached 
    for (var y = 0; y < totalHeight; y += viewportHeight) 
    { 
     var newHeight = viewportHeight; 
     // Fix if the height of the element is too big 
     if (y + viewportHeight > totalHeight) 
     { 
      newHeight = totalHeight - y; 
     } 
     // Loop until the totalWidth is reached 
     for (var x = 0; x < totalWidth; x += viewportWidth) 
     { 
      var newWidth = viewportWidth; 
      // Fix if the Width of the Element is too big 
      if (x + viewportWidth > totalWidth) 
      { 
       newWidth = totalWidth - x; 
      } 
      // Create and add the Rectangle 
      var currRect = new Rectangle(x, y, newWidth, newHeight); 
      rectangles.Add(currRect); 
     } 
    } 
    // Build the Image 
    var stitchedImage = new Bitmap(totalWidth, totalHeight); 
    // Get all Screenshots and stitch them together 
    var previous = Rectangle.Empty; 
    foreach (var rectangle in rectangles) 
    { 
     // Calculate the scrolling (if needed) 
     if (previous != Rectangle.Empty) 
     { 
      var xDiff = rectangle.Right - previous.Right; 
      var yDiff = rectangle.Bottom - previous.Bottom; 
      // Scroll 
      ((IJavaScriptExecutor) driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff)); 
     } 
     // Take Screenshot 
     var screenshot = driver.TakeScreenshot(); 
     // Build an Image out of the Screenshot 
     var screenshotImage = ScreenshotToImage(screenshot); 
     // Calculate the source Rectangle 
     var sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height); 
     // Copy the Image 
     using (var graphics = Graphics.FromImage(stitchedImage)) 
     { 
      graphics.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel); 
     } 
     // Set the Previous Rectangle 
     previous = rectangle; 
    } 
    return stitchedImage; 
} 

private static Image ScreenshotToImage(Screenshot screenshot) 
{ 
    Image screenshotImage; 
    using (var memStream = new MemoryStream(screenshot.AsByteArray)) 
    { 
     screenshotImage = Image.FromStream(memStream); 
    } 
    return screenshotImage; 
} 
+0

Отличный ответ! Я использую его в течение нескольких месяцев, но теперь обнаружил здесь небольшую ошибку. Например, если общая высота в 4 раза больше, чем область просмотра, вы получите скриншоты, состоящие из 4 изображений. Допустим, вы сбросили SS на тест. Если ваш тест завершится неудачно в нижней части страницы, вы получите только нижнюю часть, повторенную 4 раза. Требуется добавить команду для прокрутки вверху в начале и сделать полную страницу независимо от того, что тест остановлен внизу или сверху или в середине страницы: '((IJavaScriptExecutor) драйвер) .ExecuteScript (" window.scrollTo (0, 0) «)' – kotoj