rHenderson
rHenderson

Reputation: 648

How can I locate this element with selenium webdriver?

This should be so simple but I'm obviously missing something:

<div>
    <label>
        Scenario
        <select id="scenarios">
            <option value="0">Default (Visa)</option>
            <option value="1">Secondary (Amex)</option>
        </select>
        <button onclick="pickScenario()">Select</button>
    </label>

    <label style="padding-left: 2em;">
        Custom Amount: $
        <input type="text" id="custom_amount">
    </label>
</div>

I keep getting NullPointerExceptions returned when trying to locate any of the three elements (scenarioDropdown, selectButton, customAmount) using the code below. I've tried all three with id, xpath, and css but below I'm showing one way per element:

  @FindBy(css = "#scenarios")
  private WebElement scenariosDropdown;

  @FindBy(xpath = "//button[contains(.,'Select')]")
  private WebElement select;

  @FindBy(how = How.ID, using = "custom_amount")
  private WebElement customAmount;

  private WebDriver driver;

  public void selectScenario(String scenario) {

    Select select = new Select(scenariosDropdown);
    select.deselectAll();
    select.selectByVisibleText(scenario);
  }

  void clickSelect() {
    select.click();
  }

  public void enterCustomAmount(String amount) {
    customAmount.clear();
    customAmount.sendKeys(amount);
  }

Running a test that uses the method below.

  public void testWhileBroken() {

    // select Scenario Two
    cc.selectScenario("Secondary (Amex)");

    // enter a Custom Amount
    cc.enterCustomAmount("1.23");

    // click Select
    cc.clickSelect();

  }

And it returns :

Aug 16, 2017 9:07:16 AM org.openqa.selenium.remote.ProtocolHandshake createSession INFO: Detected dialect: OSS

java.lang.NullPointerException at org.openqa.selenium.support.ui.Select.(Select.java:44) at apps.web.modules.staplespay.CreditCardsScreen.selectScenario(CreditCardsScreen.java:27)

What is the super obvious thing that I'm missing here?

Upvotes: 1

Views: 164

Answers (3)

undetected Selenium
undetected Selenium

Reputation: 193338

Your testWhileBroken() method looks good to me. (Lets assume the Class name is ABC.class)

But the reason you are facing java.lang.NullPointerException at org.openqa.selenium.support.ui.Select.(Select.java:44) is because in your PageFactory class (let us assume the Class name is XYZ.class) you have only declared the instance of the WebDriver as:

private WebDriver driver;

As far as PageFactory with POM is concerned, we must initialize the page objects in the test class (i.e. in ABC.class) by calling the initElements() method where you pass the instance of the WebDriver i.e. driver as an argument as follows:

//ABC.class
@Test (priority=2)
public void method_name()
{
    //Initialize page objects
    XYZ xyz = PageFactory.initElements(driver, XYZ.class);

    //Call the method
    xyz.my_method();
}

Now, in the page object class (i.e. in XYZ.class) along with declaring an instance of the WebDriver, additionally you have to define a constructor as follows:

//XYZ.class
WebDriver driver;

//constructor
public XYZ(WebDriver XYZDriver)
{
    this.driver=XYZDriver;
}

This will take care of the NullPointerException

Upvotes: 1

Gaurang Shah
Gaurang Shah

Reputation: 12940

or the alternate solution is to change the way you are creating the object for pages. change this:

CreditCardsScreen cc = new CreditCardsScreen();

to:

CreditCardsScreen cc = PageFactory.initElements(driver, CreditCardsScreen.class);

Upvotes: 0

NarendraR
NarendraR

Reputation: 7708

You are missing the driver to pass in page class constructor. So it is not finding the driver and throw the NullPointerException :

Expected code would be :

public class TestClass
{

    // all your webelements
    public TestClass(WebDriver driver)
    {
        PageFactory.initElements(driver, this);

     }
     // all your intended function

}

And in your test executor class make sure you have instantiated the webdriver and pass it at the time of object creation like

CreditCardsScreen cc = new CreditCardsScreen(driver);

 public void testWhileBroken() {

    // select Scenario Two
    cc.selectScenario("Secondary (Amex)");

    // enter a Custom Amount
    cc.enterCustomAmount("1.23");

    // click Select
    cc.clickSelect();

  }

Upvotes: 0

Related Questions