How to implement the DriverSetup class in Selenium Webdriver framework - selenium

How to implement the DriverSetup class in Selenium Webdriver framework..
Currently I am launching driver in #BeforeClass for each testng test class, please let me know if how can I implement the common driverLaunch/driverSetup class for all test
Thanks in Advance..

Did u mean a common setup for all classes? If so create a base class and extend it in every test class. In Base class have #BeforeClass to do the required.
It would be somewhat like:
public class BaseClass {
WebDriver driver;
#BeforeClass
public void setUp() {
driver = new FirefoxDriver(); // or any driver u want, or based on requirement create a if else scenario
}
}
And in Testclass do like:
public class TestClass extends BaseClass {
// your class body with tests here
}
So whenever u run ur tests through testng it will call the setUp method in BaseClass and setup browser for u.

Init your WebDriver in #BeforeTest or in #BeforeSuite and close it in #AfterTest or #AfterSuite. So in this case every test method will get run in the same browser.

Related

Explanation required for WebDriver object mapping using Selenium

While creating WebDriver object we use, for example
WebDriver driver = new ChromeDriver();
Why it cannot be as below,
WebDriver driver = new WebDriver();
Just wanted to know the reason for this.
WebDriver is an interface, we can not create an instance of it.
where as ChromeDriver is a class which extends RemoteWebDriver class.
and RemoteWebDriver class basically implements WebDriver Interface.
so writing new WebDriver(); is not valid in Java, since we can not create object of Interface. This will result in compile time error.
Internal Implementation of WebDriver Interface :
public interface WebDriver extends SearchContext{
void get(String url);
String getCurrentUrl();
// and so on....
}
all the methods which are present above are overridden in RemoteWebDriver

How can I control how many JUnit5 Test Instances are going to be generated in Runtime and apply separate ParameterResolver to each of the instance

I'd like to execute Selenium Grid tests using Maven like this:
mvn verify-Dtest=BaseTest -Dprop.selenium.server.url=http://localhost:4444/wd/hub
-Dprop.browser=chrome
-Dprop.version=80.0.3987.106
I inject ChromeDriver into Test constructor using JUnit5 ParameterResolver interface
#ExtendWith(ChromeRemoteWebDriverParameterResolver.class)
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MultiBrowserDemoTest {
RemoteWebDriver driver;
public MultiBrowserDemoTest(RemoteDriver driver) {
this.driver = driver.getDriver();
}
#SneakyThrows
#Test
public void testGrid() {
driver.get("https://www.google.com/");
WebElement search = driver.findElement(By.name("q"));
search.sendKeys("JUnit5 extensions");
search.submit();
}
#AfterAll()
void tearDown() {
driver.quit();
}
}
It works fine. But I can't see how to implement multi-browser test execution.
Let's say, I want to add multiple browsers -Dprop.browser=chrome, firefox, opera, ie11
I created multiple classes implementing ParameterResolver Interface. But JUnit5 does not let me inject them all into my Test Class. It does not create new instances of Test class either.
I tried to use TestInstanceFactory to create new Instances of my Test class and apply separate implementation of ParameterResolver interface, but it did not work for me.
End Result: I can run the same test in multiple browsers in parallel using Selenium Grid and only one Test Class that I will be able to instantiate multiple times with separate webdriver.
If I understood your scenario correctly, what you are asking for is support for what we call "parameterized containers" (i.e., something analogous to #ParameterizedTest but at the class level), which does not exist yet in JUnit Jupiter.
See JUnit Jupiter issues #871 and #878 for details.

How did TestNg annotation mentioned in one class get executed from another from another class?

While learning Testng on Udemy, I come across a code which I am unable to understand. Instructor has created class named "testcore" where he defined #BeforeMethod/#aftermethod.Later he created another class named "LoginTest" where he wrote actual test with #test. He extended testcore class in loginTest to get variable initiated in testcore class. When he ran loginTest then #BeforeMethod/#aftermethod also ran with this. How did these two method ran along with #test when these methods are in different class.
here are both codes:
public class testcore {
public static Properties config = new Properties();
public static Properties obj = new Properties();
public static Xls_Reader xls = null;
public static WebDriver driver;//=null;
#BeforeMethod
public void init() throws Exception{
if(driver==null) {
// Loading Config Properties File
File Config_f = new File(System.getProperty("user.dir")+"\\src\\dd_Properties\\config.properties");
FileInputStream fs = new FileInputStream(Config_f);
config.load(fs);
// Loading Object Properties File
File Obj_f = new File(System.getProperty("user.dir")+"\\src\\dd_Properties\\Object.properties");
fs = new FileInputStream(Obj_f);
obj.load(fs);
//Loading xlsx file
xls = new Xls_Reader(System.getProperty("user.dir")+"\\src\\dd_Properties\\Data.xlsx");
System.out.println(config.getProperty("browerName"));
if(config.getProperty("browerName").equalsIgnoreCase("Firefox")) {
driver = new FirefoxDriver();
}
else if(config.getProperty("browerName").equalsIgnoreCase("Chrome")) {
driver = new ChromeDriver();
}
else {
throw new Exception("Wrong/No Browswer sepcified");
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
#AfterMethod
public void quitdriver() throws EmailException {
driver.quit();
//monitoringMail.Sendmail();
}
Here are LoginTest class:
public class LoginTest extends testcore {
#Test
public void doLogin() {
driver.findElement(By.xpath(obj.getProperty("LoginBtn"))).click();
driver.findElement(By.xpath(obj.getProperty("username"))).sendKeys();
driver.findElement(By.xpath(obj.getProperty("password"))).sendKeys();
}
1) How did these two method ran along with #test.
First of all LoginTest extends the testcore .
Due to this we can inherit the method of testcore in our LoginTest class.
2) When he ran loginTest then #BeforeMethod/#aftermethod also ran with this.
Please refer below details
Configuration information for a TestNG class:
#BeforeSuite: The annotated method will be run before all tests in this suite have run.
#AfterSuite: The annotated method will be run after all tests in this suite have run.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
#AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
#BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
#AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
#AfterClass: The annotated method will be run after all the test methods in the current class have been run.
#BeforeMethod: The annotated method will be run before each test method.
#AfterMethod: The annotated method will be run after each test method.
It's very simple inheritance related question. When you have extended testcore class in LoginTest class all the methods and data member available in parent will be available to child class including methods annotated with #Before Method etc.
I think you are confused due to miss concept regarding the way TestNG run a program. There are different different way to run a testNG annotated program to get executed and among them XML is a way. So don't get get confuse that all class, methods need to include in that xml. You just need an entry point only and rest will call accordingly.

How to pass the same driver instance in page Object model?

My automation framework is using selenium + TestNG + PageObject model.
Structure :
My Testng class / test case :
nullpointer error
How can i pass the driver instance into my page objects?
I can see you are declaring a new instance of WebDriver inside the #BeforeTest method. You need to use the WebDriver instance that you declared outside the #BeforeTest i.e. you have already declared
static WebDriver driver;
Use the same driver inside your #BeforeTest. So inside the before method, instead of doing WebDriver driver = new FirefoxDriver(); write like driver = new FirefoxDriver();
Do same for other browser types (ie, safari, chrome).
And for you page object classes, you can do something as follows:
public class TaxPage {
public static WebDriver driver;
public TaxPage(WebDriver driver) {
this.driver = driver;
}
}
Create a class like below and pass WebDriver in parametrize constructor and Call driver like Page.driver whenever you need it
public class Page
{
public static WebDriver driver;
public Page(WebDriver driver)
{
Page.driver = driver;
}
}
Hope it will help you :)

How to execute concurrent tests with Selenium WebDriver on a single machine?

My goal is to run multiple tests on a single machine in parallel. For that I'm using Selenium WebDriver with Firefox and Mbunit. Unfortunately it looks like like driver creation in Selenium is not thread safe and I have to wrap this part of the code with global lock. This is not the end of the world but my question is if this is all I need to do or maybe there are other parts that need synchronization? Another option would be to have AppDomain or Process isolation in MBUnit but I'm not sure if this is implemented.
[TestFixture]
[Parallelizable]
public class Class1
{
public static object padlock = new object();
[Test]
[Parallelizable]
public void Test1()
{
var driver = CreateDriver();
driver.Navigate().GoToUrl("http://www.mozilla.org");
driver.FindElementByCssSelector("a[href='/projects/']").Click();
Thread.Sleep(TimeSpan.FromSeconds(5));
driver.Quit();
}
[Test]
[Parallelizable]
public void Test3()
{
var driver = CreateDriver();
driver.Navigate().GoToUrl("http://www.mozilla.org");
driver.FindElementByCssSelector("a[href='/contribute/']").Click();
Thread.Sleep(TimeSpan.FromSeconds(5));
driver.Quit();
}
**private FirefoxDriver CreateDriver()
{
lock(padlock)
{
return new FirefoxDriver();
}
}**
}
I've been using MbUnit and Selenium in parallel, and I can assure you MbUnit is completely thread safe, and works perfectly once you instantiate WebDriver correctly. You should be fine with just the lock.
I would like to point out that using your code example your tests will not fail correctly. On any failed assertion or thrown exception you will not reach the Quit() section of your code. This is why the Setup/Teardown methods are typically used to start/stop the browser.
FYI, You can still use the setup/teardown methods in parallel, you just need a way of storing/referencing the Driver. You can use an IDictionary referenced by TestStep name.
I don't know how work MBunit, but there are differences between cocnurency and parallelism.
My opinion it's that an selenium test can be well integrated in concept of parallelism execution. Anyway, discution can be confusing.
So, how can be done.
1. Create an class that implements Runnable or extends Thread class. This class will launch test, something like this:
class MyClass implements Runnable
{
private Thread t;
public MyClass()
{
t=new Thread (this);
t.start();
}
#Override
public void run() {
WebDriver w = new FirefoxDriver();
// begin your test
}
}
In Main class, create multiple instance of MyClass. Each of them will launch an test into it's own thread.
Here it's link for Thread class documentation: http://docs.oracle.com/javase/1.3/docs/api/java/lang/Thread.html