Package net.thucydides.core.scheduling

Source Code of net.thucydides.core.scheduling.ThucydidesFluentWait

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;
import static java.util.concurrent.TimeUnit.SECONDS;

public abstract class ThucydidesFluentWait<T> implements Wait<T> {

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

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

    private List<Class<? extends RuntimeException>> 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> V until(Function<? super T, V> isTrue) {
        long end = getClock().laterBy(timeout.in(MILLISECONDS));
        RuntimeException lastException = null;
        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)) {
                throw timeoutException(String.format("Timed out after %d seconds",
                        timeout.in(SECONDS)), 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<? extends RuntimeException> ignoredException : ignoredExceptions) {
            if (ignoredException.isInstance(e)) {
                return e;
            }
        }
        throw e;
    }

    public ThucydidesFluentWait<T> ignoring(Class<? extends RuntimeException>... types) {
        ignoredExceptions.addAll(Arrays.asList(types));
        return this;
    }

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

    public ThucydidesFluentWait<T> 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);
    }
}
TOP

Related Classes of net.thucydides.core.scheduling.ThucydidesFluentWait

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.