-
-
Notifications
You must be signed in to change notification settings - Fork 764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wait.until(ExpectedConditions.visibilityOf(elementName)) related issue #574
Comments
@TikhomirovSergey @SrinivasanTarget @saikrishna321 I feel this issue is related to #572 please have a look |
Hi @vikramvi @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));
}
Could you provide the value of 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 Also I'am trying to read the log and it seems everything works ok. |
@TikhomirovSergey Please find below answers
Per my understanding this is implicit wait which is applied to all the elements on this page , is this correct ?
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 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
|
yes
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);
}
}
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 )
Here I have 3 times set for same element In this case even though appium server log says [debug] [BaseDriver] Set implicit wait to 0ms 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 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 But you can see that
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. 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
Summary: PS:
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
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. |
It is not the issue. It is the normal behaviour. @priyankshah217 is right. And before I have adviced you to use |
@vikramvi I am closing this ticke as |
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. JavaClient : 3.2 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.
|
Hello @vikramvi and all,
I have Java client: 5.0.4 Is this method deprecated for Appium? Is there any method to wait until the element is no longer visible? Thank you |
@zuzeac can you ask this query in https://discuss.appium.io/ ? |
@vikramvi I asked, but unfortunately no so much success :( Here is the thread: |
yes agree. But doesn't work even using latest version 6.1.0 too :( |
seems to work for me with uiAutomator2 latest version. |
Can you additionally specify which versions of Appium, Java-client and uiAutomator you are using? |
Appium 1.8.1 |
I am facing issues with appium 8.1.1 can anyone help how to resolve it |
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
Details
@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
The text was updated successfully, but these errors were encountered: