Java 在未找到Selenium元素的页面上测试AJAX/POST的效果
这可能类似于,但我正在做一个GET-first 我认为这里的关键是硒,因此标签。 以防万一:我使用Java,使用NinjaFramewor、FluentLenium和Firefox。它在本地运行,但也在带有Xvfb的无头CI盒上运行。 我有一些荧光测试通过了,所以整件事都没坏 我有一个网页,它有一个简单的登录表单,可以执行对JavaScript的调用,JavaScript可以执行AJAX POST。AJAX响应被JavaScript捕获,并导致页面的某些主体更新,登录、注册和失败的结果不同。当我手工测试时,甚至当我在本地运行这些测试时,我都能看到这种情况 测试如下所示:Java 在未找到Selenium元素的页面上测试AJAX/POST的效果,java,ajax,selenium,selenium-webdriver,fluentlenium,Java,Ajax,Selenium,Selenium Webdriver,Fluentlenium,这可能类似于,但我正在做一个GET-first 我认为这里的关键是硒,因此标签。 以防万一:我使用Java,使用NinjaFramewor、FluentLenium和Firefox。它在本地运行,但也在带有Xvfb的无头CI盒上运行。 我有一些荧光测试通过了,所以整件事都没坏 我有一个网页,它有一个简单的登录表单,可以执行对JavaScript的调用,JavaScript可以执行AJAX POST。AJAX响应被JavaScript捕获,并导致页面的某些主体更新,登录、注册和失败的结果不同。当我
import org.fluentlenium.adapter.util.SharedDriver;
import org.fluentlenium.core.annotation.Page;
import org.junit.Test;
@SharedDriver(deleteCookies=true)
public class UserControllerTest extends JSTest {
@Page
HomePage home;
@Page
LoginPage login;
@Test
public void test_cantLoginUntilReg() {
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseLogin(); // script that POSTS and does AJAX update
login.isErrorResult(); // errors
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseRegister(); // script that POSTS and does AJAX update
login.isWelcomeResult(); // errors
login.chooseHome(); // GET on home
home.isLoggedIn(); // this works
}
// more tests
}
我遇到麻烦的地方是LoginPage,它看起来像是一个超类,其中包含折叠回的常量:
public class LoginPage extends FluentPage {
protected static final String HOME_PAGE = "http://localhost:8080";
private static final String PAGE = HOME_PAGE + "/login";
@AjaxElement
FluentWebElement welcomeDiv;
@AjaxElement
FluentWebElement errorDiv;
@Override
public String getUrl() {
return PAGE;
}
@Override
public void isAt() {
assertTrue("url is " + url(), url().contains("login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Register"));
}
public void isErrorResult() {
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Failed"));
assertNull("cookie is " + getCookie(SESSION_COOKIE_NAME), getCookie(SESSION_COOKIE_NAME));
}
public void fillOutReg(String testName) {
fill("#email").with(testName + "@UserControllerJSTests.test.com"); // this passes the minimal validation in place so far
fill("#password").with("reallyBadPassword");
fill("#identName").with(testName);
}
public void chooseLogin() {
executeScript(LOGIN_SCRIPT); // I'd prefer click on the form, but that seemed to be a source of trouble as well
}
// and so on
}
结果方法永远不会令人满意!
FindH1显示h1文本仍然与第一次加载页面时一样。
清除会话cookie会在不同的机器上显示不同的行为,可能需要等待。
我也试过测试WelcometIV的内容。
我有一种感觉,我应该能够使用@AjaxElement在这里提供帮助,但我还没有完全弄清楚如何使用
我不想检查返回的JSON。我已经做了一些不涉及硒元素的测试,这些测试已经非常接近这一点了
我想做的是自动检查用户在发布帖子后是否能在浏览器端看到正确的内容。即使这段代码有解决办法,其他功能也会有足够大的上传量,这真的是不明智的;可测试的AJAX似乎是一种合理的需求
有什么想法吗?我有一个可行的解决方案。和以往一样,一系列的变化让我到达了我想要的地方。按照重要性的大致顺序,我认为它们是: 在任何给定测试中只查询一次@页的状态。Ajaxed内容的首次测试获胜。随后的一组发现了错误的值。 进行assert调用以测试ajax元素是否应该是来自测试对象而不是页面对象的元素。下面的代码中注释掉了损坏的版本,因为这是意外的。 使用@AjaxElement,然后查询这些元素的内容。 如果有一个网页在我要查找的元素上缺少一个id标记,那么就不能解释所有的问题。 在其他一些小的变化中,我现在正在测试标题h1元素和列表元素,而不是包含它们的div;不同版本的h1具有不同的id值。还没有回归检验这有多重要。 测试代码现在是:
import org.fluentlenium.adapter.util.SharedDriver;
import org.fluentlenium.core.annotation.Page;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
@SharedDriver(deleteCookies=true)
public class UserControllerTest extends JSTest {
@Page
HomePage home;
@Page
LoginPage login;
@Test
public void test_cantLoginBeforeReg() {
// try to login without being registered
goTo(login);
login.fillOutReg("test_cantLoginUntilReg");
login.chooseLogin();
isErrorResult();
goTo(home);
home.isNotLoggedIn();
}
@Test
public void test_registerLogout() {
goTo(login);
login.fillOutReg("test_registerLogout");
login.chooseRegister();
isWelcomeResult();
login.chooseLogout();
home.isAt();
home.isNotLoggedIn();
}
// tests etc
public void isWelcomeResult() {
assertTrue(login.getWelcomeText(), login.getWelcomeText().contains("Welcome"));
}
public void isErrorResult() {
assertTrue(login.getErrorText(), login.getErrorText().contains("Failed"));
}
}
和page类:
import org.fluentlenium.core.annotation.AjaxElement;
import org.fluentlenium.core.domain.FluentWebElement;
import static org.junit.Assert.assertTrue;
public class LoginPage extends TripVisPage {
private static final String PAGE = HOME_PAGE + "/login";
@AjaxElement
FluentWebElement welcomeHeading;
@AjaxElement
FluentWebElement errorHeading;
@Override
public String getUrl() {
return PAGE;
}
public String getWelcomeText() {
return welcomeHeading.getText();
}
public String getErrorText() {
return errorHeading.getText();
}
@Override
public void isAt() {
assertTrue("url is " + url(), url().contains("login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Login"));
assertTrue("h1 is " + find("h1").getText(), find("h1").getText().contains("Register"));
}
/* calling these from the test is broken
public void isWelcomeResult() {
assertTrue(getWelcomeText(), getWelcomeText().contains("Welcome"));
}
public void isErrorResult() {
assertTrue(getErrorText(), getErrorText().contains("Failed"));
}
*/
public void fillOutReg(String testName) {
fill("#email").with(testName + "@UserControllerJSTests.tripvis.co.uk");
fill("#password").with("reallyBadPassword");
fill("#identName").with(testName);
}
public void chooseAbout() {
click(LINK_ABOUT_ID);
}
public void chooseLegal() {
click(LINK_LEGAL_ID);
}
public void chooseRegister() {
executeScript(REGISTER_SCRIPT);
}
public void chooseLogin() {
executeScript(LOGIN_SCRIPT);
}
public void chooseLogout() {
click(LINK_LOGOUT_ID);
}
}