写一个获取元素 xpath 的 chrome 插件

需求

哈哈哈,本人还是很暖的,开会的时候大家一起聊天,聊到了测试是怎么做测试的。

然后测试给我们演示了一下,每次编写测试用例,都要通过 chrome 获
取元素的 xpath,很麻烦。

我就多嘴问了一句,为什么不自己弄一个自动获取 xpath 然后读成想要格式的插件呢?

测试:我不会,没研究过。
老板:那你来帮他实现一个吧。***,你把需求理顺了放进 tapd 。
我:反手给我自己一个大嘴巴子!

梳理

好在之前对 chrome 插件也略有所闻,嘿嘿。

先想想需求,鼠标点击一个元素的时候,自动读取该元素的 xpath,放到
另一个页面,然后提示:auto saved

ok,开搞。

目录结构

对于 chrome 插件开发者而言,chrome 做了最大的努力使得插件的开发简单而高效。

固定了项目的结构,开发者可以自由的将精力和时间放置在真正的代码和逻辑层面。

比如我的项目结构,就非常简单。
├── background.html
├── background.js
├── icon.png
├── manifest.json
└── xpath.js
大概说一下:
- manifest.json 是必须的,记录这个插件相关的信息和配置
- background.html 常驻页面,生命周期最长,随浏览器打开而打开,随浏览器关闭而关闭,所以把需要一直运行的、启动就运行的、全局的代码放在background里面
- icon 图标,插件的图标
- xpath 自己的逻辑

内容很多很长,这里不细说了,详细了解请点击

代码

// xpath.js
(function (doc) {
  var xh = {}
  xh.elementsShareFamily = function (primaryEl, siblingEl) {
    var p = primaryEl, s = siblingEl;
    return (p.tagName === s.tagName &&
      (!p.id || p.id === s.id));
  };

  xh.getElementIndex = function (el) {
    var index = 1;
    var sib;
    for (sib = el.previousSibling; sib; sib = sib.previousSibling) {
      if (sib.nodeType === Node.ELEMENT_NODE && xh.elementsShareFamily(el, sib)) {
        index++;
      }
    }
    if (index > 1) {
      return index;
    }
    for (sib = el.nextSibling; sib; sib = sib.nextSibling) {
      if (sib.nodeType === Node.ELEMENT_NODE && xh.elementsShareFamily(el, sib)) {
        return 1;
      }
    }
    return 0;
  };

  xh.makeQueryForElement = function (el) {
    var query = '';
    for (; el && el.nodeType === Node.ELEMENT_NODE; el = el.parentNode) {
      var component = el.tagName.toLowerCase();
      var index = xh.getElementIndex(el);
      if (index >= 1) {
        component += '[' + index + ']';
      }
      query = '/' + component + query;
    }
    return query;
  };
  doc.addEventListener('dblclick', (e) => {
    var target = e.target,
      data = xh.makeQueryForElement(target) + '\r\n';
    
    chrome.extension.sendRequest({ data }, function (response) {
      alert(response.farewell);
    });
  })
})(document)
// background.js
chrome.extension.onRequest.addListener(
  function (request, sender, sendResponse) {
    // var content = document.getElementById('app').innerText
    document.getElementById('app').innerText += request.data
    sendResponse({ farewell: "auto saved" });
  });

chrome.browserAction.onClicked.addListener(
  function () {
    if (chrome.runtime.openOptionsPage) {
      chrome.runtime.openOptionsPage();
    } else {
      window.open(chrome.runtime.getURL('background.html'));
    }
  }
);
// bacground.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #app{
      margin: 0;padding:0;
      font-size: 12px;
      background-color: #fff;
      color: silver;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div id=app></div>
  <script src="background.js"></script>
</body>
</html>
{
  "name": "xpath2.0",
  "description": "Get the current element xpath",
  "version": "1.0",
  "permissions": [
    "activeTab","tabs",
    "http://*/*",
    "https://*/*"
  ],
  "browser_action": {
      "default_title": "Get the current element xpath.",
      "default_icon": "icon.png"
  },
  "background": {
    "scripts": [
      "background.js"
    ]
  },
  "options_page": "background.html",
  "content_scripts": [
    {
      "matches": [
        "http://*/*",
        "https://*/*"
      ],
      "js": [
        "xpath.js"
      ]
    }
  ],
  "manifest_version": 2
}

猜你喜欢

转载自blog.csdn.net/zhai_865327/article/details/107492276