info.novatec.testit.webtester.waiting.WaitUntil Maven / Gradle / Ivy
package info.novatec.testit.webtester.waiting;
import java.util.function.Supplier;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import info.novatec.testit.webtester.conditions.Condition;
import info.novatec.testit.webtester.conditions.Conditions;
/**
* This class offers a number of methods which allow for the waiting until a specific condition is met for any object type.
*
* @see Wait
* @since 2.0
*/
@Getter(AccessLevel.PACKAGE)
public class WaitUntil {
@NonNull
private final Waiter waiter;
@NonNull
private final WaitConfig config;
@NonNull
private final Supplier objectSupplier;
public WaitUntil(Waiter waiter, WaitConfig config, T object) {
this(waiter, config, () -> object);
}
public WaitUntil(Waiter waiter, WaitConfig config, Supplier objectSupplier) {
this.waiter = waiter;
this.config = config;
this.objectSupplier = objectSupplier;
}
/**
* Waits until the given condition is met. A set of default conditions can be initialized from {@link Conditions}.
*
* @param condition the condition to wait for
* @return the same instance for fluent API use
* @throws TimeoutException in case the condition is not met within the configured timeout
* @see Wait
* @see Conditions
* @since 2.0
*/
public WaitUntil is(Condition condition) throws TimeoutException {
return doWait(condition);
}
/**
* Waits until the given condition is met. A set of default conditions can be initialized from {@link Conditions}.
*
* @param condition the condition to wait for
* @return the same instance for fluent API use
* @throws TimeoutException in case the condition is not met within the configured timeout
* @see Wait
* @see Conditions
* @since 2.0
*/
public WaitUntil has(Condition condition) throws TimeoutException {
return doWait(condition);
}
/**
* Waits until the given condition is NOT met. A set of default conditions can be initialized from {@link Conditions}.
*
* @param condition the condition to wait for
* @return the same instance for fluent API use
* @throws TimeoutException in case the condition is not met within the configured timeout
* @see Wait
* @see Conditions
* @since 2.0
*/
public WaitUntil isNot(Condition condition) throws TimeoutException {
return doWait(condition.negate());
}
/**
* Waits until the given condition is NOT met. A set of default conditions can be initialized from {@link Conditions}.
*
* @param condition the condition to wait for
* @return the same instance for fluent API use
* @throws TimeoutException in case the condition is not met within the configured timeout
* @see Wait
* @see Conditions
* @since 2.0
*/
public WaitUntil hasNot(Condition condition) throws TimeoutException {
return doWait(condition.negate());
}
/**
* Waits until the given condition is NOT met. A set of default conditions can be initialized from {@link Conditions}.
*
* @param condition the condition to wait for
* @return the same instance for fluent API use
* @throws TimeoutException in case the condition is not met within the configured timeout
* @see Wait
* @see Conditions
* @since 2.0
*/
public WaitUntil not(Condition condition) throws TimeoutException {
return doWait(condition.negate());
}
private WaitUntil doWait(Condition condition) {
waiter.waitUntil(config, () -> {
T value = objectSupplier.get();
try {
return condition.test(value);
} catch (ClassCastException e) {
throw handleClassCastException(condition, value, e);
}
});
return this;
}
private RuntimeException handleClassCastException(Condition condition, Object value, ClassCastException e) {
return new ConditionParameterMismatchException(condition.getClass(), value.getClass(), e);
}
/**
* This method does nothing by it's own. It is intended to be used in order to write more expressive linked wait
* statements.
*
* Example: {@code Wait.until(button).is(visible()).and().not(editable());}
*
* @return the same instance for fluent API use
* @see Wait
* @since 2.0
*/
public WaitUntil and() {
return this;
}
/**
* This method does nothing by it's own. It is intended to be used in order to write more expressive linked wait
* statements.
*
* Example: {@code Wait.until(button).is(visible()).but().not(editable());}
*
* @return the same instance for fluent API use
* @see Wait
* @since 2.0
*/
public WaitUntil but() {
return this;
}
}