Tuisceanach
Tuisceanach

Reputation: 21

Running Selenium Webdriver tests with TestNG in parallel does not sent correct data to browser

I have two TestNG classes with one test method in each. Each test class has its own @Dataprovider. Each test executes functionality on a web application using Selenium Webdriver. The driver is created for each TestNG class via a factory method and threadlocal so driver should be threadsafe. However when running the tests in parallel using testng.xml the same data is being used across both tests causing one to fail. Here is the code. I'm thinking it might be a problem with the thread safety of the Excel Utility class.

 / DriverFactory

    @Listeners(ScreenshotListener.class)
    public class DriverFactory {

        public final static String URL = "http://localhost/Quotation/Development/index.php";

        private static List<WebDriverThread> webDriverThreadPool = Collections.synchronizedList(new ArrayList<WebDriverThread>());
        private static ThreadLocal<WebDriverThread> driverThread;

        @BeforeClass
        public static void instantiateDriverObject() {
            System.out.println("Before Class");
            driverThread = new ThreadLocal<WebDriverThread>() {
                @Override
                protected WebDriverThread initialValue() {
                    WebDriverThread webDriverThread = new WebDriverThread();
                    webDriverThreadPool.add(webDriverThread);
                    return webDriverThread;}};
            }
        @BeforeTest
        public void setUp() throws Exception {

            System.out.println("Before Test");}

        public static WebDriver getDriver() throws Exception {
            return driverThread.get().getDriver();}

        protected String debug(String methodName) throws Exception {
            return methodName + " running on Thread " + Thread.currentThread().getId() +
                    " with instance as " + this + " and driver " + driverThread.get().getDriver().toString();
        }

        @AfterSuite
        public static void closeDriverObjects() {
            System.out.println(webDriverThreadPool.size());
            for (WebDriverThread webDriverThread : webDriverThreadPool) {
                webDriverThread.quitDriver();}
            }
    }

// WebDriver thread
public class WebDriverThread {

    private WebDriver webdriver;
    private DriverType selectedDriverType;
    private final DriverType defaultDriverType = FIREFOX;
    private final String browser = "CHROME"; //System.getProperty("browser").toUpperCase();
    private final String operatingSystem = System.getProperty("os.name").toUpperCase();
    private final String systemArchitecture = System.getProperty("os.arch");
    private final boolean useRemoteWebDriver = Boolean.getBoolean("remoteDriver");

    public WebDriver getDriver() throws Exception {

        if (null == webdriver) {
            selectedDriverType = determineEffectiveDriverType();
            DesiredCapabilities desiredCapabilities = selectedDriverType.getDesiredCapabilities();
            instantiateWebDriver(desiredCapabilities);}

        return webdriver;}

    public void quitDriver() {
        if (null != webdriver) {
            webdriver.quit();
            webdriver = null;
        }}

    private DriverType determineEffectiveDriverType() {
        DriverType driverType = defaultDriverType;

        try {
                driverType = valueOf(browser);} 

        catch (IllegalArgumentException ignored) {
            System.err.println("Unknown driver specified,defaulting to '" + driverType + "'...");} 

        catch (NullPointerException ignored) {
            System.err.println("No driver specified, defaulting to '" + driverType + "'...");}

        return driverType;}

    private void instantiateWebDriver(DesiredCapabilities desiredCapabilities) throws MalformedURLException {
        System.out.println(" ");
        System.out.println("Current Operating System: " + operatingSystem);
        System.out.println("Current Architecture: " + systemArchitecture);
        System.out.println("Current Browser Selection: " + selectedDriverType);
        System.out.println(" ");

        if (useRemoteWebDriver) {
            URL seleniumGridURL = new URL(System.getProperty("gridURL"));
            webdriver = new RemoteWebDriver(seleniumGridURL,desiredCapabilities);
            }
        else
            webdriver = selectedDriverType.getWebDriverObject(desiredCapabilities);
        }
}

// ValidLoginTest
public class ValidLoginTest extends DriverFactory{

    @BeforeMethod
    public void setup() throws Exception {
        System.err.println(debug("validLoginTest"));

    }

    //@Test(dataProvider="ValidLogin" ,dependsOnMethods = { "inValidLoginTest" })
    @Test(dataProvider="ValidLogin")
    public void validLoginTest(String username, String password, String expectedUserName, String expectedUserEmail) throws Exception {
        Login login = new Login();
        getDriver().get(URL);

        String[] loggedin = login.navigateTo()
                                .enterUserName(username)
                                .enterPassword(password)
                                .andSubmit()
                                .andCheckLoggedIn();

        assertEquals(loggedin[0],expectedUserName);
        assertEquals(loggedin[1],expectedUserEmail);


    }



    @AfterMethod
    public void teardown() throws Exception {
        JavascriptExecutor jsExecutor = (JavascriptExecutor) getDriver();
        jsExecutor.executeScript("sessionStorage.clear();");

    }

    @DataProvider

    public Object[][] ValidLogin() throws Exception{

        Object[][] testObjArray = ExcelUtils.getTableArray("SystemTestData.xlsx","ValidLogin");

        return (testObjArray);}


}

public class InvalidLoginTest extends DriverFactory{

    @BeforeMethod
    public void setup() throws Exception {
        System.err.println(debug("inValidLoginTest"));

    }

    @Test(dataProvider="InvalidLogin")
    public void inValidLoginTest(String username, String password, String expectedResult) throws Exception {
        Login login = new Login();
        getDriver().get(URL);

        String error = login.navigateTo()
                                .enterUserName(username)
                                .enterPassword(password)
                                .andSubmit()
                                .andCheckValidation();

        assertEquals(error, expectedResult);

        login.andClose();

    }

    @DataProvider

    public Object[][] InvalidLogin() throws Exception{

        Object[][] testObjArray = ExcelUtils.getTableArray("SystemTestData.xlsx","InvalidLogin");

        return (testObjArray);}
    }

public class Login {

    @FindBy(xpath = "/html/body/nav/div/div[2]/ul/li[3]/a")
    private WebElement loginMenu;

    @FindBy(name = "user")
    private WebElement usernameLocator;

    @FindBy(name = "password")
    private WebElement passwordLocator;

    @FindBy(id = "loginUser")
    private WebElement loginUserLocator;

    @FindBy(css = "#loginForm > div:nth-child(2) > button:nth-child(2)")
    private WebElement closeLocator;

    @FindBy(id = "loginError")
    private WebElement error;

    @FindBy(xpath = "/html/body/nav/div/div[2]/ul/li[3]/ul/li[1]/div/div/div/p[1]/strong")
    private WebElement loggedInUserName;

    @FindBy(xpath = "/html/body/nav/div/div[2]/ul/li[3]/ul/li[1]/div/div/div/p[2]/strong")
    private WebElement loggedInUserEmail;

    @FindBy(xpath = "/html/body/nav/div/div[2]/ul/li[3]")
    private WebElement account;





    private WebDriverWait wait;


    public Login() throws Exception {

        PageFactory.initElements(DriverFactory.getDriver(), this);
        wait = new WebDriverWait(DriverFactory.getDriver(), 30);
        System.out.println("Login " + DriverFactory.getDriver().toString());

    }

    public Login navigateTo() throws Exception {

        wait.until(ExpectedConditions.visibilityOf(loginMenu));
        loginMenu.click();

        return this;
    }

    public Login enterUserName(String username) {

        wait.until(ExpectedConditions.visibilityOf(usernameLocator));

        usernameLocator.clear();

        for(int i = 0; i < username.length(); i++){
            char c = username.charAt(i);
            String s = new StringBuilder().append(c).toString();
            usernameLocator.sendKeys(s);
        }

        return this;

    }

    public Login enterPassword(String password)  {

        wait.until(ExpectedConditions.visibilityOf(passwordLocator));

        passwordLocator.clear();

        passwordLocator.sendKeys(password);
        return this;

    }

    public Login andSubmit()  {

        wait.until(ExpectedConditions.visibilityOf(loginUserLocator));

        loginUserLocator.click();

        return this;
    }

    public String[] andCheckLoggedIn() {
        String[] actualResult = new String[2];

        wait.until(ExpectedConditions.visibilityOf(account));
        account.click();
        wait.until(ExpectedConditions.visibilityOf(loggedInUserName));
        actualResult[0] = loggedInUserName.getText();
        actualResult[1] = loggedInUserEmail.getText();
        return actualResult;


    }

    public String andCheckValidation() {

        wait.until(ExpectedConditions.visibilityOfAllElements(error));

        return error.getText();
    }

    public void andClose() throws Exception  {

        wait.until(ExpectedConditions.visibilityOf(closeLocator));

        closeLocator.click();

    }

}

public class ExcelUtils {

            private static XSSFSheet ExcelWSheet;

            private static XSSFWorkbook ExcelWBook;

            private static XSSFCell Cell;

            private static XSSFRow Row;

        public static Object[][] getTableArray(String FilePath, String SheetName) throws Exception {   

           String[][] tabArray = null;

           try {

               FileInputStream ExcelFile = new FileInputStream(FilePath);

               // Access the required test data sheet

               ExcelWBook = new XSSFWorkbook(ExcelFile);

               ExcelWSheet = ExcelWBook.getSheet(SheetName);

               int startRow = 1;

               int startCol = 1;

               int totalRows = ExcelWSheet.getLastRowNum();
               int totalCols = ExcelWSheet.getRow(0).getLastCellNum();

               tabArray = new String[totalRows][totalCols -startCol];

               for (int row = startRow; row <= totalRows; row++) {                 

                   for (int col = startCol; col < totalCols; col++){

                       tabArray[row - startRow][col - startCol] = getCellData(row, col);

                       }}}

            catch (FileNotFoundException e){

                System.out.println("Could not read the Excel sheet");

                e.printStackTrace();

                }

            catch (IOException e){

                System.out.println("Could not read the Excel sheet");

                e.printStackTrace();

                }

            return(tabArray);

            }

        public static String getCellData(int RowNum, int ColNum) throws Exception {


            try{

                Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);

                if (Cell == null || Cell.getCellTypeEnum() == CellType.BLANK) {

                    return "";

                }else{

                    String CellData = Cell.getStringCellValue();

                    return CellData;

                }}catch (Exception e){

                System.out.println(e.getMessage());

                throw (e);

                }}}

    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <suite name="Quotation" parallel="classes" thread-count="3" verbose="1" >
        <test name="System Test" >
            <classes>
                <class name="com.quotation.systemtest.tests.ValidLoginTest"/>
                <class name="com.quotation.systemtest.tests.InvalidLoginTest"/>
                </classes>
        </test>

    </suite>



[Testng_Result][1]


  [1]: https://i.sstatic.net/vLx0y.png

Upvotes: 1

Views: 205

Answers (0)

Related Questions