我试图使用SeleniumWebDriverWait类型,在检查元素是否存在之前,等待页面完全加载。我尝试了两种不同的方法。
第一个方法使用IgnoreExceptionTypes,然后在Until方法内调用FindElement。这会立即抛出NoTouchElementException,而无需等待。我希望这会继续尝试查找元素,直到超时,同时忽略NosTouchElementException。它似乎不是这样工作的。为什么方法1不起作用?
第二种方法使用预期条件。元素存在,并且似乎正确等待。
driver.Navigate().GoToUrl("http://www.google.com");
var myId = "myId";
//Method 1
var wait1 = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait1.IgnoreExceptionTypes(typeof(NoSuchElementException));
//Does not wait. Immediately throws NoSuchElementException
var result1 = wait1.Until(x => x.FindElement(By.Id(myId)));
//Method 2 - works as expected
var wait2= new WebDriverWait(driver,TimeSpan.FromSeconds(10))
.Until(ExpectedConditions.ElementExists(By.Id(myId)));
回答新改写的问题...
所以我一直都这样。我使用页面对象模型来编写自动化,因此这很好地解决了这一问题,但即使不使用页面对象模型,您仍然可以使用它。
基本概念是。。。找到最后加载的元素并等待该元素。此时,您知道页面已完成加载,您的脚本可以继续,而不用担心与页面上尚未完成加载的某些元素交互。
警告...我怎么知道哪个元素是最后加载的?我完全不知道。你基本上做一个猜测(希望有根据的猜测),并使用它,直到它失败。如果你的页面不是非常动态,那么就选择任何元素。如果页面的某一部分加载较晚,请选择页面该部分内的元素。
这是我的典型做法。我为某个页面编写一个页面对象。我在页面上选择一个唯一的元素,并通过waitForLocator将其声明为。现在,当我想等待页面完成加载时,我会调用
By waitForLocator = By.Id("myId");
new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(waitForLocator));
现在我(相当)确信页面已经完成了加载,我开始编写页面对象的方法等等。我编写一个脚本,该脚本使用该页面对象,并根据测试用例与页面交互,然后运行该脚本。希望我选择了我的
waitForLocator
。如果没有,在脚本运行期间的某个时候,我会得到一些异常,因为某些元素没有完全加载(它是在我拾取的元素之后加载的)。因此,我将waitForElement
更改为我刚刚与之交互并引发异常的元素,现在我应该可以更好地猜测最后一个加载元素。基本上重复这个过程,直到不再出现异常为止。
你可能会说,这是一种非常随意的方式。这看起来确实比实际情况更随意。如果你知道你的网站和网页,你会做出一个很好的第一个猜测。很少有人会改变我的猜测一次,也很少有人会改变不止一次。也就是说,改变它真的很容易。您已经拥有引发异常的元素的定位器,只需将其粘贴到
waitForLocator
的声明中,就完成了。
因此,您可能遇到的一个例外是,如果您正确选择了
waitForLocator
,并且在加载页面后,您单击页面上的某个元素,该元素会动态加载页面的其他部分。此场景超出了等待页面加载的范围。在这种情况下,您必须构建另一个等待,等待页面的新加载部分在执行单击后完成加载。它不会影响页面加载机制。
补充意见
在回去阅读你的问题后,这里有一些额外的信息可以让你的生活更轻松。
你最初的问题有一个方法,我在下面简化/修改了这个方法来证明这个原则
public void ClickElementById(RemoteWebDriver driver, string id)
{
driver.FindElement(By.Id(id)).Click();
}
按照这种方法的编写方式,您强制自己为每个定位器类型、ID、名称、CSS选择器、XPath等创建一个方法。不要传入字符串,而是传入
By
定位器。
public void ClickElement(RemoteWebDriver driver, By locator)
{
driver.FindElement(locator).Click();
}
现在有了这个新方法,它是完全灵活的。您可以传入任何定位器类型,它都可以工作。你可以用这样的词来称呼它
ClickElement(driver, By.Id("someId"));
下面是我为firefox浏览器初始化的selenium web驱动程序。 尽管我给出了隐式等待,但我没有等待元素。它会立即抛出not found异常。如果我放那么它工作正常,没有任何问题。但是把现在测试用例包含更多线程的任何地方。sleep比实际的测试用例代码低。有人能给我建议正确的方法吗?
正在研究尝试理解显式等待的方法。 所以单选按钮被点击后,输入形式发生了变化,所以我把给它一个时间元素出现,否则会出错“元素不可见......”。所以我认为现在是理解显式等待的好时机,因为我需要等到元素出现。 但出现错误“Selenium::WebDriver::error::ElementNotVisibleError:Element当前不可见,因此可能无法与之交互”。为什么这段代码不等到元素出现
问题内容: 我们正在将Selenium与Java API和一些Javascript用户扩展一起使用。我们在应用程序中使用了很多AJAX调用。我们的许多测试都是随机失败的,因为有时AJAX调用的完成速度比其他时间慢,因此页面未完全加载。我们通过等待特定元素或Thread.sleep来解决此问题。我试图找到一种方法来代替等待网络流量完成。这样我们就可以做到这一点: 这样,我们可以摆脱线程休眠,并在服务
我在eclipse中使用SeleniumWebDriver和TestNG。问题是页面在某些数据的中途重新登录,并且重新加载的时间是灵活的,这就是为什么我不能应用显式等待时间。我想让webdriver等待,直到重新加载完成。 我正在尝试通过此代码执行此操作……但它不起作用。
如何等待硒Web驱动程序中的子窗口 当我点击提交按钮,它会把我带到子窗口,我断言URL,但有时子窗口需要时间来目前使用thread.sleep(4000),但这是错误的方式。
我还是想不通。几天前我的硒工作得很好;现在它给我带来了一些错误。我首先使用Nuget,然后我尝试手动安装它。 如何重现问题: 错误: OpenQA. Selenium.WebDriverExcture:抛出一个带有空响应的异常,向远程WebDriver服务器发送HTTP请求以获取URLhttp://localhost:60695/session.异常的状态为ReceiveFailure,消息为:基