How make webdriver not to close browser window after each test? - java

I'm new in both Selenium WebDriver and Java. I have some webservices on my site on page /someservice.php. I've wrote few tests on Selenuim and they work fine. Code example (Main Class):
public class SiteClass {
static WebDriver driver;
private static boolean findElements(String xpath,int timeOut ) {
public static void open(String url){
//Here we initialize the firefox webdriver
driver=new FirefoxDriver();
driver.get(url);
}
public static void close(){
driver.close();
}
WebDriverWait wait = new WebDriverWait( driver, timeOut );
try {
if( wait.until( ExpectedConditions.visibilityOfElementLocated( By.xpath( xpath ) ) ) != null ) {
return true;
} else {
return false;
}
} catch( TimeoutException e ) {
return false;
}}
public static Boolean CheckDiameter(String search,String result){
driver.findElement(By.xpath("//input[#id='search_diam']")).sendKeys(search);
WebDriverWait wait = new WebDriverWait(driver, 5);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#class='ac_results'][last()]/ul/li")));
WebElement searchVariant=driver.findElement(By.xpath("//div[#class='ac_results'][last()]/ul/li"));
Actions action = new Actions(driver);
action.moveToElement(searchVariant).perform();
driver.findElement(By.xpath("//li[#class='ac_over']")).click();
Boolean iselementpresent = findElements(result,5);
return iselementpresent;
}
}
Code Example (Test Class)
#RunWith(Parameterized.class)
public class DiamTest {#Parameters
public static Collection<Object[]> diams() {
return Arrays.asList(new Object[][] {
{ "111", "//div[#class='jGrowl-message']",true},
{ "222", "//div[#class='jGrowl-message']",false},
{ "333", "//div[#class='jGrowl-message']",true},
});
}
private String inputMark;
private String expectedResult;
private Boolean assertResult;
public DiamTest(String mark, String result, boolean aResult) {
inputMark=mark;
expectedResult=result;
assertResult=aResult;
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
/**
* Test of CheckDiameter method, of class CableRu.
*/
#Test
public void testCheckDiameter() {
SiteClass obj=new SiteClass();
obj.open("http://example.com/services.php");
assertEquals(assertResult, obj.CheckDiameter(inputMark, expectedResult));
obj.close();
}
}
Now I have 2 tests like that with 3 parameters each (total 6 variants). As you can see in every variant I create new browser window and when I run all 6 variants that take too much time (up to 80 seconds).
How can I run all variants in one browser window to speed up my tests?

Just move contents of public static void close() method from your SiteClass to tearDownClass() method in DiamTest class. In this way the browser window will be closed when the class execution finished (because of #AfterClass annotation). Your code then should look like this:
//DiamTest class
#AfterClass
public static void tearDownClass() {
driver.close();
}
It's also a good practice to move browser window initialization to setUpClass() method which will be executed before each test class (according to #BeforeClass annotation)
//DiamTest class
#BeforeClass
public static void setUpClass() {
//Here we initialize the firefox webdriver
driver=new FirefoxDriver();
driver.get(url);
}

What you need to do is share your help class with all your tests, this mean, you should create an instance of SiteClass inside your setUpClass method.
This method are annotated with #BeforeClass assuring your test class will create this method will be executed before all the test be executed.
You can read more about #BeforeClass in jUnit doc: or have a simple overview in this response.
You will also need do some rewrite some code to allow share the driver with the another test, something like this:
#RunWith(Parameterized.class)
public class DiamTest {
#Parameters
public static Collection<Object[]> diams() {
return Arrays.asList(new Object[][] {
{ "111", "//div[#class='jGrowl-message']",true},
{ "222", "//div[#class='jGrowl-message']",false},
{ "333", "//div[#class='jGrowl-message']",true},
});
}
private String inputMark;
private String expectedResult;
private Boolean assertResult;
private static SiteUtil siteUtil;
public DiamTest(String mark, String result, boolean aResult) {
inputMark=mark;
expectedResult=result;
assertResult=aResult;
}
#BeforeClass
public static void setUpClass() {
siteUtil = new SiteUtil();
}
#AfterClass
public static void tearDownClass() {
siteUtil.close();
}
#Test
public void testCheckDiameter() {
siteUtil.open("http://example.com/services.php");
assertEquals(assertResult, obj.CheckDiameter(inputMark, expectedResult));
}
}
and:
public class SiteClass {
static WebDriver driver;
public SiteClass() {
driver = new FirefoxDriver();
}
public void open(String url){
driver.get(url);
}
...
Tip:
You should read about the TestPyramid.
Since functional tests are expensive, you should care about what is really necessary test. This article is about this.

Related

How to replace static driver method

public class CommonFunctions {
public static WebDriver driver;
public void openWebsite(String url) {
driver.get(url);
}
public void closeBrowser() {
driver.close();
}
}
public class TestCase {
CommonFunctions commonFunctions = new CommonFunctions();
#BeforeMethod
public void openWeb() {
homePage.openWeb();
}
#Test
public void navigateLoginPage() {
homePage.login();
}
#AfterMethod
public void closeBrowser() {
commonFunctions.closeBrowser();
}
}
I have two class (commonfunction,homepage and testcase). When I run code without "static" at "public static Webdriver driver", the code throw nullpointerexception at function "closeBrowser". How to fix this error. I don't want use method "public static Webdriver driver" as code.
You need to initialize your driver variable in your CommonFunctions class.
WebDriver driver = new WebDriver(... etc);
Or, write a constructor that initializes this variable.
public class CommonFunctions
{
public WebDriver driver;
public CommonFunctions() // Constructor
{
driver = new WebDriver();
}

Error While creating PageObject Module in selenium For simple Tesng Testcase

I tried to Create a Simple Program in Selenium Using PageObjectModel. While Running the Program it throws Null Pointer Exception. Don't Know what i am doing wrong.Is my initialization of Variable is Wrong. I know i am making mistake in initializing the By locator but don't know what i am doing wrong.
public class main extends Base{
private static final int TIMEOUT = 5;
private static final int POLLING = 100;
protected WebDriverWait wait;
protected static WebElement ele;
protected By locator;
public void Base() {
wait = new WebDriverWait(driver, TIMEOUT, POLLING);
}
public WebElement waitForElementToAppear(By locator) {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));//Line which Throws Null
return ele;
}
protected void waitForElementToDisappear(By locator) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
}
protected void waitForTextToDisappear(By locator, String text) {
wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(locator, text)));
}
#Test()
public void getURL() {
driver.get("https://www.google.com");
waitForElementToAppear(By.name("q")).sendKeys("Pom");// Line Which Throws Null.
}
And My Base Class Code where i have saved the properties of the driver.
public class Base {
protected WebDriver driver;
public WebDriver getDriver() {
return driver;
}
public void setDriver(WebDriver driver) {
this.driver = driver;
}
#BeforeSuite
public void beforeSuite() {
System.setProperty("webdriver.chrome.driver", "D:\\Selenium\\chromedriver.exe"); // You can set this property elsewhere
driver=new ChromeDriver();
driver.manage().window().maximize();
}
}
The problem lies in the way in which you are initialising the WebDriverWait object.
Your WebDriver object will get instantiated only when the #BeforeSuite method runs in your Base class.
The logic of initialising the WebDriverWait is part of the method public void Base() in your main class.
But your #Test annotated getURL() method does not invoke Base() method. So your wait object is always null.
To fix this, invoke Base() within your #Test method or have your Base() method annotated with #BeforeClass annotation, so that it gets automatically called by TestNG.
There are multiple problems in your code
Probably you do not need global variable declarations. Of course you can do it like that but make sure you initialize them.
Do not put test methods in your page object
ele will always be null
Call the constructor
Probably you need something like following:
public class MyPageObject extends Base{
private static final int TIMEOUT = 5;
private static final int POLLING = 100;
protected WebDriverWait wait;
public void MyPageObject() {
super(); //Call constructor of Base if needed
wait = new WebDriverWait(driver, TIMEOUT, POLLING); //init wait
}
public WebElement waitForElementToAppear(By locator) {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
return driver.findElement(locator); //return WebElement
}
protected void waitForElementToDisappear(By locator) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
}
protected void waitForTextToDisappear(By locator, String text) {
wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(locator, text)));
}
}
public class MyTestClass {
#Test()
public void getURL() {
MyPageObject myPageObject = new MyPageObject(); //Initialize your page object
driver.get("https://www.google.com");
myPageObject.waitForElementToAppear(By.name("q")).sendKeys("Pom");
}

Cannot store WebDriver as global variable and execute a test more than once in the same Swing instance

In Swing, I have a JButton which executes the following test script when clicked on:
#RunWith(Parameterized.class)
public class ExampleTest{
private static csvTools csvTools = new csvTools();
private static WebDriver driver = CreateWebDriver.getDriver("chrome");
public static URLS urls;
// ..
// Data variables
private String fullName;
// ..
public ExampleTest(Map<String, String> testDataRow) {
this.fullName = testDataRow.get("Full name");
//..
}
#Rule
public TestName currentlyRunningTest = new TestName();
#Rule
public final ErrorCollector collector = new ErrorCollector();
#Parameterized.Parameters
public static Collection<Map<String, String>> testData() throws Exception {
return csvTools.getTests("ExampleTestData.csv");
}
#BeforeClass
public static void openBrowser() throws Exception {
page = new BasePage(driver);
userInformation = new UserInformation();
loginPage = new LoginPage(driver);
registrationPage = new RegistrationPage(driver);
evidenceCollector = new resources.EvidenceCollector(ExampleTest.class.getName());
}
#Before
public void setUp() throws Exception {
csvTools.saveData(currentlyRunningTest, "Fail/Pass", "");
evidenceCollector.newTestCase();
}
#Test
public void ExampleTest() throws Exception {
try {
driver.get(URLS.LOGINPAGEURL);
driver.findElement(By.id("d"));
//..
driver.get("examplesite");
page.screenShot(driver);
}
#After
public void tearDown() throws Exception {
evidenceCollector.moveScreenshotsAndTestData("ExampleTestData.csv");
}
#AfterClass
public static void closeBrowser() {
driver.quit();
}
}
The issue I have is, it will not let me execute the same script more than twice in the same Swing GUI instance. I have identified that this line, is the culprit:
private static WebDriver driver = CreateWebDriver.getDriver("chrome");
I determied this by commenting the line out and moving:
WebDriver driver = CreateWebDriver.getDriver("chrome");
into the test itself, where it is then possible to execute the test more than once in the same Swing GUI instance. However, as the the chrome driver is no longer stored as a global variable I cannot access it outside of the test, such as as #BeforeClass and #After
Here is the GUI Code:
JButton exTest1 = new JButton("Run ExampleTest");
exTest1.setLocation(290, 70);
exTest1.setSize(120, 30);
buttonPanel.add(exTest1);
exTest1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (exTest1.isEnabled()) {
executor.execute(new Runnable() { // This is how we run stuff in background. You can use lambdas instead of Runnables.
public void run() {
JUnitCore junit = new JUnitCore();
final Result result = junit.run(ExampleTest.class);
SwingUtilities.invokeLater(new Runnable() { // Now we go back to the GUI thread
public void run() {
errorMessageDisplay(result);
}
});
}
});
}
}});
What about initializing the driver in #BeforeClass ?
#RunWith(Parameterized.class)
public class ExampleTest{
private static csvTools csvTools = new csvTools();
private static WebDriver driver;
// ...
#BeforeClass
public static void openBrowser() throws Exception {
driver = CreateWebDriver.getDriver("chrome");
page = new BasePage(driver);
// ...
}
// ...
}

How to call a method with two parameter one as xPath and other as sendkey value?

How can I solve this issue?
public class myClass {
WebDriver driver;
#Test
public void myTest() {
oasEnterValue("//input[#name='user']", "user1");
oasEnterValue("//input[#name='password']", "pwd1");
}
public void oasEnterValue(String fXPath, String fText) {
driver.findElement(By.xpath(fXPath)).sendKeys(fText);
}
}
I am getting NullpointerException at driver.findElement(By.xpath(fXPath)).sendKeys(fText);
Below is my full code:
public class myClass {
WebDriver driver;
#Test
public void myTest() {
browserGo("linkedin.com/");
oasEnterValue("//input[#name='user']", "user1");
oasEnterValue("//input[#name='password']", "pwd1");
}
public void oasEnterValue(String fXPath, String fText) {
driver.findElement(By.xpath(fXPath)).sendKeys(fText);
}
public void browserGo(String fURL) {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(fURL);
}
From what I can tell, those XPaths don't exist. I think you want:
oasEnterValue("//*[#id='login-email']", "user1");
oasEnterValue("//*[#id='login-password']", "pwd1");

How to reuse the exiting instance of webdriver for different classes

I have gone through the existitng questions on this site, but unable to resolve
the following issue
Tools:Junit,IntelliJ,Java Language
//SetUp Class
public class SetUpTest {
public static WebDriver driver;
#BeforeClass
public static void setUpTest() throws InterruptedException
{
driver=new FirefoxDriver();
driver.get("http://www.ABC.co.uk");
Thread.sleep(5000);
}
//Test1
public class HomePageTest extends SetUpTest {
#Test
public void titleTest()
{
assertTrue(driver.getTitle().startsWith("ABC"));
//Test2
public void merchandisingTest() throws InterruptedException {
#Test
public void merchandisingTest()
{
driver.navigate().to("http://ABC.co.uk/deals");
assertThat(driver.getPageSource(),containsString("deals"));
I have tried running the tests with #TestBefore but still two browser windows are opened
one for Test1 and the other for Test2.I have also used #Suite.SuiteClasses
but the problem is still there.
Can you try this code
public class BaseTest{
public WebDriver driver;
#BeforeSuite
public void startDriver(){
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(5l, TimeUnit.SECONDS);
driver.get("http://www.ABC.co.uk");
}
}
public class HomePageTest extends BaseTest{
#Test
public void titleTest(){
assetTrue(driver.getTitle().startsWith("ABC"));
}
#Test
public void merchanisingTest(){
driver.navigate().to("http://www.ABC.co.uk/deals");
assertTrue(driver.getTitle().startsWith("deals"));
}
}
Also, you are running this using TestNG XML I guess, within which the #BeforeSuite method is called only once

Categories

Resources