Reputation: 182
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.
Upvotes: 2
Views: 8816
Reputation: 6168
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:
I also like @mfulton26 answer about using TestNG Guice. So I am going to look into it.
Upvotes: 0
Reputation: 71
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>
Upvotes: 0
Reputation: 31214
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.
Upvotes: 3
Reputation: 3927
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
Upvotes: 0
Reputation: 1145
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. :)
Upvotes: 1