Search code examples
seleniumcucumbertestnglistenerextentreports

Getting error in listeners after extending my selenium TestNG framework to Cucumber


Q1) I have an existing framework in Selenium-TestNG along with Listeners class. I close the browser using @AfterTest annotation of TestNG:

 @AfterTest
    public void teardown()
    {
        driver.quit();
    } 

Here onTestSuccess method of Listeners class works perfectly fine when I run as plain old Selenium TestNG without cucumber feature file:

public void onTestSuccess(ITestResult result) 
    {
        test.log(Status.PASS, "Test case Passed");
                
        try 
        {
        String path = takeScreenshot(driver, "Pass/" + result.getInstanceName() + "/" + result.getMethod().getMethodName());        
        test.addScreenCaptureFromPath(path, result.getMethod().getMethodName());
        }
        catch (Exception e) 
        {
            log.fatal("Exception in onTestSuccess Method of Listeners class");
            log.fatal(e.getMessage() +" : " + e.getStackTrace());
            System.out.println("Exception " + e.getMessage());
            System.out.println("Exception " + e.getStackTrace());
        }
    }

When Test passes, onTestSuccess() method of Listeners class is called first and then teardown() method is called. So every thing goes smooth.

Now I use this feature file in cucumber:

Feature: Logout feature

Background: 
    Given User is on Salesforce login page
  
  @SmokeTest @Low @PositiveTest @Logout
  Scenario: Logout of application
    Given "RMUser" has logged into Salesforce application
    When User clicks on logout button
    Then Users is logged-out from the application

And use @After hook to close the browser:

@After
    public void teardown() {        
        driver.quit();
    }

Now when I run this feature file as TestNG then teardown method in Hooks file is called first and then onTestSuccess() method of Listeners class is called due to which I get error "Exception Session ID is null. Using WebDriver after calling quit()?" at the line where I try to use driver variable:

String path = takeScreenshot(driver, "Pass/" + result.getInstanceName() + "/" + result.getMethod().getMethodName()); 

This can be resolved if onTestSuccess() method of Listeners class is called first before @After hook gets called.

Seeking some workaround or idea to resolve this issue in Cucumber.

Q2) While running as plain Selenimm-TestNG, Extent Reports gives the correct TestName in the report but when running as TestNG Cuccumber framework, Extent reports just shows all the test names as "runScenario".

ExtentReport when run in cucumber framework

How to make ExtentReport give proper feature file scenario names instead of just "runScenario"


Solution

  • I resolved the TestNG Listeners class exception by removing driver.quit(); from Hooks class file and putting it inside onTestStart and onTestFailure methods of the Listeners class:

    public void onTestSuccess(ITestResult result) 
        {
            test.log(Status.PASS, "Test case Passed");
            
            
            try 
            {
            String path = takeScreenshot(driver, "Pass/" + result.getInstanceName() + "/" + result.getMethod().getMethodName());        
            test.addScreenCaptureFromPath(path, result.getMethod().getMethodName());
            }
            catch (Exception e) 
            {
                log.fatal("Exception in onTestSuccess Method of Listeners class");
                log.fatal(e.getMessage() +" : " + e.getStackTrace());
                System.out.println("Exception " + e.getMessage());
                System.out.println("Exception " + e.getStackTrace());
            }
            driver.quit();
        }
    
        public void onTestFailure(ITestResult result) {
            test.log(Status.FAIL, "Test case Failed");
            test.fail(result.getThrowable());   
            
            try 
            {       
            String path = takeScreenshot(driver, "Fail/" + result.getInstanceName() + "/" + result.getMethod().getMethodName());        
            test.addScreenCaptureFromPath(path, result.getMethod().getMethodName());        
            }
            catch(Exception e)
            {
                log.fatal("Exception in onTestFailure Method of Listeners class");
                log.fatal(e.getMessage() +" : " + e.getStackTrace());
                System.out.println("Exception " + e.getMessage());
                System.out.println("Exception " + e.getStackTrace());
            }
            driver.quit();
        }
    

    Since the testcase will either pass or fail hence control will always come either in onTestSuccess or onTestFailure methods and this will quit the driver after Testcase is completed execution.