selenium 踩坑记录(一) frame/iframe定位

这两天尝试一个页面的自动化测试,看上去很简单的一个页面,然而坑了我两天(

是这样的,这个页面是个很简单的表单弹窗,但是我死活定位不到这个元素。。。不管用是xpathidclass等等
打开控制台发现原来这是一个iframe弹窗,经过神奇的百度我找到了如下的解决方法

1
driver.switch().frame() // frame 参数可填frame标签的id或name, 或driver.findElement()

然而并没有什么卯月

报了No frame element found by name or id xxx错误


我又尝试用id去定位这个弹窗的顶层元素,结果报了No such element错误:

1
driver.findElement(By.className("popWindow-reduction"))

通过自己尝试和翻阅各种资料,发现可能是动态id惹的祸

于是我尝试用粗暴的Actions(python为ActionChains)键鼠操作进行实验然后成功:

1
2
3
4
5
6
7
8
Actions actions = new Actions(driver);
actions
.click()
.sendKeys(Keys.TAB, "123413551235", Keys.TAB, Keys.ENTER)
.click()
.sendKeys(Keys.TAB, Keys.ENTER)
.perform();
System.out.println("执行成功");

但是这种方法虽然很方便有效,不过看上去太过凌乱了,而且操作都是我实际在页面上进行操作尝试出来的,比较麻烦

所以我又开始寻找元素定位的方法,最后得到的代码是这样的:

1
2
3
4
5
6
7
// 语句太长所以定义一个变量进行存储
WebElement iframe = driver.findElement(By.className("popWindow-box")).findElement(By.tagName("iframe"));
driver.switchTo().frame(iframe); //切换到frame标签
driver.findElement(By.id("pimNote_content")).sendKeys("12345666");
driver.findElement(By.id("submitButton")).click();
driver.switchTo().defaultContent(); //切换回默认页面
driver.findElement(By.xpath("//*[@id=\"alt1\"]/div[2]/input")).click();

为什么要用class进行定位呢?具体的我也没有深究过,不过推测可能是因为这个modal对话框是用jq实时生成的,所有组件内部的id定位无效
还有我一开始尝试定位的是modal的根标签#popWindow-all,结果并没有成功,可能是因为这个标签没有高度的原因。

我也是一边摸索着学习一边记录,如果有不正确或不严谨的地方还请各路大佬斧正。


补充

driver.switchTo().frame()参数并不是只能传idname以及WebElement,当上述参数都不能正常使用时可以尝试使用index进行定位,比如:

1
driver.switchTo().frame(0)	// 跳转到页面第一个frame