JavaScript自動化測試添加頁面DOM元素唯一ID方案示例
需求
測試編寫測試自動化腳本,需要定位到頁面元素。需要每個(gè)操作元素添加唯一標(biāo)識ID,并且每次前端構(gòu)建不能導(dǎo)致相同頁面相同元素的ID變化。方便測試快速寫自動化測試腳本。
解決方案1:處理渲染前的HTML根據(jù)正則去匹配操作元素,添加唯一id
webpack-loader打包的時(shí)候處理渲染前的HTML根據(jù)正則去匹配操作元素,添加唯一id。最后渲染出來的頁面操作元素有唯一id。
webpack-loader chainWebpack代碼:
chainWebpack: (config) => { config.resolveLoader.alias.set('my-loader', path.resolve(__dirname, 'build/preLoader-makeId.js')) config.module .rule('vue').test(/\.vue$/) .use('my-loader') .loader('my-loader').end() ; },
preLoader-makeId.js文件:
module.exports = function (contentStr, val) { var first = contentStr.indexOf('<template>') var end = contentStr.indexOf('<script>') content = contentStr.slice(first, end) let returnContent = content.replace(/\r\n/g, ' ') returnContent = returnContent.replace(/\r/g, ' ') returnContent = returnContent.replace(/\n/g, ' ') returnContent = returnContent.replace(/<\/el-/g, '\n</el-') returnContent = returnContent.replace(/<el-/g, '\n<el-') var regModule = /(model=\")([^\"]*)\"/g var regId = /(id=\")([^\"]*)\"/g var regBtn = /<(el-button)([^<>]*)>/g var regInput = /<(el-input)([^<>]*)>/g var regSele = /<(el-select)([^<>]*)>/g var regDate = /<(el-date-picker)([^<>]*)>/g var regInputNumber = /<(el-input-number)([^<>]*)>/g function makeId_input(index, item) { let id let res = regModule.exec(item) if (res && res.length > 0) { id = res[0] .replace('model="', '') .replace(/\"/g, '') .replace(/\./g, '_') } if (id) { return id } else { return index } // return id || index } function makeId_btn(index, item) { let id let clickAllArr = item.split(/click=/g) let subClick = '' let subClickArr = [] if (clickAllArr.length > 1) { subClick = clickAllArr[1].substring(1, clickAllArr[1].length) subClickArr = subClick.split(/"/g) if (subClickArr.length > 1) { id = subClickArr[0] .split(/\=/g)[0] .split(/\(\"/g)[0] .split(/\(\'/g)[0] .split(/\(/g)[0] } else { id = index } } else { id = index } if (id) { return id } else { return index } } let contentArr = returnContent.split('\n') let resultArr = contentArr.map((item, index) => { let id if (!regId.test(item)) { // 輸入框 - 數(shù)字 if (regInputNumber.test(item)) { item = '<el-input-number' + ' id="zgwww-input_number_' + makeId_input(index, item) + '"' + item.substring('<el-input-number'.length, item.length) + ' ' } else if (regInput.test(item)) { // 輸入框 item = '<el-input' + ' id="zgwww-input_' + makeId_input(index, item) + '"' + item.substring('<el-input'.length, item.length) + ' ' } if (regSele.test(item)) { // 選擇框 item = '<el-select' + ' id="zgwww-select_' + makeId_input(index, item) + '"' + item.substring('<el-select'.length, item.length) + ' ' } if (regDate.test(item)) { // 日期選擇 item = '<el-date-picker' + ' id="zgwww-date_' + makeId_input(index, item) + '"' + item.substring('<el-date-picker'.length, item.length) + ' ' } if (regBtn.test(item)) { // 按鈕 item = '<el-button' + ' id="zgwww-btn_' + makeId_btn(index, item) + '"' + item.substring('<el-button'.length, item.length) + ' ' } } // alert(1) return item }) return resultArr.join('\n') + '\n' + contentStr.slice(end) // return contentStr }
結(jié)果:但是如果使用webpack-loader去處理vue文件里面的html-template。
會導(dǎo)致同一個(gè)頁面使用多個(gè)相同的前端組件-同一個(gè)vue文件。生成出來的ID一樣。
不符合測試要求的一個(gè)頁面每個(gè)操作DOM元素生成不同的ID。
解決方案2:監(jiān)聽window瀏覽器地址欄事件
包括window.history.pushState,window.history.replaceState,window.onpopstate這三個(gè)window事件。
給頁面框架最外層盒子添加id-appmain,這里要用setTimeout宏任務(wù)進(jìn)行遞歸childNodes。因?yàn)閐ocument.getElementById('appmain')取得到的html-object對象是個(gè)異步的對象。
window.history.pushState = patchRouter( window.history.pushState, 'micro_push' );
window.addEventListener('micro_push', turnApp);
function turnApp() { var that = this; setTimeout(function () { var appMain = document.getElementById('appmain'); var a = 0; function forDom(root1) { if (root1) { if (root1.setAttribute) { if (root1.id != 'appmain' && !root1.id) { if (root1._prevClass) { root1.setAttribute('id', root1._prevClass + a); } else if (root1.nodeName) { root1.setAttribute('id', root1.nodeName + a); } else if (root1.localName) { root1.setAttribute('id', root1.localName + a); } else { root1.setAttribute('id', 'Id' + a); } } // console.log('root1', root1); } } a = a + 1; if (root1) { if (root1.childNodes) { if (root1.childNodes.length != 0) { for (var i = 0; i < root1.childNodes.length; i++) { forDom(root1.childNodes[i]); } } } } } forDom(appMain); }, 3000); }
對于一些點(diǎn)擊操作使用v-if重新改變頁面dom結(jié)構(gòu)的。
我們監(jiān)聽window的click事件去重新觸發(fā)turnApp重新給頁面dom結(jié)構(gòu)添加id,對于一些頁面加載的時(shí)候已經(jīng)加載過id的,我們做判斷不重新賦值id。
window.addEventListener('click', turnApp);
if (root1.id != 'appmain' && !root1.id) { }
總結(jié)
本文對測試自動化測試-添加前端頁面DOM元素唯一ID進(jìn)行了解決方案與代碼實(shí)現(xiàn)。也對里面代碼實(shí)現(xiàn)的細(xì)節(jié)點(diǎn)進(jìn)行了詳細(xì)說明。講解部分到此結(jié)束,謝謝閱讀!
更多關(guān)于JavaScript添加頁面DOM ID的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js封裝一個(gè)websocket實(shí)現(xiàn)及使用詳解
這篇文章主要為大家介紹了js封裝一個(gè)websocket實(shí)現(xiàn)示例及使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07微信小程序 監(jiān)聽手勢滑動切換頁面實(shí)例詳解
這篇文章主要介紹了微信小程序 監(jiān)聽手勢滑動切換頁面實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06詳解Three.js?場景中如何徹底刪除模型和性能優(yōu)化
這篇文章主要為大家介紹了詳解Three.js?場景中如何徹底刪除模型和性能優(yōu)化,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04