All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.thucydides.core.scheduling.ThucydidesFluentWait Maven / Gradle / Ivy

There is a newer version: 4.2.1
Show newest version
package net.thucydides.core.scheduling;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import net.thucydides.core.steps.StepEventBus;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.support.ui.Clock;
import org.openqa.selenium.support.ui.Duration;
import org.openqa.selenium.support.ui.Sleeper;
import org.openqa.selenium.support.ui.Wait;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public abstract class ThucydidesFluentWait implements Wait {

    public final static Duration FIVE_HUNDRED_MILLIS = new Duration(500, MILLISECONDS);

    protected Duration timeout = FIVE_HUNDRED_MILLIS;
    protected Duration interval = FIVE_HUNDRED_MILLIS;

    private List> ignoredExceptions = Lists.newLinkedList();

    private final Clock clock;
    private final T input;
    private final Sleeper sleeper;

    public ThucydidesFluentWait(T input, Clock clock, Sleeper sleeper) {
        this.input = checkNotNull(input);
        this.clock = checkNotNull(clock);
        this.sleeper = checkNotNull(sleeper);
    }

    protected Clock getClock() {
        return clock;
    }

    protected T getInput() {
        return input;
    }

    protected Sleeper getSleeper() {
        return sleeper;
    }

    public  V until(Function isTrue) {
        long end = getClock().laterBy(timeout.in(MILLISECONDS));
        RuntimeException lastException = null;
        String waitForConditionMessage = isTrue.toString();
        while (true) {
            if (aPreviousStepHasFailed()) {
                return (V) Boolean.TRUE;
            }
            try {
                V value = isTrue.apply(input);
                if (value != null && Boolean.class.equals(value.getClass())) {
                    if (Boolean.TRUE.equals(value)) {
                        return value;
                    }
                }
                else {
                    throw new IllegalArgumentException("Condition should be a boolean function");
                }
            } catch (RuntimeException e) {
                lastException = propagateIfNotIngored(e);
            }

            if (!getClock().isNowBefore(end)) {
                String message = String.format("Timed out after %d milliseconds: ",timeout.in(MILLISECONDS)) + waitForConditionMessage;
                throw timeoutException(message, lastException);
            }

            try {
                doWait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new WebDriverException(e);
            }
        }
    }

    private boolean aPreviousStepHasFailed() {
        return StepEventBus.getEventBus().aStepInTheCurrentTestHasFailed();
    }

    public abstract void doWait() throws InterruptedException;

    private RuntimeException propagateIfNotIngored(RuntimeException e) {
        for (Class ignoredException : ignoredExceptions) {
            if (ignoredException.isInstance(e)) {
                return e;
            }
        }
        throw e;
    }

    public ThucydidesFluentWait ignoring(Class... types) {
        ignoredExceptions.addAll(Arrays.asList(types));
        return this;
    }

    public ThucydidesFluentWait withTimeout(long duration, TimeUnit unit) {
        this.timeout = new Duration(duration, unit);
        return this;
    }

    public ThucydidesFluentWait withTimeout(Duration timeout) {
        this.timeout = timeout;
        return this;
    }

    public ThucydidesFluentWait pollingEvery(long duration, TimeUnit unit) {
        this.interval = new Duration(duration, unit);
        return this;
    }

    protected RuntimeException timeoutException(String message, RuntimeException lastException) {
        throw new TimeoutException(message, lastException);
    }

    public TimeoutSchedule withTimeoutOf(int amount) {
        return new TimeoutSchedule(this, amount);
    }

    public PollingSchedule pollingEvery(int amount) {
        return new PollingSchedule(this, amount);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy