import com.google.common.base.Function;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import play.libs.F.Callback;
import play.test.TestBrowser;
import play.test.TestServer;
import javax.annotation.Nullable;
import java.util.NoSuchElementException;
import static org.fest.assertions.Assertions.assertThat;
import static play.test.Helpers.*;
/**
* Tests the game engine by starting a server and connecting two browsers.
*/
public class IntegrationTest {
/**
* {@link play.test.Helpers#running(play.test.TestServer, Class, play.libs.F.Callback)} alternative that requires no servers.
*/
protected static synchronized void _running(Class<? extends WebDriver> webDriver, final Callback<TestBrowser> block) {
TestBrowser browser = null;
try {
browser = testBrowser(play.api.test.WebDriverFactory.apply(webDriver));
block.invoke(browser);
}
catch (Error | RuntimeException e) { throw e; }
catch (Throwable t) { throw new RuntimeException(t); }
finally { if (browser != null) browser.quit(); }
}
private static void waitForStatus(TestBrowser browser, final String text) {
browser.waitUntil(new Function<WebDriver, Object>() {
@Nullable
@Override
public Object apply(@Nullable WebDriver input) {
if (input == null) return false;
WebElement status;
try { status = input.findElement(By.cssSelector("#status span")); }
catch (NoSuchElementException nsee) { return false; }
return status.getText().equals(text);
}
});
}
@Test
public void test() {
int port = 3333;
final TestServer server = testServer(port);
final String serverURL = String.format("http://localhost:%d/", port);
final Class<? extends WebDriver> driver = FIREFOX;
// Start the web server and the first browser.
running(server, driver, new Callback<TestBrowser>() {
public void invoke(final TestBrowser fstBrowser) {
// Let the first browser to join the game.
fstBrowser.goTo(serverURL);
assertThat(fstBrowser.pageSource())
.contains("There are 0 game(s) and 0 pending player(s) online.");
// Wait until the WebSocket connection gets established and
// game engine adds us to the pending players queue.
waitForStatus(fstBrowser, "Connected. Waiting for opponent...");
// Start a second browser.
_running(driver, new Callback<TestBrowser>() {
public void invoke(TestBrowser sndBrowser) {
sndBrowser.goTo(serverURL);
// Make sure that we observe the pending first player.
assertThat(sndBrowser.pageSource())
.contains("There are 0 game(s) and 1 pending player(s) online.");
// Wait until getting paired with the first user.
waitForStatus(sndBrowser, "Paired. Waiting for move...");
// Make sure that the first browser is also informed of pairing.
waitForStatus(fstBrowser, "Paired. Waiting for move...");
// Close the second browser.
sndBrowser.quit();
// Make sure that the first browser observes the lost connection.
waitForStatus(fstBrowser, "Connection lost!");
}
});
}
});
}
}