How to select from a dropdown using POM Selenium

15,467

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');");
Share:
15,467
GingerFish
Author by

GingerFish

Updated on June 04, 2022

Comments

  • GingerFish
    GingerFish almost 2 years

    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