我必须测试一个使用内部框架的“老式”网络应用程序。就像:
<html>
....
<frameset name="fooSet">
<frame name="myFrame">
<html>
.....
<frame name="whatever">
.....
</html>
....
</html>
我使用 rekursions 来读取所有帧......我现在唯一的问题是是否有一种方法可以像 windowsHandler 一样存储帧的处理程序......就像:
WebDriver driver = new HtmlUnitDriver();
driver.get(Constant.URL);
WebDriver fooDriver = driver.switchTo().frame("myFrame");
String handler = fooDriver.getWindowHandle();
我的意图是,一旦焦点丢失,我可以轻松导航到该框架,否则我必须再次迭代所有框架才能获得我想要选择的框架。
最佳答案
不,没有。
事实上,处理iframe
元素与 Selenium 是非常棘手的。
您可以通过三种方式切换到框架:
- 使用其索引 (0, 1, ..., N-1)
- 使用其名称或 ID(如上例所示)
- 使用
WebElement
从 DOM 获取的对象
但是您只有一个退出选项:
-
driver.switchTo().defaultContent()
一旦你切换出一个框架,你实际上就“一路向上”切换了。
因此,如果您认为使用简单的 DFS 来递归帧,那么您很可能是错的。
我发现这样做的方法是“留下面包屑”。换句话说,在切换到某个框架之前,我“记住”了从 DOM 根到该框架的整个路径。
切换出去后,因为我“回到了根”,所以我执行了到该帧的整个路径(当然除了切换到该帧之外),然后继续到它旁边的帧。
请注意,一旦切换到框架,之前的所有 WebElement
您存储的对象已变得“过时”,因此您必须在切换后再次找到它们。
P.S.:我发现几乎所有的网站都在iframe
里面存储广告。标签,所以我怀疑这是一种“旧时尚”的东西。
无论如何,这是我使用的代码(Java):
private void searchFrames(List<Integer> route)
{
doWhateverYouWannaDoHere();
if (route.size() < MAX_DEPTH)
{
int numOfFrames = webDriver.findElements(By.tagName("iframe")).size();
for (int i=0; i<numOfFrames; i++)
{
try
{
webDriver.switchTo().frame(i);
List<Integer> newRoute = new ArrayList<Integer>(route);
newRoute.add(i);
searchFrames(newRoute);
webDriver.switchTo().defaultContent();
for (int j : route)
webDriver.switchTo().frame(j);
}
catch (NoSuchFrameException error)
{
break;
}
catch (Exception error)
{
}
}
}
}
要启动该程序,请调用 searchFrames(new ArrayList<Integer>())
.
希望对你有帮助...
更新:
此方法不仅在每个帧内执行所需的操作,而且还在 DOM 本身中执行所需的操作。如果您想避免 DOM 本身,请将调用移至 try
中第一行之后的方法“doWhateverYouWannaDoHere”子句,即 webDriver.switchTo().frame(i)
之后.
关于java - 使用 Selenium 处理 InnerFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20891246/