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

geb.waiting.Wait.groovy Maven / Gradle / Ivy

/* 
 * Copyright 2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package geb.waiting

/**
 * Represents a particular configuration of waiting, but does not encompass what is to be waited on.
 * 

* Generally not used by user code, but used internally by {@link geb.conf.Configuration} and {@link geb.waiting.WaitingSupport}. * * @see #waitFor(Closure) */ class Wait { /** * 5 seconds */ static public final Double DEFAULT_TIMEOUT = 5 /** * 100 milliseconds */ static public final Double DEFAULT_RETRY_INTERVAL = 0.1 /** * The maximum amount of seconds that something can be waited on. */ final Double timeout /** * How many seconds to wait before trying something again while waiting. */ final Double retryInterval String customMessage Wait(Double timeout = DEFAULT_TIMEOUT, Double retryInterval = DEFAULT_RETRY_INTERVAL) { this.timeout = timeout this.retryInterval = [timeout, retryInterval].min() } String toString() { "Wait[timeout: $timeout, retryInterval: $retryInterval]" } boolean equals(other) { if (this.is(other)) { true } else if (!other instanceof Wait) { false } else { this.timeout == other.timeout && this.retryInterval == other.retryInterval } } int hashCode() { int code = 41 code = 31 * code + timeout.hashCode() code = 31 * code + retryInterval.hashCode() code } Date calculateTimeoutFromNow() { calculateTimeoutFrom(new Date()) } Date calculateTimeoutFrom(Date start) { def calendar = Calendar.instance calendar.time = start calendar.add(Calendar.MILLISECOND, Math.ceil(timeout * 1000) as int) calendar.time } /** * Invokes the given {@code block} every {@code retryInterval} seconds until it returns * a true value according to the Groovy Truth. If {@code block} does not return a truish value * within {@code timeout} seconds then a {@link geb.waiting.WaitTimeoutException} will be thrown. *

* If the given block is executing at the time when the timeout is reached, it will not be interrupted. This means that * this method may take longer than the specified {@code timeout}. For example, if the {@code block} takes 5 seconds * to complete but the timeout is 2 seconds, the wait is always going to take at least 5 seconds. *

* If {@code block} throws any {@link Throwable}, it is treated as a failure and the {@code block} will be tried * again after the {@code retryInterval} has expired. If the last invocation of {@code block} throws an exception * it will be the cause of the {@link geb.waiting.WaitTimeoutException} that will be thrown. */ def waitFor(Closure block) { def stopAt = calculateTimeoutFromNow() def pass def thrown try { pass = block() } catch (Throwable e) { pass = false thrown = e } def i = 0 def timedOut = new Date() > stopAt while (!pass && !timedOut) { sleepForRetryInterval() try { pass = block() thrown = null } catch (Throwable e) { pass = false thrown = e } finally { timedOut = new Date() > stopAt } } if (timedOut) { throw new WaitTimeoutException(this, thrown) } pass } /** * Blocks the caller for the retryInterval */ void sleepForRetryInterval() { Thread.sleep((retryInterval * 1000) as long) } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy