Description
Wicket has a convenient feature to make using Selenium IDE easy to use. By adding getDebugSettings().setOutputComponentPath(true) to your application, the wicketpath attribute is emitted.
Unfortunately, that does not hold for the radios inside a RadioChoice because they are not proper Components.
Also unfortunately, RadioChoice.onComponentTagBody() is final.
The result is that you either have to write additional xpath selectors, or clone RadioChoice and extend AjaxFormChoiceComponentUpdatingBehavior.
The following code, added to RadioChoice.onComponentTagBody(), solves the problem. It is similar to the same code in Component, but appends a bit more to the path for the input tags:
if (getApplication().getDebugSettings().isOutputComponentPath())
{
String path = getPageRelativePath();
path = path.replace("", "_");
path = path.replace(":", "_");
buffer.append(" wicketpath=\"")
.append(path)
.append("input")
.append(index)
.append("\"");
}
The full code for RadioChoice.onComponentTagBody() is as follows:
@Override
protected final void onComponentTagBody(final MarkupStream markupStream,
final ComponentTag openTag)
{
// Iterate through choices
final List<? extends T> choices = getChoices();
// Buffer to hold generated body
final AppendingStringBuffer buffer = new AppendingStringBuffer((choices.size() + 1) * 70);
// The selected value
final String selected = getValue();
// Loop through choices
for (int index = 0; index < choices.size(); index++)
{
// Get next choice
final T choice = choices.get(index);
Object displayValue = getChoiceRenderer().getDisplayValue(choice);
Class<?> objectClass = (displayValue == null ? null : displayValue.getClass());
// Get label for choice
String label = "";
if (objectClass != null && objectClass != String.class)
{ final IConverter converter = getConverter(objectClass); label = converter.convertToString(displayValue, getLocale()); }else if (displayValue != null)
{ label = displayValue.toString(); } // If there is a display value for the choice, then we know that the
// choice is automatic in some way. If label is /null/ then we know
// that the choice is a manually created radio tag at some random
// location in the page markup!
if (label != null)
{
// Append option suffix
buffer.append(getPrefix());
String id = getChoiceRenderer().getIdValue(choice, index);
final String idAttr = getMarkupId() + "-" + id;
boolean enabled = isEnabledInHierarchy() && !isDisabled(choice, index, selected);
// Add radio tag
buffer.append("<input name=\"")
.append(getInputName())
.append("\"")
.append(" type=\"radio\"")
.append((isSelected(choice, index, selected) ? " checked=\"checked\"" : ""))
.append((enabled ? "" : " disabled=\"disabled\""))
.append(" value=\"")
.append(id)
.append("\" id=\"")
.append(idAttr)
.append("\"");
// Should a roundtrip be made (have onSelectionChanged called)
// when the option is clicked?
if (wantOnSelectionChangedNotifications())
{
CharSequence url = urlFor(IOnChangeListener.INTERFACE);
Form<?> form = findParent(Form.class);
if (form != null)
{
RequestContext rc = RequestContext.get();
if (rc.isPortletRequest())
buffer.append(" onclick=\"").append(form.getJsForInterfaceUrl(url)).append(
";\"");
}
else
}
// ADDED BY JULIAN TO OUTPUT THE WICKET:PATH ATTRIBUTE TO EASE SELENIUM TESTING.
if (getApplication().getDebugSettings().isOutputComponentPath())
buffer.append("/>");
// Add label for radio button
String display = label;
if (localizeDisplayValues())
final CharSequence escaped;
if (getEscapeModelStrings())
else
{ escaped = display; } buffer.append("<label for=\"").append(idAttr).append("\">").append(escaped).append(
"</label>");
// Append option suffix
buffer.append(getSuffix());
}
}
// Replace body
replaceComponentTagBody(markupStream, openTag, buffer);
}