3 Replies Latest reply: May 10, 2012 6:50 PM by Tim Evers RSS

Setting value of a PrimeFaces selectOneMenu

Davy Herben Newbie

Hello all,

 

Has anyone found a way to test a Primefaces SelectOneMenu component using JSFUnit 2 / HtmlUnit? I can't select a value, and I can't get access to displayed values either.

 

First of all, the primefaces component renders a selectOneMenu, used for VAT percentage selection in a product form, as follows:

 

<div id="productDetailForm:productVatPercentage" class="ui-selectonemenu ui-widget ui-state-default ui-corner-all ui-helper-clearfix" style="width: 75px; ">
     <div class="ui-helper-hidden-accessible">
          <select id="productDetailForm:productVatPercentage_input" name="productDetailForm:productVatPercentage_input">
               <option value="0.0">0.0%</option>
               <option value="6.0">6.0%</option>
               <option value="12.0" selected="selected">12.0%</option>
               <option value="21.0">21.0%</option>
          </select>
     </div>
     <input type="text" name="productDetailForm:productVatPercentage_editableInput" class="ui-selectonemenu-label ui-inputfield ui-corner-all" tabindex="-1" value="21.0" style="cursor: pointer; width: 59px; ">
     <div class="ui-selectonemenu-trigger ui-state-default ui-corner-right">
          <span class="ui-icon ui-icon-triangle-1-s"></span>
     </div>
</div>

 

When I check the values being sent over the wire in POST, I see the following:

 

productDetailForm:productVatPercentage_input:12.0
productDetailForm:productVatPercentage_editableInput:12.0%

 

So I've used the following java code:

 

    private void selectVat(String percentage, JSFClientSession client) {
        HtmlSelect vatPct =
                (HtmlSelect) client.getElement("productDetailForm:productVatPercentage_input");
        // set selected (percentage = "12.0")
        vatPct.getOptionByValue(percentage).setSelected(true);
        // unset default, just to make sure
        vatPct.getOptionByValue("21.0").setSelected(false);
        // make sure that 12.0 is the selected one
        assertEquals(1, vatPct.getSelectedOptions().size());
        assertEquals("12.0", vatPct.getSelectedOptions().get(0).getValueAttribute());

        // get access to _editableInput field via parent
        HtmlElement parent =
                (HtmlElement) client.getElement("productDetailForm:productVatPercentage");
        HtmlInput input = (HtmlInput) parent.getElementsByTagName("input").get(0);
        input.setValueAttribute(percentage + "%");
    }

 

However, when I submit the form and check the saved values, I see that the VAT percentage is set to the default 21.0% in the newly created product. I have made sure that the backend works: the correct percentage is saved when I run this in the browser.

 

If anyone has any idea on how to solve this issue, it would be much appreciated.

 

Thanks in advance,

 

Davy

  • 1. Re: Setting value of a PrimeFaces selectOneMenu
    Tim Evers Master

    Instead of manually trying to set your values try performing the click() operation on the appropriate option. I have found that most times this resolves the issue.

  • 2. Re: Setting value of a PrimeFaces selectOneMenu
    Davy Herben Newbie

    I couldn't get it to work using click(). I've found a way to do it, though. In my test base class, I've added the following methods that do the trick:

     

     

     /**
         * Selects the option of the given p:selectOneMenu with the given index (0-based). This
         * method uses a click() on the <li>on the selectOneMenu_panel element, instead of the
         * selectOneMenu_input element
         * 
         * @param elementId the element id of the p:selectOneMenu
         * @param index index of the element to click on
         * @return new page
         * @throws IOException in case of IO error while clicking on the option
         */
        public Page selectOneMenuOptionByIndex(String elementId, int index) throws IOException {
            HtmlDivision panelDiv = (HtmlDivision) client.getElement(elementId + "_panel");
            DomNodeList<HtmlElement> lis = panelDiv.getElementsByTagName("li");
            return lis.get(index).click();
        }
    
    
        /**
         * Selects the option of the given p:selectOneMenu with the given text. This method uses a
         * click() on the <li>on the selectOneMenu_panel element, instead of the selectOneMenu_input
         * element
         * 
         * @param elementId the element id of the p:selectOneMenu
         * @param text the text of the item to click on
         * @return new page
         * @throws IOException in case of IO error while clicking on the option
         */
        public Page selectOneMenuOptionByText(String elementId, String text) throws IOException {
            HtmlDivision panelDiv = (HtmlDivision) client.getElement(elementId + "_panel");
            DomNodeList<HtmlElement> lis = panelDiv.getElementsByTagName("li");
            for (HtmlElement li : lis) {
                if (text.equals(li.getTextContent())) {
                    return li.click();
                }
            }
            throw new IllegalArgumentException("Could not find option with text [" + text + "]");
        }
    
    

     

    Hope this helps someone.

     

    Davy

  • 3. Re: Setting value of a PrimeFaces selectOneMenu
    Tim Evers Master

    Nice work.

     

    I just had a look back at what I had done and I have something quite similar. Only difference is that I was clicking the <span> containing the text inside my selectOneMenu (richfaces). JSFUnit now has a method for handeling richfaces comboBox components but, I haven't been able to try it yet as upgrading my libs causes me a whole world of pain at the moment.

     

    Now, if only I can get approval to spend some time to fix the library problem...*sigh*

     

     

    Maybe it would be a good idea to update the JSFUnit wiki to provide these types of code snippets for other people. At the moment the wiki basically says to drop down to the HtmlUnit API to deal with more complex components (richfaces) and doesn't deal with PrimeFaces at all.

     

    Pretty sure Stan wouldn't mind if you started a page similar to https://community.jboss.org/wiki/JSFUnitWithRichFaces which is linked to from JSFUnit FAQ.