简体   繁体   中英

Multiple waiting approaches in #Appium

What is the best possible Explicit Wait implementation in Appium?

There are 3 possibilities I am aware of:

  • Use wait FluentWait provided by Selenium
  • Use WebDriverWait from Selenium-Support which internally extends FluentWait only
  • Use Appium's native AppiumFluentWait which also extends FluentWait from Selenium .

Our framework is going through some major changes and this is the perfect time to make this future ready.

Current implementation is using, WebDriverWait but for this we have to explicitly add import for selenium-support library as Appium's implementation imports it in runtime only scopy.

Is there some issue using explicitly importing selenium-support library because of which Appium team thought of adding library import in this scope, could AppiumFluentWait be a better approach?

But Again appium has removed some common functions which are there in selenium ex: MobileElement with its new version, is this method prone to be removed in future?

Output for: mvn dependency:tree

 +- io.appium:java-client:jar:8.3.0:compile
[INFO] |  +- org.seleniumhq.selenium:selenium-api:jar:4.7.1:compile (version selected from constraint [4.7.0,5.0))
[INFO] |  +- org.seleniumhq.selenium:selenium-remote-driver:jar:4.7.1:compile (version selected from constraint [4.7.0,5.0))
[INFO] |  |  +- com.google.auto.service:auto-service-annotations:jar:1.0.1:compile
[INFO] |  |  +- com.google.auto.service:auto-service:jar:1.0.1:compile
[INFO] |  |  |  \- com.google.auto:auto-common:jar:1.2:compile
[INFO] |  |  +- io.netty:netty-buffer:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-codec-http:jar:4.1.84.Final:compile
[INFO] |  |  |  \- io.netty:netty-codec:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-common:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-transport-classes-epoll:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-transport-classes-kqueue:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-transport-native-epoll:jar:4.1.84.Final:linux-x86_64
[INFO] |  |  +- io.netty:netty-transport-native-kqueue:jar:4.1.84.Final:osx-x86_64
[INFO] |  |  +- io.netty:netty-transport-native-unix-common:jar:4.1.84.Final:compile
[INFO] |  |  +- io.netty:netty-transport:jar:4.1.84.Final:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-api:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-context:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-exporter-logging:jar:1.19.0:compile
[INFO] |  |  |  +- io.opentelemetry:opentelemetry-sdk-metrics:jar:1.19.0:compile
[INFO] |  |  |  \- io.opentelemetry:opentelemetry-sdk-logs:jar:1.19.0-alpha:compile
[INFO] |  |  |     \- io.opentelemetry:opentelemetry-api-logs:jar:1.19.0-alpha:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-sdk-common:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:jar:1.19.0-alpha:compile
[INFO] |  |  |  \- io.opentelemetry:opentelemetry-exporter-common:jar:1.19.0:runtime
[INFO] |  |  +- io.opentelemetry:opentelemetry-sdk-trace:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-sdk:jar:1.19.0:compile
[INFO] |  |  +- io.opentelemetry:opentelemetry-semconv:jar:1.19.0-alpha:compile
[INFO] |  |  +- io.ous:jtoml:jar:2.0.0:compile
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.12.18:compile
[INFO] |  |  +- org.apache.commons:commons-exec:jar:1.3:compile
[INFO] |  |  +- org.asynchttpclient:async-http-client:jar:2.12.3:compile
[INFO] |  |  |  +- org.asynchttpclient:async-http-client-netty-utils:jar:2.12.3:compile
[INFO] |  |  |  +- io.netty:netty-codec-socks:jar:4.1.60.Final:compile
[INFO] |  |  |  +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.60.Final:compile
[INFO] |  |  |  +- io.netty:netty-transport-native-kqueue:jar:osx-x86_64:4.1.60.Final:compile
[INFO] |  |  |  +- org.reactivestreams:reactive-streams:jar:1.0.3:compile
[INFO] |  |  |  +- com.typesafe.netty:netty-reactive-streams:jar:2.0.4:compile
[INFO] |  |  |  \- com.sun.activation:jakarta.activation:jar:1.2.2:compile
[INFO] |  |  +- org.seleniumhq.selenium:selenium-http:jar:4.7.1:compile
[INFO] |  |  |  \- dev.failsafe:failsafe:jar:3.3.0:compile
[INFO] |  |  +- org.seleniumhq.selenium:selenium-json:jar:4.7.1:compile
[INFO] |  |  \- org.seleniumhq.selenium:selenium-manager:jar:4.7.1:compile
[INFO] |  +- org.seleniumhq.selenium:selenium-support:jar:4.7.1:runtime (version selected from constraint [4.7.0,5.0))
[INFO] |  +- com.google.code.gson:gson:jar:2.10:compile
[INFO] |  +- cglib:cglib:jar:3.3.0:runtime
[INFO] |  |  \- org.ow2.asm:asm:jar:7.1:runtime
[INFO] |  +- commons-validator:commons-validator:jar:1.7:runtime
[INFO] |  |  +- commons-beanutils:commons-beanutils:jar:1.9.4:runtime
[INFO] |  |  +- commons-digester:commons-digester:jar:2.1:runtime
[INFO] |  |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  |  \- commons-collections:commons-collections:jar:3.2.2:runtime
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] |  +- commons-io:commons-io:jar:2.11.0:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:2.0.5:compile

So first of all it depends on the architecture.
Second, Do you really need FluentWait? The WebDriverWait class has optional arguments: timeout, poll_frequency, and ignored_exceptions and you could supply them there.

:Args:
            - driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote)
            - timeout - Number of seconds before timing out
            - poll_frequency - sleep interval between calls
              By default, it is 0.5 second.
            - ignored_exceptions - iterable structure of exception classes ignored during calls.
              By default, it contains NoSuchElementException only.

How I see it:

  1. wait = WebDriverWait(driver, 15)

  2. s_wait = WebDriverWait(driver, 5)

  3. l_wait = WebDriverWait(driver, 30)

  4. fl_wait = WebDriverWait(driver, 15, poll_frequency=1, ignored_exceptions=[ElementNotVisibleException])

  5. Then implement methods that return: waits

    def wait(self, locator, wait: WebDriverWait = None): if wait is None: wait = self._wait return wait.until(ec.presence_of_element_located(locator))

Then call the necessary method when it is needed, in general, it can be implemented within base class
An example in python, but you can reuse the logic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM