2

so i need to select from a drop down and all the code seems to do is highlight the value and not select it,

package uk.co.brightfuture.bfslogin.selenium.page;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;

import uk.co.brightfuture.bfslogin.selenium.PagePath;
import uk.co.brightfuture.bfslogin.selenium.PageTitle;

public class CreateNewUserPage extends Page {

@FindBy(name = "firstname")
private WebElement firstNameTextBox;

@FindBy(name = "surname")
private WebElement surnameTextBox;

@FindBy(name = "phonenumber")
private WebElement phonenumberTextBox;

@FindBy(name = "username")
private WebElement userNameTextBox;

@FindBy(name = "password")
private WebElement passwordTextBox;

@FindBy(name = "next of kin firstname")
private WebElement nextOfKinFirstnameTextBox;

@FindBy(name = "next of kin surname")
private WebElement nextOfKinSurnameTextBox;

@FindBy(name = "next of kin phonenumber")
private WebElement nextOfKinPhonenumberTextBox;

@FindBy(name = "dropdown2")
private WebElement authorityDropdown;

@FindBy(name = "Admin")
private WebElement adminFromDropdown;

@FindBy(name = "User")
private WebElement userFromDropdown;

@FindBy(name = "Fire")
private WebElement fireMarshallFromDropdown;

@FindBy(name = "dropdown")
private WebElement groupDropdown;

@FindBy(name = "group")
private WebElement groupFromDropdown;

@FindBy(name = "add")
private WebElement addButton;

public CreateNewUserPage(WebDriver driver) {
    super(driver, PageTitle.CREATEUSER, PagePath.CREATEUSER);

    // COMPULSORY
    this.driver = driver;
    PageFactory.initElements(driver, this);

}

public void enterFirstName(String firstNameText) {
    firstNameTextBox.sendKeys(firstNameText);
}

public void enterSurName(String surnameNameText) {
    surnameTextBox.sendKeys(surnameNameText);
}

public void enterPhonenumber(String phonenumberText) {
    phonenumberTextBox.sendKeys(phonenumberText);
}

public void enteruserName(String userNameText) {
    userNameTextBox.sendKeys(userNameText);
}

public void enterpassword(String passwordText) {
    passwordTextBox.sendKeys(passwordText);
}

public void enternextOfKinFirstname(String nextOfKinFirstNameText) {
    nextOfKinFirstnameTextBox.sendKeys(nextOfKinFirstNameText);
}

public void enternextOfKinSurname(String nextOfKinSurnameText) {
    nextOfKinSurnameTextBox.sendKeys(nextOfKinSurnameText);
}

public void enternextOfKinPhonenumber(String nextOfKinPhonenumberText) {
    nextOfKinPhonenumberTextBox.sendKeys(nextOfKinPhonenumberText);
}

public void AuthorityDropDown() {
    authorityDropdown.click();
}

public  void adminViaDropDown() {
      Select drop = new Select(authorityDropdown);
      drop.selectByIndex(1);  
}

public void userFromDropdown() {
    userFromDropdown.click();
}

public void userFromDropDown() {
    fireMarshallFromDropdown.click();
}

public void GroupDropDown() {
    groupDropdown.click();
}

public Boolean getGroupDropown(String textToCheck) {
    return groupFromDropdown.getText().equals(textToCheck);
}

public NewUserConfirmationPage AddUserButton() {
    addButton.click();
    return new NewUserConfirmationPage(driver);
}

}

and here's the test i'm trying to run,

    /**
 * this test will go to the new create new user page via the dash board and
 * it will enter the required data into the text fields.
 */

@Test
public void createNewUserWithCorrectData() {
    createNewUserPage = dashboardPage.clickCreateNewUserLink();
    assertTrue(isOnThisPage(PagePath.CREATEUSER));
    createNewUserPage.enterFirstName(FIRST_NAME);
    createNewUserPage.enterSurName(SURNAME);
    createNewUserPage.enterPhonenumber(PHONE_NUMBER);
    createNewUserPage.enteruserName(EMAIL);
    createNewUserPage.enterpassword(PASSWORD);
    createNewUserPage.enternextOfKinFirstname(NEXT_OF_KIN_FIRST_NAME);
    createNewUserPage.enternextOfKinSurname(NEXT_OF_KIN_SURNAME);
    createNewUserPage.enternextOfKinPhonenumber(NEXT_OF_KIN_PHONE_NUMBER);

    JavascriptExecutor jse = (JavascriptExecutor)driver;
    jse.executeScript("window.scrollBy(0,250)", "");

    createNewUserPage.AuthorityDropDown();
    createNewUserPage.adminViaDropDown();
    createNewUserPage.GroupDropDown();
    createNewUserPage.getGroupDropown(GROUP);
    newUserConfirmationPage = createNewUserPage.AddUserButton();
    assertTrue(isOnThisPage(PagePath.CREATECONFIRMED));
}

However i can only use Page object models as my manager won't allow us to use anything else.

<body>
<div class="back">
    <div id="different">
        <form method="post">
            <div class="center">
                <h1 id="large">ADD NEW USER</h1>
            </div>
            <input type="string" class="form-control" name="firstname"
                placeholder="Firstname"> <input type="string"
                class="form-control" name="surname" placeholder="Surname">
            <input type="number" class="form-control" name="phonenumber"
                placeholder="Phonenumber"> <input type="string"
                class="form-control" name="username" placeholder="Username">
            <c:if test="${UserAlreadyExists}">
                <h6
                    style="margin-bottom: 10px; margin-top: -10px; margin-left: 14px; color: red;">User:${username},
                    already exists</h6>
            </c:if>
            <input type="password" class="form-control" name="password"
                placeholder="Password"> <input type="string"
                class="form-control" name="next of kin firstname"
                placeholder="Next of kin firstname"> <input type="string"
                class="form-control" name="next of kin surname"
                placeholder="Next of kin surname"> <input type="number"
                class="form-control" name="next of kin phonenumber"
                placeholder="Next of kin Phonenumber">

            <!-- this section is for the button and the drop down section -->
            <div class="centered">
                <div class="row">
                    <div id="groupMenu">
                        <div class="btn-group">
                            <form>
                                <select class="form-control" id="dropdown2"
                                    style="width: 160px;" name="dropdown2">
                                    <option value="feedback" name="choose">Select
                                        Authority</option>
                                    <option name="admin">Admin</option>
                                    <option name="user">User</option>
                                    <option name="fire">Fire Marshall</option>
                                </select> <select class="form-control" id="dropdown"
                                    style="width: 160px;" name="dropdown">
                                    <option value="feedback" name="choose">Select Group</option>
                                    <c:forEach items="${Groups}" var="group" varStatus="status">
                                        <option name="group" value="${group.id}">
                                            ${group.groupName}</option>
                                    </c:forEach>
                                </select>
                            </form>
                        </div>
                    </div>
                    <button class="btn btn-default" type="submit" name="add" id="btn1"
                        onclick="javascript: form.action='Submit';">ADD</button>
                </div>
            </div>
        </form>
    </div>
</div>

here is the HTML

GingerFish
  • 457
  • 3
  • 11
  • 26

1 Answers1

2

You need to give us the stacktrace and

public  void adminViaDropDown() {
      Select drop = new Select(authorityDropdown);
      drop.selectByIndex(1);  
}

only selects the dropdown with first index

You should do

public  void adminViaDropDown(int index) {
      Select drop = new Select(authorityDropdown);
      drop.selectByIndex(index);  
}

use:

createNewUserPage.adminViaDropDown(1);

You also have multiple options on how you want to select the dropdown. See this

However, sometimes the element mapping technique does not work as expected if the element is dynamically loaded. I would find the element in realtime in that case.

public  void adminViaDropDown(int index) {
      WebEelement ele = driver.findElement("your by selector")
      Select drop = new Select(ele );
      drop.selectByIndex(index);  
}

And, another possibility is the wait. I would plug that in at the end if nothing works. This is explicit wait

public  void adminViaDropDown(int index) {
          WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));  
          Select drop = new Select(myDynamicElement );
          drop.selectByIndex(index);  
    }

Edit: find the option directly using css

//css
public  void adminViaDropDownByName() {
    By byCss = By.cssSelector("#dropdown2>option[name='admin']");
    driver.findElement(byCss).click();      
}

2nd Edit I don't like the HTML design here. You should talk to the developer. however, I found a real bad way to handle this. I wouldn't suggest this. But a workaround only.

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('dropdown2').querySelector('[name=admin]').setAttribute('selected','selected');");
Saifur
  • 16,081
  • 6
  • 49
  • 73
  • so, i made those changes, however adding the wait and the dynamically loaded change didn't work either. but with the index it still only highlights the selection, i need it to click the selection but can't seem to get my head around how to do that. – GingerFish Jan 29 '15 at 14:49
  • Can you provide the `html` snippet? – Saifur Jan 29 '15 at 15:15
  • Typically with a drop down element you only 'select' an option, highlight it. Normally you would then click on something else to 'confirm' that selection for example. If your requirements deem that you need to click your option directly, you will find using the `Select()` class tricky - as that is for selecting and not clicking an option. You can click an option directly, finding the option via its actual DOM position with the normal locators and calling the `.click()` method on it. – Mark Rowlands Jan 29 '15 at 15:19
  • i've added the hml for clarity and sorry what do you mean by DOM position? – GingerFish Jan 29 '15 at 15:21
  • it still doesn't click the option, it act's as though it has been, i.e the list closes but it still just says "select authority" in the box. any thoughts? – GingerFish Jan 29 '15 at 15:54
  • 1
    i'm still getting the same issue, i'm going to take it up with the devs to see if they can sort out their code and other things, thanks for your help though, i'll mark this as correct because it seems like it would work with better code. – GingerFish Jan 30 '15 at 09:30