首页 文章

我如何告诉Graphene加载我的@Page?

提问于
浏览
2

TL;DR: 如何告诉Graphene为@ Page注入的对象加载哪个(相对)URL?


我正在尝试使用“最先进的”设置我的网络前端集成测试,即Arquillian,Arquillian Drone,Selenium 2和Graphene 2的组合 .

使用Arquillian,Drone和普通Selenium WebDriver(即没有任何Graphene特定的东西),测试可能如下所示:

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的非当前文档,我花了一些时间才能正确部署 . )

这个简单的测试只是检查我们是否从主页重定向到登录页面,并且它的 Headers 是正确的 . It works.

石墨烯2增加了一个重要的新功能,"autowiring" Page abstractions . 然后我的测试看起来像这样(省略上面的导入和部署部分):

@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();
    }
}

这实际上有效,我的测试不会失败,甚至输出正确的 Headers . 但是,这并不知道为什么我认为它确实如此,我必须看看上一次测试的输出)...

我得到一个“org.openqa.selenium.NoSuchElementException:无法找到名称为:title的元素”,其中包含非常长的堆栈跟踪(通过所有Arquillian,Graphene,Java Reflection API,Maven Surefire插件和我的两行代码) ) .

调试方法显示它最终尝试访问Html元素,而手头的HtmlPage是 about:blank -page,而不是我的登录页面 .

Is this how it is supposed to work? 为什么它对我不起作用?

然后我想测试除登录页面之外的其他页面,为此我需要使用其他开始URL .

使用普通的Drone Selenium Webdriver,我只想使用

driver.get(deploymentUrl + "/otherPage");

作为测试的第一行 . 但是如何处理Graphene 2 @ Page-Annotation呢?

How do I tell Graphene which URL (relative to the deploymentUrl) to load for the @Page-injected object?

2 回答

  • 2

    我个人使用继承和泛型来实现这一点(但它可能不是最好的解决方案) . 您可以查看示例here . 你需要像这样定义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 . 看看那个示例项目,我希望有所帮助!

  • 5

    行为是预期的 . 石墨烯初始化页面对象字段 .

    要自动加载页面,您可以在 @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 自动加载 . 您可以在documentation上阅读有关此功能的更多信息 .

相关问题