UIAutomator2 prevents element from changing its state

Hello, guys. This is the second time I’m trying to convert my framework to using UIAutomator 2 and failing again. Here’s the issue: we have an android element that dynamically changes its state after a certain action has been done. To be precise, after the input field element was found to contain a certain value, a button should change its “enabled” property value from false to true and become clickable. But when I use UIAutomator 2, “enabled” property value never changes for this button.
Appium version is 1.13.

Update: the same issue exhibits with any version of UIAutomator on the Appium 1.14.

Update Appium to latest version.

Thank you for the reply. I just did, but the issue persists.

Actually, there’s an update about the latest version of Appium. After I installed it, the element property wouldn’t change even with the original UIAutomator. After I have downgraded back to 1.13 version, the property state wouldn’t change only with UIAutomator2.

You did not mention your code. How you find element? How you call element after it is updated?

I believe problem in a way you writing test…

Well, there’s a method that taps the element after is’s been updated. We do not interact with the element in any way before it changes its property state:

public AndroidNewConversationObjects act_startConversation() {
    appiumcontroller().tap(NewConversationUIElements.BTN_START_NEW_CONVERSATION.get());
    log.info("Tapped \"Start conversation\" button");
    return this;
}

Locator id is the following:
BTN_START_NEW_CONVERSATION(“id=com.package.name:id/action_conversationnew_start”)

And there’s an implementation of tap() method:

public MobileController tap(String locator) {
    this.performTouchAction(getTouchAction().tap(tapOptions().withElement(element(waitForMobileElement(Constants.VISIBILITY.get(), locator, appiumDriver)))));
    return this;
}

But I don’t see how any of this could be a problem if UIAutomator actually changes the way in which the app behaves.
The problem is not that I cannot find the element. The test finds it and taps it alright. Locator id always stays the same, the only thing that differs is that the button becomes clickable. And with UIAutomator2 (or the latest Appium version) it never does.

@alex-k did you double check that element you looking for can be found in “driver.getPageSource()” output ?

I did not use your way but appium annotation way intead and never have problem.

Yes, the element is always found by the driver. The problem is not that UIAutomator not being able to find it.
Here, I made some screenshots to make it more clear. This is our app screen and the element info:


As you see, “enabled” property is false and the button not clickable while the input field is empty That’s the way it works.

Now, that’s what happens when we enter username into the input field:


“Enabled” property switches to true and button becomes clickable. This is also the way the app works. Everything’s fine for now.

And now, that’s what happens when launching the tests with UIAutomator2 or Appium 1.14:


We have a legit username in the input field, but “enabled” property stays false and the button is unlickable, although the driver is able to find it and interact with it. This issue exhibits only under UIAutomator2 in Appium 1.13 or any UIAutomator in Appium 1.14. There’s no way I could reproduce this issue by any other means.
It clearly doesn’t have anything to do with the way the tests are written. UIAutomator2 somehow prevents the element from changing its property value. (Or, more likely, it has something to do with the way it sends keys to the input field).

@alex-k the way you finding elements a bit tricky. try simple code:

        List<MobileElement> elements;
        String result;
        elements = driver.findElements(MobileBy.id("action_conversationnew_start"));
        System.out.println("el size: " + elements.size());
        if (elements.size() > 0) {
            result = elements.get(0).getAttribute("enabled");
            System.out.println("el enable attr: " + result);
        }
        // do your test steps...
        elements = driver.findElements(MobileBy.id("action_conversationnew_start"));
        System.out.println("el size: " + elements.size());
        if (elements.size() > 0) {
            result = elements.get(0).getAttribute("enabled");
            System.out.println("el enable attr: " + result);
        }

Thank you for the code, but, I guess, it would tell me what I’ve already knew: there’s an element with an
“action_conversationnew_start” id and its “enabled” value equals false while I need it to be true.
Again, the issue is not that I cannot find the element. The issue is that the element never changes its value under UIAutomator2. The app itself changes its logic under testing. SendKeys() method doesn’t activate the button as it should and always did.
Anyway, I have resolved this issue by implementing my custom sendKeys() method that uses method pressKeyCode, but the method is deprecated and works very slowly, so this resolution may only be temporal.

So. You run code and in both cases you got value ‘Enabled’ false? Or you just suggested that it will not work and will return in both cases false?

Yes, I’ve tried it. I’ve got “el size: 1 el enable attr: false” before step and I’ve predictably got nothing after step since there is no element to interact with so the second part of the code does now even get executed. I’ve even changed my sendKeys() implementation this way:
MobileElement element;
element = (MobileElement) getDriver().findElement(MobileBy.id(locator));
element.sendKeys(str);
But it didn’t help.
And again, when I’m switching from sendKeys() method to pressKeyCode(), it works perfectly fine.
I don’t think there’s a problem with the way my tests are written. The framework has been running for more than three years and has never developed such a specific issue. Something is wrong with the way UIAutomator2 sends keys.

Normally when user does TAP happens first. So to make it 100% like user does you need first tap on it and then sendkeys.

Yes, that was actually one of the first things I’ve tried. But tapping the input field doesn’t help. The button does not become active.

One more thing I’ve noticed, there’s a strange “text” value after sending keys with UIAutomator2:

Compared to what it looks like normally:

When you tap on it in test - does keyboard appears? Try to type text with keyboard. Your app just does not see that some text entered without keyboard in this input.

Yes, the keyboard is always there when I tap input field.