Multiple browser windows opening automatically when one class is called in another class - selenium

I have created a class in which I am creating all the methods I require for my test automation. Issue which I am facing is that when I run main class, it works fine. But when I call that class in other class it opens 2 browser windows. The test is performed on 1 and other remains ideal. Also when I use close() or quit() method for #After, it closes the ideal window not the one which I am working on.
Below is my code snippet for ref.
Main class
public class ProjectManagement{
WebDriver driver = new FirefoxDriver();
public void navigateCreate(String uid, String pass) throws Throwable {
driver.manage().window().maximize();
driver.get(baseurl);
driver.findElement(By.id("Email")).sendKeys(uid);
driver.findElement(By.id("Password")).sendKeys(pass);
driver.findElement(By.id("loginBtn")).click();
driver.findElement(By.linkText("Projects")).click();
driver.findElement(By.linkText("Create New Project")).click();
}
}
Test Class
public class NewTest extends ProjectManagement{
ProjectManagement project1 = new ProjectManagement();
#Test
public void createPro() throws Throwable {
project1.navigateCreate(UId,Password);
}
#AfterTest
public void afterTest() {
driver.quit();
}
}

If you are extending ProjectManagement, you don't need to instantiate it on the sub-class. By doing so, you're effectively creating two instances of the class and, as such, two instances of WebDriver (which in turn generates two browser windows).
So, remove the following:
ProjectManagement project1 = new ProjectManagement();
And change your createPro() method to:
#Test
public void createPro() throws Throwable {
navigateCreate(UId,Password);
}

Related

Testng how to get all the log steps in aftermethod for post issue on some bug tracking tools

I am working on a project where if test case is failed I have to post a bug on their bug tracking tools through the tools. But they want in a bug report all the steps should mentioned properly with error.
Like in the description they want like this
Open Url
List item
Click the submit button Dashboard title is not match properly
In My automation code, I have written log
public class logtest {
WebDriver driver;
#BeforeMethod
public void Before(){
driver=new ChromeDriver();
}
#Test
public void test1(){
Log.info("Open URl");
//Opened url
Log.info("Click on the submit button");
// Submit button Clicked
Log.info("Open Dashboard");
Log.info("Dashboard Title match");
}
#AfterMethod
public void AfterMethod(ITestResult result){
if (result.getStatus() == ITestResult.FAILURE) {
PostIssue_to_Somewhere();
}
}
}
Is there any want I can get all the steps that I print inside #Test in the after method
so I can post bugs to their board through API
I think I can save the result somewhere and print it the end of the test case but I don't think it's an ideal solution. If you have any suggestion or way that I can manage it using testing that will really helpful
You cannot get the result in after test method. you should use TestNG listener for get the results
Steps to get them :
First create your own class with extend listener class
public class Listener implements ITestListener
Then use the override method to get the results
#Override
public void onTestSuccess(ITestResult iTestResult) {
}
there are several method to get the exact data,
OnStart- OnStart method is called when any Test starts.
onTestSuccess- onTestSuccess method is called on the success of any test
onTestFailure- onTestFailure method is called on the failureof any Test.
onTestSkipped- onTestSkipped method is called on
skipped of any Test
onTestFailedButWithinSuccessPercentage- method
is called each time Test fails but is within success percentage.
onFinish- onFinish method is called after all Tests are executed.
Use Extent Report and then use its method like (log, pass, fail ) to log your steps in your report, based on your test result, if you still need help let me know :)
You can see the full project demo code at ( below is code for the extent report) https://github.com/0kakarot0/ExtentReportBasic.git
public class MyExtentReport {
private WebDriver driver;
ExtentSparkReporter spark;
ExtentReports extentReports;
ExtentTest extentTest;
public MyExtentReport(WebDriver driver) {
this.driver = driver;
}
//Created Extent Report Html File
public void extentReporter() {
Date date = new Date();
String rightNow = "Spark"+ date.getTime() + ".html" ;
String pathOfFile = "allReports/"+rightNow;
spark = new ExtentSparkReporter(pathOfFile);
extentReports = new ExtentReports();
extentReports.attachReporter(spark);
}
public void logTestNameAndDescription(String name, String description){
extentTest = extentReports.createTest(name, description);
}
public void logTestInfo(String testInfo){
extentTest.log(Status.INFO,testInfo);
}
public void logPassedTestSteps(String logPassMessage){
extentTest.pass(logPassMessage);
}
public void logFailTestSteps(String logFailMessage){
extentTest.fail(logFailMessage);
}
public void logFailTestScreenShot(String reasonOfFailure){
extentTest.fail(reasonOfFailure,MediaEntityBuilder.createScreenCaptureFromPath("utils/failedTestScreenShot/screenshot.png").build());
}
public void flushExtentReport(){
extentReports.flush();
}

How to skip a testNG class based on element visibility and switch to another class

I am using testNG for my selenium suite. There is a class having 35 test cases. But these test cases will execute only if a particular element is visible. If that element is not visible, the compiler goes through all the test cases. Is there any way that I could check that element visibility condition in an #BeforeClass annotation only. If an element is not visible, it should come out from that class and switch to the next one? It will save my time to go through all the test cases?
To achieve it use #Test annotation on class level and #BeforeTest to check element visibility so it will skip all test cases of class if it will not satisfy condition in #BeforeTest. See below code (it's tested and working).
#Test
public class SkipAllTestCases {
boolean elementNotVisible=true;
#BeforeTest
public void setUp() {
if (elementNotVisible) {
throw new SkipException("skipping test cases...");
}
}
public void test1() {
System.out.println("Test1");
}
public void test2() {
System.out.println("Test2");
}
public void test3() {
System.out.println("Test3");
}
}
Hope it will help.
You can use dependsOnMethods of TestNG Test annotation.
#Test
public void elementVisibleTest(){
//Fail or skip here
}
#Test(dependsOnMethods = {"elementVisibleTest"})
public void myOtherTest(){
//Do something
}
...
That means if elementVisibleTest fails or gets skipped all tests which depend on that test will be skipped too. The advantage of that would be that you can still have other tests in that class which will be executed (because they do not depend on elementVisibleTest).
One of the approach is add group to all such tests let say flow-1. Add before group method and throw exception if it doesn't match required condition. For example:
#BeforeGroups(groups="flow-1")
public void flow1() {
if(!requiredCondtionMatch) {
throw new SkipException("Flow not applicable");
}
}
If all tests falls under same class then you can use #BeforeClass as well.

Assertion in selenium webdriver -report showing only falied methods, not passed methods

In my selenium TestNG class, there are some
methods, like method1, method2 etc.
I have added fail and success conditions to each method.
public class TestNGClass {
public void method1(String value) throws Exception {
if(value.equals("PASS"){
org.testng.Assert.assertTrue(condition, message);
}
}
//This is another method
public void method2(String value) throws Exception {
if(value.equals("FAIL"){
org.testng.Assert.fail(message);
}
}
But after the TestNG class execution, in the Test-Output folder "Index.html" will be created, which shows only the failed methods. How to display the passed methods also (custom report) .?
Thank you
Convert your test methods using #Test annotation. Modified Code Snippet:
public class TestNGClass {
#Test
public void method1(){
Assert.assertTrue(condition, "Your Message goes here");
}
//This is another method
#Test
public void method2(){
Assert.fail("Your Message goes here");
}
Now, you will have your testcases reported.

How to get the current remote webdriver instance inside onTestFailure(ITestResult)

I want to integrate the code to take screenshot using remoteWebdriver inside, testng's onTestFailure(ITestResult). I am unable to get the current webdriver instance inside onTestFailure().
Okay, I had a similar problem.
And since there's no clear answer here, I would post my ( working) solution
On your BaseTest / TestBase class, make your RemoteWebdriver instance accessible ( either by having it as a public property or with a getter)
In the Listener class (In my case its a public property):
public class BaseTest {
public RemoteWebDriver remoteDriver;
//... initalize driver
}
public class TestListener implements ITestListener {
#Override
public void onTestFailure(ITestResult result) {
BaseTest test = (BaseTest) result.getInstance();
if (test == null) {
return;
}
RemoteWebDriver driver = test.remoteDriver;
}
}

Run multiple tests in one class in parallel in multiple instances of browsers using testNG

Please tell me sample code for the fallowing scenario using Web-driver + TestNG framework.
One class having the multiple tests. While running these tests it should run all the tests as parallel in multiple instances of same browser (Ex: Firefox) at a time. So for every test it should open a new instance of a browser.
My solution so far has been something like this:
public MyTestClass {
SupportedBrowser browser;
private static ThreadLocal<WebDriver> threadLocalDriver = new ThreadLocal<WebDriver>();
#DataProvider (name = "getBrowsers")
public Object[][] getBrowsers {
return Object[][] {
{
SupportedBrowser.FIREFOX;
},
{
SupportedBrowser.CHROME;
}
};
}
#Factory (dataProvider = "getBrowsers")
public MyTestClass(SupportedBrowser browser) {
this.browser = browser;
}
#BeforeMethod
public void setup()
{
threadLocalDriver.set(browser.getDriver());
}
#Test
public void test1()
{
WebDriver driver = threadLocalDriver.get();
//do stuff
}
#AfterMethod
public void tearDown()
{
WebDriver driver = threadLocalDriver.get();
driver.quit();
}
}
here is my enum:
public enum SupportedBrowser {
FIREFOX, CHROME; //add more as needed
public getDriver() {
if(this == SupportedBrowser.FIREFOX) {
return new RemoteDriver(hubAddress, DesiredCapabilities.firefox()); //alternatively could be new FirefoxDriver()
}
else {
return new RemoteDriver(hubAddress, DesiredCapabilities.chrome());
}
}
}
Please forgive bad code conventions, I didn't write this in an IDE (though I have used something like this and it works).
The class is run once fore each different browser. Each method has its own independent driver, making sure your test can run concurrently. It also allows each method to take its own DataProvider, in case you need a test method to run multiple times with different arguments. Also make sure that the parallel attribute is set to the "method" level in your testng.xml file.
The only issue with my code is making sure the driver quits if the test fails. Right now, this method leaves closing failed tests up to selenium grid (using -timeout). Please see my question: Sharing driver between #BeforeMethod and #AfterMethod in TestNG.
Edit: I have now added a ThreadLocal variable to the code that shares the driver throughout the thread, so you can call driver.quit() in the #AfterMethod.