4

我在一些地方读到,使用 WebDriver API 时在页面之间导航通常是由页面对象完成的,该页面对象返回在导致导航发生的操作时应返回的下一页。

该解决方案非常适用于总是返回相同页面的操作(例如,SearchPage.search() 返回新的 ResultPage),但是当某个操作可能会根据某些输入或状态将用户置于不同的页面时会发生什么情况。Java 不允许基于返回类型重载方法。那么如何做到这一点呢?

我粗略地尝试实现一个Navigator对象,该对象可用于Page根据预期结果返回通用对象。

public class Navigator {

    private WebDriver driver;
    private String baseUrl;
    private Map<Class, String> pagesToRelativePaths;


    public Navigator(WebDriver driver) {
        this.driver = driver;
    }

    public Navigator(WebDriver driver, String baseUrl, Map<Class, String> pagesToRelativePaths) {
        this.driver = driver;

        setBaseUrl(baseUrl);
        setPagesToRelativePaths(pagesToRelativePaths);
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public void setPagesToRelativePaths(Map<Class, String> pagesToRelativePaths) {
        this.pagesToRelativePaths = pagesToRelativePaths;
    }

    public <T extends PageBase> T navigateTo(Class<T> type) {
        driver.get(baseUrl + pagesToRelativePaths.get(type));

        return type.cast(new PageBase(driver));
    }

    public <T extends PageBase> T expectedLandingPage(Class<T> type) {
        return type.cast(new PageBase(driver));
    }
}

导致页面从一个页面对象移动到另一个页面对象的操作将实现如下方法:

public Navigator signIn(String username, String password) {
    usernameField.type(username);
    passwordField.type(password);
    signInButton.click();

    return new Navigator(driver);
}

一个测试看起来像这样:

@Test
public void SignInWithInvalidCredentialsTest() {
    SignInPage signInPage = navigator.navigateTo(SignInPage.class);

    signInPage = signInPage.signIn("invalid", "invalid").expectedLandingPage(SignInPage.class);

    assertThat(signInPage.getTitle(), is(equalTo(driver.getTitle())));
}

但不幸的是,我无法让导航器根据用户输入转到任何页面。有没有办法做到这一点,或者有另一种方法可以做到这一点?

资源:

4

1 回答 1

4

我对返回 Generic Types 进行了更多研究,并找到了解决问题的方法。关键是创建所提供类型的实例。可能会发生一些例外情况,因此我已尽力在此处概述它们:

public <T extends PageBase> T navigateTo(Class<T> type) {
    driver.get(baseUrl + pagesToRelativePaths.get(type));

    return getPage(type);
}

public <T extends PageBase> T expectedLandingPage(Class<T> type) {
    return getPage(type);
}

private <T extends PageBase> T getPage(Class<T> type) {
    T page = null;

    try {
        page = type.getDeclaredConstructor(WebDriver.class).newInstance(driver);
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

    return page;
}
于 2013-04-29T03:53:56.883 回答