如何在定位元素之前等待加载帧?

时间:2018-04-05 16:29:31

标签: c# selenium selenium-webdriver webdriver frames

我正在等待Selenium在等待另一个元素之前切换更改帧。即。

var wait = new WebDriverWait(driver, 15);
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.Id("frameA"));

var wait2 = new WebDriverWait(driver, 15);
// wait for element within frameA to exist
wait2.Until(ExpectedConditions.ElementExists(By.Id("elementA")));

如果我在第二次等待之前输入一个简单的Thread.Sleep(1000);它可以正常运行,但没有它我会收到以下错误:

'unknown error: unhandled inspector error: {"code":-32000,"message":"Cannot find context with specified id"}
    enter code here

在等待填充该帧中的元素之前,有没有更好的方法等待帧上下文切换完成?

4 个答案:

答案 0 :(得分:3)

您需要考虑以下几点:

切换到框架的代码行看起来很完美,不会引发任何错误:

var wait = new WebDriverWait(driver, 15);
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.Id("frameA"));

在下一行中,您尝试了 ExpectedConditions 方法 ElementExists 。根据 API文档 ElementExists方法定义为:

An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.

Selenium 无法与元素互动,直到元素可见。因此,您需要使用方法ElementIsVisible,如下所示:

var wait2 = new WebDriverWait(driver, 15);
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("elementA")));

您可以在此处找到有关Ways to deal with #document under iframe

的详细讨论

答案 1 :(得分:2)

您可以等待框架本身可点击:

wait2.Until(ExpectedConditions.ElementExists(By.Id("YOURFRAMEID")));

答案 2 :(得分:0)

我不确定你正在使用哪种语言。但是在C#中,你需要首先切换到默认内容,然后切换到你正在处理的iframe,这就是frameA。所以这是我建议的代码:

driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(frameA);

<强>更新 实现一个明确等待元素的方法:

public void WaitForElementExplicitly(int WaitInMilliSeconds = 3000, By Selector = null)
{
  WebDriverWait wait = new WebDriverWait(CommonTestObjects.IWebDriver, TimeSpan.FromSeconds(WaitInMilliSeconds / 1000));
  IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
  {
    return d.FindElement(Selector);
  });
}

然后调用方法等待你的元素

WaitForElementExplicitly(Selector: By.Id("elementA"));

答案 3 :(得分:0)

这是你可以做到的:

var wait = new WebDriverWait(new SystemClock(), driver, TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(sleepInterval)); 
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt("yourFrameName"); 
driver.SwitchTo().Frame("yourFrameName");