appium / appium-flutter-driver

Appium Flutter Driver is a test automation tool for Flutter apps on multiple platforms/OSes. Appium Flutter Driver is part of the Appium mobile test automation tool maintained by community
MIT License
440 stars 179 forks source link

`scrollUntilVisible` and `scrollUntilTappable` are broken. #621

Closed felix-barz-brickmakers closed 7 months ago

felix-barz-brickmakers commented 8 months ago

Currently, the scrollUntilVisible and scrollUntilTappable methods are broken. The will not correctly try to find the element due to a logic error in the while loop.

Expected behaviour

The app scrolls continuesly until either the item is found, or the waitTimeoutMilliseconds is reached

Actual behaviour

The app scrolls continuesly until both the item is found, and the waitTimeoutMilliseconds is reached. This results in the following two error scenarios:

  1. The item to be found is at the bottom of the scrollable area. In this case, the driver will try to scroll until waitTimeoutMilliseconds is reached and then succeed, as the item was found.
  2. The item is somewhere in the middle of the scrollable area. In this case, the driver will scroll past the element, but still continues after waitTimeoutMilliseconds, as the item was found somewhere on the way to the bottom. Whether the command succeeds depends on whether the final scrollIntoView will work or not

Problem

I identified the problem as a logic error in the while loop, that affects both scrollUntilVisible and scrollUntilTappable. As you can see in the copied code snippet below, the while loop uses || - which means it will continue as long as the item was not found or the timeout was not reached. It should however be an &&. The loop should only continue if both is true - the item was not found and the timeout was not reached.

  let isVisible = false;
  // it should be `!isVisible && shouldRetry(...)` in the following line
  while (!isVisible || shouldRetry(startAt, waitTimeoutMilliseconds)) {
    (async () => {
      try {
        await waitFor(self, item, durationMilliseconds);
        isVisible = true;
      } catch (ign) {}
    })();

    // ...
  }
KazuCocoa commented 8 months ago

It is welcome to create a pr