TesstNg parallel execution concatenate the input test data in one browser - selenium

I have two test cases in a class.when run parallel using TestNg it concatenate all the test data and put it one browser While the other browser is empty.
selenium Version: 3.8.21
Firefox: Latest
testng: 6.8.21
Below is the Code
package cli;
import java.net.MalformedURLException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class test1 {
public WebDriver driver;
#BeforeMethod
public void setUp() throws MalformedURLException {
System.out.println("#BeforeMethod: The annotated method will be run before each test method.");
}
#Test
public void test() throws MalformedURLException, InterruptedException {
driver = jenkinHub.hub();
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}
#Test
public void NotTesting() throws MalformedURLException, InterruptedException {
driver = jenkinHub.hub();
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Not Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}
}
xmlFile
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Regression Suite" verbose="1" parallel="methods" thread-count="3">
<test name="REgressionSuite" group-by-instances="true">
<classes>
<class name="cli.test1" />
</classes>
</test>
</suite>

May be it is because your driver is class level field. When first test method initializes it(driver = jenkinHub.hub()) and tries to use it, another method reassigns to it new value, so all your actions are done with the same WebDriver instance.
Try to move it in test method like this
#Test
public void test() throws MalformedURLException, InterruptedException {
WebDriver driver = jenkinHub.hub(); // create WebDriver instance
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}
#Test
public void NotTesting() throws MalformedURLException, InterruptedException {
WebDriver driver = jenkinHub.hub(); // create another WebDriver instance
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Not Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}

Here is the example of the how you can do it parallel, you may change the driver instantiation method as you like. Try this and then make adjustment in your code accordingly, It will open two chromes and search for test item in them and will not concatenate.
package Grid
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class test1 {
DesiredCapabilities caps;
#BeforeMethod
public void setUp() throws MalformedURLException {
System.out.println("#BeforeMethod: The annotated method will be run before each test method.");
caps = new DesiredCapabilities();
caps = DesiredCapabilities.chrome();
}
#Test
public void testing() throws MalformedURLException, InterruptedException {
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"),caps);
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}
#Test
public void NotTesting() throws MalformedURLException, InterruptedException {
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"),caps);
driver.get("https://www.google.com/");
driver.findElement(By.xpath("//*[#id=\"lst-ib\"]")).sendKeys("Not Testing");
System.out.println("This is current Url " + driver.getCurrentUrl());
Thread.sleep(9000);
driver.quit();
}
}
testng.xml file (same as you have edit package name)
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Regression Suite" verbose="1" parallel="methods" thread-count="4">
<test name="REgressionSuite">
<classes>
<class name="Grid.test1" />
</classes>
</test>
</suite>

Related

Getting this error " [TestNG] No tests found. Nothing was run" while running testng.xml file

Here i am trying to execute test cases in same class with only one browser instance. But struck here. How can i refresh and come back to same page to execute further cases of same classes.If i execute the cases in different classes, they are executing fine but giving error when executing in same class.
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class Parallel {
Parallel objectb;
WebDriver driver;
public Parallel(WebDriver driver) {
this.driver=driver;
// TO DO Auto-generated constructor stub
}
public void Open(WebDriver driver) {
this.driver=driver;
// TO DO Auto-generated constructor stub
}
#BeforeClass
public void beforeclass() {
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+".\\drivers\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://www.browserstack.com/users/sign_up");
}
#Test
public void testOnChromeWithBrowserStackUrl() throws InterruptedException {
Open(driver);
Thread.sleep(2000);
driver.manage().window().maximize();
driver.findElement(By.id("user_full_name")).sendKeys("Mamta Singh");
driver.findElement(By.id("user_email_login")).sendKeys("mamtasingh24#gmail.com");
driver.findElement(By.id("user_password")).sendKeys("browserstack");
System.out.println(
"this is the test related to chrome browserstack homepage" + " " + Thread.currentThread().getId());
}
#Test
public void testOnChromeWithBrowserStackSignUp() throws InterruptedException
{
objectb= new Parallel(driver);
Thread.sleep(2000);
driver.manage().window().maximize();
driver.findElement(By.id("user_full_name")).sendKeys("Sadhvi Singh");
driver.findElement(By.id("user_email_login")).sendKeys("sadhvisingh24#gmail.com");
driver.findElement(By.id("user_password")).sendKeys("browserstack");
System.out.println("this is the test related to chrome browserstack login"+ " " +Thread.currentThread().getId());
}
#AfterClass
public void close()
{
driver.quit();
}
}
You need a standard constructor in your test class.
public class Parallel {
public Parallel() {
// Do something
}
...
}
BTW: There are a few things in your code that do not make sense.
You have a constructor and a public method Open with a WebDriver argument but you are initializing the driver in the beforeclass anyway. So you could remove the constructor and the Open method.

Parallel methods do not run as expected

I need all the tests to be part of single class and run these tests in parallel. I'm using parallel="methods" in Testng.xml. I have class like
Public class DemoParallel{
#Test
/* some code to launch Google.*/
#Test
/* some code to launch Facebook*/
}
Actual : 2 instances of chrome launches. Google test is running completely.Facebook test is only launched but does not run. Gets hanged. Only one test passes and also have tried implementing listeners but no luck.
Any suggestions would be helpful.
Local Driver Factory :
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
class LocalDriverFactory {
static WebDriver createInstance(String browserName) {
WebDriver driver = null;
if (browserName.toLowerCase().contains("firefox")) {
System.setProperty("webdriver.firefox.marionette","path to driver exe");
driver = new FirefoxDriver();
return driver;
}
if (browserName.toLowerCase().contains("internet")) {
driver = new InternetExplorerDriver();
return driver;
}
if (browserName.toLowerCase().contains("chrome")) {
System.setProperty("webdriver.chrome.driver","path to driver exe");
driver = new ChromeDriver();
return driver;
}
return driver;
}
}
use ThreadLocal class as follows :
public class LocalDriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return webDriver.get();
}
static void setWebDriver(WebDriver driver) {
webDriver.set(driver);
}
}
Create Webdriver Listener class :
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
public class WebDriverListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
}
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
Test Class
public class ThreadLocalDemo {
#Test
public void testMethod1() {
invokeBrowser("https://www.google.com/");
}
#Test
public void testMethod2() {
invokeBrowser("http://www.facebook.com");
}
private void invokeBrowser(String url) {
System.out.println("Thread id = " + Thread.currentThread().getId());
System.out.println("Hashcode of webDriver instance = " + LocalDriverManager.getDriver().hashCode());
LocalDriverManager.getDriver().get(url);
}
}
Suite Xml File :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="methods">
<listeners>
<listener class-name="path-to-class-WebDriverListener"></listener>
</listeners>
<test name="Test">
<parameter name="browserName" value="firefox"></parameter>
<classes>
<class name="path-to-class-ThreadLocalDemo" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->

How to use two classes in same package where one class is dependent on other class?

My class 1 is 'Login'
My class 2 is 'checkout'
To run a class 2(checkout), I have to first log in(class 1) so my class 2 is dependent on class 1. But when I run the below code, a blank chrome screen is shown:
Chrome browser
The chrome driver is not going to the URL I have provided it just stuck with the blank screen.
My class 1 is a login class and to do a checkout, I need to first login so when I am doing that its not working.
Please let me know whats the mistake I am doing here?
Class 1 code:
package testcases;
public class Login{
static WebDriver driver= new ChromeDriver();
#BeforeClass
public void init() {
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.get("URL");
}
#Test
public static void testcase1()
{
driver.findElement(By.xpath(".//*[#id='email']")).click();
driver.findElement(By.xpath(".//*[#id='email']")).sendKeys("testid#g.com");
driver.findElement(By.xpath(".//*[#id='password']")).click();
driver.findElement(By.xpath(".//*[#id='password']")).sendKeys("3222"); driver.findElement(By.xpath("/html/body/div[4]/div/form/div[3]/div[2]/button")).click();
}
Class 2 code:
public class checkout {
static WebDriver driver= new ChromeDriver();
#BeforeClass
public void init() {
driver.manage().window().maximize();
driver.get("URL");
}
#Test(dependsOnMethods={"com.test.Login.testcase1"})
public void checkout() throws InterruptedException{
System.out.println("test");
driver.quit(); }}
testng.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none" preserve-order="true">
<test name="Test">
<classes>
<class name="com.test.Login"/>
<class name="com.test.checkout"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Errors:
Errors
Could please update Chrome Driver and Chrome Browser to latest and retry and confirm
Chrome browser launches with blank page in Selenium webdriver
I am not sure whether you are following Page Object model or not.
You need to make changes accordingly :
There is no need to create instance of WebDriver in check out class. You can just pass the reference of driver from Login Class.
You need to set the path of chromeDriver before launching it.
You can introduce Groups and dependsOnGroups concept. Make testcase1() in a group which is present in Login class and make checkout() method as depends on groups by introducing dependsOnGroups concept.
Here you can follow this code :
Login.java
public class Login {
static WebDriver driver;
#BeforeClass
public void init() {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\user***\\Downloads\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.get("https://www.google.com/");
}
#Test(groups={"Login.testcase1"})
public static void testcase1()
{
driver.findElement(By.xpath(".//*[#id='email']")).click();
driver.findElement(By.xpath(".//*[#id='email']")).sendKeys("testid#g.com");
driver.findElement(By.xpath(".//*[#id='password']")).click();
driver.findElement(By.xpath(".//*[#id='password']")).sendKeys("3222");
driver.findElement(By.xpath("/html/body/div[4]/div/form/div[3]/div[2]/button")).click();
getCheckoutPage(driver);
}
public static CheckOut getCheckoutPage(WebDriver driver) {
return new CheckOut(driver);
}
}
Checkout.java
public class CheckOut {
private WebDriver driver;
public CheckOut(WebDriver driver) {
this.driver = driver;
}
#Test(dependsOnGroups={"Login.testcase1"})
public void checkout() throws InterruptedException{
System.out.println("test");
driver.quit(); }
}

Selenium "no such session" error on TestNG testing.xml

I am trying to run a simple test with crossbrowsers using testing.xml of TestNG. Script runs fine on the first run which is Chrome. But gives "no such session" error on the firefox test beginning.
I simplified the codes to make it easy to read. I hope it helps.
Here's my TestNG testing.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="DefaultSuite" thread-count="1" parallel="tests">
<test name="ChromeTest">
<parameter name="browser" value="Chrome" />
<classes>
<class name="loginTest">
</class>
</classes>
</test>
<test name="FirefoxTest">
<parameter name="browser" value="Firefox" />
<classes>
<class name="loginTest">
</class>
</classes>
</test>
</suite>
And here's my code
public class loginTest {
private static WebDriver driver;
#BeforeTest
#Parameters("browser")
public void testSetup(String browser) throws Exception {
//Check if parameter passed from TestNG is 'firefox'
if(browser.equalsIgnoreCase("firefox")){
driver = webBrowsers.browserAl("Firefox");
}
//Check if parameter passed as 'chrome'
else if(browser.equalsIgnoreCase("chrome")){
driver = webBrowsers.browserAl("Chrome");
}
else{
//If no browser passed throw exception
throw new Exception("Browser is not correct");
}
}
#Test(priority=0)
public void LoginTest(){
driver.get("http://www.hurriyet.com.tr/");
}
#AfterTest
public void kapat() {
webBrowsers.closeDriver();
}
}
and finally my webBrowsers.class
public class webBrowsers {
private static WebDriver driver = null;
private static String browserName;
public static WebDriver browserAl(String browserName) {
if (browserName.equals("Firefox")) {
if (driver == null) {
System.setProperty("webdriver.gecko.driver","./drivers/geckodriver.exe");
driver = new FirefoxDriver();
}
} else if (browserName.equals("Edge")) {
if (driver == null) {
System.setProperty("webdriver.edge.driver", "./drivers/MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
} else if (browserName.equals("Chrome")) {
if (driver == null) {
System.setProperty("webdriver.chrome.driver","./drivers/chromedriver.exe");
driver = new ChromeDriver();
}
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
return driver;
}
public static void closeDriver() {
driver.close();
}
}
The problem is in your class webBrowsers. You are working with a static webdriver instance. So for the first <test> execution the driver instance will not be null and it would get instantiated properly. But when you execute the second <test> tag, the condition driver == null would be false, and you end up getting reference to the webdriver object that was created for the previous <test> tag. To make matters worse, you have a #AfterTest method which cleans up the driver instance as well. So you are now essentially working with a valid webdriver instance but for which the opened session has already been cleaned up.
End result : Your error.
Here's a cleaned up version of your code that should get past this problem.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.util.concurrent.TimeUnit;
public class WebBrowsers {
public static WebDriver browserAl(String browserName) {
WebDriver driver = null;
if (browserName.equals("Firefox")) {
System.setProperty("webdriver.gecko.driver", "./drivers/geckodriver.exe");
driver = new FirefoxDriver();
} else if (browserName.equals("Edge")) {
System.setProperty("webdriver.edge.driver", "./drivers/MicrosoftWebDriver.exe");
driver = new EdgeDriver();
} else if (browserName.equals("Chrome")) {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
return driver;
}
public static void closeDriver(WebDriver driver) {
if (driver != null) {
driver.quit();
}
}
}
Here's how your test class would look like
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class LoginTest {
private WebDriver driver;
#BeforeTest
#Parameters("browser")
public void testSetup(String browser) throws Exception {
//Check if parameter passed from TestNG is 'firefox'
if (browser.equalsIgnoreCase("firefox")) {
driver = WebBrowsers.browserAl("Firefox");
}
//Check if parameter passed as 'chrome'
else if (browser.equalsIgnoreCase("chrome")) {
driver = WebBrowsers.browserAl("Chrome");
} else {
//If no browser passed throw exception
throw new Exception("Browser is not correct");
}
}
#Test
public void loginTest() {
driver.get("http://www.hurriyet.com.tr/");
}
#AfterTest
public void kapat() {
WebBrowsers.closeDriver(driver);
}
}

How to close a window after running each test case in Selenium IntelliJ?

I have a set of three test cases, and I want to avoid keeping open multiple browser windows since I automated this process in Selenium. Is there a way to close a browser after each test case is finished without giving an error?
Using close() and quit() both give me error codes of 1.
We use below approach to handle these issue.
1) create a base class which has beforeSuite , beforeTest , afterTest , afterSuite methods which will run always.
2) Each test plan should extend this class to create driver and close the driver.
BasePage.java
package com.test.test3;
import java.lang.reflect.Method;
import java.util.Date;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
public class BasePage {
public WebDriver driver = null;
private Date start;
/*
* Below method will initialize the driver once test method started
* execution
*/
public void initializeDriver(WebDriver driver) {
this.driver = driver;
}
/*
* Below method will kill driver
*/
public void tearDown() {
if (this.driver != null) {
this.driver.quit();
}
}
#AfterMethod(alwaysRun = true)
public void afterTestMethod(Method method) {
// Clean ups for test level services
tearDown();
}
#AfterSuite(alwaysRun = true)
public void afterTestSuite() {
tearDown();
}
}
Testplan.java
package com.test.test3;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
public class TestPlan extends BasePage{
#Test(groups = { "test"})
public void test() {
FirefoxDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
System.out.println("TestAutomation test");
}
#Test(groups = { "test"})
public void test1() {
FirefoxDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
System.out.println("TestAutomation test");
}
#Test(groups = { "test"})
public void test2() {
FirefoxDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
System.out.println("TestAutomation test");
}
}
testNg.xml
<suite name="API TEST CASES">
<test name="api test" parallel="methods">
<groups>
<run>
<include name="test" />
</run>
</groups>
<classes>
<class name="com.test.test3.TestPlan" />
</classes>
</test>