我在使用selenium时遇到了一些问题,特别是使用了操作,尽管这可能只是一个更大问题的症状。要快速解释尝试做什么:
这里奇怪的是,即使我使用相同的功能,我在步骤1中滚动也没有问题,但在步骤3中我收到错误消息:
OpenQA.Selenium.StaleElementReferenceException:'元素引用是陈旧的;元素不再附加到DOM,它不在当前帧上下文中,或者文档已刷新'
我试图重新声明我的页脚变量,并将其作为Footer类变量包含(原来它不是),但我没有改变任何东西
我使用SendKeys而不是MoveToElement的原因是因为MoveToElement不适用于Firefox中的屏幕外元素。我在下面列出了所有相关代码,包括错误的图像以及何时发生。
有人可以建议我做错了吗?
[TestMethod]
public void Reset_newsletter_subscription_form_BR_site()
{
Browser.Goto(siteUrl);
Webpage.Footer.GoTo_CountryPageViaFooter("br");
Webpage.Footer.ScrollToFooter(); // -> This is where it fails!
Other.Irrelevant.Stuff();
}
下面是Selenium部分:
public static class Browser
{
public static IWebDriver webDriver;
public static Actions actions;
public static void Goto(string url)
{
webDriver.Url = url;
}
}
public static class Webpage
{
public static Footer Footer
{
get
{
var footer = new Footer(Browser.webDriver, Browser.actions);
return footer;
}
}
}
public class Footer
{
private IWebDriver webDriver;
private Actions actions;
private IWebElement footer;
public Footer(IWebDriver webDriver, Actions actions)
{
this.webDriver = webDriver;
this.actions = actions;
}
public void GoTo_CountryPageViaFooter(string CountryTag)
{
footer = webDriver.FindElement(By.ClassName("c-footer"));
var changeCountryButton = footer.FindElement(By.ClassName("c-footer__toggle-country-selector"));
ScrollToFooter();
actions.MoveToElement(footer).Perform();
actions.MoveToElement(changeCountryButton).Perform();
changeCountryButton.Click();
var intPageLink = footer.FindElement(By.XPath("//*[@href='/" + CountryTag + "/']"));
intPageLink.Click();
}
public void ScrollToFooter()
{
footer = webDriver.FindElement(By.ClassName("c-footer"));
//MoveToElement does not work for Firefox, so a workaround is needed.
if (webDriver is FirefoxDriver)
{
int i = 0;
while (i < 5)
{
actions.SendKeys(Keys.ArrowDown).Perform(); //This is where it fails!
i++;
}
}
actions.MoveToElement(footer).Perform();
}
答案 0 :(得分:1)
我不会使用.SendKeys()
滚动页面。它不会一致。想象一下,如果页面更长或更短......你需要滚动多少次?我认为更好的方法是使用JS将页面滚动到所需的元素。
public void ScrollToFooter()
{
footer = webDriver.FindElement(By.ClassName("c-footer"));
// MoveToElement does not work for Firefox, so a workaround is needed
if (webDriver is FirefoxDriver)
{
IJavaScriptExecutor jse = (IJavaScriptExecutor)webDriver;
jse.ExecuteScript("arguments[0].scrollIntoView();", footer);
}
else
{
actions.MoveToElement(footer).Perform();
}
}
如果您决定坚持使用您的方法,那么由于缺少else
,您就会遇到错误。如果驱动程序是FF,则在执行滚动代码后,它将执行.MoveToElement()
并失败。
您可以简化此功能,只为所有驱动程序使用JS。
public void ScrollToFooter()
{
footer = webDriver.FindElement(By.ClassName("c-footer"));
IJavaScriptExecutor jse = (IJavaScriptExecutor)webDriver;
jse.ExecuteScript("arguments[0].scrollIntoView();", footer);
}
答案 1 :(得分:0)
而不是
actions.SendKeys(Keys.ArrowDown).Perform();
我建议:
webDriver.FindElement(By.cssSelector("body")).sendKeys(Keys.ArrowDown);
答案 2 :(得分:0)
每当调用Perform()方法时,它都会计算如何与Page进行交互。因此,它的工作是找出页面中存在的活动元素(如果未在MoveToElement(元素)中指定元素或在使用Actions单击元素期间)。
所以在你的情况下,因为没有指定Element actions.SendKeys(Keys.ArrowDown).Perform();
所以Actions会关注页面中存在的任何活动元素并对其执行SendKeys操作。
Details about Actions Interaction with Web Page..
因此,一旦单击语言更改链接,附加到DOM的元素就会发生变化,因此Selenium Webdriver会将此检测为当前活动元素的更改 StaleElementReference异常抛出。
为了摆脱异常,您可以在两者之间添加等待语句,或者有一种很好的方式handle StaleElementReference Exception given here
谢谢:)