Tokci Tokci - 2 months ago 9
Java Question

I don't want to repeat code selenium in Java

I don't want to repeat following code in each test case using TestNG. Please give a suggestion.
I kept

prop
and
fis
as the global variables, initialized them in
openBrowser()
, then used in other methods, but I get
NullPointerExeption
on a prop. If I add the lines below, then I don't get it.

I just want to load the property file once and re-use it.

Properties prop = new Properties();
FileInputStream fis = new
FileInputStream("C:\\Users\\xxxxx\\URL.properties");
prop.load(fis);


Code:

public class CallUrl {
WebDriver driver;
Properties prop ;
FileInputStream fis;
@BeforeTest
public void openBrowser() throws IOException
{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("C:\\Users\\xxxx\\URL.properties");
prop.load(fis); System.setProperty("webdriver.chrome.driver","C:\\Users\\xxxx\\chromedriver.exe");
String browserType = prop.getProperty("Browser");
if ( browserType.equals("Chrome"))
{ System.setProperty("webdriver.chrome.driver","C:\\Users\\Ashish\\Documents\\Selenium\\drivers\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver(options);
}
else if(browserType.equals("FireFox"))
{
driver = new FirefoxDriver();
}
}

@Test
public void openURL() throws IOException
{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("C:\\Users\\xxxxx\\URL.properties");
prop.load(fis);
driver.get(prop.getProperty("URL"));
WebDriverWait myDynamicElement = new WebDriverWait(driver,30); myDynamicElement.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@name='userName']")));
}

@Test(dependsOnMethods={"openURL"})
public void loginToTours () throws InterruptedException, IOException
{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("C:\\Users\\xxxxx\\URL.properties");
prop.load(fis); driver.findElement(By.name("userName")).sendKeys(prop.getProperty("login")); driver.findElement(By.name("password")).sendKeys(prop.getProperty("password"));
driver.findElement(By.name("login")).click();
}
}

Answer

You can move them to BeforeClass which will execute only once before all the tests of the class. I personally do not like the idea of tests initiating the browsers, directly dealing with page elements. I would suggest you implement page object model - check here

public class CallUrl {
 WebDriver driver;
 Properties prop;

 @BeforeClass
 public void loadProps(){
    prop = new Properties();
    FileInputStream fis = new FileInputStream("C:\\Users\\xxxx\\URL.properties");
    prop.load(fis);
 }


 @BeforeTest
 public void openBrowser() throws IOException {
  System.setProperty("webdriver.chrome.driver", "C:\\Users\\xxxx\\chromedriver.exe");
  String browserType = prop.getProperty("Browser");
  if (browserType.equals("Chrome")) {
   System.setProperty("webdriver.chrome.driver", "C:\\Users\\Ashish\\Documents\\Selenium\\drivers\\chromedriver_win32\\chromedriver.exe");
   driver = new ChromeDriver(options);
  } else if (browserType.equals("FireFox")) {
   driver = new FirefoxDriver();
  }
 }

 @Test
 public void openURL() throws IOException {
  driver.get(prop.getProperty("URL"));
  WebDriverWait myDynamicElement = new WebDriverWait(driver, 30);
  myDynamicElement.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@name='userName']")));
 }

 @Test(dependsOnMethods = {
  "openURL"
 })
 public void loginToTours() throws InterruptedException, IOException {
  driver.findElement(By.name("userName")).sendKeys(prop.getProperty("login"));
  driver.findElement(By.name("password")).sendKeys(prop.getProperty("password"));
  driver.findElement(By.name("login")).click();
 }
}