I want to run different classes particular method from TestNG but everytime it opens a new window when i include beforeclass in each class so i have now excluded beforeclass from add and logout classes so it can use same browser to run rest methods but its not working
The first class is of login class which is as below
public class LoginWeb {
public WebDriver driver;
WebDriverWait wait;
LoginScreen loginExcel;
@BeforeClass
public void beforeClass (){
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://10.7.1.180/views/index.html#/login");
System.out.println(driver.getTitle());
}
@Test (description = "Valid Credentials!")
public void LoginWithValidWebExcelEmailAndPass() throws IOException, BiffException {
loginExcel= new LoginScreen(driver);
FileInputStream fi = new FileInputStream("D:\\Programs\\New\\Sourcesmartdata.xls");
Workbook w = Workbook.getWorkbook(fi);
Sheet s = w.getSheet(0);
int z = s.getRows();
System.out.println("no of rows------------------------:"+z);
String email = s.getCell(0, 1).getContents();
System.out.println("Email -----------------"+email);
loginExcel.EnterEmail(email);
String password= s.getCell(1, 1).getContents();
System.out.println("Password------------------- "+password);
loginExcel.EnterPassword(password);
loginExcel.ClickToLogin();
wait= new WebDriverWait(driver, 10);
WebElement GetLogo = wait.until(ExpectedConditions.visibilityOf(loginExcel.TopRightMenu));
String str= GetLogo.getText();
System.out.println("Text------------"+str);
Assert.assertEquals(str, "Source Smart");
}
}
The second class is of adding commodities here i have excluded beforeclass as if i include before class it opens a new window and here login script is not written
public class AddCommoditiesWeb{
WebDriver driver;
WebDriverWait wait;
AddCommodities addcommodity;
@Test (description="Add Multiple Commodities!")
public void AddMultipleNewCommodities () throws Exception, Exception{
addcommodity = new AddCommodities(driver);
addcommodity.MenuCommodities(); //click left menu to open manage commodities page
FileInputStream fi = new FileInputStream("D:\\Programs\\New\\Sourcesmartdata.xls");
Workbook w = Workbook.getWorkbook(fi);
Sheet s = w.getSheet(1);
int z=s.getRows();
System.out.println("no of rows------------------------:"+z);
for(int row=1; row <2; row++){
Thread.sleep(5000);
addcommodity.ClickAddCommodities(); // click add commodity button
String commodityname = s.getCell(0, row).getContents();
System.out.println("commodityname -----------------"+commodityname);
//enterdefinecommodityTxtBox.sendKeys(commodityname);
addcommodity.Enterdefinecommodity(commodityname);
String grade= s.getCell(1, row).getContents();
System.out.println("grade------------------- "+grade);
//entergradeTxtBox.sendKeys(grade);
String unit= s.getCell(2, row).getContents();
System.out.println("unit------------------- "+unit);
//enterunitTxtBox.sendKeys(unit);
String minprice= s.getCell(3, row).getContents();
System.out.println("min price------------------- "+minprice);
//enterminpriceTxtBox.sendKeys(minprice);
String maxprice= s.getCell(4, row).getContents();
System.out.println("max price------------------- "+maxprice);
//entermaxpriceTxtBox.sendKeys(maxprice);
addcommodity.EnterAddCommoditiesData(grade,unit,minprice,maxprice);
}
wait=new WebDriverWait(driver,10);
WebElement commodityname= wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div/div[4]/div/section[2]/div[4]/d-expand-collapse[1]/div/div/div[1]/h4/a")));
String commoditynamejustadded= commodityname.getText();
System.out.println("name--------------"+commoditynamejustadded);
assertEquals(commoditynamejustadded, "Rice");
}
}
TestNG code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Login check">
<classes>
<class name="SourceSmartWeb.LoginWeb"/>
<class name = "SourceSmartWeb.AddCommoditiesWeb">
<methods>
<include name="AddMultipleNewCommodities"/>
</methods>
</class>
<class name ="SourceSmartWeb.LogoutWeb"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Logout class:
public class LogoutWeb{
WebDriver driver;
// @BeforeClass
// public void beforeClass (){
// System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
// driver=new ChromeDriver();
// driver.manage().window().maximize();
// driver.get("http://10.7.1.180/views/index.html#/login");
// System.out.println(driver.getTitle());
// super.beforeClass();
//
// }
@Test
public void Logout() throws InterruptedException {
LogoutScreen logout=new LogoutScreen(driver);
logout.ClickToLogout();
}
@AfterClass
public void exit(){
driver.quit();
}
}
What its doing is it opens the browser logins and then do nothing. How can i make it do rest of activities on same browser as if i add before class in second class it opens a new browser and then there i dont have login code. please guide
From what you are stating, it looks like you need to basically have a browser spawned per <test>
tag and then share that browser amongst all your test classes. But you cannot make use of the @BeforeTest
and @AfterTest
annotations because you would need to bring in inheritance into the picture and since these methods are executed only once per <test>
you will start seeing NullPointerException
.
So the idea is to basically leverage TestNG listeners for this webdriver instantiation and cleanup and have your test classes/methods just query them from within a helper method.
Here's some sample code, that shows all of this in action.
Here's how the listener would look like
package com.rationaleemotions.stackoverflow.qn46239358;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
public class WebdriverSpawner extends TestListenerAdapter {
private static final String WEBDRIVER = "webdriver";
@Override
public void onStart(ITestContext testContext) {
testContext.setAttribute(WEBDRIVER, createDriver());
}
@Override
public void onFinish(ITestContext testContext) {
getWebDriverFromContext(testContext).quit();
}
public static RemoteWebDriver getCurrentWebDriver() {
ITestResult result = Reporter.getCurrentTestResult();
if (result == null) {
throw new IllegalStateException("Please invoke this from within a @Test annotated method");
}
ITestContext context = result.getTestContext();
return getWebDriverFromContext(context);
}
private static RemoteWebDriver getWebDriverFromContext(ITestContext context) {
Object object = context.getAttribute(WEBDRIVER);
if (!(object instanceof RemoteWebDriver)) {
throw new IllegalStateException("Encountered problems in retrieving the webdriver instance");
}
return (RemoteWebDriver) object;
}
private static RemoteWebDriver createDriver() {
return new ChromeDriver();
}
}
Here's how your test classes which now use this above listener can look like (I have intentionally kept it simple and have it open up just a URL, but if you run them you would notice a single browser opening up multiple URLs. So only one browser instance)
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class LoginWeb {
@Test(description = "Valid Credentials!")
public void LoginWithValidWebExcelEmailAndPass() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.google.com"));
}
}
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class LogoutWeb {
@Test
public void Logout() throws InterruptedException {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.facebook.com"));
}
}
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class AddCommoditiesWeb {
@Test(description = "Add Multiple Commodities!")
public void AddMultipleNewCommodities() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.yahoo.com"));
}
@Test
public void anotherTestMethod() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.ndtv.com"));
}
}
The PageLoader utility class looks like this
package com.rationaleemotions.stackoverflow.qn46239358;
import org.openqa.selenium.remote.RemoteWebDriver;
public final class PageLoader {
private PageLoader() {
//Utility class defeat instantiation
}
public static String loadAndGetTitle(String url) {
RemoteWebDriver driver = WebdriverSpawner.getCurrentWebDriver();
driver.get(url);
return driver.getTitle();
}
}
Here's how the suite xml looks like :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="46216357_Suite" verbose="2">
<listeners>
<listener class-name="com.rationaleemotions.stackoverflow.qn46239358.WebdriverSpawner"/>
</listeners>
<test name="Login_check">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46239358.LoginWeb"/>
<class name="com.rationaleemotions.stackoverflow.qn46239358.AddCommoditiesWeb">
<methods>
<include name="AddMultipleNewCommodities"/>
</methods>
</class>
<class name="com.rationaleemotions.stackoverflow.qn46239358.LogoutWeb"/>
</classes>
</test>
</suite>
So here none of your @Test
classes invoke driver.quit()
explicitly. The webdriver cleanup is managed by the listener.
This model is going to work only when you want to run multiple tests on the same browser.
The flip side of this would be that, you can NEVER run your @Test
methods in parallel, because now all your tests are sharing the same browser.