Search code examples
c#seleniumspecflowtest-reportingspecrun

Insert screenshots in SpecRun/SpecFlow test execution reports


I'm using SpecFlow with Selenium WebDriver and SpecRun as test runner to create and execute automated test cases and I'm looking for a solution to insert screenshots in the test execution report.

I wrote a method to create screenshots after every Assert function. The images are saved to a specific location, but when I make the result analysis I have to follow the report and the images as well. It would be nice to have them in the same location (precisely in the report html).

Is there any way to perform this (something similar to Console outputs)?


Solution

  • (reposting from https://groups.google.com/forum/#!topic/specrun/8-G0TgOBUbY)

    Yes, this is possible. You have to do the following steps:

    1. save the screenshot to the output folder (this is the current working folder where the tests are running).
    2. Write out a file line to the console from the test: Console.WriteLine("file:///C:\fullpath-of-the-file.png");
    3. Make sure that the generated images are also saved on the build server as artifacts

    During the report generation, SpecRun scans the test output for such file URLs and convert them to anchor tags with relative path, so that these will work wherever you distribute your report file (as long as the images are next to it). You can of course tup the images to a subfolder as well.

    Here is a code snippet that works with Selenium WebDriver. This also saves the HTML source together with the screenshot.

        [AfterScenario]
        public void AfterWebTest()
        {
            if (ScenarioContext.Current.TestError != null)
            {
                TakeScreenshot(cachedWebDriver);
            }
        }
    
        private void TakeScreenshot(IWebDriver driver)
        {
            try
            {
                string fileNameBase = string.Format("error_{0}_{1}_{2}",
                                                    FeatureContext.Current.FeatureInfo.Title.ToIdentifier(),
                                                    ScenarioContext.Current.ScenarioInfo.Title.ToIdentifier(),
                                                    DateTime.Now.ToString("yyyyMMdd_HHmmss"));
    
                var artifactDirectory = Path.Combine(Directory.GetCurrentDirectory(), "testresults");
                if (!Directory.Exists(artifactDirectory))
                    Directory.CreateDirectory(artifactDirectory);
    
                string pageSource = driver.PageSource;
                string sourceFilePath = Path.Combine(artifactDirectory, fileNameBase + "_source.html");
                File.WriteAllText(sourceFilePath, pageSource, Encoding.UTF8);
                Console.WriteLine("Page source: {0}", new Uri(sourceFilePath));
    
                ITakesScreenshot takesScreenshot = driver as ITakesScreenshot;
    
                if (takesScreenshot != null)
                {
                    var screenshot = takesScreenshot.GetScreenshot();
    
                    string screenshotFilePath = Path.Combine(artifactDirectory, fileNameBase + "_screenshot.png");
    
                    screenshot.SaveAsFile(screenshotFilePath, ImageFormat.Png);
    
                    Console.WriteLine("Screenshot: {0}", new Uri(screenshotFilePath));
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error while taking screenshot: {0}", ex);
            }
        }