如何使用Selenium和C#捕获整个页面截图

时间:2014-04-02 19:55:39

标签: c# selenium

我使用以下方法截取屏幕截图,并注意到所有屏幕截图图像都没有捕获整个窗口,而是裁剪窗口。例如,我将获得一个.jpg,我无法看到屏幕上可见的整个网页。我怀疑当DOM中不可见某些元素并因此未包含在屏幕截图中时会发生这种情况。这是预期的行为吗?如果这是预期的,有没有办法编程驱动程序一致地使用Selenium 32位Internet Explorer驱动程序进行全屏捕获?这是我打电话截取屏幕截图的方法。

public static void TakeScreenshot(IWebDriver driver, string saveLocation)
{
    ITakesScreenshot ssdriver = driver as ITakesScreenshot;
    Screenshot screenshot = ssdriver.GetScreenshot();
    screenshot.SaveAsFile(saveLocation, ImageFormat.png);
}

3 个答案:

答案 0 :(得分:3)

这是我用来捕捉整个屏幕的内容:

Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
    using (Graphics g = Graphics.FromImage(bitmap))
    {
        g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
    }
    bitmap.Save(saveLocation, System.Drawing.Imaging.ImageFormat.Png);
}

答案 1 :(得分:3)

决议:

  1. 检测网页是否可以在当前浏览器上显示
    1. 如果当前窗口截图足够,则使用当前浏览器窗口的屏幕截图
    2. 如果当前页面包含滚动条,则通过相应滚动页面拍摄每个窗口的屏幕截图,并剪切屏幕截图以将所有屏幕截图组合在一起
  2. 为整页截图设置代码:

    using System.Linq;
    using System.Threading;
    using OpenQA.Selenium;
    using DotRez.Utilities.WebDriver;
    using System.Drawing;
    using System.Drawing.Imaging;
    // decide take full screenshot and take current window screenshot according to the height 
    public static void TakeSnapshot()
            {
    
                IJavaScriptExecutor js = Driver as IJavaScriptExecutor;
                var fileName = ScenarioContext.Current.ScenarioInfo.Title.ToIdentifier() + DateTime.Now.ToString("HH_mm_ss") + "JS" + ".png";
                var fileLocation = Path.Combine(Configuration.SCREEN_SHOT_LOCATION, fileName);
                Image finalImage;
                // get the full page height and current browser height
                string getCurrentBrowserSizeJS =
                    @"
    
                    window.browserHeight = (window.innerHeight || document.body.clientHeight);
                    window.headerHeight= document.getElementById('site-header').clientHeight;;
                    window.fullPageHeight = document.body.scrollHeight;
                ";
                js.ExecuteScript(getCurrentBrowserSizeJS);
    
    
                // * This is async operation. So we have to wait until it is done.
                string getSizeHeightJS = @"return window.browserHeight;";
                int contentHeight = 0;
                while (contentHeight == 0)
                {
                    contentHeight = Convert.ToInt32(js.ExecuteScript(getSizeHeightJS));
                    if (contentHeight == 0) System.Threading.Thread.Sleep(10);
                }
    
                string getContentHeightJS = @"return window.headerHeight;";
                int siteHeaderHeight = 0;
                while (siteHeaderHeight == 0)
                {
                    siteHeaderHeight = Convert.ToInt32(js.ExecuteScript(getContentHeightJS));
                    if (siteHeaderHeight == 0) System.Threading.Thread.Sleep(10);
                }
    
                string getFullPageHeightJS = @"return window.fullPageHeight";
                int fullPageHeight = 0;
                while (fullPageHeight == 0)
                {
                    fullPageHeight = Convert.ToInt32(js.ExecuteScript(getFullPageHeightJS));
                    if (fullPageHeight == 0) System.Threading.Thread.Sleep(10);
                }
    
                if (contentHeight == fullPageHeight)
                {
                    TakeSnapshotCurrentPage();
    
                }
                else
                {
                    int scollEachHeight = contentHeight - siteHeaderHeight;
                    int shadowAndBorder = 3;
                    int scollCount = 0;
                    int existsIf = (fullPageHeight - siteHeaderHeight) % scollEachHeight;
                    bool cutIf = true;
    
                    if (existsIf == 0)
                    {
                        scollCount = (fullPageHeight - siteHeaderHeight) / scollEachHeight;
                        cutIf = false;
                    }
                    else
                    {
                        scollCount = (fullPageHeight - siteHeaderHeight) / scollEachHeight + 1;
                        cutIf = true;
                    }
    
    
                    // back to top start screenshot
                    string scollToTopJS = "window.scrollTo(0, 0)";
                    js.ExecuteScript(scollToTopJS);
    
                    Byte[] imageBaseContent = ((ITakesScreenshot)Driver).GetScreenshot().AsByteArray;
                    Image imageBase;
                    using (var ms = new MemoryStream(imageBaseContent))
                    {
                        imageBase = Image.FromStream(ms);
                    }
    
                    finalImage = imageBase;
    
                    string scrollBar = @"window.scrollBy(0, window.browserHeight-window.headerHeight);";
                    for (int count = 1; count < scollCount; count++)
                    {
    
                        js.ExecuteScript(scrollBar);
                        Thread.Sleep(500);
                        Byte[] imageContentAdd = ((ITakesScreenshot)Driver).GetScreenshot().AsByteArray;
                        Image imageAdd;
                        using (var msAdd = new MemoryStream(imageContentAdd))
                        {
                            imageAdd = Image.FromStream(msAdd);
                        }
    
                        imageAdd.Save(fileLocation, ImageFormat.Png);
                        Bitmap source = new Bitmap(imageAdd);
                        int a = imageAdd.Width;
                        int b = imageAdd.Height - siteHeaderHeight;
                        PixelFormat c = source.PixelFormat;
    
    
                        // cut the last screen shot if last screesshot override with sencond last one
                        if ((count == (scollCount - 1)) && cutIf)
                        {
    
                            Bitmap imageAddLastCut =
                                source.Clone(new System.Drawing.Rectangle(0, contentHeight - existsIf, imageAdd.Width, existsIf), source.PixelFormat);
    
                            finalImage = combineImages(finalImage, imageAddLastCut);
    
                            source.Dispose();
                            imageAddLastCut.Dispose();
                        }
                        //cut the site header from screenshot
                        else
                        {
                            Bitmap imageAddCutHeader =
                                source.Clone(new System.Drawing.Rectangle(0, (siteHeaderHeight + shadowAndBorder), imageAdd.Width, (imageAdd.Height - siteHeaderHeight - shadowAndBorder)), source.PixelFormat);
                            finalImage = combineImages(finalImage, imageAddCutHeader);
    
                            source.Dispose();
                            imageAddCutHeader.Dispose();
                        }
    
                        imageAdd.Dispose();
    
                    }
    
                    finalImage.Save(fileLocation, ImageFormat.Png);
                    imageBase.Dispose();
                    finalImage.Dispose();
    
                }
            }
    
    //combine two pictures
            public static Bitmap combineImages(Image image1, Image image2)
            {
                Bitmap bitmap = new Bitmap(image1.Width, image1.Height + image2.Height);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.DrawImage(image1, 0, 0);
                    g.DrawImage(image2, 0, image1.Height);
                }
    
                return bitmap;
            }
    
    // take current window screenshot  
          private static void TakeSnapshotCurrentPage()
            {
                try
                {
                    var screenshot = ((ITakesScreenshot)Driver).GetScreenshot();
                    var urlStr = Driver.Url;
                    var fileName = ScenarioContext.Current.ScenarioInfo.Title.ToIdentifier() + DateTime.Now.ToString("HH_mm_ss") + ".png";
                    var fileLocation = Path.Combine(Configuration.SCREEN_SHOT_LOCATION, fileName);
    
                    if (!Directory.Exists(Configuration.SCREEN_SHOT_LOCATION))
                    {
                        Directory.CreateDirectory(Configuration.SCREEN_SHOT_LOCATION);
                    }
    
                    screenshot.SaveAsFile(fileLocation, ScreenshotImageFormat.Png);
                    Console.WriteLine(urlStr);
                    Console.WriteLine("SCREENSHOT[{0}]SCREENSHOT", Path.Combine("Screenshots", fileName));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
    

答案 2 :(得分:2)

事实上,理查德的答案将能够截取整个当前桌面区域的截图 - 如果这就是您所追求的,那么它将起作用。如果你实际上是在拥有一个没有最大化的特定应用程序(例如Internet Explorer)之后。使用Selenium时,您可能需要采用不同的方法。考虑强制应用程序最大化,甚至可以在使用上面的理查德方法拍摄屏幕截图之前获得焦点 - 或者使用Selenium的ITakesScreenshot界面......

要在Console应用程序中使用System.Windows.Forms命名空间,您需要&#34;添加引用...&#34;到项目。在解决方案资源管理器中,右键单击&#34;参考&#34;并选择&#34;添加参考...&#34 ;;滚动到System.Windows.Forms,检查它,然后单击“确定”。完成后,您将能够使用System.Windows.Forms键入&#34;&#34;在您的类文件的顶部。