I can not passing variable to Main method (Cucumber) - java

I had tried to create method and call it from another file to the main class but It won't work the error message said "java.lang.NullPointerException"
Main.class
Keywords kw = new Keywords();
#When("^gmailDD$")
public void gmailDD() throws Throwable{
WebDriverWait wait5s = new WebDriverWait(driver, 5);
String regis = "/html/body/div[2]/div[1]/div[5]/ul[1]/li[3]/a";
String dd = "/html/body/div[1]/div/footer/div/div/div[1]";
String empty = "/html/body/div[1]/div/footer";
kw.clickbyxpath(regis);
String handle= driver.getWindowHandle();
System.out.println(handle);
// Store and Print the name of all the windows open
Set handles = driver.getWindowHandles();
System.out.println("Log window id: "+handles);
driver.switchTo().window("6442450949");
kw.clickbyxpath(empty);
kw.clickbyxpath(dd);
}`
Method.class
WebDriver saddriver;
public void clickbyxpath (String xpathvalue) throws InterruptedException, IOException
{
WebDriverWait sad = new WebDriverWait(saddriver, 10);
//To wait for element visible
System.out.println(xpathvalue);
String x = xpathvalue;
sad.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(x)));
wowdriver.findElement(By.xpath(x)).click();
}
I had tried to do the same coding in the same file, It has no problem but when I move Method.class to the new file, error message said "java.lang.NullPointerException" but I can get "xpathvalue" value.

This Error occur because of it will not able to find your driver instance.
refer below code snippet. this is not cucumber example but you can get idea by this.
Method.class
package testing.framework;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Method {
public WebDriver driver;
WebElement _clickForSearch;
public Method(WebDriver driver) {
this.driver = driver;
}
public Method clickByXpath(String xpathValues) {
WebDriverWait wait = new WebDriverWait(driver, 10);
_clickForSearch = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpathValues)));
_clickForSearch.click();
return this;
}
}
Testing.class
package testing.framework;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Testing {
public static WebDriver driver;
public static void main(String[] args) {
getWebDriver();
String xpathValues= "//div[#class='FPdoLc VlcLAe']//input[#name='btnK']";
Method m1 = new Method(driver);
m1.clickByXpath(xpathValues);
}
public static void getWebDriver() {
System.setProperty("webdriver.chrome.driver", "Your chrome driver path");
driver = new ChromeDriver();
driver.get("https://www.google.com");
}
}
You need to pass your driver instance to another.

So I would suggest you take the webdriver wait out of your method and instantiate it when instantiating your webdriver. I would then create methods like so:
Driver class
private final String USER_DIRECTORY = System.getProperty("user.dir");
private final int GLOBAL_TIMEOUT = 30;
private WebDriver webDriver;
private WebDriverWait webDriverWait;
public Driver(String browserName) {
this.browserName = browserName;
System.out.println(browserName);
switch (this.browserName.toUpperCase()) {
case "CHROME":
initializeChromeDriver();
break;
}
}
private void initializeChromeDriver() {
System.setProperty("webdriver.chrome.driver", USER_DIRECTORY.concat("\\drivers\\chromedriver.exe"));
webDriver = new ChromeDriver();
webDriver.manage().window().maximize();
webDriverWait = new WebDriverWait(webDriver, GLOBAL_TIMEOUT);
}
Click method
public void buttonClickByXpath(String xpath) {
try {
WaitForPreseneOfElement(xpath);
webDriver.findElement(By.xpath(xpath)).click();
} catch (Exception e) {
takeScreenshot();
AllureLog("Failed to click on the button object. Please check your xpath. | xpath used = " + xpath + "");
Assert.fail();
}
}
Test Class
Import your driver class
import Base.Driver;
Then you would need declair your driver class like so:
Driver driver;
Now you will have access to your method using
driver.buttonClickByXpath(//YourXpathHere)

The problem is "Method m1 = new Method(driver);" keyword,
I had coded this line outside the main method.
thank you very much, Sir

Related

I received this message and failed: java.lang.NullPointerException at org.openqa.selenium.support.pagefactory.DefaultElementLocator.find

I am creating Page Object Model for the first time using selenium and I came across the below error, while executing the code give below. Need help in figuring out what am I missing...
java.lang.NullPointerException at org.openqa.selenium.support.pagefactory.DefaultElementLocator.find
My Code for reference:
package Pages;
import org.openqa.selenium.*;
public class BaseClass {
public static WebDriver driver;
public static String URL1 = "https://math-dad.com";
public void setupWebDriver(String drivername)
{
if (drivername.equalsIgnoreCase("Chrome"))
{
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
driver =new ChromeDriver(options);
}
else if (drivername.equalsIgnoreCase("Fire Fox"))
{
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver.exe");
driver =new FirefoxDriver(options);
}
}
public BaseClass()
{
System.out.println("Base Class Initiate");
}
}
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class HeaderPage extends BaseClass{
#CacheLookup
#FindBy(xpath = "//div[#class='navbar-header']")
public static WebElement LOGO;
public displayHeader()
{
System.out.println(driver.findElement(By.xpath("//div[#class='navbar-header']")).getText());
}
public HeaderPage()
{
PageFactory.initElements(driver,this);
}
}
public class testHeaderPage extends HeaderPage{
#BeforeTest
public void beforeTest()
{
System.out.println("Before Test");
setupWebDriver("Chrome");
driver.get(URL1);
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
}
#Test
public void test1HeaderLOGO()
{
displayHeader(); // this is succesful
String Actual = LOGO.getText(); // Fails from this statement
System.out.println("Header LOGO: "+Actual);
String expected = "Math Dad";
Assert.assertEquals(Actual, expected, "Invalid Header");
}
#AfterTest
public void afterTest() {
drive.close();
}
}
In HeaderPage Classs, I am able to use 'driver' directly, but declaration of Page Factory element is failing. Any help on this please?
Use #BeforeClass annotation with this method so that Before Test driver can be initialized. This method will then execute Before every test.
#BeforeClass
public void setupWebDriver(String drivername) {
if (drivername.equalsIgnoreCase("Chrome"))
{
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
driver =new ChromeDriver(options);
}
else if (drivername.equalsIgnoreCase("Fire Fox"))
{
FirefoxOptions options = new FirefoxOptions();
options.addArguments("--disable-notifications");
System.setProperty("webdriver.gecko.driver", "C:\\Drivers\\geckodriver.exe");
driver =new FirefoxDriver(options);
}
}

Problems with the variable Webdriver driver when I use PageObjects

I want to use: Login_Page Login = PageFactory.initElements(driver, Login_Page.class); in a unique way in all steps.
When I use it for each step I have no problems, but on the contrary Java shows me the error: " Value driver is always 'null'".
I would also like to replace Thread.sleep (2000); for a better solution.
Here is my Code:
package stepdefs;
import Pages.Login_Page;
import cucumber.api.java.pt.Dado;
import cucumber.api.java.pt.Entao;
import cucumber.api.java.pt.Quando;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
import java.util.concurrent.TimeUnit;
public class StepDefinitions {
WebDriver driver;
Login_Page Login = PageFactory.initElements(driver, Login_Page.class);
#Dado("^que que estou na pagina principal do Gmail\\.$")
public void que_que_estou_na_pagina_principal_do_Gmail () throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\browsers\\chromedriver.exe");
driver = new ChromeDriver();
driver.navigate().to("https://www.gmail.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Quando("^forneco as credenciais validas\\.$")
public void forneco_as_credenciais_validas () throws Exception {
// Login_Page Login = PageFactory.initElements(driver, Login_Page.class);
Login.setEmail("rbkamontana#gmail.com");
Login.ClickOnNextButton();
Thread.sleep(2000);
Login.setSenha("automation10");
Thread.sleep(3000);
Login.ClickOnEnterButton();
driver.manage().window().maximize();
Thread.sleep(3000);
}
#Entao("^posso ver que estou logado\\.$")
public void posso_ver_que_estou_logado () throws Exception {
driver.findElement(By.xpath("//*[#id=\"gb\"]/div[2]/div[3]/div[1]/div[2]/div/a/span")).click();
String stringAtual = driver.findElement(By.xpath("//*[#id=\"gb\"]/div[2]/div[4]/div[1]/div[2]/div[1]")).getText();
String StringEsperada = "Rebeka Montana";
Assert.assertTrue(stringAtual.contains(StringEsperada));
//driver.quit();
}
}
Instead of Thread.sleep you can use selenium WebDriverWait function by a Locator.
Ref:
https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/WebDriverWait.html
void waitForElement(By Locator){
WebDriverWait myWait = new WebDriverWait(myDriver, 20);
myWait.until(ExpectedConditions.visibilityOfElementLocated(Locator));
}
Try initiating this inside of a constructor instead:
public StepDefinitions(){
driver = new ChromeDriver();
Login = PageFactory.initElements(driver, Login_Page.class);
}
An instance method is initializing the driver field at runtime, which explains why things work inside the step definition method. The solution is deceptively simple: create a getter method for the page model:
public class StepDefinitions {
WebDriver driver;
Login_Page login;
private Login_Page getLoginPage() {
if (login == null) {
login = PageFactory.initElements(driver, Login_Page.class);
}
return login;
}
#Quando("^forneco as credenciais validas\\.$")
public void forneco_as_credenciais_validas () throws Exception {
Login_Page login = getLoginPage();
login.setEmail("rbkamontana#gmail.com");
login.ClickOnNextButton();
Thread.sleep(2000);
login.setSenha("automation10");
Thread.sleep(3000);
login.ClickOnEnterButton();
driver.manage().window().maximize();
Thread.sleep(3000);
}

java.lang.NullPointerException using static WebDriver instance

I want to separate my code in to smaller functions.
But had an issue as driver was not available to all functions.
So i declared it as a constant (or is there a better way of doing this ?)
but in 3rd function it is failing on line :
Select dropdown_finance_product = new Select(driver.findElement(By.xpath("//select[#id='ResultsNumber']")));
Here is the console message :
Exception in thread "main" java.lang.NullPointerException
at Scraping.scrapeit.fetch_urls(scrapeit.java:49)
at Scraping.scrapeit.main(scrapeit.java:24)
Code :
package Scraping;
import java.io.IOException;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import tools.Xls_Reader;
public class scrapeit {
static WebDriver driver;
public static void main(String[] args) throws IOException {
start_browser();
fetch_urls();
read_excel();
}
public static void start_browser() {
System.setProperty("webdriver.chrome.driver", "C:\\Chrome Driver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().deleteAllCookies();
driver.get("http://www.example.com/search/items/new/");
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("New items));
}
public static void fetch_urls() {
Select dropdown_finance_product = new Select(driver.findElement(By.xpath("//select[#id='ResultsNumber']")));
dropdown_finance_product.selectByVisibleText("100");
System.out.println("Selected 100 Items Dropdown");
// Open Excel and write urls back
Xls_Reader datatable = new Xls_Reader("C:\\scrape.xlsx");
List<WebElement> num_items = driver.findElements(
By.xpath("//a [contains(#href,'http://www.example.com/search/items/new/latest-')] "));
for (int i = 0; i < num_items.size(); i++) {
System.out.println("How many items on page = : " + num_items.size() + " counter = " + i);
String link = num_items.get(i).getAttribute("href");
datatable.setCellData("New", "URL", i + 2, link);
System.out.println("URL : " + link);
}
}
public static void read_excel() {
// Read in url and process...
Xls_Reader datatable = new Xls_Reader("C:\\scrape.xlsx");
int r = datatable.getRowCount("URL");
int c = datatable.getColumnCount("URL");
System.out.println("num of rows = " + r + " num of cols = " + c);
}
}
The error says it all :
Exception in thread "main" java.lang.NullPointerException
In class scrapeit you have already declared webdriver as an instance of WebDriver as static as follows :
static WebDriver driver;
But then you are again initializing another driver as a new instance of WebDriver as follows :
WebDriver driver = new ChromeDriver();
Hence you see java.lang.NullPointerException
Solution
A quick solution will instead of creating another instance of the WebDriver you need to use the static instance of WebDriver. So you need to remove WebDriver from WebDriver driver = new ChromeDriver(); as follows :
driver = new ChromeDriver();

How come I am getting InvalidSelectorException when trying to click a button using Selenium?

I am very new at working with Selenium. I am trying to click on the following Select button:
Here is my code:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class FirstTest
{
private static WebDriver driver;
public static void main(String[] args) throws Exception
{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.navigate().to("http://www.metro.ca/flyer/index.en.html");
WebElement postalCodeInputBox = driver.findElement(By.name("postalcode"));
postalCodeInputBox.sendKeys("L6R1A1");
postalCodeInputBox.submit();
String pageSource = driver.getPageSource();
if(pageSource.contains("setstore btn"))
System.out.println("setstore btn FOUND");
WebElement selectButton = driver.findElement(By.className("setstore btn"));
selectButton.click();
}
}
Picture confirming that "setstore btn" is in the source:
Here is "setstore btn" in the source:
It's very likely caused by you trying to search for two separate classes in the single By.className(). "setstore" and "btn" are each their own classes.
Try replacing
WebElement selectButton = driver.findElement(By.className("setstore btn"));
with
WebElement selectButton = driver.findElement(new ByAll(By.className("setstore"), By.className("btn")));
Alternatively, https://stackoverflow.com/a/16090160/1055102 provides another good option.
WebElement selectButton = driver.findElement(By.cssSelector(".setstore.btn"));

Using eval function to create driver object in Selenium

I'm trying to use eval function to create a driver object in selenium. But am getting an error - "ReferenceError: "FirefoxDriver" is not defined". At line - "Object objBrow = objJSEngine.eval(strTxt);"
As I want to put the string -driver type in property file eventually. Below is the code.
Could anyone help me on this. Thanks.
package septmeber;
import java.util.concurrent.TimeUnit;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Initial {
public static void main(String arrParm[]) throws ScriptException
{
//Declare Variables
String strClassName;
By objBYTwiter;
WebElement objTwitterTag;
String strBorwserType;
String strTxt;
String strURL;
objBYTwiter = null;
objTwitterTag = null;
strClassName = "span[class = 'at16nc at300bs at15nc at15t_twitter at16t_twitter']";
strBorwserType = "FirefoxDriver";
strURL = "http://www.tutorialspoint.com/java/java_enumeration_interface.htm";
//Create Driver object
ScriptEngineManager objManager = new ScriptEngineManager();
ScriptEngine objJSEngine = objManager.getEngineByName("js");
strTxt = "new"+"\t "+strBorwserType+"();" ;
Object objBrow = objJSEngine.eval(strTxt);
WebDriver objBrowser = (WebDriver)objBrow;
//Launch the application
objBrowser.get(strURL);
objBrowser.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
System.out.println("Application launched");
objBrowser.manage().window().maximize();
//Click Twitter Link
objBYTwiter = By.cssSelector(strClassName);
objTwitterTag = objBrowser.findElement(objBYTwiter);
objTwitterTag.click();
}
}
What you are asking is not possible.
You can create a method something like:
WebDriver selenium;
public void setSelenium(String driver) {
if (driver.equals("firefox")) {
selenium = new FirefoxDriver();
} else if (driver.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "path to chrome");
selenium = new ChromeDriver();
} // define more as you need
}
Then you can call this method with something like:
setSelenium(System.getenv("browser"));
Where in your environment you first set the variable "browser" to whichever you want to run. You can also get this value from something else, like a file.

Categories