2

I couldnt find a difinitive answer to this anywhere on the net.

I have multiple TestNg classes to run tests, BrowserFunctions, Login, Search, Filter (testing Amazon uk for practice). I also have a BrowserLauncher class that returns the appropriate webdriver based on browser name, and a testng.xml file.

BrowserFunctions.java

public class BrowserFunctions {

BrowserLauncher bl = new BrowserLauncher();
WebDriver driver;
StringBuilder sb = new StringBuilder();

@BeforeSuite
public void initialioseBrowser() {
    driver = bl.launchBrowser("Firefox");
}

@Parameters({ "URL" })
@BeforeSuite
public void invokeURL(String URL) {
    driver.get(URL);
}

@AfterSuite
public void closeBrowser() {
    driver.close();
}

Login.java

public class Login {

BrowserLauncher bl = new BrowserLauncher();
WebDriver driver;
StringBuilder sb = new StringBuilder();

@Parameters({ "email", "password" })
@Test
public void logInTest(String email, String passowrd) {
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKsignInCTA), "Sign in CTA visible");
    CommonFunctions.clickButton(driver, PageElements.amzUKsignInCTA);
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKEmailField), "Email field visible");
    CommonFunctions.inputToField(driver, PageElements.amzUKEmailField, email);
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKPasswordField),
            "Password field visible");
    CommonFunctions.inputToField(driver, PageElements.amzUKPasswordField, passowrd);
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKSignInButton),
            "Sign in button visible");
    CommonFunctions.clickButton(driver, PageElements.amzUKSignInButton);
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    Assert.assertEquals(driver.getCurrentUrl(), "https://www.amazon.co.uk/?ref_=nav_ya_signin&");
}

Search.java

public class Search {

BrowserLauncher bl = new BrowserLauncher();
WebDriver driver;
StringBuilder sb = new StringBuilder();

@Parameters({ "searchTerm" })
@Test
public void searchTest(String searchTerm) {
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKSearchField),
            "Search field visible");
    CommonFunctions.inputToField(driver, PageElements.amzUKSearchField, searchTerm);
    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKSearchButton),
            "Search button visible");
    CommonFunctions.clickButton(driver, PageElements.amzUKSearchButton);
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKResultContainer),
            "Results container visible");
    if (driver.findElements(PageElements.amzUKResultContainer).size() > 0) {
        List<WebElement> resultContainerList = driver.findElements(PageElements.amzUKResultContainer);
        for (WebElement w : resultContainerList) {
            if (w.findElements(PageElements.amzUKResultTitle).size() > 0) {
                if (w.findElement(PageElements.amzUKResultTitle).getText().contains(searchTerm)) {
                } else {
                    sb.append(w.findElement(PageElements.amzUKResultTitle).getText() + " does not contain"
                            + searchTerm + "\n");
                }
            }
            Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKResultImage),
                    "Result image visible");
            if (w.findElements(PageElements.amzUKResultImage).size() > 0) {
            } else {
                sb.append(w.findElement(PageElements.amzUKResultTitle).getText() 
                        + " does not contain an image\n");
            }
            Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKResultPrice),
                    "Result price visible");
            if (w.findElements(PageElements.amzUKResultPrice).size() > 0) {
                if (w.findElement(PageElements.amzUKResultPrice).getText().contains("£")) {
                } else {
                    sb.append(w.findElement(PageElements.amzUKResultTitle).getText() 
                            + " does not contain a price\n");
                }
            }
        }
    }
    System.out.println("searchTest(" + searchTerm + ") Failures:\n" + sb.toString());
}

Filter.java public class Filter {

BrowserLauncher bl = new BrowserLauncher();
WebDriver driver;
StringBuilder sb = new StringBuilder();

@Test
public void filterTest() {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    List<String> filterOptionsList = new ArrayList<String>();

    sb.append(CommonFunctions.clickButton(driver, PageElements.amzUKFilterSeeMore));

    Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKFilterOptions),
            "Filter options visible");
    for (int i = 0; i < driver.findElements(PageElements.amzUKFilterOptions).size(); i++) {
        filterOptionsList.add(driver.findElements(PageElements.amzUKFilterOptions).get(i).getText());
    }

    for (String s : filterOptionsList) {
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, By.partialLinkText(s)), "" 
                + s + " link visible");
        if (driver.findElements(By.partialLinkText(s)).size() > 0) {
            driver.findElement(By.partialLinkText(s)).click();
        }else {
            sb.append("Link " + s + " not visible");
            continue;
        }
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKFilterAnyCategory),
                "\"Any Category\" button visible");
        CommonFunctions.clickButton(driver, PageElements.amzUKFilterAnyCategory);
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        sb.append(CommonFunctions.clickButton(driver, PageElements.amzUKFilterSeeMore));
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }
    System.out.println("filterTest Failures:\n" + sb.toString());
}

BrowserLauncher.java

public WebDriver launchBrowser(String BrowserName) {
    if(BrowserName.equalsIgnoreCase("Firefox")) {
        driver = new FirefoxDriver();
        driver.manage().window().maximize();
    } else if(BrowserName.equalsIgnoreCase("IE")) {
        DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
        capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
        capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
        capabilities.setCapability(InternetExplorerDriver.INITIAL_BROWSER_URL, "");
        System.setProperty("webdriver.ie.driver", "C:\\Eclipse EE x86 Workspace\\ResidentAdvisorLabels\\IEDriverServer.exe");
        driver = new InternetExplorerDriver(capabilities);
        driver.get("javascript:document.getElementById('overridelink').click();");
    } else if(BrowserName.equalsIgnoreCase("Chrome")) {
        ChromeOptions op = new ChromeOptions();
        op.addArguments("--user-data-dir=C:\\Users\\Bernard\\Desktop\\Selenium Data");
        op.addArguments("--start-maximized");
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
        System.setProperty("webdriver.chrome.driver", "C:\\Eclipse EE x86 Workspace\\ResidentAdvisorLabels\\chromedriver.exe");
        driver = new ChromeDriver(op);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    } else if(BrowserName.equalsIgnoreCase("PhantomJS")) {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("takesScreenshot", false);
        String d = "\\";
        capabilities.setCapability("phantomjs.binary.path", "C:"+d+"Eclipse EE x86 Workspace"+d+"phantomjs-2.0.0-windows"+d+"bin"+d+"phantomjs.exe");
        capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
        capabilities.setCapability("load-images", false);
        driver = new PhantomJSDriver(capabilities);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    }

    return driver;
}

testng.xml

<suite name="Suite1" verbose="1">
<parameter name="searchTerm" value="Selenium Webdriver" />
<parameter name="URL" value="Http://www.amazon.co.uk" />
<parameter name="email" value="scrubbed" />
<parameter name="password" value="scrubbed" />
<test name="AmazonUKTesting">
    <classes>
        <class name="tests.amazonUKTests.BrowserFunctions" />
        <class name="tests.amazonUKTests.Login" />
        <class name="tests.amazonUKTests.Search" />
        <class name="tests.amazonUKTests.Filter" />
    </classes>
</test>

My problem is that i cannot seem to be able to pass the WebDriver that is returned to the BrowserFunctions.java class on to the other classes in my test suite without having to create a new instance of WebDriver in each java file. I am looking to open the browser, open the URL, then run the 3 tests one after another in the same browser window, and have the browser close when done.

1

5 Answers 5

3

You can extend a base class as others have suggested or you can use TestNG Guice dependency injection. e.g.:

TestModule.class

import com.google.inject.Binder;
import com.google.inject.Module;

public class TestModule implements Module {
    @Override
    public void configure(Binder binder) {
        BrowserLauncher bl = new BrowserLauncher();
        WebDriver driver = bl.launchBrowser("Firefox");
        binder.bind(WebDriver.class).toInstance(driver);
    }
}

BrowserFunctions.java

import com.google.inject.Inject;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Guice;
import org.testng.annotations.Parameters;

@Guice(modules = {TestModule.class})
public class BrowserFunctions {
    @Inject
    WebDriver driver;

    @Parameters({ "URL" })
    @BeforeSuite
    public void invokeURL(String URL) {
        driver.get(URL);
    }

    @AfterSuite
    public void closeBrowser() {
        driver.close();
    }
}

Login.java

import com.google.inject.Inject;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

@Guice(modules = {TestModule.class})
public class Login {
    @Inject
    WebDriver driver;
    StringBuilder sb = new StringBuilder();

    @Parameters({ "email", "password" })
    @Test
    public void logInTest(String email, String passowrd) {
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKsignInCTA), "Sign in CTA visible");
        CommonFunctions.clickButton(driver, PageElements.amzUKsignInCTA);
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKEmailField), "Email field visible");
        CommonFunctions.inputToField(driver, PageElements.amzUKEmailField, email);
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKPasswordField),
                "Password field visible");
        CommonFunctions.inputToField(driver, PageElements.amzUKPasswordField, passowrd);
        Assert.assertTrue(CommonFunctions.checkVisibility(driver, PageElements.amzUKSignInButton),
                "Sign in button visible");
        CommonFunctions.clickButton(driver, PageElements.amzUKSignInButton);
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Assert.assertEquals(driver.getCurrentUrl(), "https://www.amazon.co.uk/?ref_=nav_ya_signin&");
    }
}

etc.

Sign up to request clarification or add additional context in comments.

4 Comments

Your TestNG Guice suggestion looks very cool. I am going to look into it. How much have you used it?
@hfontanez I mostly work in JavaScript these days but whenever I do use TestNG I almost always end up using Guice with it as my suite grows and/or I want to be able to run my tests in different ways.
this approach is opening 2 browsers, how can we execute all the tests in different classes in same browser which is opened
Ok this method worked when all my test classes are in same class in testng.xml file under single test, if there are different tests in testng.xml file with multiple classes then those number of browsers are opened
1

Yes, this is possible to use the same driver instance across multiple classes without closing the browser window each time. Sorry didn't get much time to set this up for your code. But here I've prepared a quick example for you. This might be of some help for sure.

Use BrowserFunctions.java as a Base class.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.*;

public class BrowserFunctions {
public static WebDriver driver;
StringBuilder sb = new StringBuilder();

@BeforeSuite
public void initialioseBrowser() {
driver = new FirefoxDriver();
}

@AfterSuite
public void closeBrowser() {
driver.quit();
}
}

Inherit this class in your other two classes: Example, Google.java

import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.*;

public class Google extends BrowserFunctions{

@Test
public void google() throws InterruptedException{
driver.get("https://www.google.com");

WebDriverWait wait = new WebDriverWait(driver, 30); 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("lst-ib"))); 

driver.findElement(By.id("lst-ib")).sendKeys("Bello");
Thread.sleep(5000);

}
}

and FB.java

import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.*;

public class FB extends BrowserFunctions{

@Test
public void google() throws InterruptedException{

driver.get("https://www.fb.com");
WebDriverWait wait = new WebDriverWait(driver, 30); 

Thread.sleep(5000);
System.out.println("Title"+driver.getTitle());
System.out.println("URL"+driver.getCurrentUrl());

wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("day"))); 

Select day= new Select(driver.findElement(By.id("day")));
day.selectByVisibleText("10");

Select month= new Select(driver.findElement(By.id("month")));
month.selectByVisibleText("Jan");

Select year= new Select(driver.findElement(By.id("year")));
year.selectByVisibleText("1950");


}
}

and Your Testng.xml will be somewhat like this:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite1" verbose="1">
<test name="Test">
<classes>
    <class name="Google" />
    <class name="FB" />
</classes>
</test>
</suite>

Try this out once on your system and then try to something similar to this using your code. Should help! and Sorry for using Thread.sleep at too many places, you should not be using it too often. :)

Comments

0

we can achieve this by extending BrowserFunctions to all other classes except BrowserLauncher.java.

in BrowserFunctions do below changes.

 public static WebDriver driver; //instead of WebDriver driver;
 //you can make only one before suite in that launchBrowser and navigate URL

extends this class to other classes except BrowserLauncher.java and delete "WebDriver driver;". below is ex for one

public class Login extends BrowserFunctions{

 //WebDriver driver; //just commented you can delete this.

Thank You, murali

Comments

0

Just change your WebDriver Declaration to static

and also change the structure of your testng.xml as given in below example

<suite name="SuiteName">
 <test name="Test1">
  <classes>
   <class name="Class1" />
  </classes>
 </test>
 <test name="Test2">
  <classes>
   <class name="Class2" />
  </classes>
 </test>
</suite>

Comments

0

My suggestion is slightly different than others. I would create (and I have for my project) a data provider class that stores the web driver instance (as well as other meaningful data). Then, when needed, just call the data provider and ask for the web driver. For example:

public class MyDataProvider {
  public static WebDriver driver;
  ...
 }

public class BrowserFunctions {
  StringBuilder sb = new StringBuilder();

  @BeforeSuite
  public void initialioseBrowser() {
    MyDataProvider.driver = new FirefoxDriver();
  }

  @AfterSuite
  public void closeBrowser() {
    MyDataProvider.driver.quit();
  }
}

The reasons for having this data provider holding the web driver's instance should be somewhat obvious. Two reasons come to mind:

  1. To have a centralized data hub from where all your meaningful data can be obtained. Doing this eliminate needing to have all these object references in your test classes.
  2. Separation of concerns. Your test classes should focus on aspects of testing. Your data provider should concern itself with managing data.

I also like @mfulton26 answer about using TestNG Guice. So I am going to look into it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.