下面基本是Robot Framework集成Selenium Library开发包,进行Mobile Web场景下发生的问题,但单独使用PC Selenium也很可能会有同样问题,大家可酌情参考使用。
1. 元素不可见时,不能取到text value
问题:${home_amount} Get Text //*[@id="row_1"]/div[2] #提示不可见,不能获取这个值
解决:通过滚动条拖动,直到该元素可见后,再使用Get Text关键字取值。
备注:元素不可见情况下,也可能通过Get Text关键字取到取值。前端框架/代码不同会有区别,所以建议脚本调试尝试后确定是否需要拖动。
2.元素不可见时,不能用Click() 操作 element locator
问题: Click Element //*[@id="row_1"]/div[2] #提示不可见,not clickable
解决:通过滚动条拖动,直到该元素可见后,再使用Click Element关键字操作元素。
备注:元素不可见情况下,也可能通过Click element关键字操作元素。前端框架/代码不同会有区别,所以建议脚本调试尝试后确定是否需要拖动。
3. 无效的元素状态
问题:log 提示 'invalid element state' to InvalidElementStateError
[debug] [W3C] Matched W3C error code 'invalid element state' to InvalidElementStateError
[debug] [W3C (bc534d44)] Encountered internal error running command: io.appium.uiautomator2.common.exceptions.InvalidElementStateException: xxxx(如Swipe) action cannot be performed
解决:2个思路如下,都可以,可酌情取其中一种。
Solution1:
To make it consistent please follow below steps :
A) create a method - isElementExists to check whether that element exists or not as follows :
public boolean isElementExists(String xpathOfElement){
return driver.findElements(By.xpath(xpathOfElement)).size() > 0;
}
B) Now create a method waitForElement and pass wait time in seconds to it, it is not a hard code wait as it will continuously check whether that element is exist or not and then it will wait for 1 seconds on every iteration of for loop as follows :
public boolean waitForElement(int timeInSeconds, String xpathOfElement){
try{
for(int i=0;i<timeInSeconds;i++){
if(isElementExists(xpathOfElement))
return true;
Thread.sleep(1000);
}
}catch(Exception ex){
ex.printStackTrace();
}
return false;
}
C) So once it return true you can perform the action on that element.
I have used xpath for locating element, you can use whichever you want.
Solution2:
elm_input = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='id' and @type='number'][@maxlength='50']")))
elm_input.clear()
elm_input.send_keys("1234567890")
4. Get Table Cell() 方法,没能取到Table value,提示找不到Locator
举例:
#这个方法OK,可行
${table} Get Table Cell //*[@id="root"]/div/div/div/section[2]/div/div[2]/table[2] 1 1
#这个方法NG,不可行
${table} Get Table Cell //*[@id="root"]/div/div/div/section[2]/div/div[2]/table[2]/tbody/tr[5] 1 1
备注:get table cell 方法中的locator只能是table[],不能是table的下一层,否则提示找不到locator
5. Get WebElements() 方法,取到list,再取长度,便于后续检索/验证多行中内容
举例:
${list} SeleniumLibrary.Get WebElements //*[@class='box-body table-responsive']/table[2]/tbody/tr
${len} Get Length ${list}
6. Page Loading 问题,提示ValueError: Element locator 'xxxx' did not match any elements
问题:页面正在loading时,若使用get text()方法 locator,会提示找不到locator - ValueError: Element locator 'xxxx did not match any elements. 因为loading中,没有任何内容/元素。
解决:所以需要等待loader(Page Loading)结束后,才可以获取元素
7.Robot Framework “全角/半角”空格,如何用脚本表示
问题:全角空格如何用表示
解决:需要用\u3000
举例:
${actual_text} AppiumLibrary.Get Text ${locator}
Should be Equal ${actual_text} または、本人確認書類1種類\u3000+\u3000補完書類1種類の用意
扩展:
1)全角---指一个字符占用两个标准字符位置。 汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是全角字符
2)半角---指一字符占用一个标准的字符位置。 通常的英文字母、数字键、符号键都是半角的,半角的显示内码都是一个字节。
3)上面的例子是一个全角,查表unicode编码可以知道是\u3000
4)Robot Framework中“半角空格”用 ${SPACE} 即可
8. Robot Framework关键字和Locator设计
1)定义格式建议:
#Keywords:
PgLogin_KW_Click_Button_Submit
#Locator:
${PgLogin_Locator_Login_Button}
2)Keyword 从最小操作,到最大,逐渐扩大关键字。这样便于脚本维护,减少工作量。
#最小:
PgLogin_KW_Click_Button_Submit
AppiumLibrary.Click Element ${PgLogin_Locator_Login_Button}
PgLogin_KW_Input_Text_Password
AppiumLibrary.Click Element ${PgLogin_Locator_Password_Text}
#最大:
PgLogin_KW_Login
PgLogin_KW_Click_Button_Submit
PgLogin_KW_Input_Text_Password
9. pyotp 谷歌服务,导致本地时间与服务器时间不一致问题。
问题:不能登陆系统,因为2fa得到错误6位码。这个是google服务,底层调用时间搓。如果电脑和服务器时间不一致(如本地慢几分钟),就会导致请求的结果和服务器的不一致,导致登陆不可。
解决:和IT沟通,使得本地电脑时间和标准日本时间是相同的(也是服务器时间),保证同步一致。
下面是谷歌服务One Time Password使用参考:
import pyotp
Secret = '7LYHYT7X54GNW4ZK'
def get_otp(Secret):
totp = pyotp.TOTP(Secret)
print("Current OTP:", totp.now())
return totp.now()