一、遇到的問題
在做移動端的UI自動化測試時,經常會遇到上圖所示的搜尋框,這裡有個麻煩就是搜尋框沒有“搜尋”按鈕,UI自動化測試時不能確認搜尋。
要解決這個問題,我們可以通過 driver.press_keycode('66') 方法模擬鍵盤迴車,具體的使用方法請參考:
但是這種方法只能適用於Android環境,iOS環境不能使用。由於我是在Webview環境做UI自動化測試,無論是Android環境,iOS環境都可以使用js方法解決疑難雜症,操作時只需要通過python傳送js方法就可以。
二、操作方法
1、找到搜尋框元素
通過document物件找到搜尋框的元素位置,如上圖搜尋框:
document.getElementsByTagName('input')[0];
2、js模擬回車事件的方法
下面是實現回車事件的JavaScript方法:
function inputeven() {
let el = document.getElementsByTagName('input')[0];
let evtType = 'keyup';
let keyCode = 13;
let evtObj;
if (document.createEvent) {
if (window.KeyEvent) {//firefox 瀏覽器下模擬事件
evtObj = document.createEvent('KeyEvents');
evtObj.initKeyEvent(evtType, true, true, window, true, false, false, false, keyCode, 0)
} else {//chrome 瀏覽器下模擬事件
evtObj = document.createEvent('UIEvents');
evtObj.initUIEvent(evtType, true, true, window, 1);
delete evtObj.keyCode;
if (typeof evtObj.keyCode === 'undefined') {//為了模擬keycode
Object.defineProperty(evtObj, 'keyCode', {
value: keyCode
})
} else {
evtObj.key = String.fromCharCode(keyCode)
}
if (typeof evtObj.ctrlKey === 'undefined') {//為了模擬ctrl鍵
Object.defineProperty(evtObj, 'ctrlKey', {
value: true
})
} else {
evtObj.ctrlKey = true
}
}
el.dispatchEvent(evtObj)
} else if (document.createEventObject) {//IE 瀏覽器下模擬事件
evtObj = document.createEventObject();
evtObj.keyCode = keyCode;
el.fireEvent('on' + evtType, evtObj)
}
}
inputeven();
在進行UI自動化時,使用selenium的 execute_script() 方法傳送js指令時,需要是字串格式的,因此需要將上面的方法壓縮:
js = function inputeven(){let el=document.getElementsByTagName('input')[0];let evtType='keyup';let keyCode=13;let evtObj;if(document.createEvent){if(window.KeyEvent){evtObj=document.createEvent('KeyEvents');evtObj.initKeyEvent(evtType,true,true,window,true,false,false,false,keyCode,0)}else{evtObj=document.createEvent('UIEvents');evtObj.initUIEvent(evtType,true,true,window,1);delete evtObj.keyCode;if(typeof evtObj.keyCode==='undefined'){Object.defineProperty(evtObj,'keyCode',{value:keyCode})}else{evtObj.key=String.fromCharCode(keyCode)}if(typeof evtObj.ctrlKey==='undefined'){Object.defineProperty(evtObj,'ctrlKey',{value:true})}else{evtObj.ctrlKey=true}}el.dispatchEvent(evtObj)}else if(document.createEventObject){evtObj=document.createEventObject();evtObj.keyCode=keyCode;el.fireEvent('on'+evtType,evtObj)}}inputeven();
3、要適應pytest自動化測試框架,上面的方法需要進行如下封裝:
def js_keyboard_enter(self, element_located):
"""
搜尋框輸入後,通過js方法確認搜尋(用於搜尋框沒有搜尋確認按鈕)
:param element_located:已定位到的搜尋框元素document物件
:return:
"""
# js方法實現搜尋確認事件
js = "function inputeven(){let el=%slet evtType='keyup';" \
"let keyCode=13;let evtObj;if(document.createEvent){if(window.KeyEvent){evtObj=document.createEvent" \
"('KeyEvents');evtObj.initKeyEvent(evtType,true,true,window,true,false,false,false,keyCode,0)}" \
"else{evtObj=document.createEvent('UIEvents');evtObj.initUIEvent(evtType,true,true,window,1);" \
"delete evtObj.keyCode;if(typeof evtObj.keyCode==='undefined'){Object.defineProperty(evtObj,'keyCode'," \
"{value:keyCode})}else{evtObj.key=String.fromCharCode(keyCode)}if(typeof evtObj.ctrlKey==='undefined')" \
"{Object.defineProperty(evtObj,'ctrlKey',{value:true})}else{evtObj.ctrlKey=true}}el.dispatchEvent(evtObj)}" \
"else if(document.createEventObject){evtObj=document.createEventObject();evtObj.keyCode=keyCode;el." \
"fireEvent('on'+evtType,evtObj)}}inputeven();" % (element_located)
# 執行搜尋確認的js方法
self.driver.execute_script(js)
這裡我將操作的搜尋框document物件作為入參,在使用該方法時只需要傳入操作的搜尋框元素document物件即可。
4、使用舉例
在前面的第1步中,我們已經通過document物件找到操作的搜尋框,search_document_loc = "document.getElementsByTagName('input')[0];"
呼叫js_keyboard_enter()方法,執行回車事件,確認搜尋:
@allure.step("搜尋框輸入後,通過js方法確認")
def search_enter(self):
self.js_keyboard_enter(search_document_loc)