对于前端隐藏元素,一直是自动化定位元素的隐形杀手,让人防不胜防。脚本跑到隐藏元素时位置时报各种各样的错误,可是这种隐藏的下拉菜单又没有办法避免,所以非常头痛,这一篇只为交流隐藏元素自动化定位处理方法以及宏哥自己的一点浅薄见解。
隐藏元素,熟悉前端的或者HTML的小伙伴或者童鞋们一定不陌生,元素的属性隐藏和显示,主要是 type="hidden"和style="display: none;"属性来控制的,当然了还有其他的方法控制,宏哥这里就不详细说明了,有兴趣的小伙伴或者童鞋们可以自己查一下资料。隐藏元素是什么,隐藏元素是通过属性值 hidden="hidden" 进行隐藏,如果前端代码中出现这个,就代表该元素已经被隐藏了,大家也知道,如果元素隐藏了,是没有办法进行操作的,所谓的操作就是输入,点击,以及清空这些基本元素操作。如果通过selenium中的点击进行操作元素的话,会报错误,没有找到元素信息,前面也介绍了,隐藏的元素只能定位到,但是没有办法进行操作。
1.有两个输入框和一个登录的按钮,本来是显示的,如下图所示:
2.接下来在登录的元素属性里面让它隐藏,代码如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login</title> <link rel="stylesheet" type="text/css" href="Login.css"/> </head> <body> <div> <h1>北京宏哥</h1> <form method="post"> <input type="text" required="required" placeholder="用户名" name="u"></input> <input type="password" required="required" placeholder="密码" name="p"></input> <button type="submit" style="display: none;" onclick="display_alert()">登录</button> </form> </div> </body> <script type="text/javascript"> function display_alert(){ alert("请关注公众号:北京宏哥") } </script> </html>
这样登录按钮就不会显示了,如下图所示:
宏哥前边说了,定位隐藏元素和普通的元素没啥区别,接下来就来验证下,是不是能定位到呢?其实前边的文章中已经验证了,可能小伙伴或者童鞋们没有留意或者注意到,那么宏哥在这里就再次验证一下。
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2024-05-15 @author: 北京-宏哥 公众号:北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!) Project: 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作 ''' # 3.导入模块 from playwright.sync_api import Playwright, sync_playwright, expect def run(playwright: Playwright) -> None: browser = playwright.chromium.launch(headless=False) context = browser.new_context() page = context.new_page() page.goto("E:\\Desktop\\test\\hidden\\login.html") loginButton = page.locator("#bjhg") print(loginButton.get_attribute("name")) # 通过id定位隐藏元素,然后进行判断(上一篇两种方法) print(page.is_visible("#bjhg")) print(page.locator("#bjhg").is_visible()) page.wait_for_timeout(1000) print("browser will be close") page.close() context.close() browser.close() with sync_playwright() as playwright: run(playwright)
1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:
2.运行代码后电脑端的浏览器的动作。如下图所示:
运行结果可以看出,隐藏元素用普通定位方法,事实上是定位到了,和普通元素的定位没有任何区别!不要觉得它有什么特殊之处,需特殊的定位方法。
大家也都知道Palywright操作方法是通过模拟人的操作方法进行的,那么元素都看不到了,就没有所谓的操作不操作了,如果真的想要操作,我们可以使用前边宏哥介绍的JS语法进行操作,因为JS语法属于直接对前端的代码进行操作,隐藏元素在HTML代码中是存在的,隐藏元素主要是对于前端页面来说是不可见的。
隐藏元素可以正常定位到,只是不能操作(定位元素和操作元素是两码事,很多初学者或者面试官有时候分不清楚),操作元素是click,clear,sendKeys这些方法。
//点击隐藏登录框 loginButton = page.locator("#bjhg") loginButton.click()
按照上边的思路设计代码非常简单。
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2024-05-15 @author: 北京-宏哥 公众号:北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!) Project: 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作 ''' # 3.导入模块 from playwright.sync_api import Playwright, sync_playwright, expect def run(playwright: Playwright) -> None: browser = playwright.chromium.launch(headless=False) context = browser.new_context() page = context.new_page() page.goto("E:\\Desktop\\test\\hidden\\login.html") loginButton = page.locator("#bjhg") # 操作隐藏元素 loginButton.click() print(loginButton.get_attribute("name")) # 通过id定位隐藏元素,然后进行判断(上一篇两种方法) print(page.is_visible("#bjhg")) print(page.locator("#bjhg").is_visible()) page.wait_for_timeout(1000) print("browser will be close") page.close() context.close() browser.close() with sync_playwright() as playwright: run(playwright)
1.运行代码,右键Run'Test',就可以看到控制台输出(报错了),如下图所示:
2.运行代码后电脑端的浏览器的动作(看到没有触发点击事件,弹出窗口,最后报错了)。如下图所示:
隐藏元素用click()方法会抛异常“element is not visible - waiting...”这个报错是说元素不可见,不等待中...,同样的对“登录”按钮上的输入框如果隐藏了,执行输入(type)操作也是会报错。
Palywright和Selenium一样是无法操作隐藏元素的(但是能正常定位到),本身这个框架就是设计如此,如果非要去操作隐藏元素,那就用js的方法去操作,Palywright提供了一个入口可以执行js脚本。 js和Palywright不同,只有页面上有的元素(在dom里面的),都能正常的操作,接下来用js试试吧!
那就继续完善上边可以定位到但是不能操作的代码。
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2024-05-15 @author: 北京-宏哥 公众号:北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!) Project: 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作 ''' # 3.导入模块 from playwright.sync_api import Playwright, sync_playwright, expect def run(playwright: Playwright) -> None: browser = playwright.chromium.launch(headless=False) context = browser.new_context() page = context.new_page() page.goto("E:\\Desktop\\test\\hidden\\login.html") loginButton = page.locator("#bjhg") # 操作隐藏元素 js = "document.getElementById('bjhg').click()" page.wait_for_timeout(10000) page.evaluate(js) print(loginButton.get_attribute("name")) # 通过id定位隐藏元素,然后进行判断(上一篇两种方法) print(page.is_visible("#bjhg")) print(page.locator("#bjhg").is_visible()) page.wait_for_timeout(1000) print("browser will be close") page.close() context.close() browser.close() with sync_playwright() as playwright: run(playwright)
1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:
2.运行代码后电脑端的浏览器的动作(触发点击事件,弹出窗口,运行完之后,会发现页面正常的点击,弹出到关注宏哥的公众号窗口。)。如下图所示:
百度搜到的可能方法是先用js去掉hidden属性,再用selenium操作,这个有点多此一举,你既然都已经会用js了,何必不一次性到位直接click呢?而且宏哥发现之前讲解的也是这种方法,有点“脱了裤子排气”。在这里宏哥纠正一下,直接一步到位哈!
如果面试官想问的是定位后操作隐藏元素的话,本质上说这个问题就是毫无意义的,web自动化的目的是模拟人的正常行为去操作。 如果一个元素页面上都看不到了,你人工也是无法操作的是不是?人工都不能操作,那你自动化的意义又在哪呢?所以这个只是为了单纯的考察面试者处理问题的能力,没啥实用性!(面试造飞机,进去拧螺丝) 既然面试官这么问了,那就想办法回答上给个好印象吧!记住一定不要回怼面试官,否则你的这次面试就凉了啊!!!
好了,今天时间也不早了,宏哥就讲解和分享到这里,感谢大家耐心的阅读!喜欢宏哥的别忘记支持一下哈!!!