Seam Identity and WebClientSpec
djn Oct 9, 2008 5:23 AMHi.
When using WebClientSpec to test secure pages, I'm having an problems obtaining seam managed beans.
The following testcase fails in the last assertNotNull:
public void testWebClientSpecLogin() throws Exception {
WebClientSpec wcSpec = new WebClientSpec("/login.seam");
BlipZonesEELoginStrategy formAuth = new BlipZonesEELoginStrategy("admin", "admin");
wcSpec.setInitialRequestStrategy(formAuth);
JSFSession jsfSession = new JSFSession(wcSpec);
JSFServerSession server = jsfSession.getJSFServerSession();
assertEquals("/home.xhtml", server.getCurrentViewID());
Object o = server.getManagedBeanValue("#{identity}");
assertNotNull(o);
}
However, if I do the following, it passes correctly. The only difference is that I locate a link and click it before obtaining the identity component.
public void testWebClientSpecLogin() throws Exception {
WebClientSpec wcSpec = new WebClientSpec("/login.seam");
BlipZonesEELoginStrategy formAuth = new BlipZonesEELoginStrategy("admin", "admin");
wcSpec.setInitialRequestStrategy(formAuth);
JSFSession jsfSession = new JSFSession(wcSpec);
JSFServerSession server = jsfSession.getJSFServerSession();
JSFClientSession client = jsfSession.getJSFClientSession();
assertEquals("/home.xhtml", server.getCurrentViewID());
Page page = client.getContentPage();
assertTrue(page instanceof HtmlPage);
HtmlPage hPage = (HtmlPage) page;
HtmlAnchor htmlAnchor = hPage.getAnchorByHref("/blipzones/report/reportlist.seam?c=navitem_site_ReportSettings");
assertNotNull(htmlAnchor);
htmlAnchor.click();
server = jsfSession.getJSFServerSession();
assertEquals("/report/reportlist.xhtml", server.getCurrentViewID());
Object o = server.getManagedBeanValue("#{identity}");
assertNotNull(o);
}
The BlipZonesEELoginStrategy is a straightforward class, adapted from example code found on the JSFUnit wiki:
public class BlipZonesEELoginStrategy extends SimpleInitialRequestStrategy {
private String userName;
private String password;
private String submitComponent = "loginform:submit";
public BlipZonesEELoginStrategy(String userName, String password) {
this.userName = userName;
this.password = password;
}
public void setSubmitComponent(String submitComponent) {
this.submitComponent = submitComponent;
}
/**
* Perform the initial request and provide FORM authentication
* credentials when challenged.
*
* @param wcSpec The WebClient specification.
* @return The requested page if authentication passed. Otherwise, return
* the error page specified in web.xml.
*/
public Page doInitialRequest(WebClientSpec wcSpec) throws IOException {
HtmlPage page = (HtmlPage) super.doInitialRequest(wcSpec);
setValue(page, "loginform:name", this.userName);
setValue(page, "loginform:password", this.password);
return clickSubmitComponent(page);
}
protected Page clickSubmitComponent(HtmlPage page) throws IOException {
HtmlElement htmlElement = getElement(page, this.submitComponent);
if (!(htmlElement instanceof ClickableElement)) {
throw new IllegalStateException("Component with name=" + this.submitComponent + " is not a ClickableElement.");
}
ClickableElement clickable = (ClickableElement) htmlElement;
return clickable.click();
}
protected void setValue(HtmlPage page, String elementName, String value) {
HtmlElement element = getElement(page, elementName);
if (!(element instanceof HtmlInput)) {
throw new IllegalStateException("Component with name=" + elementName + " is not an HtmlInput element.");
}
HtmlInput inputElement = (HtmlInput) element;
inputElement.setValueAttribute(value);
}
protected HtmlElement getElement(HtmlPage page, String elementName) {
List<HtmlElement> elements = page.getHtmlElementsByName(elementName);
if (elements.size() == 0) {
throw new IllegalStateException("Component with name=" + elementName + " was not found on the login page.");
}
if (elements.size() > 1) {
throw new IllegalStateException("More than one component with name=" + elementName + " was found on the login page.");
}
return elements.get(0);
}
}