Mark elements when debugging!!!

This commit is contained in:
naibo
2023-12-13 10:28:06 +08:00
parent 0c30b27756
commit 64070fb146
10 changed files with 695 additions and 390 deletions
Binary file not shown.
Binary file not shown.
+26 -28
View File
@@ -360,7 +360,7 @@ async function beginInvoke(msg, ws) {
}
let elementInfo = {"iframe": parameters.iframe, "xpath": xpath, "id": -1};
//用于跳转到元素位置
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
let element = await findElementAcrossAllWindows(elementInfo);
} else if (option == 3) {
let paras = parameters.paras; //所有的提取数据参数
let para = paras[0];
@@ -368,10 +368,13 @@ async function beginInvoke(msg, ws) {
if (para.relative) {
let parent_node = JSON.parse(msg.message.parentNode);
let parent_xpath = parent_node.parameters.xpath;
if (parent_node.parameters.loopType == 2) {
parent_xpath = parent_node.parameters.pathList.split("\n")[0].trim();
}
xpath = parent_xpath + xpath;
}
let elementInfo = {"iframe": para.iframe, "xpath": xpath, "id": -1};
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
let element = await findElementAcrossAllWindows(elementInfo);
} else if (option == 11) {
let paras = parameters.paras; //所有的提取数据参数
let i = parameters.index;
@@ -380,25 +383,14 @@ async function beginInvoke(msg, ws) {
if (para.relative) {
let parent_node = JSON.parse(msg.message.parentNode);
let parent_xpath = parent_node.parameters.xpath;
if (parent_node.parameters.loopType == 2) {
parent_xpath = parent_node.parameters.pathList.split("\n")[0].trim();
}
xpath = parent_xpath + xpath;
}
let elementInfo = {"iframe": para.iframe, "xpath": xpath, "id": -1};
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
let element = await findElementAcrossAllWindows(elementInfo);
} else if (option == 8) {
// <select v-model='loopType' class="form-control" @change = "handleLoopTypeChange" >
// < option
// :
// value = 0 > 单个元素(多用于循环点击下一页)</option>
// <option :value = 1 > 不固定元素列表 < /option>
// <option :value = 2 > 固定元素列表 < /option>
// <option :value = 3 > 文本列表(多用于循环在文本框输入文本)</option>
// <option :value = 4 > 网址列表(多用于循环打开网页)</option>
// <option :value = 5 > JavaScript命令返回值(需以return
// 开头)</option>
// <option :value = 6 > 系统命令返回值 < /option>
// <option :value = 7 > 执行环境下的Python表达式值(eval操作)</option>
// </select>
//
let loopType = parameters.loopType;
if (loopType <= 2) {
let xpath = "";
@@ -408,7 +400,7 @@ async function beginInvoke(msg, ws) {
xpath = parameters.pathList.split("\n")[0].trim();
}
let elementInfo = {"iframe": parameters.iframe, "xpath": xpath, "id": -1};
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
let element = await findElementAcrossAllWindows(elementInfo);
} else if (loopType == 5) { //JavaScript命令返回值
let code = parameters.code;
let waitTime = parameters.waitTime;
@@ -488,7 +480,7 @@ async function beginInvoke(msg, ws) {
let parent_xpath = parent_node.parameters.xpath;
elementInfo.xpath = parent_xpath + elementInfo.xpath;
}
let element = await findElementAcrossAllWindows(elementInfo); //通过此函数找到元素并切换到对应的窗口
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false); //通过此函数找到元素并切换到对应的窗口
await execute_js(parameters.beforeJS, element, parameters.beforeJSWaitTime);
if (option == 2) {
await click_element(element);
@@ -521,6 +513,9 @@ async function beginInvoke(msg, ws) {
if (para.relative) {
let parent_node = JSON.parse(msg.message.parentNode);
let parent_xpath = parent_node.parameters.xpath;
if (parent_node.parameters.loopType == 2) {
parent_xpath = parent_node.parameters.pathList.split("\n")[0].trim();
}
xpath = parent_xpath + xpath;
}
let elementInfo = {"iframe": para.iframe, "xpath": xpath, "id": -1};
@@ -557,7 +552,7 @@ async function beginInvoke(msg, ws) {
await new Promise(resolve => setTimeout(resolve, 2000));
notify_browser("检测到文字中包含Field(\"\")或eval(\"\"),试运行时无法输入两项表达式的替换值,请在任务正式调用阶段测试是否有效。", "Field(\"\") or eval(\"\") is detected in the text, and the replacement value of the two expressions cannot be entered during trial operation. Please test whether it is valid in the formal call stage.", "warning");
}
let element = await findElementAcrossAllWindows(elementInfo);
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
await execute_js(beforeJS, element, beforeJSWaitTime);
await element.sendKeys(Key.HOME, Key.chord(Key.SHIFT, Key.END), keyInfo);
if (enter) {
@@ -587,7 +582,7 @@ async function beginInvoke(msg, ws) {
}
}
let elementInfo = {"iframe": parameters.iframe, "xpath": parameters.xpath, "id": -1};
let element = await findElementAcrossAllWindows(elementInfo);
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
execute_js(beforeJS, element, beforeJSWaitTime);
let dropdown = new Select(element);
// Interacting with dropdown element based on optionMode
@@ -629,10 +624,13 @@ async function beginInvoke(msg, ws) {
if (para.relative) {
let parent_node = JSON.parse(msg.message.parentNode);
let parent_xpath = parent_node.parameters.xpath;
if (parent_node.parameters.loopType == 2) {
parent_xpath = parent_node.parameters.pathList.split("\n")[0].trim();
}
xpath = parent_xpath + xpath;
}
let elementInfo = {"iframe": para.iframe, "xpath": xpath, "id": -1};
let element = await findElementAcrossAllWindows(elementInfo);
let element = await findElementAcrossAllWindows(elementInfo, notifyBrowser = false);
if (element != null) {
await execute_js(para.beforeJS, element, para.beforeJSWaitTime);
await execute_js(para.afterJS, element, para.afterJSWaitTime);
@@ -787,12 +785,12 @@ wss.on('connection', function (ws) {
await driver.switchTo().window(current_handle);
console.log("New tab opened, change current_handle to: ", current_handle);
// 调整浏览器窗口大小,不然扩展会白屏
let size = await driver.manage().window().getRect();
let width = size.width;
let height = size.height;
await driver.manage().window().setRect({width: width, height: height + 10});
// height = height - 1;
await driver.manage().window().setRect({width: width, height: height});
// let size = await driver.manage().window().getRect();
// let width = size.width;
// let height = size.height;
// await driver.manage().window().setRect({width: width, height: height + 10});
// // height = height - 1;
// await driver.manage().window().setRect({width: width, height: height});
}
await new Promise(resolve => setTimeout(resolve, 2000));
handle_pairs[msg.message.id] = current_handle;
+14 -5
View File
@@ -34,6 +34,7 @@ let vueData = {nowNodeIndex: 0}; //存储目前所在节点的索引号,不能
let option = 0; //工具箱选项
let title = "";
let parameterNum = 1; //记录目前的参数个数
let debuggable = true; //是否可以调试
// window.resizeTo( screen.availWidth, screen.availHeight );
@@ -351,7 +352,7 @@ function newNode(node) {
{
return `<div class="sequence"><div class="node clk" draggable="true" data="${id}" dataType=${type} id = "${id}" position=${node["position"]} pId=${node["parentId"]}>
<div >
<p>${title}</p>
<p style="margin-top: 2px">${title}</p>
</div>
</div>
<p class="arrow" draggable="true" position=${node["position"]} data = "${id}" pId=${node["parentId"]}>↓</p></div>`;
@@ -407,7 +408,8 @@ function branchClick(e) {
parentId: 0,
type: 3,
option: 10,
title: LANG("条件分支" + (nodeList[actionSequence[judgeId]]["sequence"].length + 1).toString(), "Condition " + (l + 1).toString()),
// title: LANG("条件分支" + (nodeList[actionSequence[judgeId]]["sequence"].length + 1).toString(), "Condition " + (l + 1).toString()),
title: LANG("无条件", "No Condition"),
sequence: [],
isInLoop: false,
};
@@ -434,7 +436,11 @@ function operationChange(e, theNode) {
vueData.nowNodeIndex = actionSequence[theNode.getAttribute("data")];
theNode.style.borderColor = "blue";
handleElement(); //处理元素
trailElement(app._data.nowNode, 0);
if(debuggable){
trailElement(app._data.nowNode, 0);
} else {
debuggable = true;
}
e.stopPropagation(); //防止冒泡
}
@@ -520,7 +526,8 @@ function toolBoxKernel(e, para = null) {
$("#" + t["id"]).click(); //复制后点击复制后的元素
e.stopPropagation(); //防止冒泡
}
} else if (option == 10) { //剪切操作
}
else if (option == 10) { //剪切操作
if (nowNode == null) {
e.stopPropagation(); //防止冒泡
} else if ($(nowNode).is(".branch")) {
@@ -563,7 +570,8 @@ function toolBoxKernel(e, para = null) {
}
e.stopPropagation(); //防止冒泡
}
} else if (option > 0) { //新增操作
}
else if (option > 0) { //新增操作
let l = nodeList.length;
let nt = null;
let nt2 = null;
@@ -652,6 +660,7 @@ function toolBoxKernel(e, para = null) {
if (para != null) {
modifyParameters(t, para);
}
debuggable = false;
if (option == 8) //循环情况下应插入在循环里面
{
app._data.nowArrow = {"position": -1, "pId": t["id"], "num": 0};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"language":"zh"}
{"language":"en"}
@@ -11,8 +11,8 @@ export var global = {
style: "", //记录上个元素的颜色
oe: null, //记录上个元素
app: null,
div:null,
tdiv:null,
div: null,
tdiv: null,
selectedColor: "rgba(151,255,255, 0.6)",
defaultbgColor: 'rgba(221,221,255,0.8)',
boxShadowColor: "blue 0px 0px 5px",
@@ -20,10 +20,11 @@ export var global = {
id: "C" + Math.floor(Math.random() * (99999999)).toString(), //处理不同标签页的handles,生成的id
ws: null,
iframe: false,
markElements: [],
justSend: false,
};
export function isInIframe() {
try {
return window.self !== window.parent;
@@ -31,7 +32,8 @@ export function isInIframe() {
return true;
}
}
export function getOS () {
export function getOS() {
if (navigator.userAgent.indexOf('Window') > 0) {
return 'Windows'
} else if (navigator.userAgent.indexOf('Mac') > 0) {
@@ -49,7 +51,7 @@ export function getElementXPaths(element, parentElement = document.body) {
// if(global.iframe){
// pre_xpath = "//iframe";
// }
paths.push(readXPath(element,1, parentElement));
paths.push(readXPath(element, 1, parentElement));
paths.push(pre_xpath + "//" + element.tagName.toLowerCase() + "[contains(., '" + element.textContent.slice(0, 10).trim() + "')]");
if (element.id) {
paths.push(pre_xpath + `id("${element.id}")`);
@@ -105,7 +107,7 @@ export function readXPath(element, type = 1, node = document.body) {
if (element.id !== "") { //判断id属性,如果这个元素有id,则显示//*[@id="xPath"] 形式内容
return pre_xpath + '//*[@id=\"' + element.id + '\"]';
}
if (element.className != ""){ //如果有class且某个class name只有一个元素,则使用class name生成xpath
if (element.className != "") { //如果有class且某个class name只有一个元素,则使用class name生成xpath
console.log("class name: " + element.className);
let names = element.className.split(" ");
for (let i = 0; i < names.length; i++) {
@@ -114,7 +116,7 @@ export function readXPath(element, type = 1, node = document.body) {
// console.log('//*[@contains(@class, \"' + names[i] + '\")]');
let elements_of_class = node.getElementsByClassName(names[i]);
// console.log("Length of elements_of_class: " + elements_of_class.length);
if(elements_of_class.length == 1){
if (elements_of_class.length == 1) {
return pre_xpath + '//*[contains(@class, \"' + names[i] + '\")]'
}
}
@@ -126,7 +128,7 @@ export function readXPath(element, type = 1, node = document.body) {
if (node == document.body) {
return pre_xpath + '/html/' + element.tagName.toLowerCase();
} else {
return "";
return "";
}
}
let ix = 1, //在nodelist中的位置,且每次点击初始化
@@ -140,7 +142,7 @@ export function readXPath(element, type = 1, node = document.body) {
//如果不符合,判断是否是element元素,并且是否是相同元素,如果是相同的就开始累加
} else if (sibling.nodeType == 1 && sibling.tagName == element.tagName) {
//注意此处,为了防止多计算了插入的操作台的3个div元素导致定位错误,这里需要屏蔽掉三个元素的索引号
if(sibling.id != "wrapperDiv" && sibling.id != "wrapperTdiv" &&sibling.id != "wrapperToolkit"){
if (sibling.id != "wrapperDiv" && sibling.id != "wrapperTdiv" && sibling.id != "wrapperToolkit") {
ix++;
}
}
@@ -151,10 +153,13 @@ export function readXPath(element, type = 1, node = document.body) {
}
//选中元素到列表中
export function addEl() {
export function addEl(e, node = global.NowNode, handle = true) {
// if (tooltips) {
// return;
// }
//如果元素不是鼠标选中的,记录该元素的style,不然按照鼠标选中的元素的style
let style = node == global.NowNode ? global.style : node.style.backgroundColor;
global.NowNode = node;
let exist = false;
for (let o of global.nodeList) {
if (o["node"] == global.oe) {
@@ -180,11 +185,19 @@ export function addEl() {
} else //不然只添加一个元素
{
clearReady(); //readylist清零重新算
global.nodeList.push({ node: global.NowNode, "step": global.step, bgColor: global.style, "boxShadow": global.NowNode.style.boxShadow == "" || global.boxShadowColor ? "none" : global.NowNode.style.boxShadow, xpath: readXPath(global.NowNode, 1), "allXPaths": getElementXPaths(global.NowNode) });
global.nodeList.push({
node: global.NowNode,
"step": global.step,
bgColor: style,
"boxShadow": global.NowNode.style.boxShadow == "" || global.boxShadowColor ? "none" : global.NowNode.style.boxShadow,
xpath: readXPath(global.NowNode, 1),
"allXPaths": getElementXPaths(global.NowNode)
});
global.NowNode.style.backgroundColor = global.selectedColor;
}
handleElement(); //处理新状态
if(handle){
handleElement(); //处理新状态
}
//将虚线框显示在元素上方但屏蔽其鼠标操作
let pos = global.NowNode.getBoundingClientRect();
global.div.style.display = "block";
@@ -206,15 +219,20 @@ export function addEl() {
}
//清除选择项
export function clearEl() {
export function clearEl(trail=false) {
//如果最后停留的元素被选中,则调整此元素的style为原始style,否则不进行调整
for (let node of global.nodeList) {
node["node"].style.backgroundColor = node["bgColor"];
node["node"].style.boxShadow = node["boxShadow"];
if (global.NowNode == node["node"]) {
global.style = node["bgColor"];
if (global.NowNode == node["node"] && !trail) {
// global.style = node["bgColor"];
}
}
for (let node of global.markElements) {
let element = node.element;
element.style.boxShadow = "none";
}
global.markElements = [];
global.step = 0;
clearReady();
clearParameters();
@@ -270,40 +288,70 @@ export function LANG(zh, en) {
return en;
}
}
function parameterName(value){
if (global.lang == 'zh'){
function parameterName(value) {
if (global.lang == 'zh') {
return value;
} else{
switch(value){
case "文本": return "text";
case "链接": return "link";
case "_链接": return "_link";
case "_文本": return "_text";
case "链接文本": return "link_text";
case "_链接文本": return "_link_text";
case "链接地址": return "link_address";
case "_链接地址": return "_link_address";
case "按钮": return "button";
case "输入文本框": return "input_text";
case "单选框": return "radio";
case "复选框": return "checkbox";
case "下拉框": return "select";
case "下拉框选项": return "select_option";
case "地址": return "address";
case "参数": return "para";
case "_图片": return "_image";
case "_图片地址": return "_image_address";
case "背景图片地址": return "background_image_address";
case "_背景图片": return "_background_image";
case "页面网址": return "page_url";
case "_页面网址": return "_page_url";
case "页面标题": return "page_title";
case "_页面标题": return "_page_title";
case "选择的选项文本": return "selected_option_text";
case "_选择的选项文本": return "_selected_option_text";
case "选择的选项": return "selected_option_value";
case "_选择的选项值": return "_selected_option_value";
default: return "";
} else {
switch (value) {
case "文本":
return "text";
case "链接":
return "link";
case "_链接":
return "_link";
case "_文本":
return "_text";
case "链接文本":
return "link_text";
case "_链接文本":
return "_link_text";
case "链接地址":
return "link_address";
case "_链接地址":
return "_link_address";
case "按钮":
return "button";
case "输入文本框":
return "input_text";
case "单选框":
return "radio";
case "复选框":
return "checkbox";
case "下拉框":
return "select";
case "下拉框选项":
return "select_option";
case "地址":
return "address";
case "参数":
return "para";
case "_图片":
return "_image";
case "_图片地址":
return "_image_address";
case "背景图片地址":
return "background_image_address";
case "_背景图片":
return "_background_image";
case "页面网址":
return "page_url";
case "_页面网址":
return "_page_url";
case "页面标题":
return "page_title";
case "_页面标题":
return "_page_title";
case "选择的选项文本":
return "selected_option_text";
case "_选择的选项文本":
return "_selected_option_text";
case "选择的选项值":
return "selected_option_value";
case "_选择的选项值":
return "_selected_option_value";
default:
return "";
}
}
}
@@ -319,19 +367,23 @@ function parameterName(value){
export function generateParameters(type, linktext = true, linkhref = true) {
clearParameters(false);
let n = 1;
chrome.storage.local.get('parameterNum', function(items) {
chrome.storage.local.get('parameterNum', function (items) {
// let at = parseInt(new Date().getTime());
n = items.parameterNum;
let ndPath = "";
let ndAllXPaths = [];
clearParameters(false);
for (let num = 0; num < global.nodeList.length; num++) {
let nd = global.nodeList[num]["node"];
ndPath = global.nodeList[num]["xpath"];
ndAllXPaths = global.nodeList[num]["allXPaths"];
let unique_index = Math.random().toString(36).substring(2) + Date.now().toString(36);; //唯一标识符
global.outputParameterNodes.push({ "node": nd,
let unique_index = Math.random().toString(36).substring(2) + Date.now().toString(36);
; //唯一标识符
global.outputParameterNodes.push({
"node": nd,
"unique_index": unique_index,
"boxShadow": nd.style.boxShadow == "" || global.boxShadowColor ? "none" : nd.style.boxShadow });
"boxShadow": nd.style.boxShadow == "" || global.boxShadowColor ? "none" : nd.style.boxShadow
});
nd.style.boxShadow = global.boxShadowColor;
let pname = parameterName("文本");
let ndText = "";
@@ -370,19 +422,19 @@ export function generateParameters(type, linktext = true, linkhref = true) {
// ndText = $(nd).prop("outerHTML");
ndText = nd.outerHTML;
pname = "outerHTML";
} else if(type == 4){
} else if (type == 4) {
ndText = nd.style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2').split(',')[0];
pname = parameterName("背景图片地址");
} else if(type == 5){
} else if (type == 5) {
ndText = window.location.href;
pname = parameterName("页面网址");
} else if(type == 6){
} else if (type == 6) {
ndText = document.title;
pname = parameterName("页面标题");
} else if(type == 10){
} else if (type == 10) {
ndText = nd.value;
pname = parameterName("选择的选项值");
} else if(type == 11){
} else if (type == 11) {
ndText = nd.options[nd.selectedIndex].text;
pname = parameterName("选择的选项文本");
}
@@ -397,7 +449,7 @@ export function generateParameters(type, linktext = true, linkhref = true) {
"extractType": 0, //提取方式 0 普通 1 OCR
"relativeXPath": global.nodeList.length > 1 ? "" : ndPath,
"allXPaths": global.nodeList.length > 1 ? "" : ndAllXPaths,
"exampleValues": [{ "num": num, "value": ndText }],
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -412,7 +464,7 @@ export function generateParameters(type, linktext = true, linkhref = true) {
"extractType": 0, //提取方式 0 普通 1 OCR
"relativeXPath": global.nodeList.length > 1 ? "" : ndPath,
"allXPaths": global.nodeList.length > 1 ? "" : ndAllXPaths,
"exampleValues": [{ "num": num, "value": ndText }],
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -426,7 +478,10 @@ export function generateParameters(type, linktext = true, linkhref = true) {
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? "" : ndPath,
"allXPaths": global.nodeList.length > 1 ? "" : ndAllXPaths,
"exampleValues": [{ "num": num, "value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href") }],
"exampleValues": [{
"num": num,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -441,7 +496,7 @@ export function generateParameters(type, linktext = true, linkhref = true) {
"extractType": 0, //提取方式 0 普通 1 OCR
"relativeXPath": global.nodeList.length > 1 ? "" : ndPath,
"allXPaths": global.nodeList.length > 1 ? "" : ndAllXPaths,
"exampleValues": [{ "num": num, "value": ndText }],
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -455,21 +510,24 @@ export function generateParameters(type, linktext = true, linkhref = true) {
"extractType": 0, //提取方式 0 普通 1 OCR
"relativeXPath": global.nodeList.length > 1 ? "" : ndPath,
"allXPaths": global.nodeList.length > 1 ? "" : ndAllXPaths,
"exampleValues": [{ "num": num, "value": ndText }],
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
}
} else { //如果元素节点已经存在,则只需要插入值就可以了
if (nd.tagName == "IMG") { //如果元素是图片
global.outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
global.outputParameters[0]["exampleValues"].push({"num": num, "value": ndText});
} else if (nd.tagName == "A") { //如果元素是超链接
global.outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
global.outputParameters[1]["exampleValues"].push({ "num": num, "value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href") });
global.outputParameters[0]["exampleValues"].push({"num": num, "value": ndText});
global.outputParameters[1]["exampleValues"].push({
"num": num,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
});
} else if (nd.tagName == "INPUT") { //如果元素是输入项
global.outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
global.outputParameters[0]["exampleValues"].push({"num": num, "value": ndText});
} else { //其他所有情况
global.outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
global.outputParameters[0]["exampleValues"].push({"num": num, "value": ndText});
}
}
}
@@ -478,6 +536,7 @@ export function generateParameters(type, linktext = true, linkhref = true) {
generateValTable();
console.log(global.outputParameters);
});
console.log("Generate Parameters");
}
//根据nodelist列表内的元素生成参数列表
@@ -485,7 +544,7 @@ export function generateParameters(type, linktext = true, linkhref = true) {
export function generateMultiParameters() {
clearParameters(false);
let n = 1;
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
chrome.storage.local.get({parameterNum: 1}, function (items) {
// let at = parseInt(new Date().getTime());
n = items.parameterNum;
let nd, ndText, ndPath, pname, ndAllXPaths;
@@ -493,8 +552,13 @@ export function generateMultiParameters() {
let nd = global.nodeList[num]["node"];
ndPath = global.nodeList[num]["xpath"];
ndAllXPaths = global.nodeList[num]["allXPaths"];
let unique_index = Math.random().toString(36).substring(2) + Date.now().toString(36);;
global.outputParameterNodes.push({ "node": nd, "unique_index": unique_index, "boxShadow": nd.style.boxShadow == "" || global.boxShadowColor ? "none" : nd.style.boxShadow });
let unique_index = Math.random().toString(36).substring(2) + Date.now().toString(36);
;
global.outputParameterNodes.push({
"node": nd,
"unique_index": unique_index,
"boxShadow": nd.style.boxShadow == "" || global.boxShadowColor ? "none" : nd.style.boxShadow
});
nd.style.boxShadow = global.boxShadowColor;
// ndText = $(nd).text();
ndText = nd.textContent;
@@ -507,7 +571,10 @@ export function generateMultiParameters() {
"desc": "", //参数描述
"relativeXPath": ndPath,
"allXPaths": ndAllXPaths,
"exampleValues": [{ "num": 0, "value": nd.getAttribute("src") == null ? "" : nd.getAttribute("src") }],
"exampleValues": [{
"num": 0,
"value": nd.getAttribute("src") == null ? "" : nd.getAttribute("src")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -520,7 +587,7 @@ export function generateMultiParameters() {
"desc": "", //参数描述
"relativeXPath": ndPath,
"allXPaths": ndAllXPaths,
"exampleValues": [{ "num": 0, "value": ndText }],
"exampleValues": [{"num": 0, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -532,7 +599,10 @@ export function generateMultiParameters() {
"desc": "", //参数描述
"relativeXPath": ndPath,
"allXPaths": ndAllXPaths,
"exampleValues": [{ "num": 0, "value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href") }],
"exampleValues": [{
"num": 0,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -545,7 +615,10 @@ export function generateMultiParameters() {
"desc": "", //参数描述
"relativeXPath": ndPath,
"allXPaths": ndAllXPaths,
"exampleValues": [{ "num": 0, "value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value") }],
"exampleValues": [{
"num": 0,
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -558,7 +631,7 @@ export function generateMultiParameters() {
"desc": "", //参数描述
"relativeXPath": ndPath,
"allXPaths": ndAllXPaths,
"exampleValues": [{ "num": 0, "value": ndText }],
"exampleValues": [{"num": 0, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
@@ -575,14 +648,14 @@ export function generateMultiParameters() {
//处理子元素,对于每个块中多出的特殊元素,需要特殊处理
export function handleDescendents(mode = 0) {
let n = 1;
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
chrome.storage.local.get({parameterNum: 1}, function (items) {
// let at = parseInt(new Date().getTime());
n = items.parameterNum;
clearParameters(); //清除原来的参数列表
global.app._data.selectedDescendents = true;
let nd, ndText, ndPath, pname, ndAllPaths, tmode;
tmode = mode;
if(mode == 2){
if (mode == 2) {
let xpath_list = [];
// mode == 1; //如果是选中全部块的共有子元素,则先选中和第一个块相同的子元素,然后最后再删除第一个块中和其他块不同的子元素
for (let num = 0; num < global.nodeList.length; num++) {
@@ -655,85 +728,85 @@ export function handleDescendents(mode = 0) {
if (num == 0) { //从第二个节点开始,只插入那些不在参数列表中的元素,根据xpath进行寻址
//如果当前节点除了子元素外仍然有其他文字或者该元素是图片/表单项,加入子元素节点
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
hash[index] = global.outputParameters.length;
if (nd.tagName == "IMG") { //如果元素是图片
global.outputParameters.push({
"nodeType": 4, //节点类型
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只选择了子元素没有选中全部的时候,需要判断
"name": parameterName("参数") + (n++) + parameterName("_图片地址"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("src") == null ? "" : nd.getAttribute("src")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else if (nd.tagName == "A") { //如果元素是超链接
global.outputParameters.push({
"nodeType": 1,
"contentType": 0, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_链接文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{"num": num, "value": nd.textContent}], //注意这里的ndtext是整个a的文字!!!
"unique_index": unique_index,
"iframe": global.iframe,
});
global.outputParameters.push({
"nodeType": 2,
"contentType": 0, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_链接地址"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else if (nd.tagName == "INPUT") { //如果元素是输入项
global.outputParameters.push({
"nodeType": 3,
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else { //其他所有情况
global.outputParameters.push({
"nodeType": 0,
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
}
hash[index] = global.outputParameters.length;
if (nd.tagName == "IMG") { //如果元素是图片
global.outputParameters.push({
"nodeType": 4, //节点类型
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只选择了子元素没有选中全部的时候,需要判断
"name": parameterName("参数") + (n++) + parameterName("_图片地址"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("src") == null ? "" : nd.getAttribute("src")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else if (nd.tagName == "A") { //如果元素是超链接
global.outputParameters.push({
"nodeType": 1,
"contentType": 0, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_链接文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{"num": num, "value": nd.textContent}], //注意这里的ndtext是整个a的文字!!!
"unique_index": unique_index,
"iframe": global.iframe,
});
global.outputParameters.push({
"nodeType": 2,
"contentType": 0, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_链接地址"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else if (nd.tagName == "INPUT") { //如果元素是输入项
global.outputParameters.push({
"nodeType": 3,
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{
"num": num,
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
}],
"unique_index": unique_index,
"iframe": global.iframe,
});
} else { //其他所有情况
global.outputParameters.push({
"nodeType": 0,
"contentType": 1, // 内容类型
"relative": global.nodeList.length > 1 ? true : false, //是否为相对xpath路径
"name": parameterName("参数") + (n++) + parameterName("_文本"),
"desc": "", //参数描述
"relativeXPath": global.nodeList.length > 1 ? ndPath : readXPath(nd),
"allXPaths": global.nodeList.length > 1 ? ndAllPaths : getElementXPaths(nd),
"exampleValues": [{"num": num, "value": ndText}],
"unique_index": unique_index,
"iframe": global.iframe,
});
}
}
} else //如果元素节点已经存在,则只需要插入值就可以了
{
try{
try {
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
if (nd.tagName == "IMG") { //如果元素是图片
global.outputParameters[hash[index]]["exampleValues"].push({
@@ -772,8 +845,7 @@ export function handleDescendents(mode = 0) {
}
}
}
}
else {
} else {
for (let num = 0; num < global.nodeList.length; num++) {
let tnode = global.nodeList[num]["node"];
let stack = new Array(); //深度优先搜索遍历元素
@@ -801,7 +873,7 @@ export function handleDescendents(mode = 0) {
}
ndText = ndText.replace(/\s+/g, ''); // remove any whitespace characters
let unique_index = ndPath;
if(ndText!= "" || nd == tnode){
if (ndText != "" || nd == tnode) {
if (mode == 0 || (mode == 1 && (index != -1 || num == 0))) { //如果不是应选尽选,则只添加和第一个元素相同类型的子元素
global.outputParameterNodes.push({
"node": nd,
@@ -809,14 +881,14 @@ export function handleDescendents(mode = 0) {
"boxShadow": nd.style.boxShadow == "" || global.boxShadowColor ? "none" : nd.style.boxShadow
});
nd.style.boxShadow = global.boxShadowColor;
} else if(mode == 1 && nd == tnode){ //最外层元素标记一下
} else if (mode == 1 && nd == tnode) { //最外层元素标记一下
nd.style.boxShadow = global.boxShadowColor;
}
}
if (index == -1) { //从第二个节点开始,只插入那些不在参数列表中的元素,根据xpath进行寻址
//如果当前节点除了子元素外仍然有其他文字或者该元素是图片/表单项,加入子元素节点
if (!(mode == 1 && num > 0)) { //如果不是应选尽选,则只添加和第一个元素相同类型的子元素
if (ndText!= "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
if (nd.tagName == "IMG") { //如果元素是图片
global.outputParameters.push({
"nodeType": 4, //节点类型
@@ -901,7 +973,7 @@ export function handleDescendents(mode = 0) {
"value": nd.getAttribute("src") == null ? "" : nd.getAttribute("src")
});
} else if (nd.tagName == "A") { //如果元素是超链接
global.outputParameters[index]["exampleValues"].push({ "num": num, "value": nd.textContent });
global.outputParameters[index]["exampleValues"].push({"num": num, "value": nd.textContent});
global.outputParameters[index + 1]["exampleValues"].push({
"num": num,
"value": nd.getAttribute("href") == null ? "" : nd.getAttribute("href")
@@ -912,7 +984,7 @@ export function handleDescendents(mode = 0) {
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
});
} else { //其他所有情况
global.outputParameters[index]["exampleValues"].push({ "num": num, "value": ndText });
global.outputParameters[index]["exampleValues"].push({"num": num, "value": ndText});
}
}
for (let i = nd.children.length - 1; i >= 0; i--) {
@@ -958,7 +1030,7 @@ export function generateValTable(multiline = true) {
// 直到找到第一个变多的节点或者追溯到根节点为止
export function findRelated() {
// let at = parseInt(new Date().getTime());
let testPath = global.nodeList[0]["xpath"].replace("//iframe","").split("/").splice(1); //分离xpath成 ["html","body","div[0]"]这样子
let testPath = global.nodeList[0]["xpath"].replace("//iframe", "").split("/").splice(1); //分离xpath成 ["html","body","div[0]"]这样子
let nodeNameList = [];
let nodeIndexList = [];
for (let i = 0; i < testPath.length; i++) {
@@ -1006,17 +1078,37 @@ export function pushToReadyList(path) {
}
}
if (!exist) {
global.readyList.push({ "node": node, "bgColor": node.style.backgroundColor, "boxShadow": node.style.boxShadow == "" || global.boxShadowColor ? "none" : node.style.boxShadow });
global.readyList.push({
"node": node,
"bgColor": node.style.backgroundColor,
"boxShadow": node.style.boxShadow == "" || global.boxShadowColor ? "none" : node.style.boxShadow
});
}
node.style.boxShadow = global.boxShadowColor;
node = result.iterateNext(); //枚举下一个元素
}
}
export function selectAllElements(context=null) {
global.step++;
readyToList(global.step, false);
handleElement();
if (context.selectedDescendents) {
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
}
}
//将readyList中的元素放入选中节点中
export function readyToList(step, dealparameters = true) {
for (let o of global.readyList) {
global.nodeList.push({ node: o["node"], "step": global.step, bgColor: o["bgColor"], "boxShadow": o["boxShadow"], xpath: readXPath(o["node"], 1), "allXPaths": getElementXPaths(o["node"]) });
global.nodeList.push({
node: o["node"],
"step": global.step,
bgColor: o["bgColor"],
"boxShadow": o["boxShadow"],
xpath: readXPath(o["node"], 1),
"allXPaths": getElementXPaths(o["node"])
});
o["node"].style.backgroundColor = global.selectedColor;
}
clearReady();
@@ -1051,7 +1143,7 @@ export function relatedTest() {
let testpath = "";
for (let i = 0; i < global.nodeList.length; i++) {
let testnumList = []; //用于比较节点索引号不同
let tpath = global.nodeList[i]["xpath"].replace("//iframe","").split("/").splice(1); //清理第一个空元素
let tpath = global.nodeList[i]["xpath"].replace("//iframe", "").split("/").splice(1); //清理第一个空元素
for (let j = 0; j < tpath.length; j++) {
if (tpath[j].indexOf("[") >= 0) { //如果存在索引值
testnumList.push(parseInt(tpath[j].split("[")[1].replace("]", ""))); //只留下数字
@@ -25,14 +25,22 @@ global.ws.onmessage = function (evt) {
createNotification(LANG(evt["msg_zh"], evt["msg_en"]), evt["level"]);
} else if (evt["type"] == "cancelSelection") { //试运行点击元素后取消选中元素
clearEl();
} else if (evt["type"] == "trial"){
} else if (evt["type"] == "trial") {
trial(evt);
}
};
function clearAfterSend() {
global.justSend = true;
// setTimeout(function () {
// if (global.justSend) {
// clearEl();
// global.justSend = false;
// }
// }, 1000);
}
export function input(value, batch=false) {
export function input(value, batch = false) {
let type = "inputText";
let useLoop = false;
if (batch) {
@@ -63,6 +71,7 @@ export function input(value, batch=false) {
message: {"keyboardStr": value, "xpath": message.xpath, "iframe": global.iframe, "id": global.id} // {}全选{BS}退格
};
global.ws.send(JSON.stringify(message_keyboard));
clearAfterSend();
}
//点击元素操作
@@ -84,6 +93,7 @@ export function sendSingleClick() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
export function sendChangeOption(optionMode, optionValue) {
@@ -104,6 +114,7 @@ export function sendChangeOption(optionMode, optionValue) {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
export function sendMouseMove() {
@@ -123,6 +134,7 @@ export function sendMouseMove() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
export function sendLoopMouseMove() {
@@ -156,6 +168,7 @@ export function sendLoopMouseMove() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
//采集单个元素
@@ -173,7 +186,7 @@ export function collectSingle() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
// createNotification(LANG("采集成功", "Collect successfully"), "success");
clearAfterSend();
}
setInterval(function () {
@@ -202,6 +215,7 @@ export function collectMultiNoPattern() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
//采集有规律多元素
@@ -240,6 +254,7 @@ export function collectMultiWithPattern() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
//循环点击单个元素
@@ -266,6 +281,7 @@ export function sendLoopClickSingle(name) {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
//循环点击每个元素
@@ -301,6 +317,7 @@ export function sendLoopClickEvery() {
message: {"pipe": JSON.stringify(message)}
};
global.ws.send(JSON.stringify(message_action));
clearAfterSend();
}
//检测是否xpath对应的元素被全选了,个数判断即可
@@ -1,7 +1,8 @@
<template>
<div id="realcontent">
<!-- <div id="EasySpiderResizer" style="width: 10px; height: 10px; background-color: black; position: absolute; left: 0; bottom: 0; cursor: ne-resize;"></div>-->
<div id="EasySpiderResizer" style="width: 10px; height: 10px; position: absolute; left: 0; top: 0; cursor: nw-resize;"></div>
<!-- <div id="EasySpiderResizer" style="width: 10px; height: 10px; background-color: black; position: absolute; left: 0; bottom: 0; cursor: ne-resize;"></div>-->
<div id="EasySpiderResizer"
style="width: 10px; height: 10px; position: absolute; left: 0; top: 0; cursor: nw-resize;"></div>
<span id="closeButton">&#x2716;</span>
<div v-if="lang == 'zh'">
<div class="tooldrag">操作台点此拖动左上角调整大小</div>
@@ -10,53 +11,71 @@
<div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
<input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"
v-on:mousedown="specialSelect"/>
<p style="margin-bottom:10px;display:inline-block">特殊点选模式<span title="普通模式下如果不能选中元素可以勾选此项"></span></p>
<div class="innercontent" v-if = "list.nl.length==0">
<p style="margin-bottom:10px;display:inline-block">特殊点选模式<span
title="普通模式下如果不能选中元素可以勾选此项"></span></p>
<div class="innercontent" v-if="list.nl.length==0">
<div><a v-on:mousedown="getCurrentTitle">采集当前页面的标题</a><span title="当前页面标题"></span></div>
<div><a v-on:mousedown="getCurrentURL">采集当前页面的网址</a><span title="当前页面URL地址"></span></div>
</div>
<p style="color:black; margin-top: 10px"> 鼠标移动到笑脸查看操作提示</p>
<p style="color:black; margin-top: 10px"> 鼠标移动到元素上后<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素
<p style="color:black; margin-top: 10px">
鼠标移动到元素上后<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素
</p>
<p style="color:black; margin-top: 10px"> 如果此操作台把页面元素挡住了可以点击此操作台右下角的×按钮键关闭操作台</p>
<p style="color:black; margin-top: 10px"> 通过鼠标左键进行点击时页面也会有反应但左键点击发生的操作不会被记录在任务流程中同理如果想输入文本框但并不想将动作记录可以鼠标移动到文本框并按键盘的<strong>F9</strong>进行输入
<p style="color:black; margin-top: 10px">
如果此操作台把页面元素挡住了可以点击此操作台右下角的×按钮键关闭操作台</p>
<p style="color:black; margin-top: 10px">
通过鼠标左键进行点击时页面也会有反应但左键点击发生的操作不会被记录在任务流程中同理如果想输入文本框但并不想将动作记录可以鼠标移动到文本框并按键盘的<strong>F9</strong>进行输入
</p>
<p style="color:black; margin-top: 10px">
如果不小心左键点选了元素导致页面跳转直接后退或者切换回标签页即可</p>
<p style="color:black; margin-top: 10px"> 操作完成后如点击确认采集后任务流程图内没有提取数据操作被添加<strong>重试一次</strong>即可
</p>
<p style="color:black; margin-top: 10px"> 如果不小心左键点选了元素导致页面跳转直接后退或者切换回标签页即可</p>
<p style="color:black; margin-top: 10px"> 操作完成后如点击确认采集后任务流程图内没有提取数据操作被添加<strong>重试一次</strong>即可</p>
{{ initial() }}
</div>
<div v-if="list.nl.length==1">
<div v-if="tname()!='null'">
已选中{{ numOfList() }}{{ tname() }}<span
v-if="numOfReady()>0&&tname()!='下一页元素'">同时发现{{ numOfReady() }}个同类元素如果不全或不准请继续手动选择其余您认为的同类元素</span>您可以:
v-if="numOfReady()>0&&tname()!='下一页元素'">同时发现{{
numOfReady()
}}个同类元素如果不全或不准请继续手动选择其余您认为的同类元素</span>您可以:
<div class="innercontent">
<div v-if="numOfReady()>0 && !selectStatus"><a v-on:mousedown="selectAll">选中全部</a> <span
title=""></span></div>
<div v-if="existDescendents()&& !selectStatus &&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents">选中子元素</a> <span title="应选尽选模式,如想使用其他模式请先选中全部再选中子元素"></span></div>
v-on:mousedown="selectDescendents">选中子元素</a> <span
title="应选尽选模式,如想使用其他模式请先选中全部再选中子元素"></span></div>
<div v-if="!selectedDescendents && !selectStatus" id="Single">
<div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">切换下拉选项</a><span title=""></span></div>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(false)">输入文字</a><span title=""></span></div>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">批量输入文字</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">切换下拉选项</a><span title=""></span>
</div>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(false)">输入文字</a><span title=""></span>
</div>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">批量输入文字</a><span
title=""></span></div>
<div v-if="tname()!='图片'"><a v-on:mousedown="getText">采集该{{ tname() }}的文本</a><span
title="采集文本"></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedValue">采集当前选中项的值</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedText">采集当前选中项的文本</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedValue">采集当前选中项的值</a><span
title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedText">采集当前选中项的文本</a><span
title=""></span></div>
<div v-if="tname()=='链接'||tname()=='图片'"><a
v-on:mousedown="getLink">采集该{{ tname() }}的地址</a><span title=""></span></div>
<div><a
v-on:mousedown="clickElement">点击该{{ tname() }}</a><span title=""></span></div>
<div v-if="tname()!='选择框' && tname()!='文本框'"><a
v-on:mousedown="loopClickSingleElement">循环点击该{{ tname() }}</a><span title="常用于循环点击下一页场景"></span></div>
<div><a v-on:mousedown="getBackgroundPic">采集该{{ tname() }}的背景图片地址</a><span title="部分元素的图片是设定为背景图像的"></span></div>
v-on:mousedown="loopClickSingleElement">循环点击该{{ tname() }}</a><span
title="常用于循环点击下一页场景"></span></div>
<div><a v-on:mousedown="getBackgroundPic">采集该{{ tname() }}的背景图片地址</a><span
title="部分元素的图片是设定为背景图像的"></span></div>
<div v-if="tname()=='链接'||tname()=='元素'"><a v-on:mousedown="getInnerHtml">采集该{{
tname()
}}的Inner
Html</a><span title="不包括元素自身标签的HTML"></span></div>
<div><a v-on:mousedown="getOuterHtml">采集该{{ tname() }}的Outer Html</a><span title="包括元素自身标签的HTML"></span></div>
<div><a v-on:mousedown="getOuterHtml">采集该{{ tname() }}的Outer Html</a><span
title="包括元素自身标签的HTML"></span></div>
<div><a href="#" v-on:mousedown="mouseMove">鼠标移动到该{{ tname() }}</a><span title=""></span></div>
<!-- <div v-if="tname()=='文本框'"><a>识别验证码</a><span title=""></span></div>-->
<div><a href="#" v-on:mousedown="mouseMove">鼠标移动到该{{ tname() }}</a><span title=""></span>
</div>
<!-- <div v-if="tname()=='文本框'"><a>识别验证码</a><span title=""></span></div>-->
</div>
<div v-if="selectedDescendents" id="Single">
<div><a v-on:mousedown="confirmCollectSingle">采集数据</a><span title=""></span></div>
@@ -80,18 +99,24 @@
<div v-if="option!=100">
已选择了{{ numOfList() }}个同类元素<span
v-if="numOfReady()>0">另外发现{{ numOfReady() }}个同类元素如果不全或不准请继续手动选择其余您认为的同类元素</span>您可以
v-if="numOfReady()>0">另外发现{{
numOfReady()
}}个同类元素如果不全或不准请继续手动选择其余您认为的同类元素</span>您可以
<div class="innercontent">
<div v-if="numOfReady()>0"><a v-on:mousedown="selectAll">选中全部</a><span title=""></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents">选中子元素应选尽选</a><span title="每个块的每个子元素都选中进来"></span></div>
v-on:mousedown="selectDescendents">选中子元素应选尽选</a><span
title="每个块的每个子元素都选中进来"></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,1)">选中子元素相对首选块共同元素</a><span title="只选中和第一个选中块的子元素共同的子元素"></span></div>
v-on:mousedown="selectDescendents(1,1)">选中子元素相对首选块共同元素</a><span
title="只选中和第一个选中块的子元素共同的子元素"></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,2)">选中子元素所有块共同元素</a><span title="只选中所有块都有的子元素"></span></div>
v-on:mousedown="selectDescendents(1,2)">选中子元素所有块共同元素</a><span
title="只选中所有块都有的子元素"></span></div>
<div><a v-on:mousedown="confirmCollectMultiAndDescendents">采集数据</a><span title=""></span></div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopClickEveryElement">循环点击每个{{ tname() }}</a><span title="常用于循环点击列表中的链接打开详情页采集场景"></span></div>
v-on:mousedown="loopClickEveryElement">循环点击每个{{ tname() }}</a><span
title="常用于循环点击列表中的链接打开详情页采集场景"></span></div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopMouseMove">循环移动到每个{{ tname() }}</a><span title=""></span></div>
<div><a v-on:mousedown="revoke">撤销本次选择</a><span title=""></span></div>
@@ -102,7 +127,9 @@
<div class="toolkitcontain">
<table cellSpacing="0" class="toolkittb2">
<tbody>
<th v-for="(i, index) in list.opp"> <div>{{ i["name"] }}</div> <span v-bind:index="index" v-on:mousedown="removeField" title="删除此字段">×</span> </th>
<th v-for="(i, index) in list.opp">
<div>{{ i["name"] }}</div>
<span v-bind:index="index" v-on:mousedown="removeField" title="删除此字段">×</span></th>
<th style="width:40px">删除</th>
</tbody>
@@ -151,7 +178,8 @@
<span style="font-size: 15px" v-if="optionMode == 3"> 选项文本</span>
<span style="font-size: 15px" v-if="optionMode == 1"> 索引值</span>
<span style="font-size: 15px" v-if="optionMode == 2"> 选项值</span>
<input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus" type="text"></input>
<input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus"
type="text"></input>
<div>
<button style="margin-left:0px!important;" v-on:click="sendChangeSelect">确定</button>
<button style="margin-left:0px!important;" v-on:click="cancelInput">取消</button>
@@ -166,19 +194,30 @@
<div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
<input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"
v-on:mousedown="specialSelect"> </input>
<p style="margin-bottom:10px;display:inline-block">Special click mode<span title="If cannot select element by mouse, select this option"></span></p>
<div class="innercontent" v-if = "list.nl.length==0">
<div><a v-on:mousedown="getCurrentTitle">Collect Title of current page</a><span title="Title of this page"></span></div>
<div><a v-on:mousedown="getCurrentURL">Collect URL of current page</a><span title="URL of this page"></span></div>
<p style="margin-bottom:10px;display:inline-block">Special click mode<span
title="If cannot select element by mouse, select this option"></span></p>
<div class="innercontent" v-if="list.nl.length==0">
<div><a v-on:mousedown="getCurrentTitle">Collect Title of current page</a><span
title="Title of this page"></span></div>
<div><a v-on:mousedown="getCurrentURL">Collect URL of current page</a><span
title="URL of this page"></span></div>
</div>
<p style="color:black; margin-top: 10px"> Mouse move to smiling face to see operation help.</p>
<p style="color:black; margin-top: 10px"> When your mouse moves to the element, please <strong>right-click</strong> your
<p style="color:black; margin-top: 10px"> When your mouse moves to the element, please
<strong>right-click</strong> your
mouse button or press <strong>F7</strong> on the keyboard to select it.</p>
<p style="color:black; margin-top: 10px"> If this toolbox blocks the page element, you can click the × button in the
<p style="color:black; margin-top: 10px"> If this toolbox blocks the page element, you can click the ×
button in the
lower right corner of this toolbox to close it.</p>
<p style="color:black; margin-top: 10px"> When clicked with the left mouse button, the page will also respond, but this click operation will not be recorded in the task flow. Similarly, if you want to input in a text box but do not want the action to be recorded , you can move the mouse to the text box and press <strong>F9</strong> on the keyboard to input.</p>
<p style="color:black; margin-top: 10px"> If you accidentally left-click on an element and cause the page to jump, simply go back or switch back to the tab.</p>
<p style="color:black; margin-top: 10px"> After the operation is completed, such as if no "Collect Data" operation is added in the task flowchart after clicking "Confirm Collect", just <strong> retry </strong> again.</p>
<p style="color:black; margin-top: 10px"> When clicked with the left mouse button, the page will also
respond, but this click operation will not be recorded in the task flow. Similarly, if you want to input
in a text box but do not want the action to be recorded , you can move the mouse to the text box and press
<strong>F9</strong> on the keyboard to input.</p>
<p style="color:black; margin-top: 10px"> If you accidentally left-click on an element and cause the page
to jump, simply go back or switch back to the tab.</p>
<p style="color:black; margin-top: 10px"> After the operation is completed, such as if no "Collect Data"
operation is added in the task flowchart after clicking "Confirm Collect", just <strong> retry </strong>
again.</p>
{{ initial() }}
</div>
<div v-if="list.nl.length==1">
@@ -190,17 +229,26 @@
<div v-if="numOfReady()>0 && !selectStatus"><a v-on:mousedown="selectAll">Select All</a><span
title=""></span></div>
<div v-if="existDescendents()&& !selectStatus &&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents">Select child elements</a> <span title="Greedy Mode, if you want to use other modes, please select 'Select All' option first"></span></div>
v-on:mousedown="selectDescendents">Select child elements</a> <span
title="Greedy Mode, if you want to use other modes, please select 'Select All' option first"></span>
</div>
<div v-if="!selectedDescendents && !selectStatus" id="Single">
<!-- <div v-if="tname()=='selection box'"> <a>循环切换该下拉项</a><span title=""></span></div> -->
<div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">Change selection option</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">Change selection option</a><span
title=""></span></div>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(false)">Input Text</a><span title=""></span>
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">Input Text (Batch)</a><span title=""></span>
</div>
<div v-if="tname()!='图片'"><a v-on:mousedown="getText">Extract {{ tname() | toEng }}'s text</a><span
<div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">Input Text (Batch)</a><span
title=""></span>
</div>
<div v-if="tname()!='图片'"><a v-on:mousedown="getText">Extract {{ tname() | toEng }}'s
text</a><span
title="collect text"></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedValue">Collect selected option value</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedText">Collect selected option text</a><span title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedValue">Collect selected option
value</a><span
title=""></span></div>
<div v-if="tname()=='选择框'"><a v-on:mousedown="getSelectedText">Collect selected option
text</a><span title=""></span></div>
<div v-if="tname()=='链接'||tname()=='图片'"><a v-on:mousedown="getLink">Collect address of this
{{ tname() | toEng }}</a><span title=""></span></div>
@@ -210,13 +258,17 @@
v-on:mousedown="loopClickSingleElement">Loop-click this {{ tname() | toEng }}</a><span
title="Usually used to loop-click the next-page button"></span>
</div>
<div><a v-on:mousedown="getBackgroundPic">Collect background image URL</a><span title="Some elements have background images"></span></div>
<div><a v-on:mousedown="getBackgroundPic">Collect background image URL</a><span
title="Some elements have background images"></span></div>
<div v-if="tname()=='链接'||tname()=='元素'"><a v-on:mousedown="getInnerHtml">Collect Inner Html of
this {{ tname() | toEng }}</a><span title="HTML not including the tag of this selected element"></span></div>
<div><a v-on:mousedown="getOuterHtml">Collect Outer Html of this element</a><span title="HTML including the tag of this selected element"></span>
this {{ tname() | toEng }}</a><span
title="HTML not including the tag of this selected element"></span></div>
<div><a v-on:mousedown="getOuterHtml">Collect Outer Html of this element</a><span
title="HTML including the tag of this selected element"></span>
</div>
<div><a href="#" v-on:mousedown="mouseMove">Move mouse to this element</a><span title=""></span></div>
<div><a href="#" v-on:mousedown="mouseMove">Move mouse to this element</a><span title=""></span>
</div>
<!-- <div v-if="tname()=='text box'"> <a>识别验证码</a><span title=""></span></div> -->
</div>
<div v-if="selectedDescendents" id="Single">
@@ -228,100 +280,113 @@
</div>
</div>
</div>
</div>
<div v-if="list.nl.length>1">
<div v-if="list.nl.length>1">
<div v-if="option==100">
Already selected the following element, you can:
<div class="innercontent">
<div><a v-on:mousedown="confirmCollectMulti">Collect Data</a><span title=""></span></div>
<div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
</div>
</div>
<div v-if="option!=100">
Already selected {{ numOfList() }} similar elements, <span
v-if="numOfReady()>0">and we find other{{ numOfReady() }} similar elements (If unsatisfied with auto-detected similar elements, you can continue to manually select the rest of the elements that you think are similar), </span>you can:
<div class="innercontent">
<div v-if="numOfReady()>0"><a v-on:mousedown="selectAll">Select All</a><span title=""></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents">Select child elements (Greedy)</a><span title="Select All child elements for all blocks"></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,1)">Select child elements (RFSE)</a><span title="Relative to First Selected Element, will only select the common child elements between the first selected block and the rest of the blocks"></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,2)">Select child elements (RASE)</a><span title="Relative to All Selected Elements, will select only the common child elements that exist in all blocks"></span></div>
<div><a v-on:mousedown="confirmCollectMultiAndDescendents">Collect Data</a><span title=""></span></div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopClickEveryElement">Loop-click every {{ tname() | toEng}}</a><span title="Usually used to click every link in a list to open detail page to collect data"></span>
</div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopMouseMove">Loop-mouse-move to every {{ tname() | toEng}}</a><span title=""></span></div>
<div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
</div>
</div>
</div>
<div v-if="valTable.length>0">
<div class="toolkitcontain">
<table cellspacing="0" class="toolkittb2">
<tbody>
<th v-for="(i, index) in list.opp"><div>{{ i["name"] }}</div> <span v-bind:index="index" v-on:mousedown="removeField" title="Remove this field">×</span> </th>
<th style="width:40px">Delete</th>
</tbody>
</table>
<table cellspacing="0" class="toolkittb4">
<tbody>
<tr v-for="i in valTable[0].length">
<td v-for="j in list.opp.length">{{ valTable[j - 1][i - 1] }}</td>
<td style="font-size: 22px!important;width:40px;cursor:pointer" v-bind:index="i-1"
v-on:mousedown="deleteSingleLine">×
</td>
</tr>
</tbody>
</table>
<div v-if="option==100">
Already selected the following element, you can:
<div class="innercontent">
<div><a v-on:mousedown="confirmCollectMulti">Collect Data</a><span title=""></span></div>
<div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
</div>
</div>
<div v-if="valTable.length==0&&tname()!='下一页元素'"></div>
<div v-if="list.nl.length>0"
style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
<div style="margin-bottom:5px">
<button v-on:mousedown="cancel">Deselect</button>
<button v-if="!selectStatus" v-on:mousedown="enlarge">Expand Path</button>
<div v-if="option!=100">
Already selected {{ numOfList() }} similar elements, <span
v-if="numOfReady()>0">and we find other{{ numOfReady() }} similar elements (If unsatisfied with auto-detected similar elements, you can continue to manually select the rest of the elements that you think are similar), </span>you
can:
<div class="innercontent">
<div v-if="numOfReady()>0"><a v-on:mousedown="selectAll">Select All</a><span title=""></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents">Select child elements (Greedy)</a><span
title="Select All child elements for all blocks"></span></div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,1)">Select child elements (RFSE)</a><span
title="Relative to First Selected Element, will only select the common child elements between the first selected block and the rest of the blocks"></span>
</div>
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
v-on:mousedown="selectDescendents(1,2)">Select child elements (RASE)</a><span
title="Relative to All Selected Elements, will select only the common child elements that exist in all blocks"></span>
</div>
<div><a v-on:mousedown="confirmCollectMultiAndDescendents">Collect Data</a><span title=""></span>
</div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopClickEveryElement">Loop-click every {{ tname() | toEng }}</a><span
title="Usually used to click every link in a list to open detail page to collect data"></span>
</div>
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
v-on:mousedown="loopMouseMove">Loop-mouse-move to every {{ tname() | toEng }}</a><span
title=""></span></div>
<div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
</div>
<p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
</div>
</div>
<div v-if="valTable.length>0">
<div class="toolkitcontain">
<table cellspacing="0" class="toolkittb2">
<tbody>
<th v-for="(i, index) in list.opp">
<div>{{ i["name"] }}</div>
<span v-bind:index="index" v-on:mousedown="removeField" title="Remove this field">×</span></th>
<th style="width:40px">Delete</th>
</tbody>
</table>
<table cellspacing="0" class="toolkittb4">
<tbody>
<tr v-for="i in valTable[0].length">
<td v-for="j in list.opp.length">{{ valTable[j - 1][i - 1] }}</td>
<td style="font-size: 22px!important;width:40px;cursor:pointer" v-bind:index="i-1"
v-on:mousedown="deleteSingleLine">×
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="page==1">
Please input text:
<input id="WTextBox" v-model="text" autofocus="autofocus" type="text"></input>
<button style="margin-left:0px!important;" v-on:click="getInput">Confirm</button>
<button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
<div style="text-align: justify;margin-top: 15px;padding-right: 15px;margin-left: 4px">
Inputting &lt;enter&gt; or &lt;ENTER&gt; represents the simulation of pressing the Enter key after input is complete, which is applicable in situations where data can only be obtained through pressing the Enter key.
</div>
</div>
<div v-if="page==2">
<span style="font-size: 15px"> Change Mode </span>
<select v-model="optionMode" @change="handleSelectChange">
<option value=0>Change to next option</option>
<option value=1>Change option by index</option>
<option value=2>Change option by value</option>
<option value=3>Change option by text</option>
</select>
<span style="font-size: 15px" v-if="optionMode == 3"> Option Text</span>
<span style="font-size: 15px" v-if="optionMode == 1"> Option Index</span>
<span style="font-size: 15px" v-if="optionMode == 2"> Option Value</span>
<input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus" type="text"></input>
<div>
<button style="margin-left:0px!important;" v-on:click="sendChangeSelect">Confirm</button>
<button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
<div v-if="valTable.length==0&&tname()!='下一页元素'"></div>
<div v-if="list.nl.length>0"
style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
<div style="margin-bottom:5px">
<button v-on:mousedown="cancel">Deselect</button>
<button v-if="!selectStatus" v-on:mousedown="enlarge">Expand Path</button>
</div>
<p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
</div>
</div>
<div v-if="page==1">
Please input text:
<input id="WTextBox" v-model="text" autofocus="autofocus" type="text"></input>
<button style="margin-left:0px!important;" v-on:click="getInput">Confirm</button>
<button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
<div style="text-align: justify;margin-top: 15px;padding-right: 15px;margin-left: 4px">
Inputting &lt;enter&gt; or &lt;ENTER&gt; represents the simulation of pressing the Enter key after input
is complete, which is applicable in situations where data can only be obtained through pressing the Enter
key.
</div>
</div>
<div v-if="page==2">
<span style="font-size: 15px"> Change Mode </span>
<select v-model="optionMode" @change="handleSelectChange">
<option value=0>Change to next option</option>
<option value=1>Change option by index</option>
<option value=2>Change option by value</option>
<option value=3>Change option by text</option>
</select>
<span style="font-size: 15px" v-if="optionMode == 3"> Option Text</span>
<span style="font-size: 15px" v-if="optionMode == 1"> Option Index</span>
<span style="font-size: 15px" v-if="optionMode == 2"> Option Value</span>
<input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus"
type="text"></input>
<div>
<button style="margin-left:0px!important;" v-on:click="sendChangeSelect">Confirm</button>
<button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
</div>
</div>
</div>
</div>
@@ -346,7 +411,7 @@ import {
pushToReadyList,
readyToList,
combineXpath,
relatedTest, getElementXPaths
relatedTest, getElementXPaths, selectAllElements
} from "./global.js";
import {
input,
@@ -381,25 +446,25 @@ export default {
optionValue: "",
mode: 0, //记录删除字段模式
},
mounted(){
mounted() {
this.$nextTick(() => {
window.addEventListener('resize', this.onResize);
});
if(isInIframe()){
if (isInIframe()) {
global.iframe = true;
}
// 获取页面上所有的iframe
let iframes = document.getElementsByTagName('iframe');
// 循环遍历所有的iframe
for(let i = 0; i < iframes.length; i++) {
for (let i = 0; i < iframes.length; i++) {
let iframe = iframes[i];
// 获取iframe的当前高度
let currentHeight = iframe.offsetHeight;
console.log("IFRAME: ", getElementXPaths(iframe), readXPath(iframe));
console.log("IFrame Height: ", currentHeight, "px")
// 如果当前高度小于600px,那么将其设置为600px
if(currentHeight < 600) {
if (currentHeight < 600) {
iframe.style.height = '600px!important';
iframe.height = '600';
}
@@ -407,7 +472,7 @@ export default {
let currentWidth = iframe.offsetWidth;
console.log("IFrame Width: ", currentWidth, "px")
// 如果当前高度小于600px,那么将其设置为600px
if(currentWidth < 600) {
if (currentWidth < 600) {
iframe.style.width = '600px!important';
iframe.width = '600';
}
@@ -483,24 +548,24 @@ export default {
let at2 = parseInt(new Date().getTime());
console.log("delete:", at2, at, at2 - at);
},
removeField: function (event){
let index = event.target.getAttribute("index");
let tParameter = global.outputParameters.splice(index, 1)[0];
if(global.outputParameters.length == 0){
this.valTable = [];
clearEl();
} else { //删除对应的列
console.log("remove:", tParameter, global);
this.valTable.splice(index, 1);
for (let i = global.outputParameterNodes.length - 1; i >= 0; i--) {
let node = global.outputParameterNodes[i];
if(node["unique_index"] == tParameter["unique_index"]){
node["node"].style.backgroundColor = "";
node["node"].style.boxShadow = "";
global.outputParameterNodes.splice(i, 1);
}
removeField: function (event) {
let index = event.target.getAttribute("index");
let tParameter = global.outputParameters.splice(index, 1)[0];
if (global.outputParameters.length == 0) {
this.valTable = [];
clearEl();
} else { //删除对应的列
console.log("remove:", tParameter, global);
this.valTable.splice(index, 1);
for (let i = global.outputParameterNodes.length - 1; i >= 0; i--) {
let node = global.outputParameterNodes[i];
if (node["unique_index"] == tParameter["unique_index"]) {
node["node"].style.backgroundColor = "";
node["node"].style.boxShadow = "";
global.outputParameterNodes.splice(i, 1);
}
}
}
},
clickElement: async function () { //点击元素操作
sendSingleClick();
@@ -510,22 +575,22 @@ export default {
// global.nodeList[0]["node"].click(); //点击元素
clearEl();
},
changeSelect: function(){
changeSelect: function () {
this.page = 2;
this.optionMode = 0;
this.optionValue = global.nodeList[0]["node"].options[global.nodeList[0]["node"].selectedIndex + 1].text;
},
sendChangeSelect: function (){
sendChangeSelect: function () {
sendChangeOption(this.optionMode, this.optionValue);
//先发送数据
try{
if(this.optionMode == 0){
try {
if (this.optionMode == 0) {
global.nodeList[0]["node"].options[global.nodeList[0]["node"].selectedIndex + 1].selected = true;
} else if(this.optionMode == 1){
} else if (this.optionMode == 1) {
global.nodeList[0]["node"].selectedIndex = this.optionValue;
} else if(this.optionMode == 2){
} else if (this.optionMode == 2) {
global.nodeList[0]["node"].value = this.optionValue;
} else if(this.optionMode == 3){
} else if (this.optionMode == 3) {
global.nodeList[0]["node"].options[global.nodeList[0]["node"].selectedIndex].selected = true;
for (let i = 0; i < global.nodeList[0]["node"].options.length; i++) {
const option = global.nodeList[0]["node"].options[i];
@@ -536,7 +601,7 @@ export default {
}
}
} catch (e) {
if(this.lang == "zh"){
if (this.lang == "zh") {
alert("切换失败,实际执行时可能失败,请注意。");
} else {
alert("Switch failed, may fail when actually executed, please note.");
@@ -545,23 +610,23 @@ export default {
clearEl();
},
handleSelectChange: function(){
handleSelectChange: function () {
console.log(this.optionMode, this.optionValue);
if(this.optionMode == 0){
if (this.optionMode == 0) {
this.optionValue = global.nodeList[0]["node"].options[global.nodeList[0]["node"].selectedIndex + 1].text;
} else if(this.optionMode == 1){
} else if (this.optionMode == 1) {
this.optionValue = global.nodeList[0]["node"].selectedIndex;
} else if(this.optionMode == 2){
} else if (this.optionMode == 2) {
this.optionValue = global.nodeList[0]["node"].value;
} else if(this.optionMode == 3){
} else if (this.optionMode == 3) {
this.optionValue = global.nodeList[0]["node"].options[global.nodeList[0]["node"].selectedIndex].text;
}
},
mouseMove: function(){
mouseMove: function () {
sendMouseMove();
clearEl();
},
loopMouseMove: function(){
loopMouseMove: function () {
sendLoopMouseMove();
clearEl();
},
@@ -581,7 +646,7 @@ export default {
// global.nodeList[0]["node"].click(); //点击元素
clearEl();
},
setInput: function (batch=false) { //输入文字
setInput: function (batch = false) { //输入文字
this.batch = batch;
this.page = 1;
this.$nextTick(function () { //下一时刻获得焦点
@@ -713,13 +778,13 @@ export default {
clearEl();
},
specialSelect: function () { //特殊选择模式
if (mousemovebind) {
global.tdiv.style.pointerEvents = "none";
this.special = false;
} else {
this.special = true;
}
mousemovebind = !mousemovebind;
// if (mousemovebind) {
// global.tdiv.style.pointerEvents = "none";
// this.special = false;
// } else {
// this.special = true;
// }
// mousemovebind = !mousemovebind;
},
enlarge: function () { // 扩大选区功能,总是扩大最后一个选中的元素的选区
if (global.nodeList[global.nodeList.length - 1]["node"].tagName != "BODY") {
@@ -752,12 +817,7 @@ export default {
}
},
selectAll: function () { //选中全部元素
global.step++;
readyToList(global.step, false);
handleElement();
if (this.selectedDescendents) {
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
}
selectAllElements(this);
},
revoke: function () { //撤销选择当前节点
let tstep = global.step;
@@ -1,12 +1,30 @@
import {LANG} from "./global.js";
import {
LANG,
clearEl,
addEl,
global,
readyToList,
handleElement,
handleDescendents,
selectAllElements
} from "./global.js";
//试运行操作标记
export function trial(evt) {
// if(global.justSend){ //如果是刚刚发送的消息到流程图,不处理
// global.justSend = false;
// return;
// }
let node = JSON.parse(evt["message"]["message"]["node"]);
let parentNode = JSON.parse(evt["message"]["message"]["parentNode"]);
let parameters = node.parameters;
let type = evt["message"]["message"]["type"];
console.log("parameters", parameters);
// console.log("parameters", parameters);
for (let node of global.markElements) {
let element = node.element;
element.style.boxShadow = "none";
}
global.markElements = [];
if (type == 0) {
let option = node.option;
console.log("option", option);
@@ -17,14 +35,125 @@ export function trial(evt) {
xpath = parentXPath + xpath;
}
let element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (element != null) {
clearEl(true);
addEl(null, element);
}
// if (element != null) {
// //移动到元素位置
// element.scrollIntoView({block: "center", inline: "center"});
// }
} else if (option == 3) {
let paras = parameters.paras; //所有的提取数据参数
clearEl(true);
for (let i = 0; i < paras.length; i++) {
let para = paras[i];
let xpath = para.relativeXPath;
let parent_xpaths = "";
let xpaths = [];
if (para.relative) {
if (parentNode.parameters.loopType <= 1) {
parent_xpaths = [parentNode.parameters.xpath];
} else if (parentNode.parameters.loopType == 2) { //循环项列表
parent_xpaths = parentNode.parameters.pathList.split("\n");
}
for (let j = 0; j < parent_xpaths.length; j++) {
let parent_xpath = parent_xpaths[j];
let realXPath = parent_xpath + xpath;
xpaths.push(realXPath);
}
}
for (let j = 0; j < xpaths.length; j++) {
let xpath = xpaths[j];
try {
let elementList = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
console.log(xpath)
for (let k = 0; k < elementList.snapshotLength; k++) {
let element = elementList.snapshotItem(k);
if (element != null) {
global.markElements.push({
"element": element, "bgColor": element.style.backgroundColor,
"boxShadow": element.style.boxShadow
});
// element.style.backgroundColor = global.selectedColor;
element.style.boxShadow = "0 0 0 1px #00a8ff";
}
}
} catch (e) {
console.log("跳过错误的xpath", xpath);
}
}
}
} else if (option == 11) {
let paras = parameters.paras; //所有的提取数据参数
let i = parameters.index;
let para = paras[i];
let xpath = para.relativeXPath;
if (para.relative) {
let parent_xpath = parentNode.parameters.xpath;
if (parentNode.parameters.loopType == 2) {
let pathList = parentNode.parameters.pathList.split("\n")[0].trim();
parent_xpath = pathList;
}
xpath = parent_xpath + xpath;
}
let elementList = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
clearEl(true);
for (let j = 0; j < elementList.snapshotLength; j++) {
let element = elementList.snapshotItem(j);
if (element != null) {
addEl(null, element);
}
}
} else if (option == 8) {
let loopType = parameters.loopType;
if (loopType <= 2) {
let xpath = "";
if (loopType == 0) {
xpath = parameters.xpath;
let element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (element != null) {
clearEl(true);
addEl(null, element);
}
} else if (loopType == 1) {
let elementList = document.evaluate(parameters.xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
let element = elementList.snapshotItem(0);
if (element != null) {
clearEl(true);
addEl(null, element);
if (elementList.snapshotLength > 1) {
selectAllElements();
}
}
} else if (loopType == 2) {
clearEl(true);
let pathList = parameters.pathList.split("\n");
for (let i = 0; i < pathList.length; i++) {
let path = pathList[i].trim();
let element = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (element != null) {
addEl(null, element);
}
}
}
}
} else if (option == 10) { //条件分支
let condition = parameters.class;
let result = 0;
let additionalInfo = "";
if (condition == 3 || condition == 4 || condition == 7) { //当前循环项判断时,选中当前循环项
let xpath = parentNode.parameters.xpath;
if (parentNode.parameters.loopType == 2) {
let pathList = parentNode.parameters.pathList.split("\n")[0].trim();
xpath = pathList;
}
let element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (element != null) {
clearEl(true);
addEl(null, element);
}
}
if (condition == 0) { //无条件
result = 1;
} else if (condition == 1) { //当前页面包含文本
@@ -52,7 +181,7 @@ export function trial(evt) {
result = 1;
}
}
if(result == 0){
if (result == 0) {
additionalInfo = LANG(",注意只会检索第一个匹配到的循环项", ", note that only the first matching loop item will be retrieved");
}
} else if (condition == 4) { //当前循环项包含元素,xpath
@@ -66,12 +195,12 @@ export function trial(evt) {
if (element != null) {
result = 1;
}
if(result == 0){
if (result == 0) {
additionalInfo = LANG(",注意只会检索第一个匹配到的循环项", ", note that only the first matching loop item will be retrieved");
}
} else if (condition == 5 || condition == 7) { //从主程序传入的结果
result = evt["message"]["message"]["result"];
if(condition == 7 && result == 0){
if (condition == 7 && result == 0) {
additionalInfo = LANG(",注意只会检索第一个匹配到的循环项", ", note that only the first matching loop item will be retrieved");
}
} else {