k_rollo
k_rollo

Reputation: 5472

Handling Single Sign On with Selenium WebDriver and TestNG

Conditions:

Problem:
It passes AMSValidation but skips SAPValidation. It is saying The FirefoxDriver cannot be used after quit() was called. But upon running the tests per class, they pass.

Code:

public abstract class Validation {
    // other variables
    public static WebDriver driver = new FirefoxDriver();

    public void doLogin() throws Exception {
        // something
    }

    public void validateDocuments(String portal, String navigation,
            String category, String title, String fileName) throws Exception {
        // driver is used here      
    }
}

public class AMSValidation extends Validation {

    @Parameters("baseUrl")
    @BeforeTest(alwaysRun = true)
    public void setUp(@Optional("https://website.com/ams/") String baseUrl)
            throws Exception {

        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl);
        doLogin();
    }

    @DataProvider
    public Object[][] getDataForAMS() throws Exception {
        // return test data for ams
    }

    @Test(dataProvider = "getDataForAMS")
    public void validateAMS(String portal, String navigation, String category,
            String title, String fileName) throws Exception {
        validateDocuments(portal, navigation, category, title, fileName);
    }

    @AfterTest(alwaysRun = true)
    public void tearDown() throws Exception {
        driver.quit();
    }
}

public class SAPValidation extends Validation {

    @Parameters("baseUrl")
    @BeforeTest(alwaysRun = true)
    public void setUp(@Optional("https://website.com/sap/") String baseUrl)
            throws Exception {

        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl);
        doLogin();
    }

    @DataProvider
    public Object[][] getDataForSAP() throws Exception {
        // return test data for sap
    }

    @Test(dataProvider = "getDataForSAP")
    public void validateSAP(String portal, String navigation, String category,
            String title, String fileName) throws Exception {
        validateDocuments(portal, navigation, category, title, fileName);
    }

    @AfterTest(alwaysRun = true)
    public void tearDown() throws Exception {
        driver.quit();
    }
}

testng.xml:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Validation Suite" verbose="2">
    <test name="AMS Test">
        <parameter name="baseUrl" value="https://website.com/ams/" />
        <classes>
            <class name="com.website.tests.AMSValidation" />
        </classes>
    </test>

    <test name="SAP Test">
        <parameter name="baseUrl" value="https://website.com/sap/" />
        <classes>
            <class name="com.website.tests.SAPValidation" />
        </classes>
    </test>
</suite>

Log:

PASSED: validateAMS("portal", "navigation", "category", "title", "filename")

===============================================
    AMS Test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

FAILED CONFIGURATION: @BeforeTest setUp("https://website.com/sap/")
org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.
// rest of stack trace

SKIPPED: validateSAP("portal", "navigation", "category", "title", "filename")

===============================================
    SAP Test
    Tests run: 1, Failures: 0, Skips: 1
    Configuration Failures: 1, Skips: 0
===============================================


===============================================
Validation Suite
Total tests run: 2, Failures: 0, Skips: 1
Configuration Failures: 1, Skips: 0
===============================================

Upvotes: 1

Views: 17695

Answers (3)

Grasshopper
Grasshopper

Reputation: 9058

Move the driver.quit() call to aftersuite() method. I am guessing the static webdriver is to keep the driver session alive across tests. If so move driver initialization to beforesuite() method.

Upvotes: 2

FayazMd
FayazMd

Reputation: 386

As per my knowledge in java, Class 'Validation' is already loaded by one of our classes that is AMSValidation, that signifies, all the static members also loads. So when first time class loads and its static content also load. And when these static members modified by any other classes, then the updated state of these contents available to other classes as well, therefore when we quit driver instance (which is static) from first class 'AMSValidation' the driver is quit and not available to second class i.e., 'SAPValidation', so we are facing such exception.

To avoid this SessionNotFoundException, better to create objects for 'Validations' so that, it can create two different drivers, but again, technically, since our Validation class is an abstract and one cannot instantiate abstract class object

Approch #1: Its better to create another concrete class to Validation class and then extends sub classes (AMSValidation and SAPValidation) from this newly created class Approch #2: Simply remove 'static' keyword while creating driver in the existing class design

After all, Java is little tricky while coming to class loaders in order to save memory and for better performance

Upvotes: 1

CARE
CARE

Reputation: 628

In your abstract base class Validation, driver instance variable is marked as static so you will have only one instance for all your child objects and once quit method is invoked from one of the instances then other child instances will not be able to use the same driver further so remove the static from the declaration like below

public WebDriver driver = new FirefoxDriver();

Hope it helps

Upvotes: 0

Related Questions