package org.fluentlenium.integration;
import net.jcip.annotations.NotThreadSafe;
import org.fluentlenium.adapter.FluentAdapter;
import org.fluentlenium.core.FluentControl;
import org.fluentlenium.core.FluentPage;
import org.fluentlenium.integration.localtest.IntegrationFluentTest;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.ui.FluentWait;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.fluentlenium.core.filter.FilterConstructor.with;
import static org.fluentlenium.core.filter.FilterConstructor.withClass;
import static org.fluentlenium.core.filter.FilterConstructor.withId;
import static org.fluentlenium.core.filter.FilterConstructor.withName;
import static org.fluentlenium.core.filter.FilterConstructor.withText;
import static org.fluentlenium.core.filter.FilterConstructor.withTextContent;
import static org.fluentlenium.core.filter.MatcherConstructor.regex;
import static org.junit.Assert.fail;
@NotThreadSafe
@SuppressWarnings("PMD.ExcessivePublicCount")
public class FluentLeniumWaitTest extends IntegrationFluentTest {
private static final int MINIMAL_TIMEOUT = 1;
public static final int SECOND_TIMEOUT = 1000;
public static final int SMALL_EXPECTED_SIZE = 3;
public static final int FIVE_SECONDS_TIMEOUT = 5;
public static final int EXACTLY_ONE = 1;
public static final int INVALID_EQUALS_NUMBER = 10;
public static final int LESS_THAN_FOUR = 4;
public static final int LESS_THAN_OR_EQ_1 = 1;
public static final int GREATER_THAN_MINUS_ONE = -1;
public static final int JOHN_FOUR_MATCHED = 4;
public static final int ONLY_ONE_ENDS_WITH_TWO = 1;
public static final int SECOND_AND_A_HALF_TIMEOUT = 1500;
public static final int LESS_THAN_SECOND_TIMEOUT = 800;
@Before
public void before() {
goTo(DEFAULT_URL);
}
@Test
public void checkAwaitIsPresent() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).present();
}
@Test
public void checkAwaitIsNotPresent() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".not-present")).not().present();
}
@Test
public void checkAwaitIsDisplayed() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).displayed();
}
@Test
public void checkAwaitIsNotDisplayed() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#hidden")).not().displayed();
}
@Test
public void checkAwaitIsClickable() throws Exception {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).clickable();
}
@Test
public void checkAwaitIsNotClickable() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("input[disabled]")).not().clickable();
}
@Test
public void checkAwaitIsSelected() throws Exception {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#selected")).selected();
}
@Test
public void checkAwaitIsNotSelected() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#non_selected")).not().selected();
}
@Test(expected = TimeoutException.class)
public void checkAwaitDisabledIsClickableThrowTimeoutException() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("input[disabled]")).clickable();
}
@Test
public void explicitWait() {
await().explicitlyFor(MINIMAL_TIMEOUT, NANOSECONDS);
}
@Test
public void explicitWaitMillis() {
await().explicitlyFor(MINIMAL_TIMEOUT);
}
@Test
public void checkAwaitHasSize() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small")).size(SMALL_EXPECTED_SIZE);
}
@Test
public void checkAwaitHasTextWithText() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withText("Small 1"))).text().equalTo("Small 1");
}
@Test
public void checkAwaitContainsNameWithName() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withName("name"))).name("name");
}
@Test
public void checkAwaitContainsNameWithClass() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("span", withClass("small"))).name("name");
}
@Test
public void checkAwaitContainsNameWithClassRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("span", withClass().contains(regex("smal?")))).name("name");
}
@Test
public void checkAwaitContainsNameWithClassAndContainsWord() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("span", withClass().containsWord("small"))).name("name");
}
@Test
public void checkAwaitContainsTextWithText() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withText("Small 1"))).text().contains("Small 1");
}
@Test
public void checkUseCustomMessage() {
try {
await().withMessage("toto").atMost(1, NANOSECONDS).until($(".small", withText("Small 1"))).text()
.contains("Small 21");
fail();
} catch (TimeoutException e) {
assertThat(e.getMessage()).contains("toto");
}
}
@Test
public void checkAwaitPageToLoad() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilPage().isLoaded();
}
@Test
public void checkAwaitPageIsAt() {
FluentPage isAtJavascriptPage = newInstance(MyFluentPage.class);
isAtJavascriptPage.go();
await().atMost(FIVE_SECONDS_TIMEOUT, TimeUnit.SECONDS).untilPage(isAtJavascriptPage).isAt();
}
@Test(expected = UnsupportedOperationException.class)
public void checkAwaitPageToLoadWithNoJSEnabled() {
FluentAdapter adapter = new FluentAdapter();
adapter.initFluent(new HtmlUnitDriver(false));
adapter.await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilPage().isLoaded();
}
@Test
public void checkAwaitContainsText() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).text().contains("Small 1");
}
@Test
public void checkAwaitContainsTextAlternative() {
$(".small").await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until().text().contains("Small 1");
$(".small", withText("Small 1")).await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach().text().contains("Small 1");
el(".small").await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until().text().contains("Small 1");
}
@Test
public void checkAwaitContainsIdWithId() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withId("id2"))).id("id2");
}
@Test
public void checkAwaitNameStartsWith() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", withName().startsWith("name"))).size(2);
}
@Test
public void checkAwaitContainsIdWithIdContains() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", withId().contains("id"))).size(2);
}
@Test
public void checkAwaitHasText() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).text().equalTo("Small 1");
}
@Test
public void checkAwaitContainsName() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).name("name");
}
@Test
public void checkAwaitContainsId() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small")).id("id2");
}
@Test
public void checkAwaitContainsTextWithTextMatcher() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withText().contains("Small 1"))).present();
}
@Test
public void checkAwaitContainsTextWithTextContentMatcher() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withTextContent().contains("Small 1"))).present();
}
@Test
public void whenAElementIsNotPresentThenIsNotPresentReturnTrue() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withText().contains("notPresent"))).not().present();
}
@Test(expected = TimeoutException.class)
public void whenAElementIsPresentThenIsNotPresentThrowAnException() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", withText().contains("Small 1"))).not().present();
}
@Test
public void checkAwaitStartWithRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").startsWith(regex(".d")))).size(2);
}
@Test
public void checkAwaitStartWithString() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").startsWith("id"))).size(2);
}
@Test
public void checkAwaitNotStartWith() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").notStartsWith("id"))).size(1);
}
@Test
public void checkAwaitNotStartWithRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").notStartsWith(regex("id")))).size(1);
}
@Test
public void checkAwaitEndsWithRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").endsWith(regex("2")))).size(1);
}
@Test
public void checkAwaitNotEndsWith() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notEndsWith("2"))).id("id");
}
@Test
public void checkAwaitNotEndsWithRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notEndsWith(regex("2")))).id("id");
}
@Test
public void checkAwaitNotContains() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").notContains("d"))).
size(EXACTLY_ONE);
}
@Test
public void checkAwaitNotContainsRegex() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($(".small", with("id").notContains(regex("d")))).
size(EXACTLY_ONE);
}
@Test
public void checkAwaitEquals() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().
equalTo(EXACTLY_ONE);
}
@Test
public void checkAwaitNotEquals() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().not().
equalTo(INVALID_EQUALS_NUMBER);
}
@Test
public void checkAwaitLessThan() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().
lessThan(LESS_THAN_FOUR);
}
@Test
public void checkAwaitLessThanOrEquals() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().
lessThanOrEqualTo(LESS_THAN_OR_EQ_1);
}
@Test
public void checkAwaitGreaterThan() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().
greaterThan(GREATER_THAN_MINUS_ONE);
}
@Test
public void checkAwaitGreaterThanOrEquals() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($(".small", with("id").notContains("d"))).size().
greaterThanOrEqualTo(1);
}
@Test
public void checkWithValue() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("input", with("value").equalTo("John"))).size(JOHN_FOUR_MATCHED);
}
@Test
public void checkMultipleFilter() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS)
.untilEach($(".small", with("id").startsWith(regex("id")), with("text").endsWith("2")))
.size(ONLY_ONE_ENDS_WITH_TWO);
}
@Test
public void checkHasAttribute() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("input")).attribute("value", "John");
}
@Test
public void checkHasAttributeWithOthersFilters() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("input", with("value").equalTo("John"))).attribute("value", "John");
}
@Test
public void whenElementIsPresentThenAreDisplayedReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#default")).displayed();
}
@Test
public void whenElementIsPresentThenIsDisplayedReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#default")).displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotDisplayedThenAreDisplayedThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#unvisible")).displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotDisplayedThenIsDisplayedThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#unvisible")).displayed();
}
@Test
public void whenElementIsNotPresentThenAreNotDisplayedReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#nonexistent")).not().displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotPresentThenAreDisplayedThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#nonexistent")).displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotPresentThenAreEnabledThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#nonexistent")).enabled();
}
@Test
public void whenElementIsNotDisplayedThenAreNotDisplayedReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#unvisible")).not().displayed();
}
@Test
public void whenElementIsNotDisplayedThenIsNotDisplayedReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#unvisible")).not().displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsDisplayedThenAreNotDisplayedThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#default")).not().displayed();
}
@Test(expected = TimeoutException.class)
public void whenElementIsDisplayedThenIsNotDisplayedThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#default")).not().displayed();
}
@Test
public void whenElementIsEnabledThenAreEnabledReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#default")).enabled();
}
@Test
public void whenElementIsEnabledThenIsEnabledReturnTrue() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#default")).enabled();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotEnabledThenAreEnabledThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#disabled")).enabled();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotEnabledThenIsEnabledThrowsException() {
goTo(JAVASCRIPT_URL);
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#disabled")).enabled();
}
@Test
public void whenElementIsSelectedThenIsSelectedReturnTrue() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#selected")).selected();
}
@Test
public void whenElementIsNotSelectedThenIsNotSelectedReturnTrue() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#non_selected")).not().selected();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotSelectedThenAreSelectedThrowsException() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).untilEach($("#non_selected")).selected();
}
@Test(expected = TimeoutException.class)
public void whenElementIsNotSelectedThenIsSelectedThrowsException() {
await().atMost(MINIMAL_TIMEOUT, NANOSECONDS).until($("#non_selected")).selected();
}
@Test(expected = TimeoutException.class)
public void checkPolling() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_AND_A_HALF_TIMEOUT, TimeUnit.MILLISECONDS).until($("#default")).text().equalTo("wait");
}
@Test
public void checkIsAt() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_TIMEOUT, TimeUnit.MILLISECONDS).untilPage(new FluentPage()).isAt();
}
@Test(expected = IllegalArgumentException.class)
public void checkIsAtWithNullPage() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_TIMEOUT, TimeUnit.MILLISECONDS).untilPage().isAt();
}
@Test
public void checkLoaded() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_TIMEOUT, TimeUnit.MILLISECONDS).untilPage().isLoaded();
}
@Test
public void checkPredicate() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(LESS_THAN_SECOND_TIMEOUT, TimeUnit.MILLISECONDS).untilPredicate(predicate -> true);
}
@Test(expected = TimeoutException.class)
public void checkPredicateFail() {
goTo(JAVASCRIPT_URL);
await().atMost(SECOND_TIMEOUT).untilPredicate(input -> false);
}
@Test
public void checkFunction() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_TIMEOUT, TimeUnit.MILLISECONDS).until(new Function<FluentControl, Boolean>() {
@Override
public Boolean apply(FluentControl fluent) {
return true;
}
});
}
@Test(expected = TimeoutException.class)
public void checkFunctionFail() {
goTo(JAVASCRIPT_URL);
await().atMost(SECOND_TIMEOUT).until(new Function<FluentControl, Boolean>() {
@Override
public Boolean apply(FluentControl fluent) {
return false;
}
});
}
@Test
public void checkSupplier() {
goTo(JAVASCRIPT_URL);
await().pollingEvery(SECOND_TIMEOUT, TimeUnit.MILLISECONDS).until(() -> true);
}
@Test(expected = TimeoutException.class)
public void checkSupplierFail() {
goTo(JAVASCRIPT_URL);
await().atMost(SECOND_TIMEOUT).until(() -> false);
}
@Test
public void seleniumWaitIsAvailable() {
FluentWait wait = await().getWait();
assertThat(wait).isInstanceOf(FluentWait.class);
}
private static class MyFluentPage extends FluentPage {
@Override
public void isAt() {
assertThat(find("#newField").texts()).contains("new");
}
@Override
public String getUrl() {
return IntegrationFluentTest.JAVASCRIPT_URL;
}
}
}