Richfaces select (dropdown)

Hi,

I’ve to test Richfaces based webpages. On the pages there are a lot of dropdown element. All defined in java code like

<rich:select enableManualInput="true" value="#{myBean.selectedItem.dirtyRescheduleStrategyId}">
<f:selectItems value="#{myBean.rescheduleStrategies}" var="reschedule" itemValue="#{reschedule.id}" itemLabel="#{reschedule.name}"/>
<a4j:ajax execute="@this" event="selectitem" render="campaignForm"/>
</rich:select>

How can I select item from this dropdownbox? Main probleam it’s rendered as DIV not SELECT in HTML code.

THX
Tamás

Katalon Studio allows you to click anything in the browser. Start by clicking the <rich:select> element then examine the elements in the dropdown (right-click an element in the list, choose “Inspect”).

If you get stuck, post back with a screen shot of the Inspect window.

Good luck.

Hi,

image

this is the rendered dropdown.

<div class="rf-sel" id="campaignForm:j_idt116" style="display: table-cell;">
<span class="rf-sel-cntr">
	<input id="campaignForm:j_idt116selValue" name="campaignForm:j_idt116" type="hidden" value="1">
	<input autocomplete="off" class="rf-sel-inp" id="campaignForm:j_idt116Input" name="campaignForm:j_idt116Input" type="text" value="Test.lh">
	<span class="rf-sel-btn" id="campaignForm:j_idt116Button">
		<span class="rf-sel-btn-arrow"></span>
	</span>
</span>
<div class="rf-sel-lst-cord" id="campaignForm:j_idt116List" style="left: 918px; top: 310px; display: none;">
	<div class="rf-sel-shdw">
		<div class="rf-sel-shdw-l"></div>
		<div class="rf-sel-shdw-r"></div>
		<div class="rf-sel-shdw-b"></div>
		<div class="rf-sel-lst-dcrtn">
			<div class="rf-sel-lst-scrl" style="min-height: 20px;max-height: 100px;width: 200px">
				<div id="campaignForm:j_idt116Items">
					<div id="campaignForm:j_idt116Item0" class="rf-sel-opt">Select an Item!</div>
					<div id="campaignForm:j_idt116Item1" class="rf-sel-opt">00</div>
					<div id="campaignForm:j_idt116Item2" class="rf-sel-opt rf-sel-sel">Test.lh</div>
					<div id="campaignForm:j_idt116Item3" class="rf-sel-opt">UPC</div>
				</div>
			</div>
		</div>
	</div>
</div>
this is the HTML of dropdown.
static void clickElement(String xPath){
	println( '\nclickElement - xPath: ' + xPath + '\n')
	def driver = DriverFactory.getWebDriver()
	try{
		driver.findElement(By.xpath( xPath)).click()
	} catch(Exception e) {
		log.logError('Click on Element (xPath - ' + xPath + ') message: ' + e.getMessage())
		WebUI.takeScreenshot()
		println('\nclickElement - Exception: ' + e.getMessage())
	}
}

this is the function what I use to click on element. Where xPath generated runtime.

00 -> ((.//table[contains(@id,‘campaignForm:SettingsPanelGrid’)]//div[contains(@class,‘rf-sel-lst-scrl’)])[1]//div[contains(@class,‘opt’)])[2]
Test.lh -> ((.//table[contains(@id,‘campaignForm:SettingsPanelGrid’)]//div[contains(@class,‘rf-sel-lst-scrl’)])[1]//div[contains(@class,‘opt’)])[3]
UPC -> ((.//table[contains(@id,‘campaignForm:SettingsPanelGrid’)]//div[contains(@class,‘rf-sel-lst-scrl’)])[1]//div[contains(@class,‘opt’)])[4]

But clickElement() return is
clickElement - Exception: element not interactable

I don’t understand why.

THX
Tamás

This looks like @Brandon_Hein’s territory…

There’s usually more to this error. Can you post the entire log?

Is it enought from console or there is a log somwhere on file system?

Either the console or the log view is fine.

Sent via message.

THX
Tamás

Sorry, just copy/paste whatever you see from either of the two tabs after execution:

image

lastrun.log (24.6 KB)

Oh, this part of your code:

log.logError('Click on Element (xPath - ' + xPath + ') message: ' + e.getMessage())

is just printing out the error message, but we need to see the stack trace, as it usually contains a “caused by” log. Try replacing the above code with:

log.logError('Click on Element (xPath - ' + xPath + ') message: ' + e.printStackTrace())

Also, please change this:

println('\nclickElement - Exception: ' + e.getMessage())

to this:

println('\nclickElement - Exception: ' + e.printStackTrace())

Often times, the error message just gives you a general idea of what went wrong, but not the reasons behind it. That’s where the stack trace comes in.

Added e.printStackTrace()

lastrun.log (41.4 KB)

Thanks for the logs, that’s what I needed.

Ok, so the true exception is a org.openqa.selenium.ElementNotVisibleException. Using the richfaces sample website, I’ve looked at how this widget (outlined in blue below) behaves when you interact with it:

  • BEFORE you click on the dropdown:

The options exist in the DOM exactly as you’ve pasted above, i.e., in a hidden <div> just below the <span> that contains the <input> element for the dropdown:

  • AFTER you click on the dropdown

Strangely, clicking on the dropdown causes this <div> to disappear from the location I’ve shown, and replace it at the very end of the HTML body:

So what’s happening in your code is that while the <div> that contains your options exists in the expected location before you click on the dropdown, it doesn’t exist after you’ve clicked it, and you get the ElementNotVisibleException. So your xpaths for clicking options needs to account for this, and instead look at the last element in the body for your options to click.

2 Likes

On another note, I sure hope your AUT isn’t a robo-calling application. Otherwise, I’ve just assisted you in better bugging the shit out of people…

Fingers crossed…

1 Like

I know this. I use xPath - //div[contains(@class,‘rf-sel-lst-scrl’)])[1]//div[contains(@class,‘opt’)])[4] to find element…
I’ll check my xPath and logic. Thx for your help. I’ll notify you of the result tomorrow :slight_smile:

BR
Tamás

According to the information you’ve provided above, your XPath is:

((.//table[contains(@id,‘campaignForm:SettingsPanelGrid’)]//div[contains(@class,‘rf-sel-lst-scrl’)])[1]//div[contains(@class,‘opt’)])[4]

which is not the same…

Also, regardless of your xpath, you may want to put a wait condition in between the click on the dropdown and the click on the option. Something like:

new WebDriverWait(driver, 2).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(myXPath)));

Efficacious means of keeping the stacking context (“flow” on the z-axis) nice and clean. Messing with z-index can be an “arms race”, especially where today’s webpages contain umpteen bits of 3rd party shenanigans.

I can’t be sure that’s why they are doing it, but I’d bet your wages on it, Brandon :stuck_out_tongue_winking_eye:

Everything about stacking contexts you never thought you’d need to know: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

This makes sense of course, and I’ve seen lots of other widgetry behave this way. What’s strange to me with this approach is that the options exist in the DOM at all prior to clicking the dropdown, not so much that they are injected after the fact. Having them there prior seems redundant and/or unnecessary, as they serve no functional purpose prior to opening the dropdown (at least as far as I can tell with my limited exposure).

I’ve certainly done this.
I’ve also maintained fragments and instantiated them dynamically where needed.
I’ve also written fully JS based HTML creation (a poor man’s React/Vue-like mechanism).

They all “work” and come with their own up/downsides.

In this particular case, and wearing the hats we do right now, they’re doing little help our job.

1 Like

Thinking of this exactly.