Selenium WebDriver C# Full Website Screenshots With ChromeDriver and FirefoxDriver

后端 未结 4 1941
北荒
北荒 2020-11-30 05:27

When I take screenshots with ChromeDriver I get screens with the size of my viewport.
When I take screenshots with FirefoxDriver I get what I want, which is a full scree

相关标签:
4条回答
  • 2020-11-30 05:30

    I cleaned up @Selvantharajah Roshanth's answer and added a check so that it won't try to stitch together screenshots that already fit in the viewport.

    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 讨论(0)
  • 2020-11-30 05:33

    we can't get the entire page screenshot with ChromeDriver2, we need to go for manual implementation.I have modified a method with is available in a blog which works fine with ChromeDriver.

    use this method as following :

    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;
        }
    
    0 讨论(0)
  • 2020-11-30 05:36

    It appears as though full-screen screenshots are not yet implemented in the ChromeDriver, due to some inaccuracies in its previous implementation.

    Source: https://code.google.com/p/chromedriver/issues/detail?id=294

    I have recently written a Selenium based application to test an Internet Explorer UI and found that:

    1. Taking screenshots with selenium was not as quick as using .NET, and
    2. Selenium is unable to take screenshots when dialog boxes are present. This was a major drawback, as I needed to identify unexpected dialogs during interaction with the pages.

    Investigate using the Graphics.CopyFromScreen method in System.Drawing as an alternative solution until the feature is implemented in Chrome. Once you have tried .the Net approach however, I don't think you will look back =]

    0 讨论(0)
  • 2020-11-30 05:49

    I stumbled accross the same problem and ChromeDriver2 just does not support it.

    So I created a little script which scrolls thru the page, takes screenshots and stitches everything together.

    You can find the script in my blog post here: http://dev.flauschig.ch/wordpress/?p=341

    0 讨论(0)
提交回复
热议问题