0

これは5660956に似ているかもしれませんが、最初に GET を実行しています...

ここでの鍵は Selenium、つまりタグだと思います。念のため: 私は Java で作業しており、NinjaFramewor、FluentLenium、Firefox を使用しています。ローカルで実行されますが、Xvfb を使用したヘッドレス CI ボックスでも実行されます。私はいくつかの FluentLenium テストに合格しているので、すべてが壊れていません!

AJAX POST を実行する JavaScript への呼び出しを実行する単純なログイン フォームを含む Web ページがあります。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
}

isErrorResult() メソッドが満たされることはありません! 検索 h1 は、h1 テキストが、ページが最初に読み込まれたときのままであることを示しています。セッション Cookie をクリアすると、異なるマシンで異なる動作が示されます (おそらく何かを待つ必要があります)。また、welcomeDiv の内容をテストしてみました。ここで @AjaxElement を使用できるはずだと感じていますが、その方法はまだわかりません。

戻ってくる JSON を検査したくありません。私は、すでにこれにかなり近づいている Selenium を含まないテストを持っています。

私がやりたいことは、ユーザーが POST 後にブラウザの最後で正しいものを見ることを自動チェックすることです。このコードの回避策があったとしても、他の機能のアップロードが非常に大きくなり、GET は実際には意味がありません。そして、テスト可能な AJAX は合理的に必要なようです。

何かアイデアはありますか?

4

1 に答える 1

0

私は実用的な解決策を持っています。いつものように、変化の組み合わせによって、私がなりたい場所にたどり着きました。重要度を大まかに並べると、次のようになると思います。

  • 特定のテストで @Page の状態を 1 回だけ照会します。Ajaxed コンテンツの最初のテストが成功しました。後続のものは間違った値を見つけました。
  • ajax要素がページオブジェクト内ではなくテストオブジェクトからあるべきものであることをテストするためにassert呼び出しを行います。これは予想外だったので、壊れたバージョンは以下のコードでコメントアウトされています。
  • @AjaxElement を使用してから、それらの要素のコンテンツをクエリします。
  • 1 つの Web ページで、探していた要素に id タグがありませんでした (すべての問題を説明することはできませんでした)。
  • 他の小さな変更の中で、h1 要素とリスト要素を含む div ではなく、見出し h1 要素とリスト要素をテストしています。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"));
 }
}

そしてページクラス:

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);
}
}
于 2014-11-05T14:49:53.140 に答える