package at.porscheinformatik.seleniumcomponents;

import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;

/**
 * A {@link SeleniumComponent} that is editable.
 *
 * @author ham
 */
public interface EditableSeleniumComponent extends ClickableSeleniumComponent
{

    /**
     * Returns true if the component is editable. Waits {@link SeleniumGlobals#getShortTimeoutInSeconds()} seconds for
     * the component to become available.
     *
     * @return true if editable
     */
    default boolean isEditable()
    {
        try
        {
            return SeleniumUtils.retryOnStale(() -> {
                WebElement element = element();

                return element.isDisplayed() && element.isEnabled();
            });
        }
        catch (NoSuchElementException e)
        {
            return false;
        }
    }

    /**
     * Returns true if the component is enabled. Waits {@link SeleniumGlobals#getShortTimeoutInSeconds()} seconds for
     * the component to become available.
     *
     * @return true if enabled
     */
    default boolean isEnabled()
    {
        try
        {
            return SeleniumUtils.retryOnStale(() -> {
                WebElement element = element();

                return element.isEnabled();
            });
        }
        catch (NoSuchElementException e)
        {
            return false;
        }
    }

    /**
     * Clears the component. Waits {@link SeleniumGlobals#getShortTimeoutInSeconds()} seconds for the component to
     * become available.
     */
    default void clear()
    {
        LOG.interaction("Clearing %s", describe());

        SeleniumAsserts.assertIsEditable(SeleniumGlobals.getShortTimeoutInSeconds(), this);
        SeleniumUtils.retryOnStale(() -> element().clear());
    }

    /**
     * Sends the key sequences to the component. Waits {@link SeleniumGlobals#getShortTimeoutInSeconds()} seconds for
     * the component to become available.
     *
     * @param keysToSend the keys to send (multiple)
     */
    default void sendKeys(CharSequence... keysToSend)
    {
        LOG.interaction("Sending \"%s\" to %s", String.join("", keysToSend), describe());

        SeleniumAsserts.assertIsClickable(SeleniumGlobals.getShortTimeoutInSeconds(), this);
        SeleniumUtils.retryOnStale(() -> {
            WebElement element = element();

            for (CharSequence current : keysToSend)
            {
                element.sendKeys(current);
            }
        });
    }

}

@@ -43,16 +43,56 @@
 nents;%0A%0A
+import static org.hamcrest.Matchers.*;%0A%0A
 import o
@@ -2239,136 +2239,199 @@
     
-SeleniumAsserts.assertIsClickable(SeleniumGlobals.getS
+// It could take some time to input the data. So we should wait longer than the s
 hort
-T
+ t
 imeout
-InSeconds(), this);%0A        SeleniumUtils.retryOnStale(() -%3E %7B%0A
+%0A        SeleniumAsserts.assertThatLater(() -%3E %7B%0A            if (isClickable())%0A            %7B%0A    
     
@@ -2463,32 +2463,36 @@
 t = element();%0A%0A
+    
             for 
@@ -2531,34 +2531,42 @@
 nd)%0A            
+  
-%7B%0A
+  %7B%0A    
                 
@@ -2608,19 +2608,104 @@
     
-%7D%0A        %7D
+    %7D%0A%0A                return true;%0A            %7D%0A%0A            return false;%0A        %7D, is(true)
 );%0A 

Make EditableSeleniumComponent more stable