【发布时间】:2020-12-29 00:35:56
【问题描述】:
因此,我正在创建一个BaseIFrame 类,以便在不使用 ID、xpath 或任何特定于 DOM 的情况下从任何页面通用解析嵌套的 iFrame。我使用递归来捕获页面上的所有 iFrame,并通过堆栈来收集它们。然而,在调试之后,我发现我的递归函数在遇到堆栈溢出之前一遍又一遍地循环在同一个 Web 元素上。
我该如何解决这个问题?
BaseIFrame 类:
namespace [Confidental namespace] {
public class BaseIFrame {
protected IWebDriver _driver;
private ReadOnlyCollection<IWebElement> _iframes;
public BaseIFrame(IWebDriver _driver) {
this._driver = _driver;
_iframes = _driver.FindElements(By.TagName("frame"));
_iframesSize = _iframes.Count();
}
public ReadOnlyCollection<IWebElement> getFrames() {
return _iframes;
}
private static IEnumerable GetAllFramesRecursive<T>(IWebElement frame, IWebDriver driver)
{
var result = new Stack<IWebElement>();
BaseIFrame baseClass = new BaseIFrame(driver);
var iFrameList = baseClass._iframes;
foreach (var i in iFrameList)
{
result.Push(i);
foreach (IWebElement e in GetAllFramesRecursive<IWebElement>(i, driver))
{
result.Push(e);
}
}
return result;
}
// Public callable method for unit test
public void GetAlliFramesRecursivePublic<T>(IWebElement test, IWebDriver driver)
{
GetAllFramesRecursive<IWebElement>(test, driver);
}
}
}
BaseIFrameTest类:
[TestMethod]
public void AssertiFrameLength()
{
Login();
var expected = 0;
BaseIFrame bif = new BaseIFrame(_driver);
bif.GetAlliFramesRecursivePublic<IWebElement>(bif.getFrames()[0], _driver);
var elementSize = _driver.FindElements(By.TagName("*")).Count;
for (var i = 0; i < elementSize; i++)
{
var iframesSize = _driver.FindElements(By.TagName("frame")).Count;
expected += iframesSize;
}
var actual = bif.getFrames();
Assert.AreEqual(expected, actual.Count);
}
【问题讨论】:
-
您的 for 循环总是将值压入堆栈,并且没有条件终止进程或弹出堆栈导致递归函数无限运行
-
感谢您的回复。我应该在 for 循环之后输入一个 break 语句吗?
-
我原以为
baseClass._iframes这一行会访问当前框架,而不是访问内部框架的基类。否则,您总是添加相同的内容,而永远不会到达iFrameList为空的地方 -
好吧,我认为我的第一个 foreach 循环会遍历所有外框,而我的第二个 foreach 循环会遍历外框内的所有内框。
-
当然,但据我所知,内部循环再次调用该函数并再次重复外部框架。
标签: c# selenium recursion stack infinite-loop