Search code examples
javaseleniumtestingselenium-webdrivertestng-dataprovider

Not able to run tests after using @Factory annotation in Selenium with Java


Here is the structure of my class:

package com.gex.base.helper;

public class InitializeDriver extends BrowserFactory 
{

    HashMap<String, String> authenticationMap;

    @Factory(dataProvider="authentication", dataProviderClass=DataProviderList.class)
    public InitializeDriver(String userName, String uPassword)
    {
        authenticationMap=new HashMap<String, String>();
        authenticationMap.put("UserName", userName);
        authenticationMap.put("Password", uPassword);
    }


    @BeforeTest
     public void Gexlogin() 
      {
          LoginPF objLogin=PageFactory.initElements(BrowserFactory.driver, LoginPF.class);
           System.out.println("Logging into GEx");
           objLogin.loginToDGEx(authenticationMap.get("UserName"), authenticationMap.get("Password"));
          System.out.println("Successfully Logged into GEx");
    }

    @AfterTest
    public void directLogout(){

        // logout from application
        LogoutPF objLogoutTest = PageFactory.initElements(BrowserFactory.driver, LogoutPF.class);
        objLogoutTest.LogOffGEx();
        extent.flush();
        driver.close();
    }
}

LoginToGEx is a function in another class like as:

public void loginToGEx(String strUsername, String strPassword)
{
    username.sendKeys(strUsername)
    password.sendKeys(strPassword);
    loginButton.click();
    System.out.println("Successfully Logged into GEx");
}

DataProviderClass

public class DataProviderList {

    @DataProvider(name="authentication")
    public static Object[][] authentication()
    {
        return new Object[][] {
            {"abc", "123"}, 
            {"xyz", "456"},
            };
    }

}

In another class there is @Test extending InitializeDriver class.

    public class SampleTest extends InitializeDriver {

        public SampleTest(String userName, String uPassword) {
            super(userName, uPassword);
            // TODO Auto-generated constructor stub
        }

        @Test
        public void CreateNewEngTest() throws InterruptedException
        {
            test=extent.createTest("Eng Test","Create Eng Test");
            -Code (which is working fine before using @Factory)-----------------------

Testng.xml structure:

<suite name="Sample Project" verbose="1" >

   <test name="Sample Test" group-by-instances="true" preserve-order="true">
  <classes>
            <class name="com.gex.base.testscripts.SampleTest" />                     
  </classes>
</test>
</suite>

My Question is: Before using @Factory with dataprovider--my tests were running fine but when I used @Factory annotation then nothing happens.. In SampleTest Class this constructor gets created itself..may be this causing issue.

public SampleTest(String userName, String uPassword) {
            super(userName, uPassword);
            // TODO Auto-generated constructor stub
        }

Please guide how to make tests run using @Factory

Also 1 more thing if I define factory annotation with my @test scenario then everytime I need to login..and I have many testcases and wanted to run login once execute all @test scenatios then logout and start again with another set of username&password...not everytime when @test starts. Is this scenario possible? thanks again


Solution

  • It does not work because you annotated the constructor with @Factory annotation and then used inheritance.

    To keep the inheritance, etc you should annotate the SampleTest class with @Factory

    Like this:

    
    public class SampleTest extends InitializeWebDriver {
        private String userName, password;
    
        @Factory(dataProvider="authentication", dataProviderClass=DataProviderList.class)
        public SampleTest(String userName, String password) {
            super(userName, password)
        }
    }
    
    
    public class InitializeDriver extends BrowserFactory {
        private String userName, password;
    
        public InitializeDriver(String userName, String uPassword)
        {
            this.userName = userName;
            this.password = password;
        }
    
    }
    

    This will cause @Factory to pass the arguments from DataProvider to your InitializeDriver class and save it as instance variables.

    Then you can use those variables like in your @BeforeTest method:

    @BeforeMethod
    public void Gexlogin() {
         LoginPF objLogin=PageFactory.initElements(BrowserFactory.driver, LoginPF.class);
         System.out.println("Logging into GEx");
         objLogin.loginToDGEx(userName, password); //changed to instance variables
         System.out.println("Successfully Logged into GEx");
    }
    

    EDIT: The @BeforeTest method will only execute once because TestNG treats @Factory tests as a single test case! If you want to log in before each test, you need to use @BeforeMethod