I am having troubles following the guide of Arquillian to make functional tests: http://ift.tt/1mCNCFK. Concretely at the last steps of the guide, with the Page Object abstraction.
I have all the java classes exactly like in the guide, but when i run the test it throws this exception:
org.jboss.arquillian.graphene.enricher.exception.PageObjectInitializationException: Can not instantiate Page Object class org.arquillian.example.HomePage declared in: org.arquillian.example.LoginScreenGrapheneTest
Those are my classes, xhtmls and test classes:
Java Classes:
User.java:
package org.arquillian.example;
public class User {
private String username;
public User() {
}
public User(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Credentials.java:
package org.arquillian.example;
import javax.enterprise.inject.Model;
@Model
public class Credentials {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
LoginController.java:
package org.arquillian.example;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@SessionScoped
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;
private static final String SUCCESS_MESSAGE = "Welcome";
private static final String FAILURE_MESSAGE = "Incorrect username and password combination";
private User currentUser;
private boolean renderedLoggedIn = false;
@Inject
private Credentials credentials;
public String login() {
if ("demo".equals(credentials.getUsername())
&& "demo".equals(credentials.getPassword())) {
currentUser = new User("demo");
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(SUCCESS_MESSAGE));
return "home.xhtml";
}
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_WARN, FAILURE_MESSAGE,
FAILURE_MESSAGE));
return null;
}
public boolean isRenderedLoggedIn() {
if (currentUser != null) {
return renderedLoggedIn;
}
else {
return false;
}
}
public void renderLoggedIn() {
this.renderedLoggedIn = true;
}
@Produces
@Named
public User getCurrentUser() {
return currentUser;
}
}
XHTMLS:
Login.xhtml:
<!DOCTYPE html>
<html xmlns="http://ift.tt/lH0Osb"
xmlns:ui="http://ift.tt/KsEgXx"
xmlns:h="http://ift.tt/HjFrZb"
xmlns:f="http://ift.tt/HcrI1S">
<head>
<title>Log in</title>
</head>
<body>
<h:messages />
<h:form id="loginForm" prependIds="false">
<h:panelGrid columns="2">
<h:outputLabel for="userName">Username:</h:outputLabel>
<h:inputText id="userName" value="#{credentials.username}" />
<h:outputLabel for="password">Password:</h:outputLabel>
<h:inputSecret id="password" value="#{credentials.password}" />
<h:commandButton id="login" value="Log in"
action="#{loginController.login}" />
</h:panelGrid>
</h:form>
</body>
</html>
Home.xhtml:
<!DOCTYPE html>
<html xmlns="http://ift.tt/lH0Osb"
xmlns:ui="http://ift.tt/KsEgXx"
xmlns:h="http://ift.tt/HjFrZb"
xmlns:f="http://ift.tt/HcrI1S">
<h:head>
<title>Home</title>
</h:head>
<h:body>
<h:messages />
<h:form prependIds="false">
<h:commandButton value="Who Am I ?"
action="#{loginController.renderLoggedIn}">
<f:ajax render="whoami" />
</h:commandButton>
<h:panelGroup id="whoami">
<h:panelGroup rendered="#{loginController.renderedLoggedIn}">
<p>You are signed in as #{currentUser.username}.</p>
</h:panelGroup>
</h:panelGroup>
</h:form>
</h:body>
</html>
Test Classes:
LoginPage.java:
package org.arquillian.example;
import static org.jboss.arquillian.graphene.Graphene.guardHttp;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Location;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@Location("login.jsf")
public class LoginPage {
@Drone
private WebDriver browser;
@FindBy(id = "loginForm:userName")
private WebElement userName;
@FindBy(id = "loginForm:password")
private WebElement password;
@FindBy(id = "loginForm:login")
private WebElement loginButton;
@FindBy
private LoginForm loginForm; // locates the root of a page fragment on a particular page
public LoginForm getLoginForm() { // we can either manipulate with the login form or just expose it
return loginForm;
}
public void login(String userName, String password) {
this.userName.sendKeys(userName);
this.password.sendKeys(password);
guardHttp(loginButton).click();
}
}
HomePage.java:
package org.arquillian.example;
import static org.jboss.arquillian.graphene.Graphene.guardAjax;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.GrapheneElement;
import org.jboss.arquillian.graphene.findby.FindByJQuery;
import org.jboss.arquillian.graphene.page.Location;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import static org.junit.Assert.assertEquals;
@Location("home.jsf")
public class HomePage {
@Drone
private WebDriver browser;
@FindBy(tagName = "li")
private WebElement facesMessage;
@FindByJQuery("whoami p:visible")
private WebElement signedAs;
@FindBy(css = "input[type=submit]")
private GrapheneElement whoAmI;
public void assertOnHomePage() {
assertEquals("We should be on home page", "Welcome", getMessage());
}
public String getMessage() {
return facesMessage.getText().trim();
}
public String getUserName() {
if (!((GrapheneElement) signedAs).isPresent()) {
whoAmI();
}
return signedAs.getText();
}
private void whoAmI() {
guardAjax(whoAmI).click();
}
}
LoginScreenGrapheneTest.java:
package org.arquillian.example;
import java.io.File;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.openqa.selenium.WebDriver;
import java.net.URL;
import org.jboss.arquillian.test.api.ArquillianResource;
import static org.jboss.arquillian.graphene.Graphene.guardHttp;
import static org.jboss.arquillian.graphene.Graphene.waitAjax;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.GenericArchive;
import org.jboss.shrinkwrap.api.importer.ExplodedImporter;
import org.jboss.arquillian.graphene.findby.FindByJQuery;
import org.jboss.arquillian.graphene.page.InitialPage;
import org.jboss.arquillian.graphene.page.Page;
import static org.jboss.arquillian.graphene.Graphene.guardAjax;
import static org.jboss.arquillian.graphene.Graphene.waitModel;
@RunWith(Arquillian.class)
public class LoginScreenGrapheneTest {
private static final String WEBAPP_SRC = "src/main/webapp";
@Deployment(testable = false)
public static WebArchive createDeployment() {
return ShrinkWrap
.create(WebArchive.class, "login.war")
.addClasses(Credentials.class, User.class,
LoginController.class)
.merge(ShrinkWrap.create(GenericArchive.class)
.as(ExplodedImporter.class).importDirectory(WEBAPP_SRC)
.as(GenericArchive.class), "/",
Filters.include(".*\\.xhtml$"))
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(
new StringAsset("<faces-config version=\"2.0\"/>"),
"faces-config.xml");
}
// @Drone
// private WebDriver browser;
// @ArquillianResource
// private URL deploymentUrl;
// @FindBy(id = "loginForm:userName") // 1. injects an element by default location strategy ("idOrName")
// private WebElement userName;
//
// @FindBy(id = "loginForm:password")
// private WebElement password;
//
// @FindBy(id = "loginForm:login")
// private WebElement loginButton;
//
// @FindBy(tagName = "li") // 2. injects a first element with given tag name
// private WebElement facesMessage;
//
// @FindByJQuery("p:visible") // 3. injects an element using jQuery selector
// private WebElement signedAs;
//
// @FindBy(css = "input[type=submit]")
// private WebElement whoAmI;
@Page
private HomePage homePage;
@Test
public void should_login_successfully( @InitialPage LoginPage loginPage ) {
// browser.get(deploymentUrl.toExternalForm() + "login.jsf"); // first page load doesn't have to be synchronized
//
// userName.sendKeys("demo");
// password.sendKeys("demo");
//
// guardHttp(loginButton).click(); // 1. synchronize full-page request
// assertEquals("Welcome", facesMessage.getText().trim());
//
// guardAjax(whoAmI).click(); // 2. synchronize AJAX request
// assertTrue(signedAs.getText().contains("demo"));
loginPage.login("demo", "demo");
homePage.assertOnHomePage();
assertEquals(homePage.getUserName(), "demo");
}
}
There is a lot of code commented in the class above, is the code pre abstraction using page objects.
Aucun commentaire:
Enregistrer un commentaire