TL;DR:如何告诉Graphene为@Page注入的对象加载哪个(相对)URL?
我正在尝试使用"最先进的"来设置我的web前端集成测试,即Arquillian、ArquillianDrone、Selenium2和Graphene2的组合。
使用Arquillian、Drone和普通的Selenium WebDriver(即没有任何石墨烯特定的东西),测试可以如下所示:
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RunWith(Arquillian.class)
public class LoginIT {
private static final Logger LOG = LoggerFactory.getLogger(LoginIT.class);
@Deployment
public static WebArchive createDeployment() {
return Maven.resolver().loadPomFromFile("pom.xml")
.resolve("de.zalando:purchasing-frontend-general:war:?")
.withoutTransitivity().asSingle(WebArchive.class);
}
@Drone
WebDriver driver;
@ArquillianResource
URL deploymentUrl;
@Test
@RunAsClient
public void testLoginPage() {
LOG.info("executing test!");
driver.get(deploymentUrl + "");
final String title = driver.getTitle();
LOG.info("title: " + title);
Assert.assertEquals("Login page title is wrong",
"Zalando General Purchasing – Login", title);
}
}
(由于ShrinkWrap的非当前文档,我花了一段时间才完成部署。)
这个简单的测试只是检查我们是否从主页重定向到登录页面,以及它的标题是否正确它有效
石墨烯2增加了一个重要的新特性,"自动布线"页面抽象。然后我的测试可能看起来像这样(省略了导入和上面的部署部分):
@RunWith(Arquillian.class)
public class LoginIT {
private static final Logger LOG = LoggerFactory.getLogger(LoginIT.class);
@Deployment
public static WebArchive createDeployment() {
// as above
}
@Page
LoginPage loginPage;
@Test
@RunAsClient
public void testLoginPage() {
String title = loginPage.getTitle();
LOG.info("title: " + title);
Assert.assertEquals("Login page title is wrong",
"Zalando General Purchasing – Login", title);
}
}
使用这个"页面抽象"对象:
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class LoginPage {
@FindBy(tagName = "title")
private WebElement titleElement;
public String getTitle() {
return titleElement.getText();
}
}
这确实有效,我的测试没有失败,甚至输出了正确的标题但这根本不起作用(我不知道为什么我似乎认为它起作用,我一定看过之前测试的结果)。。。
我得到了一个"org.openqa.selenium.NoSuchElementException:Unable to locate element with name:title"和一个非常长的堆栈跟踪(通过Arquillian、Graphene、Java Reflection API、Maven Surefire插件和我的两行代码)。
对该方法的调试表明,它最终尝试访问Html元素,并且手头的HtmlPage是一个about:blank
页面,而不是我的登录页面。
它应该是这样工作的吗为什么它对我不起作用?
然后我想测试登录页面之外的其他页面,为此我需要使用其他启动URL。
使用普通的无人机+硒网络驱动程序,我只需使用
driver.get(deploymentUrl + "/otherPage");
作为测试的第一行。但是石墨烯2@页面注释该怎么办呢?
如何告诉Graphene为@Page注入的对象加载哪个URL(相对于deploymentUrl)
该行为是预期的。石墨烯初始化页面对象字段。
要自动加载页面,可以将页面对象的位置封装在@Location
注释中。与@InitialPage
一起,您可以实现所需的行为。
您的页面对象声明看起来像:
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import import org.jboss.arquillian.graphene.page.Location;
@Location("login.html")
public class LoginPage {
@FindBy(tagName = "title")
private WebElement titleElement;
public String getTitle() {
return titleElement.getText();
}
}
您的测试:
@Test
@RunAsClient
public void testLoginPage(@InitialPage LoginPage loginPage) {
String title = loginPage.getTitle();
LOG.info("title: " + title);
Assert.assertEquals("Login page title is wrong",
"Zalando General Purchasing – Login", title);
}
现在,作为测试执行期间的第一个操作,login.html
将相对于contextRoot
自动加载。您可以在文档中阅读有关此功能的更多信息。
我个人使用继承和泛型来实现这一点(但这可能不是最好的解决方案)。你可以在这里举个例子。你需要像这个一样定义AbstractPage
public interface AbstractPage {
public abstract String getURL();
}
@RunWith(Arquillian.class)
public abstract class AbstractWebDriverTest<P extends AbstractPage> {
@Page
private P page;
@Before
public void goToUrl() {
driver.get(deploymentURL + page.getURL());
}
}
然后,每个测试类将使用<>
中指定的页面来实现AbstractPage
。看看这个示例项目,我希望它能有所帮助!