我有一个运行速度太快的Selenium Grid和WebDriver 2.48.2测试。大多数时间测试停止,因为在按下按钮之前未选择单选按钮。
使用基于JSON文件的JavaScript设置单选按钮,以便在一个部分内动态创建任意数量的单选按钮。单击“继续”按钮后,该部分将被销毁,并使用新的单选按钮创建一个新部分。
我尝试了隐含的等待但没有成功。
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
唯一对我有用的解决方案是延迟,以便有足够的时间点击单选按钮。
driver.findElement(By.id("radiobuttonid")).click();
Thread.sleep(delay);
但在我看来,这不是一个理想的解决方案,延迟时间可能不够长,或者时间太长,浪费时间;可以有任意数量的单选按钮,因此时间会呈指数级增长。
我尝试使用不同的explicit waits设置各种expected conditions,但没有成功。
我已经尝试等待创建单选按钮,因为它可能不存在(presenceOfElementLocated
& elementToBeClickable
)。我已经尝试等待它被选中(elementToBeSelected
)。
由于描述简短且容易被误解,我无法准确找到预期的条件应该做什么。
理想情况下,我希望在单击单选按钮后立即继续测试。如果可能的话,最好的方法是什么?
修改
下面的L.Bar suggestion对我来说不起作用,但确定单选按钮存在非常有帮助,只是在单选按钮被选中之前点击了继续按钮
编辑2
这只是为了扩展耶利米的正确答案。我将代码放入一个方法,使其可重用。
private static Predicate<WebDriver> forceSelectionOfElement (final String id)
{
return new Predicate<WebDriver>()
{
@Override
public boolean apply(WebDriver arg0)
{
WebElement element = arg0.findElement(By.id(id));
boolean rval = element.isSelected();
if (!rval) {
element.click();
}
return rval;
}
};
}
用法
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(forceSelectionOfElement("q___01_02_01___1___a"));
记得要导入这个命名空间,我花了很长时间才弄清楚我导入了错误的命名空间:)
import com.google.common.base.Predicate;
答案 0 :(得分:4)
我遇到了类似的问题,但在我的情况下,我的“点击”事件在某个地方丢失了。我的测试将继续,点击代码将触发,但元素的状态永远不会明显改变,测试将失败。我最后通过添加一个对所选状态更持久的自定义谓词来利用WebDriverWait的循环行为。
WebDriverWait wait = new WebDriverWait(driver, 5);
final By lookup = By.id("radio");
LOG.debug("Wait for radio to be clickable.");
wait.until(ExpectedConditions.elementToBeClickable(lookup)); //I assume this implies visibility.
LOG.debug("Element clickable. Proceeding into click behavior.");
wait.until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver arg0) {
LOG.debug("Resolving 'myId' Element");
WebElement radio = arg0.findElement(lookup);
boolean rval = radio.isSelected();
LOG.debug("Element Resolved and has a state of " + (rval ? "selected" : "not selected"));
if (!rval) {
LOG.debug("Clicking on the Element!");
radio.click();
}
//If we return false we will loop. So the first time through we let this click the radio for us.
//Second time through we should find that the element is clicked. If it's not we click it again until it represents the state we're wanting.
return rval;;
}});
自定义谓词
所以这不应该允许测试继续进行,直到元素的点击状态是我想要的。到目前为止,基本上完成了我想要的工作。
值得注意的是,Thread.sleep被认为不是硒相互作用的最佳实践。这就是ExplicitWait概念所要考虑的内容。我已经链接了一个最新的主题,其中我知道正在讨论这个问题。
Thread.sleep works but implicit wait, webdriverwait and fluent wait does not?
最好的运气!
答案 1 :(得分:3)
我的方法:
public bool IsElementPresent(By by, IWebDriver driver)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
public bool IsElementPresent(By by, IWebDriver driver, int sec)
{
bool itemExist = false;
itemExist = IsElementPresent(by, driver);
while (!itemExist && sec >= 0)
{
Thread.Sleep(1000);
itemExist = IsElementPresent(by, driver);
sec--;
}
if (sec == -1)
return false;
else
return true;
}
调用测试是否存在
//Checking if element exist 10 sec
if(IsElementPresented(By.Id("radiobuttonid"),driver,10))
{
//element exist click on it
}
else
{
//didn't exist.
}
答案 2 :(得分:1)
你说过你探索过ExpectedConditions,你试过ExpectedConditions.elementToBeSelected()
吗?您应该能够检测是否选中了单选按钮,然后向前移动。试试这样的事情
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement radio = driver.findElement(By.id("radiobuttonid"));
radio.click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("ID of message element")));
// do stuff
修改
从OP
获取更多信息后更改了代码