我在C#开始了一个Selenium项目。尝试等待页面完成加载,然后才进行下一步操作。
我的代码看起来像这样:
loginPage.GoToLoginPage();
loginPage.LoginAs(TestCase.Username, TestCase.Password);
loginPage.SelectRole(TestCase.Orgunit);
loginPage.AcceptRole();
在loginPage.SelectRole(TestCase.Orgunit)中:
RoleHierachyLabel = CommonsBasePage.Driver.FindElement(By.XPath("//span[contains(text(), " + role + ")]"));
RoleHierachyLabel.Click();
RoleLoginButton.Click();
我搜索元素RoleHierachyLabel。我一直在尝试使用多种方式等待页面加载或搜索元素属性允许一些超时:
1. _browserInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
2. public static bool WaitUntilElementIsPresent(RemoteWebDriver driver, By by, int timeout = 5)
{
for (var i = 0; i < timeout; i++)
{
if (driver.ElementExists(by)) return true;
}
return false;
}
你会如何解决这个障碍?
我这样做是为了解决这类问题。它是定时器和循环的组合,它们寻找特定的元素,直到它在一定的毫秒数后超时。
private IWebElement FindElementById(string id, int timeout = 1000)
{
IWebElement element = null;
var s = new Stopwatch();
s.Start();
while (s.Elapsed < TimeSpan.FromMilliseconds(timeout))
{
try
{
element = _driver.FindElementById(id);
break;
}
catch (NoSuchElementException)
{
}
}
s.Stop();
return element;
}
我也为元素启用了一个
private IWebElement ElementEnabled(IWebElement element, int timeout = 1000)
{
var s = new Stopwatch();
s.Start();
while (s.Elapsed < TimeSpan.FromMilliseconds(timeout))
{
if (element.Enabled)
{
return element;
}
}
s.Stop();
return null;
}
如Wait for page load in Selenium所述:
通常,使用Selenium 2.0时,Web驱动程序只应在确定页面已加载后才将控制权返回给调用代码。如果没有,你可以调用
waitforelemement
,它循环调用findelement
直到找到它或超时(超时可以设置)。
由于它的简单性,我喜欢这个解决方案。此外,它还有一个好处,即避免过多的等待,并将猜测工作排除在等待上限之外:
public bool WaitToLoad(By by)
{
int i = 0;
while (i < 600)
{
i++;
Thread.Sleep(100); // sleep 100 ms
try
{
driver.FindElement(by);
break;
}
catch { }
}
if (i == 600) return false; // page load failed in 1 min
else return true;
}
如果需要监控页面加载延迟,可以将其修改为还包括“计时器”:
public int WaitToLoad(By by)
{
int i = 0;
while (i < 600)
{
i++;
Thread.Sleep(100); // sleep 100 ms
try
{
driver.FindElement(by);
break;
}
catch { }
}
return i; // page load latency in 1/10 secs
}