0

I have online text editor page. There are two buttons: "Save" and "Close".

"Save" - is clickable, when changes are not saved:

<button class="btn save-btn" title="Save content">Save</button>

"Save" - is not clickable, when there are no changes:

<button class="btn save-btn" title="Save content" disabled="">Save</button>

Close button is always clickable.

I need to have following test:

  • Click on Save
  • Wait until changes are saved (Save button is not clickable)
  • Click Close

How to check, whether "Save" button is not clickable?

3

When element becomes not clickable this will also probably be accompanied by additional UI change, for example new class "inactive" will be added to the Save button classes. If so you can do:

driver.FindElement(By.CssSelector(".save-btn.inactive"));

Update: If no additional css class is added, but the disabled="" attribute only present when disabled, this should work too

driver.FindElement(By.CssSelector(".save-btn[disabled='']"));

If Saving takes more time, than your default waiting time (the time WebDriver waits for elements to appear), you can set ImplicitlyWait to some higher value, and then set it back to what was your default

int defaultTimeout = driver.Manage().Timeouts().ImplicitlyWait;
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(100));
//find the disabled button in a preferred manner
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(defaultTimeout));
  • 1
    If button is not clickable, there is an attribute disabled="", without disabled='true' – Artur Mar 12 at 17:40
  • Updated accordingly – Jeni Mar 12 at 18:12
0

A way to do this without delving into FluentWait is to just use a while loop. Because disabled is being added to the button, it means we can use WebDriver's isEnabled method, and just loop until it returns false.

    int attempts = 0;
    int maxAttempts = 10;
    boolean buttonDisabled = false;

    while(attempts++ <= maxAttempts) {
        if(!driver.findElement(By.xpath("//button[text()='Save']")).isEnabled()) {
            buttonDisabled = true;
            break;
        } else {
            Thread.sleep(500);
        }
    }

    if(buttonDisabled) {
        // Your success code
    } else {
        // Your failure code
    }

Not super pretty, but hopefully enough to demonstrate a possible solution.

0

You can use FluentWait, and wait for ExpectedConditions.elementToBeClickable.

Create fluent wait with timeout and pooling which you need:

FluentWait wait = new FluentWait<WebDriver>(driver)
                .pollingEvery(pooling, TimeUnit.MILLISECONDS)
                .withTimeout(timeout, TimeUnit.MILLISECONDS)
                .ignoring(StaleElementReferenceException.class)
                .ignoring(NoSuchElementException.class)
                .withMessage(message);

Edit: And then specify your custom function:

Function<WebDriver, Boolean> notEnabled = new Function<WebDriver, Boolean>() {
    public Boolean apply(WebDriver driver) {
    return !driver.findElement(By.xpath("//button[text()='Save']")).isEnabled();
    }
};

And use it:

wait.until(notEnabled);

This should loop until isEnabled() return false, or until FluentWait timeouts.

Read for example:

Understand Webdriver Fluent Wait with Examples

WebDriver Implicit, Explicit and Fluent Wait Examples

  • Operator '!' cannot be applied to 'org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement>' – Artur Mar 12 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.