Commit 858d4bba by 高源

Merge branch 'master' of http://git.kivii.org/gy/Vue-WebDriver

parents 25c253b3 96ddaeb9
......@@ -3,12 +3,12 @@
<div id="KiviiWebTool" style="width: 10px; height: 10px; position: absolute; left: 0; top: 0; cursor: nw-resize;">
<img style="width: 25px;height: 25px;" src="./assets/enlarge.svg">
</div>
<div>
<!-- 页头信息 -->
<div class="tooldrag">
<img style="width: 20px;height: 20px;" src="./assets/logo.svg">
<span style="padding-left: 3px;">K5 网页自动化工具</span>
</div>
<!-- 页头信息 -->
<div class="tooldrag">
<img style="width: 20px;height: 20px;" src="./assets/logo.svg">
<span style="padding-left: 5px;">K5 网页自动化工具</span>
</div>
<div style="text-align: left;">
<!-- 任务信息 -->
<div style="display: flex;align-items: center;height: 25px;justify-content: space-between;margin-right: 15px;">
<div style="width: 65%;display: flex;flex-direction: column;text-align: left;">
......@@ -16,8 +16,7 @@
<span style="width: 95px;padding-left: 5px;">任务名称:</span>
<el-input v-model="taskName" placeholder="请输入内容" style="height: 20px;"></el-input>
</div>
<div
style="width: 100%;height: 25px;display: flex;align-items: center;padding-left: 10px;display: none;">
<div style="width: 100%;height: 25px;display: flex;align-items: center;padding-left: 10px;display: none;">
<span style="width: 95px; padding-left: 5px;">任务地址:</span>
<el-input v-model="taskAddress" placeholder="请输入内容" style="height: 20px;" disabled></el-input>
</div>
......@@ -35,15 +34,12 @@
<span>动作集合:</span>
<div class="scroll-container" @wheel="handleScroll" style="width: 325px;">
<div class="scroll-content" style="margin-left: 10px;">
<span id="Breadcrumb" @click="onBreadcrumb(item)" v-for="item in actionAll" :key="item.Kvid"
:style="{ color: item.Kvid == parentKvid ? '#68C23A!important' : '#409EFF' }">{{ item.name
}}></span>
<span id="Breadcrumb" @click="onBreadcrumb(item)" v-for="item in actionAll" :key="item.Kvid" :style="{ color: item.Kvid == parentKvid ? '#68C23A!important' : '#409EFF' }">{{ item.name }}></span>
</div>
</div>
</div>
<div style="display:flex;align-items: center;margin-right: 15px;">
<el-button :disabled="state" type="primary" size="mini" style="width: 20px;height: 20px;"
@click="newAction">
<el-button :disabled="state" type="primary" size="mini" style="width: 20px;height: 20px;" @click="newAction">
<img style="width: 12px;height: 12px;" src="./assets/add.svg">
</el-button>
</div>
......@@ -51,38 +47,28 @@
<div style="display: flex;align-items: flex-start;justify-content: space-between;width: 460px;">
<!-- 动作标签 -->
<div style="margin-bottom: 5px;margin-right: 1px;white-space: wrap;display: flex;width: 88%;">
<draggable v-model="treeNode" chosenClass="chosen" forceFallback="true" group="people" animation="1000"
@start="onStart" @end="onEnd" v-if="isChildrenTree == false">
<draggable v-model="treeNode" chosenClass="chosen" forceFallback="true" group="people" animation="1000" @start="onStart" @end="onEnd" v-if="isChildrenTree == false">
<transition-group>
<el-tag class="boxtags" :key="tag.tagId" v-for="(tag, index) in treeNode"
@click="selectTag(tag)"
:style="{ backgroundColor: tag.Kvid == Kvid ? '#68C23A!important' : '#409EFF' }">
<el-tag class="boxtags" :key="tag.tagId" v-for="(tag, index) in treeNode" @click="selectTag(tag)" :style="{ backgroundColor: tag.Kvid == Kvid ? '#68C23A!important' : '#409EFF' }">
<div style="display: flex;align-items: center;height: 25px;position: relative;">
<span style="min-width: 40px;display: flex;align-items: center;">
<div class="circle">{{ index + 1 }}</div>
<span style="margin-left: 2px;">{{ tag.actionName }}</span>
</span>
<img id="closeimg" @click="handleClose(tag)"
style="width: 17px;position: absolute;top: -6px;right: -16px;"
src="./assets/close.svg">
<img id="closeimg" @click="handleClose(tag)" style="width: 17px;position: absolute;top: -6px;right: -16px;" src="./assets/close.svg">
</div>
</el-tag>
</transition-group>
</draggable>
<draggable v-model="childrenTreeNode" chosenClass="chosen" forceFallback="true" group="people"
animation="1000" @start="onStart" @end="onEnd" v-if="isChildrenTree == true">
<draggable v-model="childrenTreeNode" chosenClass="chosen" forceFallback="true" group="people" animation="1000" @start="onStart" @end="onEnd" v-if="isChildrenTree == true">
<transition-group>
<el-tag class="boxtags" :key="item.tagId" v-for="(item, index) in childrenTreeNode"
@click="selectTag(item)"
:style="{ backgroundColor: item.Kvid == Kvid ? '#68C23A!important' : '#409EFF' }">
<el-tag class="boxtags" :key="item.tagId" v-for="(item, index) in childrenTreeNode" @click="selectTag(item)" :style="{ backgroundColor: item.Kvid == Kvid ? '#68C23A!important' : '#409EFF' }">
<div style="display: flex;align-items: center;height: 25px;position: relative;">
<span style="min-width: 40px;display: flex;align-items: center;">
<div class="circle">{{ index + 1 }}</div>
<span style="margin-left: 2px;">{{ item.actionName }}</span>
</span>
<img id="closeimg" @click="handleClose(item)"
style="width: 17px;position: absolute;top: -6px;right: -16px;"
src="./assets/close.svg">
<img id="closeimg" @click="handleClose(item)" style="width: 17px;position: absolute;top: -6px;right: -16px;" src="./assets/close.svg">
</div>
</el-tag>
</transition-group>
......@@ -92,17 +78,15 @@
<el-divider></el-divider>
<!-- 容器配置 -->
<div v-if="isShowAction">
<div
style="height: 35px;display: flex;justify-content: space-between;align-items: center;margin-left: 15px;margin-right: 15px;">
<div style="height: 35px;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid #888888;">
<div style="width: 211px;display: flex;align-items: center;">
<span style="width: 90px;">动作名称:</span>
<el-input class="input-new-tag dongzuo" v-model="actionName" size="small" placeholder="请输入动作名称">
</el-input>
</div>
<div style="margin-right: 5px;">
<div style="margin-right: 15px;">
<span style="width: 90px;">动作类型:</span>
<el-select id="eventType" name="eventType" v-model="actionType" placeholder="请选择类型"
@change="handleChange" filterable remote>
<el-select id="eventType" name="eventType" v-model="actionType" placeholder="请选择类型" @change="handleChange" filterable remote>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
......@@ -111,8 +95,7 @@
<div style="margin-left: 15px;margin-top: 10px;" v-if="actionType == 'actions'">
<el-button @click="toActions">进入容器</el-button>
</div>
<component :is="dynamicComponent" :actionName="actionName" :actionType="actionType"
@dataChanged="handleDataChange" :dynamicTagObj="dynamicTagObj" v-if="actionType !== ''"></component>
<component :is="dynamicComponent" :actionName="actionName" :actionType="actionType" @dataChanged="handleDataChange" :dynamicTagObj="dynamicTagObj" v-if="actionType !== ''"></component>
</div>
</div>
</div>
......@@ -122,13 +105,14 @@
// 导出json文件使用的库
import { saveAs } from 'file-saver';
import draggable from 'vuedraggable'
import { elClick, sysSleep, elOutput, loopClick, onInput, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions } from './components/index.js'
import { pageNavigate, elClick, sysSleep, elOutput, loopClick, onInput, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions } from './components/index.js'
export default {
name: 'App',
components: { elClick, sysSleep, draggable, elOutput, loopClick, onInput, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions },
components: { pageNavigate, elClick, sysSleep, draggable, elOutput, loopClick, onInput, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions },
props: {},
data () {
return {
subData: [],
state: false,
dynamicComponent: null,
taskName: '',
......@@ -139,18 +123,24 @@ export default {
winHeight: window.outerHeight,
isShowAction: false,
options: [{
value: 'page.Navigate',
label: '页面跳转'
}, {
value: 'elClick',
label: '点击'
}, {
value: 'sysSleep',
label: '等待'
}, {
value: 'input',
value: 'el.input',
label: '输入'
}, {
value: 'elOutput',
label: '取值'
}, {
value: 'collectionTable',
label: '采集表'
}, {
value: 'loopClick',
label: '循环点击'
}, {
......@@ -166,9 +156,6 @@ export default {
value: 'pageJavascipt',
label: '脚本执行'
}, {
value: 'collectionTable',
label: '采集表'
}, {
value: 'submit',
label: '提交'
}, {
......@@ -256,6 +243,9 @@ export default {
// 组件配置
loadComponent (componentName) {
switch (componentName) {
case 'page.Navigate':
this.dynamicComponent = pageNavigate
break;
case 'elClick':
this.dynamicComponent = elClick
break;
......@@ -265,7 +255,7 @@ export default {
case 'elOutput':
this.dynamicComponent = elOutput
break;
case 'input':
case 'el.input':
this.dynamicComponent = onInput
break;
case 'loopClick':
......@@ -298,7 +288,9 @@ export default {
},
// 接收子组件信息
handleDataChange (newData) {
console.log('接收到的数据:', newData);
this.subData = [newData];
// console.log(this.subData);
// console.log('接收到的数据:', newData);
const targetObject = this.dynamicTags.find(obj => obj.Kvid === this.dynamicTagObj.Kvid);
// console.log(targetObject)
if (targetObject) {
......@@ -619,9 +611,11 @@ export default {
// 保存任务
submitPlan (formName) {
this.isShowAction = true
console.log(this.subData)
// console.log(this.treeNode)
// 将JSON对象转换为JSON字符串
const jsonString = JSON.stringify(this.treeNode, null, 2);
// const arrayOfObjects = [this.subData];
const jsonString = JSON.stringify(this.subData, null, 2);
// 创建一个Blob对象
const blob = new Blob([jsonString], { type: 'application/json' });
// 使用file-saver库保存文件
......@@ -701,6 +695,71 @@ export default {
</script>
<style>
/* 窗口整体样式 */
.tooltips {
min-width: 460px;
min-height: 500px;
background-color: white;
border: solid #3384FF 3px;
position: fixed;
border-radius: 10px;
z-index: 9999;
right: 20px;
bottom: 20px;
font-size: 13px !important;
font-weight: normal !important;
/* 文字不可被选中 */
user-select: none;
-webkit-user-select: none;
}
.tooltips button {
font-size: 10px;
border-radius: 5px;
border: solid 1px #409EFF;
background-color: #409EFF;
color: #ffffff;
width: 100px;
height: 30px;
cursor: pointer;
padding: 0 !important;
}
/* 输入框样式 */
.tooltips input[type=text] {
font-size: 13px;
width: 145px;
height: 20px;
}
.tooltips select {
display: block;
margin-top: 7px !important;
padding-left: 5px !important;
margin-bottom: 7px !important;
font-size: 15px;
border-radius: 5px;
border: solid 2px #3384FF;
width: 204px;
height: 30px;
}
.tooltips button:hover {
color: #3384FF;
}
/* 页头样式 */
.tooldrag {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #3384FF;
text-align: center;
font-size: 15px;
color: white;
}
.scroll-container {
overflow-y: hidden;
overflow-x: hidden;
......@@ -737,35 +796,6 @@ export default {
cursor: pointer;
}
/* 拖拽窗口大小 */
.tooldrag {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #3384FF;
text-align: center;
font-size: 15px;
color: white;
}
.tooltips {
min-width: 460px;
min-height: 500px;
background-color: white;
position: fixed;
z-index: 9999;
right: 30px;
bottom: 30px;
font-size: 13px !important;
font-weight: normal !important;
border: solid #3384FF 3px;
border-radius: 10px;
user-select: none;
-webkit-user-select: none;
/* 文字不可被选中 */
}
.el-input__icon {
line-height: 0px !important;
}
......@@ -837,24 +867,7 @@ export default {
padding-left: 5px !important;
}
.tooltips button {
font-size: 10px;
border-radius: 5px;
border: solid 1px #409EFF;
background-color: #409EFF;
color: #ffffff;
width: 100px;
height: 30px;
cursor: pointer;
padding: 0 !important;
}
/* 输入框样式 */
.tooltips input[type=text] {
font-size: 13px;
width: 145px;
height: 20px;
}
.el-input--small .el-input__inner {
width: 140px !important;
......@@ -864,25 +877,9 @@ export default {
width: 145px !important;
}
.tooltips select {
display: block;
margin-top: 7px !important;
padding-left: 5px !important;
margin-bottom: 7px !important;
font-size: 15px;
border-radius: 5px;
border: solid 2px #3384FF;
width: 204px;
height: 30px;
}
.tooltips button:hover {
color: #3384FF;
}
/* 下面用来对冻结表格首行元素和固定表格宽度和高度设定样式 */
.toolkitcontain {
border: 1px solid #cdd !important;
/*width: 280px !important;*/
......@@ -908,7 +905,6 @@ export default {
.toolkitcontain th,
.toolkitcontain td,
.toolkitcontain tr {
/* border: 1px solid rgb(78, 78, 78) !important; */
height: 25px !important;
width: 100px !important;
text-align: center !important;
......@@ -966,12 +962,6 @@ export default {
z-index: 99999 !important;
}
/* .vxe-table--render-default .vxe-body--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-footer--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-header--column:not(.col--ellipsis) {
padding: 2px 0 !important;
} */
.item {
padding: 6px;
background-color: #fdfdfd;
......
<template>
<div class="onInput">
<!-- 操作按钮区域 -->
<div style="height: 35px; margin-left: 15px; text-align: left;">
<el-button size="small" class="button-new-tag" @click="selectElement">选择元素</el-button>
<el-button size="small" class="button-new-tag" @click="cancelSelect">取消选择</el-button>
</div>
<!-- 表单区域 -->
<el-form label-position="right" label-width="80px" :model="actionConfig">
<el-form-item label="查找方式">
<el-input v-model="actionConfig.Target.Type" disabled></el-input>
</el-form-item>
<el-form-item label="当前标签">
<el-input v-model="actionConfig.Target.tagName" disabled></el-input>
</el-form-item>
<el-form-item label="文本内容">
<el-input v-model="actionConfig.Attributes.innerText"></el-input>
</el-form-item>
<el-form-item label="查询时间">
<el-input v-model="actionConfig.Target.Timeout"></el-input>
</el-form-item>
</el-form>
<!-- 提交按钮 -->
<div style="width: 100%; text-align: right;">
<el-button size="small" class="button-new-tag" @click="submit" style="margin-right: 5px;">提交信息</el-button>
</div>
</div>
</template>
<script>
export default {
name: 'onInput',
components: {},
props: ['actionName', 'actionType', 'dynamicTagObj'],
data () {
return {
elementInfos: {}, // 存储当前选中元素的信息
actionConfig: {
"Target": {
"Type": "xpath",
"Xpath": "",
"Timeout": 5000,
"tagName": ''
},
"Attributes": {
"innerText": ""
},
"Name": this.actionName,
"Alias": this.actionType
},
selectDisabled: true // 控制选择按钮的禁用状态
}
},
created () {
console.log(this.dynamicTagObj);
// if (Object.keys(this.dynamicTagObj.actionConfigs).length == 0) return
// this.actionConfig = this.dynamicTagObj.actionConfigs
},
mounted () { },
watch: {},
computed: {},
methods: {
// 提交表单信息
submit () {
console.log(this.actionConfig);
// 防止父级改变,子级未改变重新赋值
this.actionConfig.Name = this.actionName;
this.actionConfig.Alias = this.actionType;
this.$emit('dataChanged', this.actionConfig);
},
// 获取页面元素方法
contextMenuHandler (event) {
event.preventDefault(); // 阻止默认的右击菜单
let element = event.target;
let elementInfo = {
Xpath: this.getElementXPath(element),
TagName: element.tagName
};
this.elementInfos = elementInfo;
console.log(event);
this.actionConfig.Target.Xpath = elementInfo.Xpath;
this.actionConfig.Target.tagName = elementInfo.TagName;
this.selectDisabled = false;
// 移除事件监听器
document.removeEventListener('contextmenu', this.contextMenuHandler);
},
// 选择元素按钮调用
selectElement () {
// 添加事件监听器
document.addEventListener('contextmenu', this.contextMenuHandler, false);
},
// 取消按钮调用
cancelSelect () {
// 在取消按钮点击时移除事件监听器
document.removeEventListener('contextmenu', this.contextMenuHandler);
},
// 获取xpath
getElementXPath (element) {
let _this = this;
if (element.tagName === 'BODY') {
return '/HTML/' + element.tagName;
}
var ix = 1, siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
if (sibling === element) {
return _this.getElementXPath(element.parentNode) + '/' + element.tagName + '[' + ix + ']';
}
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
ix++;
}
}
},
},
}
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
......@@ -36,7 +36,7 @@ export default {
actionConfig: {
"Target": {
"Type": "xpath",
"Xpath": "",
"Selector": "",
"InnerText": "",
"Timeout": 5000
},
......@@ -62,8 +62,8 @@ export default {
submit () {
console.log(this.actionConfig);
// 防止父级改变,子级未改变重新赋值
this.actionConfig.Name = this.actionName;
this.actionConfig.Alias = this.actionType;
// this.actionConfig.Name = this.actionName;
// this.actionConfig.Alias = this.actionType;
this.$emit('dataChanged', this.actionConfig);
},
......@@ -76,7 +76,7 @@ export default {
Text: element.innerText
};
this.elementInfos = elementInfo;
this.actionConfig.Target.Xpath = elementInfo.Xpath;
this.actionConfig.Target.Selector = elementInfo.Xpath;
this.actionConfig.Target.InnerText = elementInfo.Text;
console.log(element.innerText);
// 移除事件监听器
......
import pageNavigate from './pageNavigates.vue';
import elClick from './elClick.vue';
import sysSleep from './sysSleep.vue';
import elOutput from './elOutput.vue';
......@@ -10,6 +11,5 @@ import collectionTable from './collectionTable.vue';
import submit from './submit.vue';
import actions from './actions.vue';
import onInput from './onInput.vue'
// import ComponentC from './ComponentC.vue';
export { elClick, sysSleep, elOutput, onInput, loopClick, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions };
\ No newline at end of file
export { pageNavigate, elClick, sysSleep, elOutput, onInput, loopClick, collectSingleElements, pageClose, mouseMove, pageJavascipt, collectionTable, submit, actions };
\ No newline at end of file
......@@ -14,7 +14,7 @@
<el-input v-model="actionConfig.Target.tagName" disabled></el-input>
</el-form-item>
<el-form-item label="文本内容">
<el-input v-model="actionConfig.Attributes.innerText"></el-input>
<el-input v-model="actionConfig.InputValue"></el-input>
</el-form-item>
<el-form-item label="查询时间">
<el-input v-model="actionConfig.Target.Timeout"></el-input>
......@@ -38,13 +38,12 @@ export default {
actionConfig: {
"Target": {
"Type": "xpath",
"Xpath": "",
"Selector": "",
"Timeout": 5000,
"tagName": ''
},
"Attributes": {
"innerText": ""
},
"InputValue": "",//输入的内容
"Script": null,
"Name": this.actionName,
"Alias": this.actionType
},
......@@ -64,8 +63,6 @@ export default {
submit () {
console.log(this.actionConfig);
// 防止父级改变,子级未改变重新赋值
this.actionConfig.Name = this.actionName;
this.actionConfig.Alias = this.actionType;
this.$emit('dataChanged', this.actionConfig);
},
......@@ -79,7 +76,7 @@ export default {
};
this.elementInfos = elementInfo;
console.log(event);
this.actionConfig.Target.Xpath = elementInfo.Xpath;
this.actionConfig.Target.Selector = elementInfo.Xpath;
this.actionConfig.Target.tagName = elementInfo.TagName;
this.selectDisabled = false;
// 移除事件监听器
......
<template>
<!-- 页面导航组件的根元素 -->
<div class="pageNavigates">
<!-- 表单元素,用于配置页面导航 -->
<el-form style="margin-left: 4px;" label-position="right" label-width="80px" :model="actionConfig">
<!-- 表单项,用于输入页面地址 -->
<el-form-item label="页面地址">
<!-- 输入框,双向绑定到 actionConfig.Url -->
<el-input v-model="actionConfig.Url"></el-input>
</el-form-item>
</el-form>
<!-- 按钮区域 -->
<div style="width: 100%; text-align: right; display: flex; justify-content: space-between;">
<!-- 获取当前页面地址的按钮 -->
<el-button size="small" class="button-new-tag" @click="getCurrentPageUrl" style="margin-left: 15px;">获取当前页面地址</el-button>
<!-- 提交信息的按钮 -->
<el-button size="small" class="button-new-tag" @click="submit" style="margin-right: 15px">提交信息</el-button>
</div>
</div>
</template>
<script>
export default {
name: "pageNavigates", // 组件名称
components: {},
props: ["actionName", "actionType", "dynamicTagObj"], // 父组件传递的属性
data () {
return {
// 页面导航配置对象
actionConfig: {
Url: "", // 页面地址
Name: this.actionName, // 页面名称,从父组件传递而来
Alias: this.actionType, // 页面类型,从父组件传递而来
},
};
},
created () {
// 如果动态标签对象中的actionConfigs属性为空,则直接返回
if (Object.keys(this.dynamicTagObj.actionConfigs).length == 0) return;
// 使用动态标签对象中的actionConfigs属性初始化actionConfig
this.actionConfig = this.dynamicTagObj.actionConfigs;
},
mounted () { },
watch: {},
computed: {},
methods: {
// 提交表单信息的方法
submit () {
// 防止父级改变,子级未改变重新赋值
// 将当前组件中的actionConfig对象通过自定义事件传递给父组件
this.$emit("dataChanged", this.actionConfig);
},
// 获取当前页面地址的方法
getCurrentPageUrl (event) {
// 使用window.location.href获取当前页面地址
let currentUrl = window.location.href;
// 将获取到的地址设置到actionConfig对象的Url属性中
this.actionConfig.Url = currentUrl;
}
},
};
</script>
<style scoped>
/* 样式表,限定在当前组件的作用域内生效 */
.el-form-item {
margin-bottom: 0;
}
.tooltips button {
width: 100px !important;
height: 30px !important;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment