我正在为网页编写自动化测试。我无法透露任何具体细节,因此,我所寻找的只是一些一般性的头脑风暴,以帮助我找出导致问题的原因。我知道这是一个长镜头,但是我已经迷上了这个问题。
网页上有一个id为“ troublesome”的元素。在手动测试中,将鼠标悬停在#troublesome上将导致它消失,并且其他地方弹出(应有的地方)。我正在尝试使用自动化测试(水豚,硒驱动器,红宝石)验证悬停时是否发生弹出窗口。但是,无论我使用哪种技术,悬停都不起作用。
但是,如果不执行JavaScript,就无法使用Capybara单击#troublesome。
即find(“#troublesome”)。click不会执行任何操作(也不会引发任何错误)。我必须使用find(“#troublesome”)。execute_script(“ this.click()”)来单击它。
但是我不需要单击它。我只需要将鼠标悬停在上面。
使用水豚:
find(“#troublesome”)。hover->将不起作用。也没有抛出任何错误。测试一直持续到失败为止,因为无法找到预期的结果。告诉红宝石入睡(however_many_seconds)没有帮助。
使用硒:
page.driver.browser.action.move_to(find(“#troublesome”)。native).perform->也不起作用。同样,没有引发任何错误。
使用触发器:
find(“#troublesome”)。trigger(:mouseover)->不起作用,因为硒驱动程序不支持触发器(并且我不想使用其他驱动程序)。
使用jquery:
不会工作。网站不使用jquery
尝试使用javascript强制:hover在元素上为true无效:
mouseHover ='var x = document.createEvent(“ MouseEvent”);x.initMouseEvent(“ mouseover”,true,true,window,0,0,0,0,0,false,false,false,false,0,null);document.getElementById(“麻烦”).dispatchEvent(x);'
page.execute_script(mouseHover)
((我可以将mouseOver更改为单击,但是它将单击!)显然,鼠标悬停不受浏览器“信任”(但单击受信任),因此将其作为选项有点用,不是吗?
我已经通过在一个inner(“#id”)do ...结束块中尝试了上述所有方法。没关系。
我什至尝试了非常规的方法来将鼠标移到#麻烦的地方:
find(“#troublesome”)。right_click->鼠标将直接悬停在#troublesome上,单击鼠标右键,然后在该元素上方弹出一个菜单!
很明显,在自动化测试期间,鼠标悬停在#麻烦上,但未在浏览器上注册。该网站没有漏洞。当我手动操作时,悬停即可工作。
我可以在网页上找到其他元素,然后将它们悬停在上面。实际上,我什至尝试将鼠标放在另一个元素上,然后将其从那里移到#troublesome上,如下所示:
page.driver.browser.action.move_to(find(“#somethingElse”)。native,1200,-50).perform
这不起作用,但是如果我将坐标调整到#somethingElse下方的第三个元素,则将触发第三个元素的悬停状态,因此很明显,该策略可以在原理和实践上起作用,但不适用于#麻烦!
[请注意,#somethingElse和“第三元素”存在于与#troublesome的祖先div相同的“层次结构”中的div上。
网页上有iframe,但iframe上没有#troublesome。
[在整个网页正文中插入了随机脚本标签。我不知道这些脚本标记在做什么,因为我看不到代码。
#麻烦事已成为我的白鲸记。
这条鲸鱼使我发疯。我已经投入太多时间了。我现在不能放弃,否则所有这些辛苦的工作都是徒劳的。
请帮助。
谢谢。
find(“#troublesome”)。hover
page.driver.browser.action.move_to(find(“#troublesome”)。native).perform
find(“#troublesome”)。trigger(:mouseover)
mouseHover ='var x = document.createEvent(“ MouseEvent”);x.initMouseEvent(“ mouseover”,true,true,window,0,0,0,0,0,false,false,false,false,0,null);document.getElementById(“ myDiv”)。dispatchEvent(x);'
page.execute_script(mouseHover)
page.driver.browser.action.move_to(find(“#somethingElse”)。native,1200,-50).perform
除了标准capybara / rspec故障日志以外,没有其他错误消息,因为它未能找到应该悬停在#troublesome上时会弹出的元素
您遇到的问题是因为示例中https://jsfiddle.net/pwo7zuL2/1/处的'.hoverme'元素的大小为0x0 px(这也是为什么无法单击它的原因)。大小为0x0,因为它仅包含绝对定位的元素,从技术上讲,在计算父对象的自动大小时,这些元素绝对不会计数。如果将鼠标悬停在元素的可见绝对定位子元素(实际上具有大小)上,而不是尝试将鼠标悬停在.hoverme元素上,则悬停将正常工作(这是在示例中手动执行时的实际操作) 。
find('#next').hover
我现在知道了问题,并且有解决方案(尽管很老套)。
问题是由于iframe覆盖了整个屏幕。即使#troublesome不在iframe内并且#troublesome的z-index设置为较高的数字,这也会阻止硒悬停在#troublesome上。(从而迫使其位于顶层)。
手动悬停工作,但是用硒悬停失败。我相信这是一个错误,因此我已经在selenium的github上报告了它。
一种有效的解决方案是使用javascript迫使iframe缩小,然后悬停(现在应该可以使用),然后使用javascript将iframe返回全屏(以免影响测试的其他方面)。
shrink_frame ='document.getElementById(“#frame”)。setAttribute(“ style”,“ width:100px; height 100px”);'
page.execute_script(shrink_frame)
这不是理想的解决方案,因为它显然不是真正的用户与网页进行交互的方式,但是考虑到这是由于硒缺陷引起的,并且可以进行手动测试,因此可以接受。