背景
为什么要做这件事?
最近我们在新项目的联调
,接测
阶段遇到了很大的问题,具体的问题我也不在这里过多的描述了,反正最终造成了前端同学们心力憔悴,怨声载道,哈哈哈哈(我这里也不是在抱怨谁谁谁,但是遇到问题我们就要去想怎么样去解决问题~)。于是我就在想如何让我们在这些阶段获得更加舒适的体验。
经过一点点的思考,我打算提供一些自动化的能力,可以让我们自动化过接测用例
,并在过接测用例的同时,同时监测接口
的信息,在过完接测用例后把有问题的接口调用
呈现给我们的开发者。
github:github.com/CodingCommu…
大家别误会,其实并没有开发完成,我也只是在茶余饭后,闲来无事的时候进行了一部分的技术调研,在这里和大家介绍一下我的想法。
怎么做这件事?
在说我的想法之前,我想说一下,我想要去做的事:
- 提供自动化过接测用例/自动化自测的能力
- 运行过程中接口监测能力
ok,既然明白了我的需求,那就可以去想一下如何去实现了。
在最开始的时候,我做了这样的一个图,图中有上到下分为四层,我逐层为大家介绍:
- 第一层:我阐述了我们要做的功能,主要是做前端的轻量自动化测试,包括
接测自测自动化
和接口测试
- 第二层:第二层其实我阐述我把这个需求分成了两部分,一部分是
自动化能力
,一部分是接口监测能力
。当然本文主要介绍的是自动化能力。 - 第三层:我对第二层中的
自动化能力
和接口监测能力
做了拆解(ps:我后面会详细介绍自动化能力部分,接口监测埋个坑吧,下次再说~) - 第四层:我希望我这个自动化测试的工具采用的呈现方式为
Chrome插件
,因为我认为,chrome插件我们使用起来更加方便,而且我可以利用到他提供的webRequest
对接口调用,流量信息的观察分析能力(此处待调研)。
自动化能力拆解
首先我对我要做的事情第一感觉就是按键精灵
。
我希望的是我们可以只操作一遍,便可以对这个操作流程完成录制
,之后只需要自动的进行这些操作就好了。ok,既然我们想要的是按键精灵
之类的东西,那我就这个需求进行拆解:
- 录制(本文重点)
我们应该都可以预想到,我们第一步要做的就是对用户的操作流程进行记录.但是我们这个阶段要思考的问题是
如何记录
?记录哪些信息
?记录哪些操作
?怎么记录才能易于自动化复现
?
- 操作流程->中间数据
我们
录制
的最终目的是要下一次需要自测或者过接测用例的时候进行复现的,所以其实,我们肯定是要对录制的信息转换为某种数据结
构,并保存在本地
。
- 中间数据->js脚本
可以将中间数据转换成js脚本,这个理解就比较容易,就是把之前本地存储的
中间数据
转换为js脚本
- 自执行脚本
js脚本自动执行,重现用户操作。这也就是重现用户操作的最后一步。
ok,自动化能力简单的拆解完成之后,我们就开始本文的主要内容,如何录制用户操作?
用户操作录制
把用户操作记录下来其实不算难,但是要考虑我们需要记录哪些信息以方便我们在后续操作中对用户操作记录进行重现。
所以我在这里不仅会介绍我对记录用户操作的想法,也会去介绍我将要如何利用我记录的信息对用户操作进行重现
。
我这里主要介绍的用户操作包括三种:
点击操作
键盘输入
屏幕滚动
看似只有三个,但是已经覆盖了我们业务中的比较多的场景。
github:github.com/CodingCommu…
可以查看webApi.html
包括本博客所有代码~
tip: 所有点击事件,滚动事件,键盘输入事件都需要记录时间点,相对最开始时间偏移,以正确重现.本文后续就不介绍记录时间相关的内容了
鼠标点击
代码
dom:
<button class="btn"> nihao </button>
js:
document.onclick = function (ev) { const x = ev.clientX; const y = ev.clientY; setTimeout(() => { document.elementFromPoint(x, y).dispatchEvent(clickEvent); }, 2000) } document.getElementsByClassName('btn')[0].onclick = function () { console.log(11, 1) }
讲解
首先,记录用户的点击事件并不是一件难事,但是我想要的结果是在将前文中的中间数据->js脚本
环节更加方便,所以我有这样的一个原则:
不使用记录
class,id等标识
再去通过其查找dom元素的方式进行复现操作。期望
直接通过坐标点寻找元素
!
所以向大家介绍一个Api,大家可能没有用过,但是在我们这个场景下特别好用:
document.elementFromPoint(x, y)
大家看我的代码,我给document
绑定点击事件,记录下clientX
和clientY
。
简单介绍一下clientX:
这里我使用一下别的文章中对于clientX
的介绍。
MDN:MouseEvent.clientX 是只读属性, 它提供事件发生时的应用客户端区域的水平坐标 (与页面坐标不同)。例如,不论页面是否有水平滚动,当你点击客户端区域的左上角时,鼠标事件的 clientX 值都将为 0 。
我们记录了点击的位置之后我们在复线操作阶段,只需要通过document.elementFromPoint(x, y)
获取元素之后再为它dispatchEvent
点击事件就ok了。
相关知识:
mouseEvent:developer.mozilla.org/zh-CN/docs/…
dispatchEvent: developer.mozilla.org/zh-CN/docs/…
更多测试:
<!-用于测试多种类型的点击事件可否派发--> <label><input name="Fruit" type="radio" value="" class="aaa" />苹果 </label> <label><input name="Fruit" type="radio" value="" class="bbb" />桃子 </label> <label><input name="Fruit" type="radio" value="" />香蕉 </label> <label><input name="Fruit" type="radio" value="" />梨 </label> <label><input name="Fruit" type="radio" value="" />其它 </label>
// 测试radio的点击事件是否可以派发 document.getElementsByClassName('bbb')[0].dispatchEvent(clickEvent) document.getElementsByClassName('aaa')[0].dispatchEvent(focusEvent)
键盘输入
代码
// 测试键盘输入事件 // 做法:假定,持续的键盘输入都是对同一个 input的输入, // 那我需要做的就是保存输入顺序,并记录上一刻点击的元素,并改变其value!!判断是不是input(有没有value属性来判断),如果不是用innerHtml/innerText去塞!!!为了支持富文本 document.onkeydown = function (ev) { console.log(ev) } const keyTestEl = document.getElementsByClassName('inputTest')[0]; keyTestEl.value = '11111'
讲解
其实键盘输入记录我的想法就很简单,我上面代码中的测试内容已经可以描述我的想法了。
用户操作流程:
用户会点击某个元素,之后会进行持续输入,知道下一个点击事件触发
则表示用户输入结束,就是对该dom元素的键盘操作事件结束。
复现键盘输入事件:
其实就是按照流程图的思路来,就可以完成建议的键盘事件的录制与复现。
借助的只是:document.onkeydown
和按照元素类型修改value
或者innerHtml
属性。当然也需要借助前文的document.elementFromPoint(x, y)
获取并缓存点击的元素。
于是点击事件到此为止了~