java实现客户端脚本录制_(二)appium-desktop录制脚本二次开发,生成我司自动化脚本...

本文介绍了如何对Appium Desktop的录制功能进行二次开发,以支持录制ATK(AutoTestKit)脚本。详细讲解了从新增JS脚本到设置默认框架,再到获取和传递当前Activity值,以及增加assert校验功能的实现步骤。此外,还探讨了元素名称输入框的添加和保存元素名称到数据库的设想。
摘要由CSDN通过智能技术生成

目的

对appium-desktop脚本录制功能进行二次开发,增加录制ATK脚本功能。录制样式为

{"preSteps": [----------前置条件为打开页面PG或者启动Driver(需要根据page参数判断)

],"stepSets": [

[----------支持 点击、输入、滑动、坐标点击、返回操作、校验功能(新增校验功能)

]

],"afterSteps": [

]

}

思路

新增ATK录制脚本的JS-----准备脚本需要的参数----增加新功能---编写脚本

实现步骤

1、增加AutoTestKit.js

新增js脚本用于实现录制ATK脚本

1.1、实现方案

新增AutoTestKit.js脚本关联到Framework,并设置为默认脚本

1.2、代码修改

1.2.1、新增脚本

注意设置脚本最后面的readableName和export

AutoTestKit.readableName = 'Java - ATK';

exportdefault AutoTestKit;

1.2.2、增加到frameworks

在lib/client-frameworks/index.js 常量中增加atk: AutoTestKit,注意要import AutoTestKit.

1.2.3、特殊处理AutoTestKit

AutoTestKit.js与其它语言录制脚本格式不一致,不能采用默认的跳转,需要重新设置。

首先需要在Inspector/RecordedActions.js中进行actionFramework参数传递。注意本次除了增加actionFramework参数外,还增加了sendElementName、page后面会用到

2b712957c2e9407f59a3c7ff8b930ff8.png

其次根据actionFramework路由到AutoTestKit.js

11b17eed1e1f5f643d39eaca6db7815a.png

1.2.4、设置为默认

在reducers/Inspector.js中设置DEFAULT_FRAMEWORK='atk'

2、增加当前Activity值参数

脚本中需要根据activity值的不同设置前置条件

2.1、实现方案

在startRecording和RefreshSource操作中获取当前页面的activity, 并设置为action,如果是RegisterGuideActivity前置条件设置为启动driver,否则设置为打开PG。

在ClearActions时把设置的activity重置为空

2.2、代码修改

2.2.1、获取activity

在Inspector/Inspector.js  修改refreshSource和startRecording的onClick 方法,在原来操作的基础上增加设置当前页面的activity到全部变量中。注意:refreshSource是先跟device交互再获取activity.

d2644d463054a37bada9e5f34bb1576e.png

atkStartRecording(){this.props.startRecording();this.getPage();

}

atkRefreshSource(){this.props.applyClientMethod({methodName: 'source'});this.getPage();

}/**

* 获取当前页面的activity

* @returns {*}*/getPage() {

let exec= require('child_process').execSync;

let last= exec('adb shell dumpsys window windows | grep mCurrent');

let page=last.toString("utf8").trim();this.props.setFieldValue("page",page.substring(page.lastIndexOf(".")+1,page.length-1));

}

2.2.2、传递到Framework

在Inspector/RecordedActions.js中进行page参数传递。

如1.2.3图

2.2.3、设置前置条件

目前没有办法直接获取当前页面的PG,只能手动维护一个activity与PG的对应关系,后续如果出现新的activity,需要手动维护。RegisterGuideActivity 是启动成功页面。

34f7d9504c547983a3d6cde2e60fa27f.png

2.2.4、clearActions

清楚actions时需要重置全局变量中page的值,否则不能获取新页面的值。

376bad37a872a41825dcc2e4c8a3d194.png

atkClearActions(){this.props.clearRecording();this.props.setFieldValue("page","");

}

3、增加assert校验功能

自动化脚本需要assert校验,现有录制没有该功能,需要新增。

3.1、实现方案

在Tap、Send Keys、Clear后面增加Assert功能,Assert只需要校验定位的元素存在即可,不需要和device交互。

3.2、代码修改

3.2.1、增加Assert按键

由于不需要和device交互,所以参数中不存在定位元素的属性,需要手动把findDataSource参数传递下去。

62fdf2de7fbe0599720dc11d3e18c22e.png

actions/Inspector.js中增加atkAssertResult()方法

export functionatkAssertResult (params) {return (dispatch) =>{

let args=[];

args= args.concat(params.args ||[]);

dispatch({type: RECORD_ACTION, action: params.methodName, params: args });----说明是录屏操作

dispatch({type: METHOD_CALL_DONE});---方法调用结束标示

};

}

4、ATK脚本编写

录制为ATK脚本

4.1、实现方案

根据操作类型action对应不同的AW,action=findAndAssign 获取定位元素的属性(ID 、xpath);action=click、sendKeys、swipe、tap对应AWAppiumComponentInit;action=back对应AWKeyBoardAction;action=assert对应AWDriverActionAssertBatch

4.2、代码实现

4.2.1、获取元素的描述信息

获取元素的text或者content-desc信息用于显示脚本中remark

let note="";if(selectedElement&&selectedElement.attributes.text!==""){

note=selectedElement.attributes.text;

}else if(selectedElement&&selectedElement.attributes["content-desc"]!==""){

note=selectedElement.attributes["content-desc"];

}

因为一个脚本会有多个action,所以要把元素和action进行绑定。

修改reducers/Inspector.js,每个录屏操作原来都有action、params参数,现在增加selectedElement

caseRECORD_ACTION:return{

...state,

recordedActions: [

...state.recordedActions,

{action: action.action, params: action.params,selectedElement:state.selectedElement}

]

};

结果如图:

8b628b7b7ce4986d9c5157b5e647ca8a.png

4.2.2、switch-case

其中assert与back逻辑一致

switch(action){case "findAndAssign"://取出type和value

type=params[0];

value=params[1];break;case "click":

str+=` ["${note}", "${type}","${action}","${value}"]`;break;case "sendKeys":

str+=` ["${note}", "${type}","${action}","${params[2]}", "${value}"]`;break;case "swipe":

str+=` ["滑屏", "","${action}","${params[2]}","${params[3]}","${params[4]}","${params[5]}"]`;break;case "tap":

str+=` ["坐标点击", "","${action}","${params[2]}","${params[3]}"]`;break;case "back":

let backAction="back",frontAction="back";//获取下一次操作

if(i!==actions.length-1){

backAction=actions[i+1].action;

}//获取上一步操作

if(i!==0){

frontAction=actions[i-1].action;

}//如果返回操作是第一个操作的情况

if(i===0){

str=`{\n \"preSteps\": [\n${preStep} ],\n \"stepSets\": [\n [\n`;

}else{

if("back"!==frontAction&&"assert"!==frontAction){

//上一步操作不是返回、校验操作,去除最后一个逗号

str=str.substring(0,str.length-2);

str+=`\n ]\n },\n`;

}

}

str+=` {\n"className":"AWKeyBoardAction"\n }`;

//如果back不是最后一个操作,则重新开始

if(i!==actions.length-1){

str+=`,\n`;

if("back"!==backAction&&"assert"!==backAction){

//如果下一个操作不是返回,校验操作,则添加

str+=` {\n"className": "AWAppiumComponentInit",\n "remark": "",\n "elementInfoList": [\n`;

}

}

break;

5、增加元素名称的输入框--暂时不需要

由于ATK脚本中元素是以“app-page-element”的方式定位元素,所以需要用户输入page名称和element名称,并保存到数据库中。

5.1、实现方案

在现有的Tap、Send Keys、Clear操作上增加元素输入框操作,如图

f0437bc3c5095c33b24ddc9065392f4b.png

5.2、代码修改

5.2.1、修改onClick方法

修改Inspector/SelectedElement.js 中tab、Tap、Send Keys、Clear的onClick方法,修改为通过在actions/Inspector.js中新增showSendElementNameModal()方法来控制弹出框, 该方法会把type设置为

SHOW_SEND_ELEMENT_NAME_MODAL, 在reducers/Inspector.js中中新增switch-case的一个分支,来设置sendElementNameModalVisible=true

3a3f47a990819200ca6e1847e33b0518.png

export functionshowSendElementNameModal () {return (dispatch) =>{

dispatch({type: SHOW_SEND_ELEMENT_NAME_MODAL});

};

}caseSHOW_SEND_ELEMENT_NAME_MODAL:return{

...state,

sendElementNameModalVisible:true};

5.2.2、增加输入框

新增输入element的输入框,当sendElementNameModalVisible=true时该输入框显示,点击OK时,调用新增的handleSendElementName()方法,进行元素的获取和这是输入框隐藏

655b50525342dd8246578d9119f277c8.png

handleSendElementName () {

const {sendElementName, applyClientMethod, hideSendElementNameModal, selectedElementId: elementId}= this.props;

applyClientMethod({methodName:'click', elementId});

hideSendElementNameModal();---同showSendElementNameModal()方法

}

6、保存元素名称到数据库-暂时不需要

表单提交元素名称后,需要把元素名称保存到数据库中,

6.1、实现方案

使用react已经引入JQuery的网络请求方案。通过POST方式把数据提交到数据库中

6.2、代码修改

Framework.js是各个语言录制脚本(java.js、python.js、ruby.js等)的父类。所以在Framework.js中进行数据库的统一添加

6.2.1、传参修改

Framework.js 的getCodeString()方法 增加sendElementName参数。通过RecordedActions传递过来。代码修改如下

如1.2.3图

6.2.2、post请求

其中page、element、expectedvalue需要用户填写,其它值可以通过代码获取。

postJSON() {var obj = { "app":"guanjia", "element":'aaaa', "expectedimg":"bbbb","expectedvalue": "cccc","os": "Android","page": "eeee","type": "id","value": "rwa"};--测试数据

const req= newXMLHttpRequest()

req.open('POST', 'http://10.247.39.5:7070/wisper/api/v1/atk/appium/elementinfo')

req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')

req.send(JSON.stringify(obj))

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值