// Path: gepard-selenium/src/main/java/com/epam/gepard/selenium/conditionwatcher/selectors/Selector.java
// public interface Selector {
//     /**
//      * Gets the selector part of the object.
//      * @return with the selector string,
//      */
//     String getSelector();
// 
//     /**
//      * Define method of how the selector should work.
//      * @return with the selected object (implementation will decide how).
//      */
//     By getBy();
// }


import com.epam.gepard.inspector.conditionwatcher.Watchable;
import com.epam.gepard.selenium.conditionwatcher.selectors.Selector;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
package com.epam.gepard.selenium.conditionwatcher;


/**
 * This class provides a Template Method pattern implementation for {@link Watchable} objects.
 * You must override at least the evaluate() method.
 * If that returns true, the detailed message logged and the conditionAction is executed.
 *
 * @author Robert_Ambrus
 */
public abstract class AbstractWebDriverWatchable implements Watchable<WebDriver> {
    private final String message;

    /**
     * Constructor for this simple implementation.
     *
     * @param message The message you want to see in the log.
     */
    public AbstractWebDriverWatchable(String message) {
        this.message = message;
    }

    @Override
    public final boolean checkCondition(WebDriver webDriver) {
        boolean retval = false;

        if (evaluate(webDriver)) {
            retval = true;
            handleCondition(webDriver);
        }

        return retval;
    }

    @Override
    public String getMessage() {
        return message;
    }

    /**
     * This method should evaluate whether the watched condition is actually true.
     *
     * @param webDriver is the webDriver object.
     * @return Returns true if the watched condition is true.
     */
    protected abstract boolean evaluate(WebDriver webDriver);

    /**
     * Return detailed message to include in the log when this event is happening.
     *
     * @param webDriver is the webDriver object.
     * @return empty string by default, override if you want a detailed message logged.
     */
    protected String getDetailedMessage(WebDriver webDriver) {
        return "";
    }

    /**
     * This method is called when the condition is true.
     *
     * @param webDriver is the webDriver object.
     */
    protected void handleCondition(WebDriver webDriver) {
    }

    /**
     * Checks Visibility of an element based on selector.
     *
     * @param webDriver is the web driver object
     * @param selector  of the element
     * @return true if visible
     */
// Path: gepard-selenium/src/main/java/com/epam/gepard/selenium/conditionwatcher/selectors/Selector.java
// public interface Selector {
//     /**
//      * Gets the selector part of the object.
//      * @return with the selector string,
//      */
//     String getSelector();
// 
//     /**
//      * Define method of how the selector should work.
//      * @return with the selected object (implementation will decide how).
//      */
//     By getBy();
// }


// Path: gepard-selenium/src/main/java/com/epam/gepard/selenium/conditionwatcher/AbstractWebDriverWatchable.java
import com.epam.gepard.inspector.conditionwatcher.Watchable;
import com.epam.gepard.selenium.conditionwatcher.selectors.Selector;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;

package com.epam.gepard.selenium.conditionwatcher;


/**
 * This class provides a Template Method pattern implementation for {@link Watchable} objects.
 * You must override at least the evaluate() method.
 * If that returns true, the detailed message logged and the conditionAction is executed.
 *
 * @author Robert_Ambrus
 */
public abstract class AbstractWebDriverWatchable implements Watchable<WebDriver> {
    private final String message;

    /**
     * Constructor for this simple implementation.
     *
     * @param message The message you want to see in the log.
     */
    public AbstractWebDriverWatchable(String message) {
        this.message = message;
    }

    @Override
    public final boolean checkCondition(WebDriver webDriver) {
        boolean retval = false;

        if (evaluate(webDriver)) {
            retval = true;
            handleCondition(webDriver);
        }

        return retval;
    }

    @Override
    public String getMessage() {
        return message;
    }

    /**
     * This method should evaluate whether the watched condition is actually true.
     *
     * @param webDriver is the webDriver object.
     * @return Returns true if the watched condition is true.
     */
    protected abstract boolean evaluate(WebDriver webDriver);

    /**
     * Return detailed message to include in the log when this event is happening.
     *
     * @param webDriver is the webDriver object.
     * @return empty string by default, override if you want a detailed message logged.
     */
    protected String getDetailedMessage(WebDriver webDriver) {
        return "";
    }

    /**
     * This method is called when the condition is true.
     *
     * @param webDriver is the webDriver object.
     */
    protected void handleCondition(WebDriver webDriver) {
    }

    /**
     * Checks Visibility of an element based on selector.
     *
     * @param webDriver is the web driver object
     * @param selector  of the element
     * @return true if visible
     */
    protected boolean isVisible(WebDriver webDriver, Selector selector) {