appium / java-client

Java language binding for writing Appium Tests, conforms to W3C WebDriver Protocol

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

wait.until(ExpectedConditions.visibilityOf(elementName)) related issue

vikramvi opened this issue · comments

Description

I've below code

WebDriverWait wait = new WebDriverWait(AppiumController.instance.driver, timeout); wait.until(ExpectedConditions.visibilityOf(elementName));

Here I pass timeout value but observed that instead of waiting for timeout value, it waits for default time mentioned in

PageFactory.initElements(new AppiumFieldDecorator(driver, 30, TimeUnit.SECONDS), this);

Environment

  • java client build version or git revision if you use some shapshot: 5.0.0-BETA3
  • Appium server version or git revision if you use some shapshot: 1.6.3
  • Desktop OS/version used to run Appium if necessary: Mac
  • Node.js version (unless using Appium.app|exe) or Appium CLI or Appium.app|exe:
  • Mobile platform/version under test: iOS 10.2
  • Real device or emulator/simulator: simulator

Details

  1. When I set wait , I expect element to wait for that time interval itself.
  2. But value set for wait is ignored and element waits for default timeout mentioned in PageFactory.initElements
  3. Later I tried @WithTimeout(time = 3, unit = TimeUnit.SECONDS) for this element but still it waits for defaulttime, my understanding is this particular tag overrides the default time.

Code To Reproduce Issue [ Good To Have ]

NA

Ecxeption stacktraces

NA

Link to Appium logs

https://gist.github.com/vikramvi/2eedd0643f89140fa3d6ffac8f347644

@TikhomirovSergey @SrinivasanTarget @saikrishna321 I feel this issue is related to #572

please have a look

Hi @vikramvi
I'm trying to reproduce the issue. It have not reproduced yet. I'm using that sample

    @WithTimeout(time = 500, unit = TimeUnit.MILLISECONDS)
    private WebElement stubSingleElement;

     ...

    @Test
    public void someTest() {
        PageFactory.initElements(new AppiumFieldDecorator(driver, 60, TimeUnit.SECONDS), this);
        FluentWait<WebDriver> wait = new WebDriverWait(driver, 5).ignoring(NoSuchElementException.class);
        long startMark = Calendar.getInstance().getTimeInMillis();
        try {
            wait.until(visibilityOf(stubSingleElement));
        } catch (TimeoutException|NoSuchElementException e) {
            System.out.print(e);
        }
        long endMark = Calendar.getInstance().getTimeInMillis();

        assertTrue(checkTimeDifference(5,
                TimeUnit.SECONDS, endMark - startMark));
    }

image

WebDriverWait wait = new WebDriverWait(AppiumController.instance.driver, timeout)

Could you provide the value of timeout? I want to try it.

However there is an issue. There is a conflict of implicit and explicit waitings. I think it is design issue of Selenium. You can reproduce it on commom Selenium.

driver.manage().timeouts().implicitlyWait(30, SECONDS);
FluentWait<WebDriver> wait = new WebDriverWait(driver, 5);

wait.until(presenceOfElementLocated(By.id("fakeId"))); //if 
//the element is not present or doen't exist

It will wait for more than 30 seconds.

One more question. Does the element xpath = //XCUIElementTypeApplication[1]//XCUIElementTypeButton[contains(@label,'Already a member')] exist?

Also I'am trying to read the log and it seems everything works ok.
Here it starts the searching
Here the searching ends. The value of timeout is reverted to 10 seconds

@TikhomirovSergey Please find below answers

  1. In page object class I have below constructor
public pageObjectClass(AppiumDriver driver) {
	this.driver = driver;
        PageFactory.initElements(new AppiumFieldDecorator(driver, 10, TimeUnit.SECONDS), this);
    }

Per my understanding this is implicit wait which is applied to all the elements on this page , is this correct ?

  1. Then in the same class; I've generic method which checks for both element availability and unavailability
public boolean isElementPresent(WebElement elementName, int timeout){
        	try{
        	        WebDriverWait wait = new WebDriverWait(AppiumController.instance.driver, timeout);
        	        wait.until(ExpectedConditions.visibilityOf(elementName));
        	        return true;
        	}catch(Exception e){
        	    return false;
        	}
    }

Here I pass smallest amount of time possible, say 1 sec to check and return if element is absent, is this correct way of doing ?

  1. xpath = //XCUIElementTypeApplication[1]//XCUIElementTypeButton[contains(@label,'Already a member')]

I check when this is suppose to be present and second instance it is suppose to be absent. For checking absent , I send 1 sec time interval but it waits for 10 sec as per implicit wait mentioned in constructor

  1. Is this failing because of mixing both implicit and explicit wait as you mentioned ?

  2. Isn't using @WithTimeout has an affect on implicit wait ?

  3. timeout I'm using 10 sec as implicit wait

@vikramvi

Per my understanding this is implicit wait which is applied to all the elements on this page , is this correct ?

yes

  1. Then in the same class; I've generic method which checks for both element availability and unavailability
    ...
    Here I pass smallest amount of time possible, say 1 sec to check and return if element is absent, is this correct way of doing ?

I'm not sure. What the purpose? May be it is better to just ask

element.isDisplayed();

What are you trying to achieve? Is it some quick checking that is used for if/else?

So you can work it out these ways:

@WithTimeout(time = 100, unit = TimeUnit.MILLISECONDS)
...
WebElement element

or

private RimeOutDuration duration; //should be initiated

...
PageFactory.initElements(new AppiumFieldDecorator(duration), this);
...

public boolean isElementPresent(WebElement elementName, int timeout){
               long time = duration.getTime();
               TimeUnit unit = duration.getTimeUnit(); 
        	try{
                        duration.setTime(100, TimeUnit.MILLISECONDS);
        	        WebDriverWait wait = new WebDriverWait(AppiumController.instance.driver, timeout);
        	        wait.until(ExpectedConditions.visibilityOf(elementName));
        	        return true;
        	}catch(Exception e){
        	    return false;
        	}
               finally {
                     duration.setTime(time, unit);
              }
    }

Is this failing because of mixing both implicit and explicit wait as you mentioned ?

I think yes. I suppose that it is design issue of Selenium.

Sorry for delayng.

@TikhomirovSergey sorry for late reply, please find below info in which things go havoc ( I tried with java client project )

AndroidPageObjectTest.java

    @WithTimeout(time = 4, unit = TimeUnit.SECONDS)
    @FindBy(id = "android:id/text11")  //this is invalid locator; purposely put up
    private WebElement textView;

@Before public void setUp() throws Exception {
        if (!populated) {
            //This time out is set because test can be run on slow Android SDK emulator
            PageFactory.initElements(new AppiumFieldDecorator(driver, 15, TimeUnit.SECONDS), this);
                   
        }

        populated = true;
    }

public boolean isElementPresent(WebElement elementName, int timeout){
        //long time = duration.getTime();
        //TimeUnit unit = duration.getTimeUnit(); 
 	try{
                // duration.setTime(100, TimeUnit.MILLISECONDS);
 	        WebDriverWait wait = new WebDriverWait(driver, timeout);
 	        wait.until(ExpectedConditions.visibilityOf(elementName));
 	        return true;
 	}catch(Exception e){
 	    return false;
 	}
        finally {
              //duration.setTime(time, unit);
       }
}
    
    @Test public void findByElementTest() {//Vikram
	//duration.setTime(10, TimeUnit.SECONDS);
	isElementPresent(textView,2);
       // assertNotEquals(null, textView.getAttribute("text"));
    }

Here I have 3 times set for same element
4 sec at element declaration
2 sec for checking that it's absent
15 sec as implicit wait

In this case even though appium server log says

[debug] [BaseDriver] Set implicit wait to 0ms
[debug] [BaseDriver] Set implicit wait to 15000ms

Test takes 15+ sec.

I feel we should make it clear not to combine all the timeouts and mention good practices wrt its usage.

@vikramvi Will try to reproduce it on the sample above soon.

@vikramvi Ok. It is interesting

The first sample

package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.android.BaseAndroidTest;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.WithTimeout;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;

public class BugReproducing extends BaseAndroidTest {

    private static final long ACCEPTABLE_DELTA_MILLS = 1500;

    @WithTimeout(time = 4, unit = TimeUnit.SECONDS)
    @FindBy(id = "android:id/text11")  //this is invalid locator; purposely put up
    private WebElement textView;

    /**
     * The setting up.
     */
    @Before
    public void setUp() throws Exception {
        PageFactory.initElements(new AppiumFieldDecorator(driver, 15, TimeUnit.SECONDS), this);
    }

    public boolean isElementPresent(WebElement elementName, int timeout){
        try{
            WebDriverWait wait = new WebDriverWait(driver, timeout);
            wait.until(ExpectedConditions.visibilityOf(elementName));
            return true;
        }catch(Exception e){
            return false;
        }
    }

    private static boolean checkTimeDifference(long expectedTime, TimeUnit expectedTimeUnit,
                                               long currentMillis) {
        long expectedMillis = TimeUnit.MILLISECONDS.convert(expectedTime, expectedTimeUnit);
        try {
            Assert.assertEquals(true,
                    ((currentMillis - expectedMillis) < ACCEPTABLE_DELTA_MILLS) && (
                            (currentMillis - expectedMillis) >= 0));
        } catch (Error e) {
            String message = String.valueOf(expectedTime) + " "
                    + expectedTimeUnit.toString()
                    + " current duration in millis "
                    + String.valueOf(currentMillis) + " Failed";
            throw new AssertionError(message, e);
        }
        return true;
    }

    @Test
    public void findByElementTest() {
        long startMark = Calendar.getInstance().getTimeInMillis();
        //isElementPresent(textView,2);
        try {
            textView.isDisplayed();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        long endMark = Calendar.getInstance().getTimeInMillis();
        assertTrue(checkTimeDifference(4,
                TimeUnit.SECONDS, endMark - startMark));
    }
}

and

image
It took about 4.5 sec.

ok.

package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.android.BaseAndroidTest;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.WithTimeout;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;

public class BugReproducing extends BaseAndroidTest {

    private static final long ACCEPTABLE_DELTA_MILLS = 1500;

    @WithTimeout(time = 4, unit = TimeUnit.SECONDS)
    @FindBy(id = "android:id/text11")  //this is invalid locator; purposely put up
    private WebElement textView;

    /**
     * The setting up.
     */
    @Before
    public void setUp() throws Exception {
        PageFactory.initElements(new AppiumFieldDecorator(driver, 15, TimeUnit.SECONDS), this);
    }

    public boolean isElementPresent(WebElement elementName, int timeout){
        try{
            WebDriverWait wait = new WebDriverWait(driver, timeout);
            wait.until(ExpectedConditions.visibilityOf(elementName));
            return true;
        }catch(Exception e){
            return false;
        }
    }

    private static boolean checkTimeDifference(long expectedTime, TimeUnit expectedTimeUnit,
                                               long currentMillis) {
        long expectedMillis = TimeUnit.MILLISECONDS.convert(expectedTime, expectedTimeUnit);
        try {
            Assert.assertEquals(true,
                    ((currentMillis - expectedMillis) < ACCEPTABLE_DELTA_MILLS) && (
                            (currentMillis - expectedMillis) >= 0));
        } catch (Error e) {
            String message = String.valueOf(expectedTime) + " "
                    + expectedTimeUnit.toString()
                    + " current duration in millis "
                    + String.valueOf(currentMillis) + " Failed";
            throw new AssertionError(message, e);
        }
        return true;
    }

    @Test
    public void findByElementTest() {
        long startMark = Calendar.getInstance().getTimeInMillis();
        isElementPresent(textView,2);
        /*try {
            textView.isDisplayed();
        }
        catch (Exception e) {
            e.printStackTrace();
        }*/
        long endMark = Calendar.getInstance().getTimeInMillis();
        assertTrue(checkTimeDifference(4,
                TimeUnit.SECONDS, endMark - startMark));
    }
}

this test was failed

image

But you can see that

4 SECONDS current duration in millis 8675 Failed
java.lang.AssertionError: 4 SECONDS current duration in millis 8675 Failed

not 15 seconds. However it looks curiously.

Ok. One more sample.

package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.android.BaseAndroidTest;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;

public class BugReproducing extends BaseAndroidTest {

    public boolean isElementPresent(By by, int timeout){
        try{
            WebDriverWait wait = new WebDriverWait(driver, timeout);
            wait.until(ExpectedConditions.visibilityOfElementLocated(by));
            return true;
        }catch(Exception e){
            return false;
        }
    }

    private static boolean checkTimeDifference(long expectedTime, TimeUnit expectedTimeUnit,
                                               long currentMillis) {
        long expectedMillis = TimeUnit.MILLISECONDS.convert(expectedTime, expectedTimeUnit);
        try {
            Assert.assertEquals(true,
                    ((currentMillis - expectedMillis) < ACCEPTABLE_DELTA_MILLS) && (
                            (currentMillis - expectedMillis) >= 0));
        } catch (Error e) {
            String message = String.valueOf(expectedTime) + " "
                    + expectedTimeUnit.toString()
                    + " current duration in millis "
                    + String.valueOf(currentMillis) + " Failed";
            throw new AssertionError(message, e);
        }
        return true;
    }

    @Test
    public void findByElementTest() {
        driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
        long startMark = Calendar.getInstance().getTimeInMillis();
        isElementPresent(By.id("android:id/text11"),2);
        /*try {
            textView.isDisplayed();
        }
        catch (Exception e) {
            e.printStackTrace();
        }*/
        long endMark = Calendar.getInstance().getTimeInMillis();
        assertTrue(checkTimeDifference(4,
                TimeUnit.SECONDS, endMark - startMark));
    }
}

Test passed.

image

But it took about 5 seconds, not 2 as it was expected.

Ok. The workaround for now.

package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.android.BaseAndroidTest;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.WithTimeout;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;

public class BugReproducing extends BaseAndroidTest {

    private static final long ACCEPTABLE_DELTA_MILLS = 1500;

    @WithTimeout(time = 100, unit = TimeUnit.MILLISECONDS)
    @FindBy(id = "android:id/text11")  //this is invalid locator; purposely put up
    private WebElement textView;

    /**
     * The setting up.
     */
    @Before
    public void setUp() throws Exception {
        PageFactory.initElements(new AppiumFieldDecorator(driver, 15, TimeUnit.SECONDS), this);
    }

    public boolean isElementPresent(WebElement elementName, int timeout){
        try{
            WebDriverWait wait = new WebDriverWait(driver, timeout);
            wait.until(ExpectedConditions.visibilityOf(elementName));
            return true;
        }catch(Exception e){
            return false;
        }
    }

    private static boolean checkTimeDifference(long expectedTime, TimeUnit expectedTimeUnit,
                                               long currentMillis) {
        long expectedMillis = TimeUnit.MILLISECONDS.convert(expectedTime, expectedTimeUnit);
        try {
            Assert.assertEquals(true,
                    ((currentMillis - expectedMillis) < ACCEPTABLE_DELTA_MILLS) && (
                            (currentMillis - expectedMillis) >= 0));
        } catch (Error e) {
            String message = String.valueOf(expectedTime) + " "
                    + expectedTimeUnit.toString()
                    + " current duration in millis "
                    + String.valueOf(currentMillis) + " Failed";
            throw new AssertionError(message, e);
        }
        return true;
    }

    @Test
    public void findByElementTest() {
        long startMark = Calendar.getInstance().getTimeInMillis();
        isElementPresent(textView,2);
        long endMark = Calendar.getInstance().getTimeInMillis();
        assertTrue(checkTimeDifference(2,
                TimeUnit.SECONDS, endMark - startMark));
    }
}

And test passed

image
The same is true for the direct using of the implicit waiting.

Summary:
It is possible that there is an issue. I'm cahanging the label to "But". I suppose that something has to be optimized. But the fluent waiting won't take lesser time than implicit waiting time out.

PS:

[debug] [BaseDriver] Set implicit wait to 15000ms

It is normal behaviour. It reverts timeout to the general value.

@TikhomirovSergey Thanks a ton for detailed analysis, I know it's built in problem with Selenium. If we can manage in better way at client side, will be good for users.

Please let me know in case further info needed on this

@vikramvi I am going to research and try to find more optimal solution.

@vikramvi The fix is merged and will be published at BETA4. Please take a look at the PR and close the issue

Thanks a ton for this fix @TikhomirovSergey , PR looks good. Once BETA4 is out, will check and close.

@vikramvi Now you can take 5.0.0-BETA4 and check it. Please close this issue if everything is ok.

@TikhomirovSergey Please find below updates

  1. With below it fix is working fine, appium waits for 5 sec in this case. It takes value of @WithTimeout
> @WithTimeout(time = 5, unit = TimeUnit.SECONDS)
>     @FindBy(id = "android:id/text11")
>     private WebElement textView;
>    
>     @Before public void setUp() throws Exception {
>         if (!populated) {
>             //This time out is set because test can be run on slow Android SDK emulator
>             PageFactory.initElements(new AppiumFieldDecorator(driver, 25, TimeUnit.SECONDS), this);
>         }
> 
>         populated = true;
>     }
> 
>     public boolean isElementPresent(WebElement elementName, int timeout){
>         //long time = duration.getTime();
>         //TimeUnit unit = duration.getTimeUnit(); 
>  	try{
>                 // duration.setTime(100, TimeUnit.MILLISECONDS);
>  	        WebDriverWait wait = new WebDriverWait(driver, timeout);
>  	        wait.until(ExpectedConditions.visibilityOf(elementName));
>  	        return true;
>  	}catch(Exception e){
>  	    return false;
>  	}
>         finally {
>               //duration.setTime(time, unit);
>        }
>    }
>     
>     @Test public void findByElementTest() {
>         //assertNotEquals(null, textView.getAttribute("text"));
> 	isElementPresent(textView,2);
>     }
> 
>    
>
  1. Issue happens when I only use explicit wait and implicit wait ( not sure if this is selenium issue )
    In this case, appium waits for 25 sec instead of 2 sec
> @Before public void setUp() throws Exception {
>         if (!populated) {
>             //This time out is set because test can be run on slow Android SDK emulator
>             PageFactory.initElements(new AppiumFieldDecorator(driver, 25, TimeUnit.SECONDS), this);
>         }
> 
>         populated = true;
>     }
> 
> public boolean isElementPresent(WebElement elementName, int timeout){
>         //long time = duration.getTime();
>         //TimeUnit unit = duration.getTimeUnit(); 
>  	try{
>                 // duration.setTime(100, TimeUnit.MILLISECONDS);
>  	        WebDriverWait wait = new WebDriverWait(driver, timeout);
>  	        wait.until(ExpectedConditions.visibilityOf(elementName));
>  	        return true;
>  	}catch(Exception e){
>  	    return false;
>  	}
>         finally {
>               //duration.setTime(time, unit);
>        }
>    }
>     
>     @Test public void findByElementTest() {
>         //assertNotEquals(null, textView.getAttribute("text"));
> 	isElementPresent(textView,2);
>     }


https://gist.github.com/vikramvi/ec16d0b10e766987616471a167bb1f67

@vikramvi , before u use explicit wait always remember to set 0 or minimal implicit wait, and reset it (Implicit wait) after your wait.until. This could be expected behaviour from selenium webdriver because ur explicit wait always user implicit wait as polling interval. So just for a try can u please increase waiting duration to 50 seconds.

@vikramvi

Issue happens when I only use explicit wait and implicit wait ( not sure if this is selenium issue )
In this case, appium waits for 25 sec instead of 2 sec

It is not the issue. It is the normal behaviour. @priyankshah217 is right. And before I have adviced you to use @WithTimeOut with the minimal acceptable value.

@vikramvi I am closing this ticke as @WithTimeOut works as expected. Please reopen it if there are some details.

Thanks @priyankshah217 @TikhomirovSergey for quick reply.

Thanks a ton @TikhomirovSergey for giving time for this issue & fixing

Closing as per above 2 comments.

Hi @vikramvi and @TikhomirovSergey , Please help me with it.

Both explicit and implicit waits aren't working for appium.
Tried several ways, mentioning below one among them. As of now I am using explicit wait and it breaks at below line of code >> wait.until(ExpectedConditions.elementToBeClickable(element));
Error : NoSuchMethodError
java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.WebDriverWait.until(Lcom/google/common/base/Function;)Ljava/lang/Object;

JavaClient : 3.2
Appium Server Version : 1.4.16.1
JavaClient : 5.0.0Beta9
Guava : Version 21
Selenium-Java Version 2.53.1

Not able to figure out, where and what is going wrong. Your help is appreciated.

@MeghaRamprasad Update Appium Server and Appium Java Client to latest versions.

  • If you can still reproduce issue, please open new issue instead of commenting on closed issue.
  • You can mention this issue in your new issue though.

Hello @vikramvi and all,
The solutions provided here, waiting for an element to be visible works for me.
But i;m trying to find a solution for waiting for an element to not be visible anymore, for e.g.: a progress bar . I'm trying to tell appium to wait until the element is not visible and them continue with the tests.
Here is my sample:

FluentWait<WebDriver> wait = new WebDriverWait(driver)
					.pollingEvery(500, TimeUnit.MILLISECONDS)
                                        .withTimeout(15, TimeUnit.SECONDS)
					.ignoring(NoSuchElementException.class);
		wait.until(ExpectedConditions.invisibilityOf(myElement));

I have Java client: 5.0.4
Appium Server Version :1.7.2
Selenium-Java Version 3.11
The problem is that sometimes, if the driver sincronize with the progress bar, it will spot that is no longer visible and continue with the test.
But most of the times, the bar is no longer visible and the driver keeps searching for it and say that no element found.

Is this method deprecated for Appium? Is there any method to wait until the element is no longer visible?

Thank you

@vikramvi I asked, but unfortunately no so much success :(
I intend to believe it might be something with the wait.until conditions from the java client.
I have tried with all suitable expected conditions from the org.openqa.selenium.support.ui.ExpectedConditions, but nothing, keeps saying no element fount when the element is no longer visible in the page.

Here is the thread:
https://discuss.appium.io/t/wait-for-element-to-disappear-not-be-preset-anymore/22122

yes agree. But doesn't work even using latest version 6.1.0 too :(
Anyone fix this issue?

seems to work for me with uiAutomator2 latest version.
I was testing on android 6 with Appium automator.
uiAutomator work stable on android 7 and 8 platforms which I use now for testing

Can you additionally specify which versions of Appium, Java-client and uiAutomator you are using?

Appium 1.8.1
Java client 6.1.0
UiAutomator2 latest version. Not sure right now the number.

I am facing issues with appium 8.1.1 can anyone help how to resolve it