Skip to content

Instantly share code, notes, and snippets.

@azakordonets
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save azakordonets/bb88ff0677e4352728bc to your computer and use it in GitHub Desktop.
Save azakordonets/bb88ff0677e4352728bc to your computer and use it in GitHub Desktop.
Class for proper handling of retrying things to do

This class gives you nice way of retrying some action several times to make sure that either works or not. Here's an example of the code where this class can be used :

/**
	 * Get value of an element using id
	 * 
	 * @param id				the location of the element
	 * @param attribute			name of an attribute
	 * @return attribute value	value that was in attribute
	 */
	public String getValueFromId(String id, String attribute) throws Exception {
        RetryStrategy retry = new RetryStrategy();
        WebElement element = null;
        String result = null;
        while(retry.shouldRetry()) {
            try {
                element = manager.getDriver().findElement(By.id(id));
                result = element.getAttribute(attribute);
                break;
            } catch (StaleElementReferenceException e){
                logger.warning("Got into StaleElement exception with id " + id);
                retry.errorOccured(e);
            }
        }
	return result;
    } 

And here's the class code itself

/**
 * This class is designed to keep track of retry mechanism for default base methods we have like
 * clickById, getText, fillText field. This class give's us a possibility to be aware of how many retries
 * did we do in this default methods in case if element was not found.
 * We have frequent problems with StaleElementException and this class will help us to fight with this problem
 */
class RetryStrategy {
    public static final int DEFAULT_RETRIES = 3;
    public static final long DEFAULT_WAIT_TIME_IN_MILLI = 1000;

    private int numberOfRetries;
    private int numberOfTriesLeft;
    private long timeToWait;

    public RetryStrategy() {
        this(DEFAULT_RETRIES, DEFAULT_WAIT_TIME_IN_MILLI);
    }

    public RetryStrategy(int numberOfRetries, long timeToWait) {
        this.numberOfRetries = numberOfRetries;
        numberOfTriesLeft = numberOfRetries;
        this.timeToWait = timeToWait;
    }

    /**
     * @return true if there are tries left
     */
    public boolean shouldRetry() {
        return numberOfTriesLeft > 0;
    }

    public void errorOccured() throws Exception {
        numberOfTriesLeft--;
        if (!shouldRetry()) {
            throw new Exception("Retry Failed: Total " + numberOfRetries
                    + " attempts made at interval " + getTimeToWait()
                    + "ms");
        }
        waitUntilNextTry();
    }

    public void errorOccured(Throwable throwable) throws Exception {
        numberOfTriesLeft--;
        if (!shouldRetry()) {
            throw new Exception("Retry Failed: Total " + numberOfRetries
                    + " attempts made at interval " + getTimeToWait()
                    + "ms.\n"
                    + "Error message is : "+throwable.getMessage()
                    + "\n"
                    +"Caused by : "+throwable.getCause());
        }
        waitUntilNextTry();
    }

    public long getTimeToWait() {
        return timeToWait;
    }

    private void waitUntilNextTry() {
        try {
            Thread.sleep(getTimeToWait());
        } catch (InterruptedException ignored) {
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment