Sharing single instance of class across multiple tests - selenium

I am using Page object pattern with selenium webdriver and testng.
I want to access instance of one page object class in another class across multiple <test>.
for e.g.
<test name="Login scenario">
<classes>
<class name="sanitytests.LoginTests">
<methods>
<include name="validLogin"/>
</methods>
</class>
</classes>
</test>
<test name="scenario2" preserve-order="true" parallel="false">
<classes>
<class name="sanitytests.HomePageTests">
<methods>
<include name="clickOnMyAccountFromHome"/>
</methods>
</class>
</classes>
</test>
in my LoginTests class I am using instance of homePage class
#Test()
public void validLogin(ITestContext context) throws Exception {
loginPage.loginDetails(username,password);
homePage = loginPage.loginAsValidUser();
context.setAttribute("homePage",homePage);
}
my HomePageTests class
#Test()
public void clickOnMyAccountFromHome(ITestContext context) throws Exception {
homePage = (HomePage) context.getAttribute("homePage");
myAccountPage = homePage.navigateToMyAccountPage();
context.setAttribute("myAccountPage", myAccountPage);
}
i am getting null pointer exception because ItestContext is used to share parameter between methods not between tests. Is there any alternative?

From what i have read about "ITestContext", it is related to TestNG classes/objects/methods. You can create the HomePage as a static and it will be available for entire suite run.

The page object pattern does not state that objects can only be created once. Create new instances in each test.

Related

extent report with one master test class

i have created 2 different test classes (test1.java and test2.java), having multiple tests in each class. to simplify, i have created one master test class, in which i have created 2 tests and called the methods from test1page.java and test2page.java. now when i create the extent reports it only gives 2 results. i want all the test result which i have created in test1.java and test2.java.
below is my MasterTest.java
public class MasterTest extends TestBase {
#BeforeClass()
//before class method
#Test(priority=1)
// methods from the test1page.java class
#Test(priority=2)
// methods from the test2page.java class
#AfterClass
}
below is my xml file to run
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="smoke">
<listeners>
<listener class-name="report.TestListener" />
</listeners>
<test name="master">
<classes>
<class name="tests.MasterTest">
</class>
</classes>
</test>
</suite>

How to launch & use separate browser for each test method inside a class

I have the below scenario
All the 3 tests run, but they are sharing only 1 browser. I have all the common methods for all the clicks etc in a Base class.
I want each of the test method -method1/2/3 to launch different browser & work,
Can somebody help?
Class A extends BaseTest{
#BeforeMethod(){
initDriver();// it does setdriver & getDriver is used across
}
public void doStuff(){
...
}
#Test
public void method1(){
doStuff()
}
#Test
public void method2(){
doStuff()
}
#Test
public void method3(){
doStuff()
}
}
You can use TestNG.xml to parameterized and control your execution as below. Here we ahve created 3 different tests , each one of them is parameterized with browser type variable and running one of your #test method.
TestNG.XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="TestChrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method1" />
</methods>
</classes>
</test>
<test name="TestForefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method2" />
</methods>
</classes>
</test>
<test name="TestIE">
<parameter name="browser" value="edge"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method3" />
</methods>
</classes>
</test>
</suite>
Get the browser type parameter in your #BeforeMethod.
#Parameters ({"browser"})
#BeforeMethod(){
initDriver(browser);/* it does setdriver & getDriver is used across. Passing browser name
to initDriver method.*/
}
Now in initDriver() method ( wherever you have implemented it), set driver based on your browser type. Something similar to below:
public void initDriver(String browser) throws Exception{
if(browser.equalsIgnoreCase("firefox")){
System.setProperty("webdriver.gecko.driver", ".\\geckodriver.exe");
driver = new FirefoxDriver();
}
else if(browser.equalsIgnoreCase("chrome")){
System.setProperty("webdriver.chrome.driver",".\\chromedriver.exe");
driver = new ChromeDriver();
}
else if(browser.equalsIgnoreCase("Edge")){
System.setProperty("webdriver.edge.driver",".\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
else{
throw new Exception("Browser is not correct");
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.window().maximize();
}
Note: Using include/exclude tag in TestNg.xml file you can run/ignore any #Test methods inside a test.

Error when calling dependency of one method of another class into other class in TestNG automation

I want to add dependency of one test method from class A to another testMethod in class B.
Whenever I am running method "testTwo()" from class B I am getting error as
"method B.testTwo() depends on nonexistent group A.Group1" , my class structure is as below .
public class A
{
#Test(groups={"A.Group1"})
public void testOne(){}
}
public class B
{
#Test(dependsOnGroups={"A.Group1"})
public void testTwo(){}
}
Can anyone please guide here ?,
also My test.xml looks like below
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="TEST-AUTOMATION" thread-count="1"
preserve-order="true" data-provider-thread-count="1">
<test name="TESTS">
<classes>
<class name="A"/>
<class name="B"/>
</classes>
</test>
</suite>

How to run test cases in different Java classes in a new window every time using TestNG and Selenium

I have 15 test methods in 3 Java classes (Selenium Script). I want to run each Test class with new window. I am using TestNg framework.
Here is the code of TestNG:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Fanfight Test" thread-count="10" parallel="methods">
<listeners>
<listener class-name="com.fanfight.test_case.ListenerClass">
</listener>
</listeners>
<test name="User Login" parallel="false">
<classes>
<class name="com.fanfight.test_case.UserLogin"></class>
</classes>
</test>
<test name="Contest Creation" parallel="false" >
<classes>
<class name="com.fanfight.test_case.ContestCreation"></class>
</classes>
</test>
<test name="User Profile Test" parallel="false" >
<classes>
<class name="com.fanfight.test_case.UserProfileTest"></class>
</classes>
</test>
<test name="Menu Bar Test" parallel="false">
<classes>
<class name="com.fanfight.test_case.MenuBarTest">
</class>
</classes>
</test>
<test name="Home Page Elements" parallel="false" >
<classes>
<class name="com.fanfight.test_case.HomePageElementTest"></class>
</classes>
</test>
</suite>
Without using parallel="false" my script is running in alphabetical order due to which selenium unable to find the path and execution got stuck.
Also please suggest how to make execution continue even after getting an exception during execution.
Add a setup and tear down method in each of the 3 test classes. The setup method should launch the browser and teardown method should close that browser instance.
class TestOne {
WebDriver driver;
#BeforeClass
public void setup(){
driver = new ChromeDriver();
}
#Test
public void testCase1(){
}
//.... Other test methods
#AfterClass
public void tearDown(){
driver.quit();
}
You can also create a parent class having just the setup and tear down methods , pseudo coded above. All 3 of your test class shall extend this parent class. It will be an optimised approach as the driver instantiation and destruction is now centralised to a single class.
And finally , change the parallel attribute in the suite tag of your testNG xml, in order to make them run parallel.
<suite name="Fanfight Test" thread-count="10" parallel="classes">

will testng initiate as many webdriver instance as test cases?

I am facing a problem of Selenium Grid and TestNG. My test scripts will NOT quite the browser until all the test class are executed.
I've configed 5 Chrome instance running on my Selenium Grid, then below is my xml file
<suite name="BrowserTest">
<test name="Test1" >
<parameter name="browserName" value="chrome"/>
<classes>
<class name= "Pagetest" />
</classes>
</test>
<test name="Test2" >
<parameter name="browserName" value="firefox"/>
<classes>
<class name= "Pagetest" />
</classes>
</test>
<test name="Overview Page Test on ie, English" >
<parameter name="browserName" value="ie"/>
<classes>
<class name= "Pagetest" />
</classes>
</test>
</suite>
Here is my test scripts
public class Pagetest {
private WebDriver browser;
public PateTest( String browser){
// create a browser instance.
}
#AfterClass (or #afterTest)
public void afterTest() throws Exception {
System.out.println("this test is done");
this.browser.quit();
}
#Test
public void test1(){
this.browser.get("www.google.com");
// doing some login stuff
}
}
Now when I am running my test, testNG will create 3 chrome webdirver instance one by one (with running the test). but after the 1st test is done, the browser instance of 1st test is not quited until all 3 tests are done, then all the 3 chrome instance are quited almost at the same time. What I want is after the 1st test is done, it's browser instance is quited, then the 2nd test case is started, did I do something wrong or how should I change my code?
Try using threadlocal it would help when you are even running tests in parallel
public ThreadLocal<WebDriver> driver=null;
#beformethod()
public void setUp
{
driver = new ThreadLocal<WebDriver>();
driver.set(new ChromeDriver());
return driver.get();
}
#AfterMethod
public void closeBrowser() {
{
driver.get().quit();
}