|
iframe是一种常见的web页面展示方式,比如斗鱼的登录框就是一个iframe实现的,下面示例Cypress如何处理嵌套iframe的元素,因为想像操作一般元素的用法去操作iframe里面的元素,一步到位是会报错的(找不到元素)。
首先写一个示例web页面
比如我们这里是用golang/gin框架随便实现的一个页面,很简单,大概html代码如下
- index.tmpl
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>iframe测试</title>
- </head>
- <body>
- <iframe id="iframe1" src="http://www.runoob.com">
- </iframe>
- <p>
- <iframe name="iframe2name" id="iframe2" src="/login" frameborder="0" align="left" width="800" height="800" scrolling="no"></iframe>
- </p>
- <span>这里是正文................</span>
- </body>
- </html>
- login.tmpl
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>登录页</title>
- </head>
- <body>
- <form>
- <input id="login_input" type="text" placeholder="登录页输入框">
- </form>
- <iframe id="innerIframe" src="/register" width="200" height="200">
- </iframe>
- </body>
- </html>
- register.tmpl
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>登录页</title>
- </head>
- <body>
- <form>
- <input id="register_input" type="text" placeholder="注册页输入框">
- </form>
- </body>
- </html>
复制代码
它大概长这样:
我们的目标是操作最里层的innerIframe。
整个页面的树形结构大概如下:
注意:运行调试这种本地起来的web server,需要在Cypress的plugins/index.js里添加如下代码,否则cypress无法调试你的应用,具体问题详见描述截止3.1.5版本的Cypress已经解决了该问题,无需再添加如下代码,Cypress<3.1.5的版本请在Cypress的plugins/index.js添加如下配置:
- module.exports = (on) => {
- on('before:browser:launch', (browser = {}, args) => {
- if (browser.name === 'chrome') {
- // ^ make sure this is your browser name, you may
- // be using 'canary' or 'chromium' for example, so change it to match!
- args.push('--proxy-bypass-list=<-loopback>')
- return args
- }
- })
- }
复制代码
测试实现代码
- describe("IframeTest", function() {
- it.only("嵌套Iframe测试", function() {
- cy.visit("/iframeTest");
- cy.get("#iframe2", { timeout: 20000 })
- // 先判断最外层topIframe的存在
- .should($topIframe => {
- expect($topIframe.contents().find("#innerIframe")).to.exist;
- })
- // 再找嵌套的innerIframe
- .then($topIframe => {
- return cy.wrap($topIframe.contents().find("#innerIframe"));
- })
- // 找我们需要的元素
- .then($innerIframe => {
- return cy.wrap($innerIframe.contents().find("#register_input"));
- })
- // 对元素的处理
- .then($expectElementLocator => {
- cy.wrap($expectElementLocator).type("TTT");
- });
- });
- });
复制代码
效果
注:截止目前为止,这个问题官方还没有完美解决,这个方案和github上的这个issue都是workround(笔者试了下该issue下paulfalgout作者的方案,其实不好用,你们试试就知道了,在某些条件下会持续很久都不进行下一步动作),希望官网早日解决这个常见情况下的页面操作,也希望更多高手参与进来,找到一个更加完美的方法!
|
|