0


Django+vue自动化测试平台(7)-- 使用Selenium+vue实现WebUI自动化及结果展示

Selenium

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。这个工具的主要功能包括:测试与浏览器的兼容性——测试应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成.Net、Java、Perl等不同语言的测试脚本。

结果预览:

在这里插入图片描述

在这里插入图片描述

实现使用到框架

django+ selenium + vue

服务端代码

django models配置

classUI_case(models.Model):
    address = models.TextField("启动的页面地址", null=False, default="")
    value = models.JSONField("执行值", null=False, default=dict)# value = [{"name": "每个元素的名称", "xpath": "xpath地址", "iframe":"0不是iframe,1是iframe", "event": "事件类型", "value": "输入值" ,"wait_time":" 等待时间"}]
    update_time = models.DateTimeField("更新时间", auto_now=True)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    user = models.ForeignKey(Userinfo, on_delete=models.CASCADE)def__str__(self):return self.value

classUI_case_result(models.Model):
    result = models.TextField("执行结果", null=False, default="")
    result_type = models.IntegerField("结果类型", null=False, default=1)# 1.执行结果, 2.截图
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    ui = models.ForeignKey(UI_case, on_delete=models.CASCADE)def__str__(self):return self.result

服务端逻辑代码

import json
from datetime import datetime
from django.http import JsonResponse
from lapi_app.models.testcase_model.testcase_tree import Menu
from lapi_app.models.ui_model.ui_case import UI_case

# 获取UI自动化的列表信息defui_ifo(request):global ui_dict, ui_result, update_time, create_time, ui_id, user_name, address
    try:
        data = json.loads(request.body)
        menu_id = data["id"]
        menu = Menu.objects.filter(id=menu_id)for i in menu:case= UI_case.objects.filter(id=i.ui_id)
            ui_id = i.ui_id
            for j incase:
                address = j.address
                user_name = j.user.account
                update_time, create_time = datetime.strftime(j.create_time,"%Y-%m-%d %H:%M:%S"), datetime.strftime(
                    j.update_time,"%Y-%m-%d %H:%M:%S")if j.value:
                    ui_result = j.value
                else:
                    ui_result =[]return JsonResponse({"code":200,"message":"获取用例信息成功","address": address,"ui_id": ui_id,"content": ui_result,"update_time": update_time,"create_time": create_time,"username": user_name
        })except Exception as e:return JsonResponse({"code":100,"message":str(e)})# 编辑UI自动化的列表信息defedit_ui_info(request):try:
        data = json.loads(request.body)id= data["id"]
        value = data["value"]
        UI_case.objects.filter(id=id).update(value=value, address=data["address"], update_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))return JsonResponse({"code":200,"message":"编辑成功"})except Exception as e:return JsonResponse({"code":100,"message":str(e)})
# 执行UI自动化defrun_ui(request):
    data = json.loads(request.body)id= data["id"]try:ifid==""or data["address"]=="":return JsonResponse({"code":100,"message":"必要参数不可为空"})case= UI_case.objects.filter(id=id)
        res = UI_case_result.objects.filter(ui_id=id)

        root =r'xxx/img/'for j in res:if j.result_type ==2:
                os.remove(os.path.join(root, j.result))
        res.delete()# chrome_address = "C:/Program Files/Google/Chrome/Application/chrome.exe"# 定义驱动
        driver = webdriver.Chrome()# 全屏显示
        driver.maximize_window()# 使用驱动 ,打开网页
        driver.get(data["address"])for i incase:if i.value =="":return JsonResponse({"code":100,"message":"自动化配置不可为空"})
            UI_case_result.objects.create(result="[info]->正在遍历操作步骤", ui_id=id)for j in i.value:if j["iframe"]==1and j["iframe_value"]!="":
                    UI_case_result.objects.create(result="[info]->正在遍历iframe", ui_id=id)try:
                        driver.switch_to.frame(j["iframe_value"])
                        UI_case_result.objects.create(result="[info]->存在这个iframe:"+ j["iframe_value"], ui_id=id)
                        driver.switch_to.frame(j["iframe_value"])
                        UI_case_result.objects.create(result="[info]->正在进入iframe:"+ j["iframe_value"], ui_id=id)
                        time.sleep(int(j["wait_time"]))
                        UI_case_result.objects.create(result="[info]->设置隐性等待时间:"+str(j["wait_time"])+"s成功",
                                                      ui_id=id)except Exception as e:
                        UI_case_result.objects.create(result="[error]->没有这个iframe元素,地址为>>"+ j["iframe_value"],
                                                      ui_id=id)
                        UI_case_result.objects.create(result="[error]->异常原因"+str(e)+',元素命为:'+ j["xpath"], ui_id=id)if j["xpath"]isnotNone:
                    UI_case_result.objects.create(result="[info]->正在遍历页面元素", ui_id=id)
                    img = save_img(driver)try:
                        xpath = driver.find_element(By.XPATH, j["xpath"])if j["event"]==1:
                            xpath.click()
                            UI_case_result.objects.create(result="[info]->点击成功>>"+ j["name"]+",xpath地址:"+':'+ j["xpath"],
                                                          ui_id=id)
                            UI_case_result.objects.create(result=img, ui_id=id, result_type=2)
                            time.sleep(int(j["wait_time"]))
                            UI_case_result.objects.create(result="[info]->设置隐性等待时间:"+str(j["wait_time"])+"s成功",
                                                          ui_id=id)elif j["event"]==2:
                            xpath.send_keys(j["value"])
                            UI_case_result.objects.create(result="[info]->输入值成功: "+str(j["value"]), ui_id=id)
                            time.sleep(int(j["wait_time"]))
                            UI_case_result.objects.create(result=img, ui_id=id, result_type=2)
                            UI_case_result.objects.create(result="[info]->设置隐性等待时间:"+str(j["wait_time"])+"s成功", ui_id=id)except Exception as e:
                        UI_case_result.objects.create(result="[error]->没有这个元素名为>>"+str(j["name"])+':'+ j["xpath"],
                                                      ui_id=id)
                        UI_case_result.objects.create(result="[error]->异常原因"+str(e)+',元素命为:'+str(j["name"]), ui_id=id)
        time.sleep(5)# 关闭浏览器
        driver.quit()
        UI_case_result.objects.create(result="[info]->已关闭浏览器", ui_id=id)
        UI_case_result.objects.create(result="结束", ui_id=id)return JsonResponse({"code":200,"message":"执行结束"})except Exception as e:
        UI_case_result.objects.create(result="[error]->异常原因"+str(e), ui_id=id)
        UI_case_result.objects.create(result="结束", ui_id=id)return JsonResponse({"code":100,"message":str(e)})# 执行过程中对步骤进行截图保存defsave_img(driver):
    now = calendar.timegm(time.gmtime())# 截图保存的文件名格式
    pic_path =str(now)+''.join(random.sample(string.ascii_letters+string.digits,4))+'_screen.png'# 截图保存的路径# print(pic_path)
    driver.save_screenshot("xxx/img/"+ pic_path)# 调用Driver的截图保存功能return pic_path

# 获取执行结果defget_run_ui_result(request):try:
        data = json.loads(request.body)if data["time"]=="":
            res = UI_case_result.objects.filter(ui_id=data["id"])else:
            res = UI_case_result.objects.filter(ui_id=data["id"], create_time__gt=data["time"])
        result =[]for i in res:
            i_dict ={"id": i.id,"result": i.result,"timestamp": datetime.strftime(i.create_time,"%Y-%m-%d %H:%M:%S"),"type": i.result_type
            }
            result.append(i_dict)return JsonResponse({"code":200,"content": result
        })except Exception as e:return JsonResponse({"code":100,"message":str(e)})

前端逻辑代码

<template><divclass="app-container"style="height: 100%;padding-left: 5px !important;"><divstyle="border-radius: 2px;float: left;width: 20%;padding-right:10px;height: 100%;overflow: auto"><el-inputv-model="filterText"placeholder="请输入要搜索的节点"style="margin-bottom:5px;"/><el-treeref="tree":data="tree_data":props="defaultProps":highlight-current="true"class="filter-tree":default-expanded-keys="[1, 10]":expand-on-click-node="false":filter-node-method="filterNode"node-key="id"draggable:allow-drop="allowDrop"@node-drop="node_drop"@node-click="node_click"><spanslot-scope="{ node, data }"class="custom-tree-node"@mouseenter="getcase(data)"><spanv-if="data.type===0"><i:class="icon0"style="padding-right: 5px"/>{{ node.label }}</span><spanv-if="data.type===3"><i:class="icon1"style="padding-right: 5px"/>{{ node.label }}</span><spanv-if="data.type===4"><i:class="icon2"style="padding-right: 5px"/>{{ node.label }}</span><spanv-if="data.type === 0"class="right":class="{newStyle: 1 === number}"><el-dropdownplacement="bottom"><iclass="el-icon-more"/><spanclass="el-dropdown-link"style="font-size: 20px"/><el-dropdown-menuslot="dropdown"class="header-new-drop"><el-dropdown-itemicon="el-icon-folder-add"@click.native="new_menu(data)">新建子菜单</el-dropdown-item></el-dropdown-menu></el-dropdown></span><spanv-if="data.type === 3"class="right":class="{newStyle: 1 === number}"><el-dropdownplacement="bottom"><iclass="el-icon-more"/><spanclass="el-dropdown-link"style="font-size: 20px"/><el-dropdown-menuslot="dropdown"class="header-new-drop"><el-dropdown-itemicon="el-icon-folder-add"@click.native="new_menu(data)">新增</el-dropdown-item><el-dropdown-itemdividedicon="el-icon-edit"@click.native="edit(data)">重命名</el-dropdown-item><el-dropdown-itemdividedicon="el-icon-folder-delete"@click.native="delete_del(node, data)">删除文件夹</el-dropdown-item></el-dropdown-menu></el-dropdown></span><spanv-if="data.type ===4"class="right":class="{newStyle: 2 === number}"><el-dropdownplacement="bottom"><iclass="el-icon-more"/><spanclass="el-dropdown-link"style="font-size: 20px"/><el-dropdown-menuslot="dropdown"class="header-new-drop"><el-dropdown-itemicon="el-icon-edit"@click.native="edit(data)">重命名</el-dropdown-item><el-dropdown-itemdividedicon="el-icon-document-delete"@click.native="delete_case(node, data)">删除接口</el-dropdown-item></el-dropdown-menu></el-dropdown></span></span></el-tree></div><divstyle="overflow: auto;height: 100%"><el-tabsv-model="TabsValue"type="card"closable@tab-remove="removeTab"@tab-click="tab_click"><el-tab-panev-for="(item) in tableTabs":key="item.name":label="item.title":name="item.name"><spanslot="label"><spanv-if="item.type===3"><i:class="icon1"style="padding-right: 5px"/>{{ item.title }}</span><spanv-if="item.type===4"><i:class="icon2"style="padding-right: 5px"/>{{ item.title }}</span></span><divv-show="1 === number">
            {{ item.title }}
          </div><divv-show="2 === number"><div><divstyle="padding-block-end: 10px"><el-buttontype="success"@click="run_ui_test">立即执行</el-button><el-buttontype="primary"@click="ui_test_result">查看上一次结果</el-button><el-buttonstyle="float: right"type="primary"@click="edit_ui_dialog()">编辑</el-button></div><divstyle="padding-block-end: 10px"><el-descriptions:column="3"border><el-descriptions-itemlabel-class-name="my-label"label="ID:":content-style="{'text-align': 'left'}"style="width: 200px">
                    {{ ui_id }}</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="用例名称:":content-style="{'text-align': 'left'}"style="width: 200px">{{ item.title }}</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="定位方式:":content-style="{'text-align': 'left'}"style="width: 200px">xpath</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="创建人:":content-style="{'text-align': 'left'}"style="width: 200px">{{ username }}</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="创建时间:":content-style="{'text-align': 'left'}"style="width: 200px">
                    {{ create_time }}</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="编辑时间:":content-style="{'text-align': 'left'}"style="width: 200px">
                    {{ update_time }}</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="执行方式:":content-style="{'text-align': 'left'}"style="width: 200px">Chrome</el-descriptions-item><el-descriptions-itemlabel-class-name="my-label"label="启动地址:":content-style="{'text-align': 'left'}"style="width: 200px">{{ address }}</el-descriptions-item></el-descriptions></div><div><el-tableclass="view_ui":data="table_data"element-loading-text="Loading"borderfithighlight-current-rowstyle="float:left;width:100%"><el-table-columnlabel="步骤名称"width="200px"><templateslot-scope="scope">
                      {{ scope.row.name }}
                    </template></el-table-column><el-table-columnlabel="xpath地址"><templateslot-scope="scope">
                      {{ scope.row.xpath }}
                    </template></el-table-column><el-table-columnlabel="是否iframe"width="100px"><templateslot-scope="scope"><spanv-if="scope.row.iframe===1"><el-tagtype="success">是</el-tag></span><spanv-if="scope.row.iframe===0"><el-tagtype="danger">否</el-tag></span></template>event
                  </el-table-column><el-table-columnlabel="iframe地址"width="200px"><templateslot-scope="scope">
                      {{ scope.row.iframe_value }}
                    </template>event
                  </el-table-column><el-table-columnlabel="事件类型"width="100px"><templateslot-scope="scope">
                      {{ scope.row.event }}
                    </template></el-table-column><el-table-columnlabel="输入值"width="100px"><templateslot-scope="scope">
                      {{ scope.row.value }}
                    </template></el-table-column><el-table-columnlabel="等待时间"width="100px"><templateslot-scope="scope">
                      {{ scope.row.wait_time }} s
                    </template></el-table-column></el-table></div></div></div></el-tab-pane></el-tabs></div><div><el-dialogtitle="重命名":visible.sync="editdialogVisible"width="30%":before-close="handleClose"><el-form:model="menu_form"><el-form-itemlabel="menu_id"><el-inputv-model="menu_form.id"readonly/></el-form-item><el-form-itemlabel="菜单名称"><el-inputv-model="tree_name"/></el-form-item></el-form><spanslot="footer"class="dialog-footer"><el-button@click="editdialogVisible = false">取 消</el-button><el-buttontype="primary"@click="edit_menu">确 定</el-button></span></el-dialog></div><div><el-dialogtitle="新增子菜单":visible.sync="dialogVisible"width="30%":before-close="handleClose"><el-form:model="menu_pid"><el-form-itemlabel="Type:"><el-selectv-model="type_value"><el-optionv-for="item in type_form":key="item.value":label="item.label":value="item.value"/></el-select></el-form-item><el-form-itemlabel="菜单名称"><el-inputv-model="menu_form.label"/></el-form-item></el-form><spanslot="footer"class="dialog-footer"><el-button@click="dialogVisible = false">取 消</el-button><el-buttontype="primary"@click="add_menu">确 定</el-button></span></el-dialog></div><div><el-dialogtitle="提示":visible.sync="del_case_dialog"width="20%"><span>是否删除改配置项</span><spanslot="footer"class="dialog-footer"><el-button@click="del_case_dialog = false">取 消</el-button><el-buttontype="primary"@click="deletepro()">确 定</el-button></span></el-dialog></div><div><el-dialogtitle="编辑配置":visible.sync="edit_case_dialog"width="80%"><el-form:model="edit_ui"><el-form-item><el-buttontype="primary"style="float: right"@click="add_ui_step">新增步骤</el-button></el-form-item><el-form-itemlabel="启动地址"><el-inputv-model="address"style="width: 500px"/></el-form-item><el-form-item><el-tableclass="edit_ui":data="edit_ui"element-loading-text="Loading"borderfithighlight-current-rowstyle="float:left;width:100%"@cell-mouse-enter="handleCellEnter"@cell-mouse-leave="handleCellLeave"@cell-click="handleCellClick"><el-table-columnlabel="步骤名称"width="200px"><divslot-scope="scope"class="item"><el-inputv-model="scope.row.name"class="item__input"placeholder="请输入内容"/></div></el-table-column><el-table-columnlabel="xpath地址"><divslot-scope="scope"class="item"><el-inputv-model="scope.row.xpath"class="item__input"placeholder="请输入内容"/></div></el-table-column><el-table-columnlabel="是否iframe"width="100px"><divslot-scope="scope"class="item"><el-selectv-model="scope.row.iframe"class="item__input"placeholder="请选择"><el-optionv-for="item in iframe":key="item.iframe":label="item.label":value="item.iframe"/></el-select></div></el-table-column><el-table-columnlabel="iframe地址"><divslot-scope="scope"class="item"><el-inputv-model="scope.row.iframe_value"class="item__input"placeholder="请输入内容"/></div></el-table-column><el-table-columnlabel="事件类型"width="120px"><divslot-scope="scope"class="item"><el-selectv-model="scope.row.event"class="item__input"placeholder="请选择"><el-optionv-for="item in event":key="item.event":label="item.label":value="item.event"/></el-select></div></el-table-column><el-table-columnlabel="输入值"width="200px"><divslot-scope="scope"class="item"><el-inputv-model="scope.row.value"class="item__input"placeholder="请输入内容"/></div></el-table-column><el-table-columnlabel="等待时间"width="80px"><divslot-scope="scope"class="item"><el-inputv-model="scope.row.wait_time"class="item__input"placeholder="请输入内容"/></div></el-table-column><el-table-columnalign="center"prop="action"label="操作"width="100px"><templateslot-scope="scope"><el-buttontype="danger"icon="el-icon-delete"circle@click="del_ui_step(scope.$index, scope.row)"/></template></el-table-column></el-table></el-form-item><el-form-item><el-buttontype="primary"style="float: right"@click="save_ui_info">保存</el-button></el-form-item></el-form></el-dialog></div><div><el-dialogtitle="执行结果":visible.sync="run_ui_dialog"width="60%"append-to-body><divstyle="overflow: auto;height: 630px"><el-timelinestyle="padding: 15px"><el-timeline-itemv-for="(activity, index) in run_ui_result":key="index":icon="icon":type="type":size="size":timestamp="activity.timestamp"><divv-if="2 === activity.type"><el-image:src="require('xxxx/img/' + activity.result + '')"style="width:800px;height:600px"@click="showImage(activity.result)"/></div><divv-if="2 !== activity.type">
                {{ activity.result }}
              </div></el-timeline-item></el-timeline></div></el-dialog></div><divv-if="img_path !== ''"><el-dialogtitle="预览大图":visible.sync="imageDialogVisible"width="70%"><img:src="require('xxx/img/' + img_path + '')"style="width:100%;height:100%"></el-dialog></div></div></template><script>import{ edit_ui_info, get_ui_info, getUI_tree, run_result, run_ui }from"@/api/ui";import{ addmenu, change_pid, deletecase, deletepeoject }from"@/api/testcase";exportdefault{name:"Ui",data(){return{img_path:"",imageDialogVisible:false,address:"",run_ui_dialog:false,size:'large',type:'primary',icon:'el-icon-bottom',timer:null,run_ui_result:[{result:'开始',// timestamp: '0000-00-00 00:00:00',id:0,}],iframe:[{label:"是",iframe:1},{label:"否",iframe:0},],event:[{label:"click",event:1},{label:"input",event:2},],// 需要编辑的属性editProp:['name','xpath','iframe','event','value','wait_time'],// 保存进入编辑的cellclickCellMap:{},ui_id:null,create_time:"",update_time:"",menu_pid:null,editableTabs:[],TabsValue:"",// 用例idcase_form:{menu_id:'',current_page:1,size_page:3,},del_case_dialog:false,menu_form:{label:'',pid:'',type:null,user_id:null,},table_data:[],type_form:[{label:"文件夹",value:3},{label:"UI用例",value:4},],icon0:'el-icon-s-home',icon1:'el-icon-folder-opened',icon2:'el-icon-s-data',number:null,filterText:'',defaultProps:{children:'children',label:'label',id:"id"},node_data:[],tree_data:[],edit_case_dialog:false,dialogVisible:false,type_value:'',tree_name:'',editdialogVisible:false,// eslint-disable-next-line no-dupe-keystableTabs:[],pidFrom:{id:''},username:"",edit_ui:[],now:"",}},watch:{filterText(val){this.$refs.tree.filter(val);}},created(){this.get_ui_tree()this.is_login()},destroyed(){clearTimeout(this.timer)},methods:{is_login(){// eslint-disable-next-line no-prototype-builtinsif(localStorage.hasOwnProperty("user_id")===false|| localStorage.getItem("user_id")===''){this.$router.push("/login")this.$message.error("未登录,请前往登录")}},showImage(data){this.imageDialogVisible =truethis.img_path = data
      console.log(this.img_path)},/** 鼠标移入cell */handleCellEnter(row, column, cell, event){const property = column.property
      if(property ==='date'|| property ==='name'|| property ==='food'){
        cell.querySelector('.item__txt').classList.add('item__txt--hover')}},/** 鼠标移出cell */handleCellLeave(row, column, cell, event){const property = column.property
      if(this.editProp.includes(property)){
        cell.querySelector('.item__txt').classList.remove('item__txt--hover')}},/** 点击cell */handleCellClick(row, column, cell, event){const property = column.property
      if(this.editProp.includes(property)){// 保存cellthis.saveCellClick(row, cell)
        cell.querySelector('.item__txt').style.display ='none'
        cell.querySelector('.item__input').style.display ='block'
        cell.querySelector('input').focus()}},/** 取消编辑状态 */cancelEditable(cell){
      cell.querySelector('.item__txt').style.display ='block'
      cell.querySelector('.item__input').style.display ='none'},/** 保存进入编辑的cell */saveCellClick(row, cell){const id = row.id
      if(this.clickCellMap[id]!==undefined){if(!this.clickCellMap[id].includes(cell)){this.clickCellMap[id].push(cell)}}else{this.clickCellMap[id]=[cell]}},/** 保存数据 */save(row){const id = row.id
      // 取消本行所有cell的编辑状态this.clickCellMap[id].forEach(cell=>{this.cancelEditable(cell)})this.clickCellMap[id]=[]},// 获取接口目录get_ui_tree(){getUI_tree().then(res=>{this.tree_data = res.data.content
      })},new_menu(data){this.dialogVisible =truethis.node_data = data
      this.tree_menu_id = data.id
      if(this.children_view(this.node_data)===0){this.node_data.children =[]}},tab_click(tab){const tabs =this.tableTabs
      for(const t of tabs){if(t.name === tab.name){if(t.type ===3){this.number =1this.pidFrom.id = t.content
          }elseif(t.type ===4){this.number =2this.case_form.menu_id = t.content
            this.case_form.size_page =3this.case_form.current_page =1this.ui_ifo(t.content)}}}},removeTab(targetName){const tabs =this.tableTabs;let activeName =this.TabsValue;if(activeName === targetName){
        tabs.forEach((tab, index)=>{if(tab.name === targetName){const nextTab = tabs[index +1]|| tabs[index -1];if(nextTab){
              activeName = nextTab.name;this.tab_click(nextTab)}}});}this.TabsValue = activeName;this.tableTabs = tabs.filter(tab=> tab.name !== targetName);},addTab(targetName, id, type){const index =this.tableTabs.findIndex(item=> item.title === targetName)if(index ===-1){this.tableTabs.push({title: targetName,name: targetName,content: id,type: type
        })}this.TabsValue = targetName;},node_click(data){this.addTab(data.label, data.id, data.type)this.tree_name = data.label
      this.m_id = data.pid
      if(data.type ===3){this.number =1;this.menu_pid = data.id;this.pidFrom.id = data.id;}elseif(data.type ===4){this.number =2;this.case_form.menu_id = data.id;this.menu_pid = data.id;this.ui_ifo(data.id)}},getcase(data){switch(data.type){case3:this.menu_pid =this.pidFrom.id = data.id;this.m_id = data.pid;breakcase4:this.case_form.menu_id =this.menu_pid =this.pidFrom.id = data.id;this.m_id = data.pid;break;case0:this.menu_pid =this.pidFrom.id = data.id;break;default:// handle unexpected data.typebreak;}},children_view(data){if("children"in data){// json就是数组,name是你要找的值return1}else{return0}},delete_case(node, data){deletecase({"menu_id": data.id }).then(res=>{if(res.data.code ===200){this.$message({message:"删除接口成功",type:"success"})const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex(d=> d.id === data.id);
          children.splice(index,1);}elseif(res.data.code ===100){this.$message({message:"删除接口失败,无此接口",type:'error'})}})},add_menu(){const req =this.menu_form
      req.type =this.type_value
      req.pid =this.node_data.id
      req.user_id =Number(localStorage.getItem("user_id"))addmenu(this.menu_form).then(res=>{if(res.data.code ===200){this.$message({message: res.data.message,type:'success'})this.dialogVisible =falsethis.node_data.children.push(res.data.data)}elseif(res.data.code ===100){this.dialogVisible =truethis.$message.error("菜单名称不可为空")}elseif(res.data.code ===101){this.dialogVisible =truethis.$message.error("名称已存在,请重新输入")}})},edit(data){this.menu_form.id = data.id
      this.editdialogVisible =truethis.tree_name = data.label
      this.node_data = data
    },edit_menu(){const req =this.menu_form
      req.id =this.menu_form.id
      req.label =this.tree_name
      req.pid =this.node_data.id
      req.user_id =Number(localStorage.getItem("user_id"))addmenu(req).then(res=>{if(res.data.code ===200){this.$message({message:'重命名成功',type:'success'})this.editdialogVisible =falseconst temp =this.tableTabs.find(o=> o.content ===this.menu_form.id)if(temp){
            temp.title = res.data.label;}this.node_data.label = res.data.label
          this.form_case.name = res.data.label
        }elseif(res.data.code ===100){this.editdialogVisible =truethis.$message.error("菜单名称不可为空")}elseif(res.data.code ===101){this.editdialogVisible =truethis.$message.error("名称已存在,请重新输入")}})},delete_del(node, data){this.del_case_dialog =truethis.node_data = node
      this.pid_list = data
    },// 删除文件夹deletepro(){const data =this.pid_list
      const node =this.node_data
      deletepeoject({"id": data.id }).then(res=>{if(res.data.code ===200){this.$message({message: res.data.message,type:"success"})const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex(d=> d.id === data.id);
          children.splice(index,1);this.del_case_dialog =false}else{this.$message({message: res.data.message,type:'error'})}})},allowDrop(from, to, type){return!(to.data.type ===3|| type !=='inner');},node_drop(from, to){const req ={}
      req.from_id = from.data.id
      req.to_id = to.data.id
      change_pid(req).then(res=>{if(res.data.code ===200){this.$message.success(res.data.message)}elseif(res.data.code !==200){this.$message.error(res.data.message)}})},filterNode(value, tree_data){if(!value)returntrue;return tree_data.label.indexOf(value)!==-1;},handleClose(done){done()},getNowTime(){let now =""const yy =newDate().getFullYear()const mm =newDate().getMonth()+1const dd =newDate().getDate()const hh =newDate().getHours()<10?'0'+newDate().getHours():newDate().getHours()const mf =newDate().getMinutes()<10?'0'+newDate().getMinutes():newDate().getMinutes()const ss =newDate().getSeconds()<10?'0'+newDate().getSeconds():newDate().getSeconds()
      now = yy +'-'+ mm +'-'+ dd +' '+ hh +':'+ mf +':'+ ss
      return now
    },ui_test_result(){this.run_ui_dialog =truethis.now =this.getNowTime()run_result({"id":this.ui_id,"time":""}).then(res=>{this.run_ui_result = res.data.content
      })},run_ui_test(){this.$message.success("开始执行")this.run_ui_dialog =truerun_ui({"id":this.ui_id,"address":this.address
      }).then(res=>{if(res.data.code !==200){this.$message.error(res.data.message)}})this.now =this.getNowTime()this.run_ui_result =[{result:'开始',// timestamp: '0000-00-00 00:00:00',id:0,}]this.ui_result()},edit_ui_dialog(){this.edit_case_dialog =truethis.edit_ui =this.table_data
    },del_ui_step(index, row){this.edit_ui.splice(index,1)},add_ui_step(){const obj ={"name":"","xpath":"","iframe":0,"iframe_value":"","value":"","event":null,"wait_time":""}this.edit_ui.push(obj)},ui_ifo(data){get_ui_info({"id": data }).then(res=>{if(res.data.code ===200){this.update_time = res.data.update_time
          this.create_time = res.data.create_time
          this.table_data = res.data.content
          this.username = res.data.username
          this.ui_id = res.data.ui_id
          this.address = res.data.address
        }else{this.$message.error(res.data.message)}})},save_ui_info(){let flag =truethis.edit_ui.forEach(item=>{if(item.name ===""|| item.wait_time ===""|| item.event ===""|| item.xpath ===""){this.$message.error("必要参数不可为空")
          flag =false}})if(flag){edit_ui_info({"id":this.ui_id,"value":this.edit_ui,"user_id": localStorage.getItem("user_id"),"address":this.address
        }).then(res=>{if(res.data.code ===200){this.$message.success(res.data.message)this.edit_case_dialog =false}else{this.$message.error(res.data.message)}})}},ui_result(){const that =thisrun_result({"id":this.ui_id,"time":this.now }).then(res=>{if(res.data.code ===200){const list = res.data.content
          for(const obj1 of list){let flag =truefor(const obj2 ofthis.run_ui_result){if(obj1.id === obj2.id){
                flag =false}}if(flag){this.run_ui_result.push(obj1)}}}else{this.$message.error(res.data.message)}}).finally(()=>{// 每隔10s循环遍历数据库获取自动化执行的结果this.run_ui_result.forEach(item=>{if(item.result ==='结束'){clearTimeout(that.timer);}else{clearTimeout(that.timer);
            that.timer =setTimeout(()=>{
              that.ui_result()},10000)}})})}}}</script><stylescoped>.el-dialog__body{padding: 10px !important;}.custom-tree-node{flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 4px;}.el-dropdown{font-size: 16px;color: #5d697a;}.my-label{background:rgba(216, 243, 234, 0.31)!important;}.my-content{background: #e2fdf1;}</style>

总结

闲暇时候写的这套代码只能执行简单的点击,输入,更高深的技术真正摸索中!!!
个人主页仍有精彩的内容,欢迎私信交流!!!!

标签: django vue.js 自动化

本文转载自: https://blog.csdn.net/ljyljyyeah/article/details/130108944
版权归原作者 测试小老弟 所有, 如有侵权,请联系我们删除。

“Django+vue自动化测试平台(7)-- 使用Selenium+vue实现WebUI自动化及结果展示”的评论:

还没有评论