lefthandedgoat / canopy

f# web automation and testing library, built on top of Selenium (friendly to c# also)
http://lefthandedgoat.github.io/canopy/
MIT License
505 stars 117 forks source link

How can I get the LiveHtmlReporter to not include screenshots, but still save the screenshots to a specific location with a specific given name? #499

Closed adalenthya closed 4 years ago

adalenthya commented 4 years ago

Description

How can I get the LiveHtmlReporter to not include screenshots, BUT still save the screenshots to a specific location with a specific given name? Reason: When I have multiple failed tests (i'm using Nunit with Canopy), I get a LiveHtmlReporter file >20MB, that I'm unable to send via email to my leader. I need the screenshots, even if they are not included in the LiveHtmlReporter file. The failScreenshotFileName also needs to include the name of my test (the "context") otherwise I can't match it with the failed test. Could you please help me out with a solution for this?

Other information

adalenthya commented 4 years ago

Hi Oliver, Not sure how these 2 are related. In the meantime I did succeed to disable the LiveHTMLReporter screenshots and still save screenshots separately in a folder for each failed test.

Still struggling to change the "failScreenshotFileName" to include the context or the test file in it's name.

[<SetUpFixture>]
type OneTimeTestsSetupClass() = 
    [<OneTimeSetUp>]
    member this.OneTimeSetup() =          
        printfn "Commercial Cafe ILS ===> OneTimeSetup"
        failScreenshotPath <- AppConfig.HtmlReportPath+"FailureScreenshots"  //path to screenshots generated for failed tests in LiveHtmlReporter   
        onFail (fun _ ->
            let screenshotFileName = [failed context or failed suite or failed test]+DateTime.Now.ToString("MMM-d_HH-mm-ss-fff")
            screenshot failScreenshotPath screenshotFileName
            |> ignore 
        )
lefthandedgoat commented 4 years ago

You may have to show me how you are getting unit to work with LiveHTMLReporter.

You are probably keeping an instance of it and calling the methods on it as things happen in NUnit. When you call reporter.fail or the context variant just pass an empty array as the screenshot and that should fix the report problem, and instead just save a screenshot to disk that you can manage later.

https://github.com/lefthandedgoat/canopy/blob/master/src/canopy/reporters.fs#L301

lefthandedgoat commented 4 years ago

Nunit has TestContext.CurrentContext which may give you what you need to make your screenshot file names better.

adalenthya commented 4 years ago

Using the let screenshotFileName = DateTime.Now.ToString("MMM-d_HH-mm-ss-fff ")+TestContext.CurrentContext.ToString() doesn't do the trick. I tried variants such as: TestContext.CurrentContext.Test.FullName TestContext.CurrentContext.Test.MethodName without success, they never return the name of the failed test/context.

This is my OneTimeSetup.fs

[<SetUpFixture>]
type OneTimeTestsSetupClass() =

    [<OneTimeSetUp>]
    member this.OneTimeSetup() =          
        printfn "Commercial Cafe ILS ===> OneTimeSetup"
        failScreenshotPath <- AppConfig.HtmlReportPath+"FailureScreenshots"  //path to screenshots generated for failed tests in LiveHtmlReporter   
        onFail (fun _ ->
            let screenshotFileName = DateTime.Now.ToString("MMM-d_HH-mm-ss-fff ")
            screenshot failScreenshotPath screenshotFileName           
            |> ignore 
        )

    [<OneTimeTearDown>]
    member this.OneTimeTearDown() = 
        printfn "Commercial Cafe ILS ===> OneTimeTearDown"  
        pageTimeout <- 20.0
        elementTimeout <- 8.0
        skipRemainingTestsInContextOnFailure <- true
        let mutable driverPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
        chromeDir <- driverPath
        safariDir <- driverPath
        ieDir <- driverPath
        edgeDir <- driverPath
        failureScreenshotsEnabled <- false //LiveHtmlReporter excludes screenshots

        reporter <- new LiveHtmlReporter(Chrome, chromeDir) :> IReporter  
        let liveHtmlReporter = reporter :?> LiveHtmlReporter
        liveHtmlReporter.reportTemplateUrl <- AppConfig.WebReportURL
        let path = AppConfig.HtmlReportPath + "Canopy Automation Test Report - " + AppConfig.Environment + " - " + DateTime.Now.ToString("MMM-d-yy_H-mm-ss-fff")
        liveHtmlReporter.reportPath <- Some path       
        run()           
        quit()

And this is the test in ILSHomePage.fs intended to Fail:

[<TestFixture>]
type ILSHomeTestClass() = 
    inherit BaseTest.BaseTestClass()
    [<Test>]
    [<Category("ILSHome")>]
    [<Category("ILSSmoke")>]
    [<Category("ILSFunctional")>]
    member this.ILSHome () = 
        for testName in ILSDataTypesForTests.rowsILSHome do
            match testName.testName with
            |"VisitAndVerifyILSHome" -> this.VisitAndVerifyILSHome(testName.input1)
            | _ -> ()

    member this.VisitAndVerifyILSHome (inputtitle) = 
        context "[ILSHomePage.fs][Test:VisitAndVerifyILSHome] Verify ILS Home Page is loaded "
        "Start Test" &&& fun _ -> 
            TestContext.Progress.WriteLine("Running TEST ===> VisitAndVerifyILSHome")
            TestContext.Progress.WriteLine("INPUT Data ===>" + " Global Page Title:" + inputtitle)
        OpenBrowserWithURL(AppConfig.ILSURL)
        "Verify the Global Page Title on Home Page is: "+inputtitle &&& fun _ ->
            highlight GlobalPageTitle
            GlobalPageTitle == inputtitle
        CloseBrowserFun()

Currently I'm saving all the screenshots in the , at a given location. But I don't know how to associate the screenshot with the failed test from the report file.

lefthandedgoat commented 4 years ago

I think you need a [TearDown] and in it you can look at the test context and if its a failure do a screenshot and it will have the correct test names etc.

https://github.com/nunit/docs/wiki/TestContext

adalenthya commented 4 years ago

I figure it out! I added the "onfail(fun -> )" in my BaseTestClass which is inherited by all the clases. Thanks so much!

module BaseTest

[<TestFixture>]
type BaseTestClass() = 

    [<TearDown>]
    member this.TearDown() = 
        let currentTestName = TestContext.CurrentContext.Test.Name
        onFail (fun _ ->
            let screenshotFileName = DateTime.Now.ToString("MMM-d_HH-mm-ss_")+currentTestName
            screenshot failScreenshotPath screenshotFileName           
            |> ignore 
        )
        context "Force closing current browser!"
        CloseBrowserFun()