一种或另一种方式,每个人都面临着在平庸的环境中发生不寻常的事情的情况。 在一百倍测试环境中测试新应用程序时,发生了类似的情况。 我们感到惊讶的是,在前端使用了一些HTML5功能,或者说,无法使用标准的Selenium WebDriver工具自动测试拖放操作。 我们想谈谈这种经历。

想象一个项目与上一个项目在技术上非常相似(在我们看来,它在正确理解和分析出现的问题方面具有较小的负面影响),但是项目之间的Angular版本从1.x更改为5.x,并且添加了用于用户界面自动测试的Selenide库。
开发的Web应用程序具有一个页面,其中包含一组可以在它们之间移动的实体。 尝试使用Selenide工具执行检查拖放功能的自检失败时,我们会感到惊讶。 看来可能出了什么问题? 在上一个项目中,在类似的测试环境中,一切工作正常。
首先,我们使用另一个Web应用程序的示例检查了当前浏览器中Selenide和Selenium函数的拖放功能。 一切正常。 更新版本,您永远不会知道...
我们决定检查是否在此处拖动。 使用Angular时错误选择元素非常容易。 我们与前端开发人员坐下来,发现拖放元素已正确选择。
通常,测试环境正常,测试方法正确编写,“手动”拖放有效,但是自动测试无效。 乍一看,没有任何理由。
最后,我们忍受了问题的事实,然后在Internet上寻找解决方案。 我们
在03/04/2016找到了未解决的问题
Chrome WebDriver#3604,这使我们感到惊讶。 试想一下,自2016年春季以来,Chrome WebDriver出现了拖放中断的问题,更不用说其他浏览器了。 不,它当然可以,但是在使用HTML5时不起作用。 事实证明,在分析问题的过程中,我们的应用程序使用了HTML5的拖放实现。
在HTML5中进行测试的拖放实现是什么? 在Internet上,找到了两个解决方案:
- 使用Java库awt.Robot(或某些第三方点击器);
- 使用javascript。
我们可能赚了一点钱或被埋在了问题中,但是我马上保留一个选择,即第一个选择的解决方案不适合我们:)可以说关于机器人的实现:
- 我们拦截鼠标,模拟完整的用户操作;
- 我们使用硒来确定元素的坐标;
- 由于使用了硒元素,因此无需更改定位器。 我们正在尝试使用xpath的项目;
- 它是用Java编写的,语法直观,文档完善。
但是我想到了有关JavaScript实现的一些信息:
- 一切都发生在浏览器内部的JavaScript上(动作对测试人员而言是隐藏的,这些动作会干扰代码);
- 在用于测试Internet上拖放的js库中,找到了一个,其来源并不那么容易找到。
- 找到的库将只需要完成一个文件即可满足您的需求,因为该库仅实现干净的拖放操作。 例如,我们需要拖动->移动->按住->放下;
- 该库是作为jQuery附加组件实现的,因此有必要了解jQuery的结构。
- 我们必须将定位符转换为css(jquery无法与xpath一起使用);
- 搜索硒元素是不可能的;您将不得不用“笔”粘住定位器。
乍看之下,第一个解决方案更加方便,并经过了测试。
总的来说,该解决方案是有效的。但是,在其开发过程中,其问题领域变得很明显。
- 在执行测试过程中鼠标移动或最小化浏览器会导致对测试过程的干扰以及它们的掉落;
- 无法使用JUnit / TestNG并行运行测试。 除非在CI中通过单独的任务并行化。
- 无法通过Selenium Grid / Selenoid控制远程计算机上的鼠标;
- 如果浏览器崩溃,Robot可以轻松地在桌面或其他打开的应用程序中单击/拖动某些内容。
最后,JavaScript实现...我想马上说一下,我们设法通过使用jquery.xpath.js jQuery插件解决了使用xpath定位器的问题。
drag_and_drop_helper.js库(
在此处提供源代码)成为js控制拖放操作的主要工具。 对她的作品进行分类没有任何意义,但是稍后我们会如何处理。
现在直接在测试中执行。 在Selenide,一切都很简单。 在使用拖放功能之前,您需要加载使用的JS库:
StringBuilder sb = new StringBuilder(); sb.append(readFile("jquery-3.3.1.min.js")); sb.append(readFile("jquery.xpath.min.js")); sb.append(readFile("drag_and_drop_helper.js")); executeJavaScript(sb.toString());
自然,如果应用程序中尚未包含jQuery,则需要对其进行加载。
在该库的原始版本中,只需编写以下内容即可:
executeJavaScript("$('" + source + "') .simulateDragDrop({ dropTarget: '" + target + "'});");
源和目标是拖放元素的CSS定位符。
如上所述,我们经常在项目中使用xpath-locator,因此经过一些改进后,库开始接受它们:
executeJavaScript("$(document).xpath('" + source + "').simulateDragDrop({ dropTarget: '" + target + "'});");
现在,实际上,关于drag_and_drop_helper.js库。 SimulationEvent代码块中有某些部分负责某些鼠标事件。 在HTML5中列出拖放操作的可能事件没有任何意义;此信息很容易找到。
为了进行测试,我们需要实现一个功能,该功能可以移动元素并将鼠标保持在目标元素上。 而且,这与源库中一样,未提供。
以此类推,我们将dragenter事件添加到库中(在dragstart和drop之间)。
type = 'dragenter'; var dragenterEvent = this.createEvent(type, {}); dragenterEvent.dataTransfer = event.dataTransfer; this.dispatchEvent($(options.dropTarget)[0], type, dragenterEvent);
但是,这还不够。 毕竟,hold事件将立即完成。 在dragEnter和drop事件之间放置固定的暂停似乎不是最方便的选择。 毕竟,最初不知道应用程序需要处理多长时间,测试中的检查次数和时间是未知的。 这些事件之间的延迟至少应可控制。 取而代之的是,我们决定将拖放测试分成多个阶段,而不是模拟整个鼠标事件集,也就是说,增加了通过参数管理涉及的事件列表的功能。
一切似乎都很好,没有出现新的缺陷,有些旧的缺陷不再存在,而且最重要的是,正在执行分配的任务。 似乎一切都很完美。 但是,现代开发工具无法处理两个事件,并使用了移动元素的各种参数。 假设在运行会导致dragStartListener错误的拖放操作时,我们有此解决方案。 但是,由于它不会破坏任何内容,因此我们没有开始更改其他任何内容。 但是,在其他应用程序中,您可能必须完成这一刻。
我们要总结以上内容。 令人惊讶的是,事实! HTML5于2013年发布,浏览器已经支持HTML5几年,为此开发了应用程序,但是webDriver仍然不知道如何使用其功能。 测试拖放操作必须使用第三方工具来实现,使体系结构复杂化,并掌握各种技巧。 是的,有这样的工具,“铃鼓跳舞”只会使我们变得更强壮,但我仍然想开箱即用地找到可行的解决方案。
根据我们的经验,可以说,尽管拖放到处都用到了,但今天这种问题并不常见。 问题可能在于Web应用程序开发技术的选择。 但是,使用HTML5的应用程序的百分比正在稳步增长,框架也在不断发展,如果浏览器和驱动程序的开发人员也没有落伍,那就太好了。
PS ,最后,一点歌词。 我想建议大家,如果可能的话,在分析问题时不要考虑这种情况的平庸或测试环境与某种模式的接近性。 这可能导致错误的结论或时间浪费。