Selenium and TestNG all test in one browser - java

I have abstract class, where initialize webdriver. All classes with the implementation of the tests are inherited from him. I want to reduce the time of test, open a browser for all tests.
class AbstractClassCase {
public static WebDriver driver;
#BeforeClass
#Parameters({"webDriver", "applicationHost", "applicationPort", "driverHost", "driverPort", "username", "password"})
public void setUp(
String webDriverIdentifier,
String applicationHost,
#Optional String applicationPort,
#Optional String driverHost,
#Optional String driverPort,
#Optional String username,
#Optional String password){
driver = new FirefoxDriver();
driver.get("localhost");
login(username, password)
}
#AfterСlass
public void tearDown() {
driver.quite();
}
}
public class TestButton extends AbstractClassCase {
#Test
public void testClickButtonNo() {
WebElement button = driver.findElement(By.id("button-no"));
button.click();
WebElement status = driver.findElement(By.id("button-status"));
Assert.assertEqual("Cancel", status.getText());
}
}
and other test class in the same spirit.
How can I reconfigure this class, so that the browser opened once?

If you want to Open Browser at the start once and run all the methods and then close it.
There are 2 steps i would recommend to follow.
Step 1:
Include browser invocation code in methods with #BeforeSuite && #AfterSuite for closing the browser/driversession. This makes sure these tests are run once before and after test suite.
protected static WebDriver Browser_Session;
#BeforeSuite
public void beforeSuite() {
Browser_Session=new FirefoxDriver();
Browser_Session.manage().timeouts().implicitlyWait(30000, TimeUnit.MILLISECONDS);
}
#AfterSuite
public void afterSuite() {
Browser_Session.quit();
}
Step2 : Open testng.xml and include all such classes (test methods) under a single Suite, Thus making sure the browser (via Selenium) is invoked first and then rest all methods are run in the same browser.
Here "Class Init" contains Browser Initiating code and ClassA & ClassB are subclassess of Init.
Hope this helps

If you want to run all test in one instance, i wrote my own WebDriverFactory so here is some examples for help:
public static WebDriver getDriver(){
if (driver == null) {
return new FireFoxDriver();
} else {
return driver;
}
}
Now remove AfterClass and add this to your class it will shutdown your browser in the end
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
dismissDriver();
} catch (Exception e) {
}
}
});
}
public static void dismissDriver() {
if (driver != null) {
try {
driver.quit();
driver = null;
} catch (Throwable t) {
}
}
}

Related

Extent Report 3 Add Screenshot

I"m trying to build selenium with extent report but i could not get the save screenshot function working because i cannot reference the WebDriver object in the ITestListener class. Below is my sample code:
Test Runner.java:
#Listeners({com.peterwkc.Listener.TestListener.class})
public class ChromeTestManager {
private WebDriverManager webDriverManager = new WebDriverManager();
private WebDriver driver;
private LoginPages loginPages;
private AdminPages adminPages;
#BeforeClass
//#Parameters({"browser"})
public void setupTest(/*String browser*/) throws MalformedURLException {
System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
// Set & Get ThreadLocal Driver with Browser
webDriverManager.createDriver("chrome");
driver = webDriverManager.getDriver();
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
}
#DataProvider(name = "loginCredentials")
public static Object[][] getLoginCredentials() {
return new Object [][] {{ "Admin123", "admin123" }, {"testUser", "test"}, {"test", "test"}};
}
#Test(groups= {"Login"}, description="Invalid Login", priority = 0, dataProvider = "loginCredentials", invocationCount = 3)
public void login_invalid(String username, String password) {
loginPages.login_invalid(driver, username, password);
}
}
TestListener.java
public class TestListener implements ITestListener {
//Extent Report Declarations
private static ExtentReports extent = ExtentManager.createInstance();
private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();
public TestListener() {
}
#Override
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail("Exception Error : \n" + result.getThrowable());
/*String feature = getClass().getName();
String screenShot;
try {
screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
test.get().addScreenCaptureFromPath(screenShot);
test.get().log(Status.FAIL, screenShot);
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}*/
}
}
Questions:
How to pass the WebDriver object from TestRunner.java to TestListener
class?
How to save screenshot in extent report 3?
Anything wrong with my code?
please help, thanks in advance!
Below are the steps to do this :
1 : Passing WebDriver object to Listener class
First create below method in ChromeTestManager class or at any another location from where you can call it, here suppose that it is present in ChromeTestManager class:
public static ITestContext setContext(ITestContext iTestContext, WebDriver driver) {
iTestContext.setAttribute("driver", driver);
return iTestContext;
}
It will set the driver object to the TestContext.
Now change your #BeforeClass setUp method to accept parameter ITestContext, below is the code :
public class ChromeTestManager {
private WebDriverManager webDriverManager = new WebDriverManager();
private WebDriver driver;
private LoginPages loginPages;
private AdminPages adminPages;
private static ITestContext context; // creating a ITestContext variable
#BeforeClass
//#Parameters({"browser"})
public void setupTest(ITestContext iTestContext) throws MalformedURLException {
System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
// Set & Get ThreadLocal Driver with Browser
webDriverManager.createDriver("chrome");
driver = webDriverManager.getDriver();
this.context = setContext(iTestContext, driver); // setting the driver into context
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
}
When you run this, it will run smoothly and will not produce an error (If you are thinking that how I will pass ITestcontext context, It is handled internally)
Now the driver has been added as an object to the ITestcontext ;
Now Accessing the driver in Listener :
#Override
public synchronized void onTestFailure(ITestResult result) {
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // here we are accessing the driver object that we added in Test class
}
2. Saving ScreenShot in extent report 3 (I am using dependency 3.1.5 in maven)
#Override
public synchronized void onTestFailure(ITestResult result) {
System.out.println("!!!!!!!!!!!!!!!!!!!! Test Failed !!!!!!!!!!!!!!!!!!!!");
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // accessing driver here
String feature = getClass().getName();
String screenShot;
try {
screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
test.addScreenCaptureFromPath(screenShotPath); // I am assuming that the "screenShot" is fully qualified path with extension e.g "C:\Users\12345\Desktop\sfgfdh.PNG"
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}
}
3. Is there anything wrong with your code ?
No
You just need driver in Listener class and while adding screenshot in extent report ,
make sure that the path to screenshot is correct and is fully qualified path with extension.
Please let me know if you face an issue in this.
First of all don't instantiate Your webDriver in #BeforeClass, because this is called only once as annotation say before class, try using interface ITestListener and using beforeInvocation implementation for initialisation of WebDriver.
Second, You can't call PageFactory for all PageObjects at once, how do You think all 3 pages are initialised at once, this should be achieved in constructor for each page object, and when You init you page object (new Login) the elements are initialised as well, so this is not ok:
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
Third I don't see initialisation of ExtentReport test. It should looks something like this:
ExtentTest extentTest = ExtentTestManager.startTest(method.getName(), "");
Here is an example part of code from my implementation of calling screenshot, I'am calling it from afterInvocation, because I'm using concurrent driver initialisation, and so it had to be from here, but also can be achived via onTestFailure implementation:
public synchronized void afterInvocation(IInvokedMethod method, ITestResult testResult){
if (method.isTestMethod() && testResult.getStatus()==2) {
File scrFile = (dataMethod.getAndroidDriver()).getScreenshotAs(OutputType.FILE);
String dest = System.getProperty("user.dir") + "/resources/screenshots/" + dataMethod.getDriver().getSessionId() + ".png";
File destination = new File(dest);
try {
FileUtils.copyFile(scrFile, destination);
dataMethod.setScreenshotPath(destination.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
System.err.println("Path:" + dataMethod.getScreenshotPath());
}
You have to think more about structure,
Hope this helps...

How to quit the page if i type hello world on google search using selenium?

Hi guys I want to quit the page afte I type "Hello World" in google search using firefox browser and selenium
WebDriver driver = null;
public static void main(String args[]) {
SimpleSelenium ss = new SimpleSelenium();
ss.openBrowser();
ss.getPage();
ss.quitPage();
}
private void openBrowser() {
System.setProperty("webdriver.gecko.driver", "C:/geckodriver.exe");
driver = new FirefoxDriver();
}
private void quitPage() {
driver.quit();
}
private void getPage() {
driver.get("http://www.google.com");
}
1) Create a Junit test class
2) Initialize the driver in your setup method like
ChromeDriver driver = new ChromeDriver();//Download chromeDriver.exe file and point to location where you have installed the like as you mentioned. `driver.System.setProperty("webdriver.gecko.driver", "C:/geckodriver.exe");`
3) Create a test method with your business logic to type hello world
3) Create After and Before Class annotations for the methods .In After class annotation method you can write driver.quit.
You can refer to following link for more clarity
https://www.guru99.com/selenium-tutorial.html
I am Added sample format which is written Using java and testNG..Here Every time First before method will run then 1st test case will execute then after method will work then again before method work then next test case......In this way you can manage your test case and it will also generate Report also.Here you will get better explanation.
public class GoogleTest {
FirefoxDriver driver;
#BeforeMethod
public void setUp1() throws Exception {
System.setProperty("webdriver.gecko.driver", "D:\\\\ToolsQA\\trunk\\Library\\drivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.google.com");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void GoogleInputField() throws InterruptedException {
System.out.println("Hello world");
System.out.println("Hello world");
//Write Your test case for test case 1
}
#Test
public void google suggestion() throws InterruptedException {
//Write Your test case for test case 1
}
#AfterMethod
public void getResult(ITestResult result) throws IOException {
driver.quit();
}
}
Dont forget to add Firefox driver on gecko.driver path
I am assuming that you want to open the browser using selenium, load google and then listen till you MANUALLY enter "hello world" in the input box. The method listenForHelloWorld() will do that.
public static void main(String args[]) {
SimpleSelenium ss = new SimpleSelenium();
ss.openBrowser();
ss.getPage();
ss.listenForHelloWorld();
ss.quitPage();
}
private void listenForHelloWorld() {
// Get the search field
WebElement searchField = driver.findElement(By.name("q"));
int count = 1;
while (count++ < 20) {
// if search field value is "hellwo world" break loop which will eventallu lead to `quit()` as it is the next method to exit.
if (searchField.getAttribute("value").equalsIgnoreCase("hello world")) {
break;
}
Thread.sleep(5000)
}
}
If you are asking how to enter "hello world" in browser automatically use below.
driver.findElement(By.name("q")).sendKeys("hello world");

Possible to create a 'Master Step' within Cucumber (java)?

Possible to create a 'Master Step' within Cucumber (java)?
For example I have created many steps files which use repeated code, the repeated code initialises the browser etc within each of the step files.
Is it even possible to create a master step file which will which will house the driver setup etc and therefore execute the setup using 'Cucumber Before' before each of the steps.
My Code:
public class LoginStep {
WebDriver driver;
LoginPage loginPage;
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\deltaUser\\Desktop\\CucumberFramework\\PimCucumberFramework\\src\\test\\java\\resources\\other\\chromedriver.exe");
this.driver = new ChromeDriver();
this.driver.manage().window().maximize();
this.driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
loginPage = PageFactory.initElements(driver, LoginPage.class);
}
#Given("^User is on the PIM login page$")
public void user_is_on_the_PIM_login_page() throws Throwable {
loginPage.loginIntoAccount();
// loginPage.test();
}
#And("^enters the correct username$")
public void enters_the_correct_username() throws Throwable {
System.out.println("User neters the correct password inside the password textefield");
// loginPage.test2();
}
#And("^enters the correct password$")
public void enters_the_correct_password() throws Throwable {
System.out.println("Entered the correct password");
}
#When("^clicks on the login button$")
public void clicks_on_the_login_button() throws Throwable {
System.out.println("Clicked on the login button");
}
#Then("^user should be taken to the successful login page$")
public void user_should_be_taken_to_the_successful_login_page() throws Throwable {
System.out.println("Succesffully taken to the login page.");
}
}
I have tried the following code listed below, but the code dosnt work it seems to open the browser but then the other steps dont work (As if it has created a separate instance of the driver):
public class MasterStep {
WebDriver driver;
LoginPage loginPage;
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\gianni.bruno\\Desktop\\BuyAGiftCucumberFramework\\PimCucumberFramework\\src\\test\\java\\resources\\other\\chromedriver.exe");
this.driver = new ChromeDriver();
this.driver.manage().window().maximize();
this.driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
loginPage = PageFactory.initElements(driver, LoginPage.class);
}
}
Yes, it is possible. Use the concept of Inheritance.
Step 1: Create a Base Class
package com.base;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class TestBase2 {
public static WebDriver driver = null;
public void initialize() {
System.setProperty("webdriver.chrome.driver", "src/com/drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("https://www.google.co.in");
}
}
Step 2: Inherit this class using the extends keyword and call the initialize() method whenever you need.
Cucumber provides Before and After hooks you could use for this.
Hooks are blocks of code that can run at various points in the Cucumber execution cycle. They are typically used for setup and teardown of the environment before and after each scenario.
Before hooks run before the first step of each scenario.
Annotated method style:
#Before
public void doSomethingBefore() {
}
Lambda style:
Before(() -> {
});
After hooks run after the last step of each scenario, even when steps are failed, undefined, pending, or skipped.
Annotated method style:
#After
public void doSomethingAfter(Scenario scenario){
// Do something after after scenario
}
Lambda style:
After((Scenario scenario) -> {
});
The scenario parameter is optional, but if you use it, you can inspect the status of the scenario.

Selenium Webdriver TestNG tests are "overwriting" each other

I am trying to run Selenium Webdriver tests in parallel on a single machine, using TestNG. I have 3 #Test methods, where 3 different users log in to the same application and reach the home page. I need #Test methods to run in parallel, and write to an ExtentReports report.
My problem is, despite 3 completely different methods in different classes, one of the users will be logged into 2 out of 3 of the browsers, leaving a user out.
The login method is located in a PageFactory page object class.
Here are my 3 test methods:
#Test(enabled = true, priority = 0)
public void JohnLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "John";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("John"));
} catch (Exception e) {
}
}
#Test(enabled = true, priority = 1)
public void BobLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "Bob";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("Bob"));
} catch (Exception e) {
}
}
#Test(enabled = true, priority = 2)
public void SamLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "Sam";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("Sam"));
} catch (Exception e) {
}
}
So, if I pause the tests on the Homepage. I will have 2 browser windows opened as "John", one "Bob" and no "Sam"... Causing failures.
Here's the PageFactory Object's login method.
public void SignIn(String strUsername, String strPassword) throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 15);
username.clear();
username.sendKeys(strUsername);
password.clear();
password.sendKeys(strPassword);
submit.click();
wait.until(ExpectedConditions.visibilityOf(homePagePanel));
}
At first I was sure the problem was in the #BeforeMethod threading (As in, the tests were in a different thread than the #Before and #After). But I don't see how that could be the case. The Base Test method successfully opens and closes 3 browsers. It just seems like the #Test methods use each other's data! But just in case, here's my #Before and #After, with my Threading code.
public class BaseTest {
public String browser;
private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
#BeforeMethod(alwaysRun = true)
#Parameters({ "browser"})
public void setup(String browser)throws MalformedURLException,
InterruptedException {
WebDriver driver = null;
if (browser.equalsIgnoreCase("Internet Explorer")) {
System.setProperty("webdriver.ie.driver", "C:\\Selenium\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
} else if (browser.equalsIgnoreCase("Firefox")) {
System.setProperty("webdriver.gecko.driver", "C:\\Selenium\\geckodriver.exe");
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe");
driver = new ChromeDriver();
} else if (browser.equalsIgnoreCase("MicrosoftEdge")) {
System.setProperty("webdriver.edge.driver", "C:\\Selenium\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
setWebDriver(driver);
this.browser = browser;
ClientReportFactory.getTest(ExtentTestName, ExtentTestDescription);
baseURL = "testApp.com";
driver.get(baseURL);
driver.manage().window().maximize();
}
public WebDriver getDriver(){
return threadedDriver.get();
}
public void setWebDriver(WebDriver driver) {
threadedDriver.set(driver);
}
#AfterMethod
public void afterMethod() {
ClientReportFactory.closeTest(ExtentTestName, ExtentTestDescription);
getDriver().quit();
threadedDriver.set(null);
}
#AfterSuite
public void afterSuite() {
ClientReportFactory.closeReport();
if (getDriver() != null) {
getDriver().quit();
} else {
System.out.println("Drivers already closed");
}
}
Assuming that all of your #Test methods are in different classes, I am guessing that the problem is perhaps due to the fact that your ThreadLocal variable is NOT STATIC but is an instance variable. This causes the behaviour to be per thread per instance rather than the desired behaviour viz., per thread across all instances. You can refer to this StackOverFlow thread for a better explanation on this.
You would resort to using an instance variant of ThreadLocal if and only if all your #Test methods belong to the same test class (Because now you are only trying to ensure that the class level data member WebDriver is shared in a thread safe manner across all the test methods that belong to the same test class)
So if each of your #Test methods reside in its own Test class, then please try changing:
private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
to
private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
You could try this.
public class DriverFactory(){
private static ThreadLocal<WebDriver> driverThread;
public WebDriver driver;
#Parameters("browser")
public WebDriver instantiateDriverObject(String browser) {
DriverFactory factory = new DriverFactory();
driver = factory.createInstance(browser); //Driver instantiation goes here
driverThread = new ThreadLocal<WebDriver>() {
#Override
protected WebDriver initialValue() {
webDriverPool.add(driver);
return driver;
}
};
return driver;
}
public WebDriver getDriver() {
return driverThread.get();
}
}

Selenium Webdriver: How do I run multiple tests, one after the other in the same window?

My goal is to have a series of tests run one after the other. I would like to have a "login" script log the user in and then the following scripts kick off continuing in the same window/driver. I'm using TestNG so my test suite is setup in the testng.xml file if that helps.
public class LoginScript {
String username, password, siteid;
private WebDriver driver;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
static Logger log = Logger.getLogger(LoginScript.class);
#BeforeSuite (alwaysRun=true)
#Parameters({ "url","username","password","site" })
public void setUp(String env, String user, String pwd, String ste) throws Exception {
username=user;
password=pwd;
siteid=ste;
driver = new FirefoxDriver();
driver.get(env);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Test
public void testLoginScript() throws Exception {
//Maximize window
driver.manage().window().maximize();
//Login
driver.findElement(By.id("TBSiteID")).clear();
driver.findElement(By.id("TBSiteID")).sendKeys(siteid);
driver.findElement(By.id("TBUserName")).clear();
driver.findElement(By.id("TBUserName")).sendKeys(username);
driver.findElement(By.name("TBPassword")).clear();
driver.findElement(By.name("TBPassword")).sendKeys(password);
driver.findElement(By.name("Login")).click();
Thread.sleep(2000);
log.info("Found requested site");
}
#AfterSuite
public void tearDown() throws Exception {
//driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
private boolean isAlertPresent() {
try {
driver.switchTo().alert();
return true;
} catch (NoAlertPresentException e) {
return false;
}
}
private String closeAlertAndGetItsText() {
try {
Alert alert = driver.switchTo().alert();
String alertText = alert.getText();
if (acceptNextAlert) {
alert.accept();
} else {
alert.dismiss();
}
return alertText;
} finally {
acceptNextAlert = true;
}
}
}
Next script that I would like to run:
public class AddNormalEE {
String username, password, siteid;
private WebDriver driver;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
static Logger log = Logger.getLogger(AddNormalEE.class);
#BeforeSuite (alwaysRun=true)
#Parameters({ "url","username","password","site" })
public void setUp(String env, String user, String pwd, String ste) throws Exception {
username=user;
password=pwd;
siteid=ste;
//driver = new FirefoxDriver();
//driver.get(env);
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Test
public void testAddNormalEE() throws Exception {
//Maximize window
//driver.manage().window().maximize();
#AfterSuite
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
private boolean isAlertPresent() {
try {
driver.switchTo().alert();
return true;
} catch (NoAlertPresentException e) {
return false;
}
}
private String closeAlertAndGetItsText() {
try {
Alert alert = driver.switchTo().alert();
String alertText = alert.getText();
if (acceptNextAlert) {
alert.accept();
} else {
alert.dismiss();
}
return alertText;
} finally {
acceptNextAlert = true;
}
}
}
If your tests are dependent, you can put them in the same class with dependsOnMethod={method1} defined on method2 so that the order is gauranteed. If it is between different classes, you might consider extending your AddNormalEE class from the LoginScript class.
To run tests in the same browser, your driver instance needs to be shared between your classes or it has to be the same in all your #Tests. Either make it static or consider having a threadlocal webdriver variable in case you plan to run parallely some day.
In the above case, you can also have a method getDriver() in your loginScript which returns the driver object to the AddNormalEE class if static needs to be avoided.
As a general practice, it is good to have independent tests. You can make use of parallel runs to overcome the time issue with independent tests. Making login as a method and not a test since we are not asserting any behavior as per your code above. If I am testing login, I would have separate tests that test login functionality only.
Each test in a test class should perform the test using a new browser session, This can be easily done by putting the browser invoke and the kill process in a base Test class and extends this class in each test class.
The usual way that Selenium people write tests is to open a separate browser per test class, which is sorta how "Selenium Grid" is designed to operate. I usually put one test method per test class. If you want multiple test methods per class, and the app your testing does not care about the order you run those methods, then in theory you could run those multiple test methods on a single browser. I've done that before but, from my experience, it is not a good idea to design Selenium tests with that pattern, and so you can do it, but I recommend against it.
For example, with one test method per test class, in your #BeforeMethod you can instantiate the WebDriver browser instance and then in the #AfterMethod you can kill it. With multiple tests per class, you'd have to use #BeforeTest and #AfterTest, which can be done but your results may vary depending on how careful you are.
I am not really clear on your question. If you want to use the same driver object across tests then create a static driver object and pass it on to the test methods and dont kill it. Or am i missing something .

Categories

Resources