Selenium 基于 Vue 的前端页面测试——元素定位

詹金辉 · 2023年07月27日 · 2954 次阅读

当我们测试 Vue 实现前端页面时,经常会面临一个问题:很难定位页面上的元素。传统的做法是开发人员为每个元素手动定义唯一的 id 属性,然而这样做的工作量很大,而且会对代码造成侵入,容易引入错误。

为了解决这个问题,我们可以使用 Vue 的 mixin 方法来实现自动化地给每个元素添加测试 id 属性。具体做法是,通过计算元素的哈希值,生成一个唯一的测试 id 属性值,并将其设置到相应的元素上。

以下是实现的步骤:

创建一个名为 testIdMixin 的 mixin 对象,其中定义了一个名为 mounted 的方法。
在 mounted 方法中,遍历当前元素的属性,排除已有的 data-test-id 属性,将其它属性及其值参与哈希计算。
使用 crypto-js 库的 SHA-256 哈希算法计算属性的哈希值。
将计算得到的哈希值作为测试 id 属性的值,并添加到当前元素的 data-test-id 属性上。
通过使用 testIdMixin,我们的每个组件在渲染时都会自动获得一个唯一的测试 id,无需手动编写。这样的自动化流程,大大降低了开发工作量,并减少了错误的可能性。

在测试过程中,我们可以通过获取元素的 data-test-id 属性来定位元素,而无需关心具体的 id 值,使测试代码更加简洁和可维护。

通过使用 mixin 自动添加测试 id 属性,我们能够提高测试效率,降低维护成本,使前端开发更加高效和可靠。

testidmixin.js

const sha256 = require('crypto-js/sha256');

// 判断属性是否在要忽略的列表中
function isIgnoredAttribute(attributeName, ignoredAttributes) {
    return ignoredAttributes.some(ignoredAttr => {
        // 支持通配符 '*',如果匹配,则认为是要忽略的属性
        return ignoredAttr.test(attributeName);
    });
}

export default {
    mounted() {
        try {
            const element = this.$el instanceof Element ? this.$el : null;
            if (!element || !element.getAttribute("data-test-id")) {

                const json = {
                    tagName: element.tagName,
                    attributes: {},
                    textContent: element.textContent
                };
                const ignoredAttributes = [/data-.*/]; // 要忽略的属性列表,支持通配符 '*'
                Array.from(element.attributes).forEach(attr => {

                    const name = attr.name;
                    const value = attr.value;
                    // 判断该属性是否在要忽略的列表中,如果在则不添加到哈希属性对象中
                    if (!isIgnoredAttribute(name, ignoredAttributes)) {
                        json.attributes[name] = value;
                    }

                });
                // 将 Element 元素转换为字符串
                const elementString = JSON.stringify(json);

                // 计算字符串的哈希值
                const hash = sha256(elementString);
                const testId = "test-id-" + hash;
                element.setAttribute("data-test-id", testId);
            }
        } catch (error) {
            // 处理错误的逻辑
            console.log("元素获取失败,跳过", error);
        }
    }
};

main.js

import testIdMixin from "@common/js/testidmixin";


if (domainObj[window.location.hostname]) {//只在测试环境生效
    Vue.mixin(testIdMixin);
}

package.json

"dependencies": {
  "crypto-js": "^4.1.1"
}
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册