java 显式等待 Selenium Webdriver 中的 findElements
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34397608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Explicit Wait for findElements in Selenium Webdriver
提问by Shino
After login, the page is redirecting to one page (I want to wait for page load), where I am finding elements by tagName,
登录后,页面重定向到一个页面(我想等待页面加载),在那里我通过 tagName 查找元素,
By inputArea = By.tagName("input");
List <WebElement> myIput = driver.findElements(inputArea);
Here I want to give Explicit Wait for findElements, I want to wait for its all its visibility or presence. There are only two inputs in my web page. If I give Implicit Wait for a long time, the code will work. But it varies. So i decided to give Explicit Wait, How can i give explicit Wait for findElements?. Or How Can I check the Visibility of the second one from the List(List myIput). ie, myIput.get(1). When I give visibilityOfAllElements() like below it throws error.
在这里,我想为 findElements 提供显式等待,我想等待它的所有可见性或存在性。我的网页中只有两个输入。如果我给 Implicit Wait 很长时间,代码就会工作。但它会有所不同。所以我决定给显式等待,我怎么能显式等待 findElements?。或者如何检查列表中第二个的可见性(List myIput)。即,myIput.get(1)。当我像下面这样给出visibilityOfAllElements() 时,它会抛出错误。
WebDriverWait waitForFormLabel = new WebDriverWait(driver, 30);
By inputArea = By.tagName("input");
List <WebElement> myIput = driver.findElements(inputArea);
waitForFormLabel.until(ExpectedConditions.visibilityOfAllElements(myIput));
myIput.get(1).sendKeys("Test");
Here is the list of code I am using in my automation program.
这是我在自动化程序中使用的代码列表。
package mapap;
import java.util.ArrayList;
import java.util.List;
import lib.ReadExcellData;
import lib.WriteExcellData;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;
public class EditForm {
public static WebDriver driver;
static String excelName = "D:\xlsx\map2.xlsx";
ReadExcellData readData = new ReadExcellData(excelName);
WriteExcellData writeData = new WriteExcellData(excelName);
String baseUrl = readData.getExcellData("base", 0, 0);
By colRadio;
ExtentReports report;
ExtentTest logger;
@BeforeClass
public void browserOpen() throws Exception{
report = new ExtentReports("D:\driver\extentRepo\Edit Map Forms.html", true);
logger = report.startTest("Map Forms Automation Testing", "Adding Forms");
driver = new FirefoxDriver();
driver.get(baseUrl);
String username = readData.getExcellData("user", 1, 0);
String password = readData.getExcellData("user", 1, 1);
WebDriverWait waitForUserName = new WebDriverWait(driver, 250);
By usernameField = By.name("username");
waitForUserName.until(ExpectedConditions.elementToBeClickable(usernameField)).sendKeys(username);
driver.findElement(By.name("password")).sendKeys(password);
driver.findElement(By.xpath("//input[contains(@src,'/images/signin.png')]")).click();
}
@Test(priority = 1)
public void addingForm() throws Exception{
driver.navigate().to(baseUrl+"/anglr/form-builder/dist/#/forms");
driver.manage().window().maximize();
WebDriverWait waitForFormLabel = new WebDriverWait(driver, 30);
By inputArea = By.tagName("input");
List <WebElement> myIput = driver.findElements(inputArea);
waitForFormLabel.until(ExpectedConditions.visibilityOfAllElements(myIput));
myIput.get(1).sendKeys("Test");
}
}
Please note: if i gave Thread.sleep for a long time after the code "driver.navigate().to(baseUrl+"/anglr/form-builder/dist/#/forms");", I will get all WebElements. But I want to avoid this, I want to just wait for WebElements to load ().
请注意:如果我在代码“driver.navigate().to(baseUrl+"/anglr/form-builder/dist/#/forms");”之后给了Thread.sleep很长时间,我将获得所有WebElements。但我想避免这种情况,我只想等待 WebElements 加载 ()。
Anyone Please help.
任何人请帮忙。
回答by Cosmin
You can do something like this:
你可以这样做:
//explicit wait for input field field
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.tagName("input")));
ExpectedConditions
class can be useful in a lot of cases and provides some set of predefined condition to wait for the element. Here are some of them:
ExpectedConditions
class 在很多情况下都很有用,并提供了一些预定义的条件来等待元素。这里是其中的一些:
alertIsPresent
: Alert is presentelementSelectionStateToBe
: an element state is selection.elementToBeClickable
: an element is present and clickable.elementToBeSelected
: element is selectedframeToBeAvailableAndSwitchToIt
: frame is available and frame selected.invisibilityOfElementLocated
: an element is invisiblepresenceOfAllElementsLocatedBy
: present element located by.textToBePresentInElement
: text present on particular an elementtextToBePresentInElementValue
: and element value present for a particular element.visibilityOf
: an element visible.titleContains
: title contains
alertIsPresent
: 存在警报elementSelectionStateToBe
: 元素状态是选择。elementToBeClickable
:元素存在且可点击。elementToBeSelected
: 元素被选中frameToBeAvailableAndSwitchToIt
: 框架可用且已选择框架。invisibilityOfElementLocated
: 一个元素是不可见的presenceOfAllElementsLocatedBy
: 当前元素位于。textToBePresentInElement
: 出现在特定元素上的文本textToBePresentInElementValue
: 和特定元素的元素值。visibilityOf
: 一个可见的元素。titleContains
: 标题包含
回答by Craig Brett
I decided to figure out how to do this to resolve my use case, my use case being wanting to do explicit waits on particular FindElements calls, but not all of them, and fiddling the Implicit Waits felt unclean and horrible. So I implemented an extension method to IWebDriver that uses a WebDriverWait (see Explicit Waits in Selenium) to implement this.
我决定弄清楚如何做到这一点来解决我的用例,我的用例想要对特定的 FindElements 调用进行显式等待,但不是所有调用,并且摆弄隐式等待感觉不干净和可怕。因此,我为 IWebDriver 实现了一个扩展方法,该方法使用 WebDriverWait(请参阅 Selenium 中的显式等待)来实现这一点。
/// <summary>
/// Allows you to execute the FindElements call but specify your own timeout explicitly for this single lookup
/// </summary>
/// <remarks>
/// If you want no timeout, you can pass in TimeSpan.FromSeconds(0) to return an empty list if no elements match immediately. But then you may as well use the original method
/// </remarks>
/// <param name="driver">The IWebDriver instance to do the lookup with</param>
/// <param name="findBy">The By expression to use to find matching elements</param>
/// <param name="timeout">A timespan specifying how long to wait for the element to be available</param>
public static ReadOnlyCollection<IWebElement> FindElements(this IWebDriver driver, By findBy, TimeSpan timeout)
{
var wait = new WebDriverWait(driver, timeout);
return wait.Until((d) =>
{
var elements = d.FindElements(findBy);
return (elements.Count > 0)
? elements
: null;
});
}