问题
def swipe_find(self, text, num=3):
# 自定义滑动查找
self.set_implicitly(1)
for i in range(num):
try:
element = self.find(AppiumBy.XPATH, f"//*[@text='{text}']")
self.set_implicitly(self.implicitly_wait_time)
return element
except:
logger.info("未找到元素,开始滑动")
self.swipe_up()
if i == num - 1:
self.set_implicitly(self.implicitly_wait_time)
raise NoSuchElementException(f"找了{num}次 ,未找到元素{text}")
报错信息
[2023-01-15 17:42:25] [INFO] [app.py]/[line: 23]/[start] driver == None
FAILED [100%][2023-01-15 17:42:38] [INFO] [contact_info.py]/[line: 17]/[get_name] name: 王丽娟
[2023-01-15 17:42:38] [INFO] [contact_info.py]/[line: 23]/[get_phonenum] phonenum: 13681072840
[2023-01-15 17:42:38] [INFO] [base_page.py]/[line: 32]/[find] 查找元素
[2023-01-15 17:42:38] [INFO] [base_page.py]/[line: 33]/[find] xpath
[2023-01-15 17:42:38] [INFO] [base_page.py]/[line: 34]/[find] //[@text=‘通讯录’]
[2023-01-15 17:42:50] [INFO] [base_page.py]/[line: 32]/[find] 查找元素
[2023-01-15 17:42:50] [INFO] [base_page.py]/[line: 33]/[find] xpath
[2023-01-15 17:42:50] [INFO] [base_page.py]/[line: 34]/[find] //[@text=‘添加成员’]
[2023-01-15 17:42:53] [INFO] [base_page.py]/[line: 93]/[swipe_find] 未找到元素,开始滑动
[2023-01-15 17:43:03] [INFO] [base_page.py]/[line: 75]/[swipe_up] 当前屏幕的宽:1170, 高:1872
[2023-01-15 17:43:03] [INFO] [base_page.py]/[line: 81]/[swipe_up] 开始滑动:585.0,1497.6000000000001 to 585.0,561.6
test_contacts.py:40 (TestContact.test_addcontact1)
self = <prac_po1.page.address_list_page.AddressListPage object at 0x10be95e20>
text = ‘添加成员’, num = 3
def swipe_find(self, text, num=3):
# 自定义滑动查找
self.set_implicitly(1)
for i in range(num):
try:
element = self.find(AppiumBy.XPATH, f"//*[@text='{text}']")
…/base/base_page.py:89:
self = <prac_po1.page.address_list_page.AddressListPage object at 0x10be95e20>
by = ‘xpath’, locator = “//*[@text=‘添加成员’]”
def find(self, by, locator):
"""
查找元素的方法
:param by:
:param locator:
:return:
"""
logger.info("查找元素 ")
logger.info(by)
logger.info(locator)
return self.driver.find_element(by, locator)
…/base/base_page.py:35:
self = <appium.webdriver.webdriver.WebDriver (session=“ee64d343-df9c-421c-bad0-d3239253e4b0”)>
by = ‘xpath’, value = “//*[@text=‘添加成员’]”
def find_element(self, by: str = AppiumBy.ID, value: Union[str, Dict] = None) -> MobileWebElement:
"""
Find an element given a AppiumBy strategy and locator
Args:
by: The strategy
value: The locator
Usage:
driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='accessibility_id')
Returns:
`appium.webdriver.webelement.WebElement`: The found element
"""
# TODO: If we need, we should enable below converter for Web context
# if by == By.ID:
# by = By.CSS_SELECTOR
# value = '[id="%s"]' % value
# elif by == By.TAG_NAME:
# by = By.CSS_SELECTOR
# elif by == By.CLASS_NAME:
# by = By.CSS_SELECTOR
# value = ".%s" % value
# elif by == By.NAME:
# by = By.CSS_SELECTOR
# value = '[name="%s"]' % value
return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/webdriver.py:353:
self = <appium.webdriver.webdriver.WebDriver (session=“ee64d343-df9c-421c-bad0-d3239253e4b0”)>
driver_command = ‘findElement’
params = {‘using’: ‘xpath’, ‘value’: “//*[@text=‘添加成员’]”}
def execute(self, driver_command: str, params: dict = None) -> dict:
"""
Sends a command to be executed by a command.CommandExecutor.
:Args:
- driver_command: The name of the command to execute as a string.
- params: A dictionary of named parameters to send with the command.
:Returns:
The command's JSON response loaded into a dictionary object.
"""
if self.session_id:
if not params:
params = {'sessionId': self.session_id}
elif 'sessionId' not in params:
params['sessionId'] = self.session_id
params = self._wrap_value(params)
response = self.command_executor.execute(driver_command, params)
if response:
self.error_handler.check_response(response)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:430:
self = <appium.webdriver.errorhandler.MobileErrorHandler object at 0x10bdebfa0>
response = {‘status’: 404, ‘value’: ‘{“value”:{“error”:“no such element”,“message”:"An element could not be located on the page u…s/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)\n at "}}’}
def check_response(self, response: Dict) -> None:
try:
super().check_response(response)
except WebDriverException as wde:
if wde.msg == 'No such context found.':
raise NoSuchContextException(wde.msg, wde.screen, wde.stacktrace) from wde
raise wde
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:30:
self = <appium.webdriver.errorhandler.MobileErrorHandler object at 0x10bdebfa0>
response = {‘status’: 404, ‘value’: ‘{“value”:{“error”:“no such element”,“message”:"An element could not be located on the page u…s/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)\n at "}}’}
def check_response(self, response: Dict) -> None:
try:
super().check_response(response)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:26:
self = <appium.webdriver.errorhandler.MobileErrorHandler object at 0x10bdebfa0>
response = {‘status’: 404, ‘value’: ‘{“value”:{“error”:“no such element”,“message”:"An element could not be located on the page u…s/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)\n at "}}’}
def check_response(self, response: Dict[str, Any]) -> None:
"""
Checks that a JSON response from the WebDriver does not have an error.
:Args:
- response - The JSON response from the WebDriver server as a dictionary
object.
:Raises: If the response contains an error message.
"""
status = response.get('status', None)
if not status or status == ErrorCode.SUCCESS:
return
value = None
message = response.get("message", "")
screen: str = response.get("screen", "")
stacktrace = None
if isinstance(status, int):
value_json = response.get('value', None)
if value_json and isinstance(value_json, str):
import json
try:
value = json.loads(value_json)
if len(value.keys()) == 1:
value = value['value']
status = value.get('error', None)
if not status:
status = value.get("status", ErrorCode.UNKNOWN_ERROR)
message = value.get("value") or value.get("message")
if not isinstance(message, str):
value = message
message = message.get('message')
else:
message = value.get('message', None)
except ValueError:
pass
exception_class: Type[WebDriverException]
if status in ErrorCode.NO_SUCH_ELEMENT:
exception_class = NoSuchElementException
elif status in ErrorCode.NO_SUCH_FRAME:
exception_class = NoSuchFrameException
elif status in ErrorCode.NO_SUCH_SHADOW_ROOT:
exception_class = NoSuchShadowRootException
elif status in ErrorCode.NO_SUCH_WINDOW:
exception_class = NoSuchWindowException
elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
exception_class = StaleElementReferenceException
elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
exception_class = ElementNotVisibleException
elif status in ErrorCode.INVALID_ELEMENT_STATE:
exception_class = InvalidElementStateException
elif status in ErrorCode.INVALID_SELECTOR \
or status in ErrorCode.INVALID_XPATH_SELECTOR \
or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
exception_class = InvalidSelectorException
elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
exception_class = ElementNotSelectableException
elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE:
exception_class = ElementNotInteractableException
elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
exception_class = InvalidCookieDomainException
elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
exception_class = UnableToSetCookieException
elif status in ErrorCode.TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.SCRIPT_TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.UNKNOWN_ERROR:
exception_class = WebDriverException
elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
exception_class = UnexpectedAlertPresentException
elif status in ErrorCode.NO_ALERT_OPEN:
exception_class = NoAlertPresentException
elif status in ErrorCode.IME_NOT_AVAILABLE:
exception_class = ImeNotAvailableException
elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
exception_class = ImeActivationFailedException
elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
exception_class = MoveTargetOutOfBoundsException
elif status in ErrorCode.JAVASCRIPT_ERROR:
exception_class = JavascriptException
elif status in ErrorCode.SESSION_NOT_CREATED:
exception_class = SessionNotCreatedException
elif status in ErrorCode.INVALID_ARGUMENT:
exception_class = InvalidArgumentException
elif status in ErrorCode.NO_SUCH_COOKIE:
exception_class = NoSuchCookieException
elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN:
exception_class = ScreenshotException
elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED:
exception_class = ElementClickInterceptedException
elif status in ErrorCode.INSECURE_CERTIFICATE:
exception_class = InsecureCertificateException
elif status in ErrorCode.INVALID_COORDINATES:
exception_class = InvalidCoordinatesException
elif status in ErrorCode.INVALID_SESSION_ID:
exception_class = InvalidSessionIdException
elif status in ErrorCode.UNKNOWN_METHOD:
exception_class = UnknownMethodException
else:
exception_class = WebDriverException
if not value:
value = response['value']
if isinstance(value, str):
raise exception_class(value)
if message == "" and 'message' in value:
message = value['message']
screen = None # type: ignore[assignment]
if 'screen' in value:
screen = value['screen']
stacktrace = None
st_value = value.get('stackTrace') or value.get('stacktrace')
if st_value:
if isinstance(st_value, str):
stacktrace = st_value.split('\n')
else:
stacktrace = []
try:
for frame in st_value:
line = self._value_or_default(frame, 'lineNumber', '')
file = self._value_or_default(frame, 'fileName', '<anonymous>')
if line:
file = "%s:%s" % (file, line)
meth = self._value_or_default(frame, 'methodName', '<anonymous>')
if 'className' in frame:
meth = "%s.%s" % (frame['className'], meth)
msg = " at %s (%s)"
msg = msg % (meth, file)
stacktrace.append(msg)
except TypeError:
pass
if exception_class == UnexpectedAlertPresentException:
alert_text = None
if 'data' in value:
alert_text = value['data'].get('text')
elif 'alert' in value:
alert_text = value['alert'].get('text')
raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here
raise exception_class(message, screen, stacktrace)
E selenium.common.exceptions.NoSuchElementException: Message: An element could not be located on the page using the given search parameters.
E Stacktrace:
E NoSuchElementError: An element could not be located on the page using the given search parameters.
E at AndroidDriver.callee$0$0$ (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:69:13)
E at tryCatch (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
E at GeneratorFunctionPrototype.invoke [as _invoke] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
E at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js21)
E at GeneratorFunctionPrototype.invoke (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
E at
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py:247: NoSuchElementException
During handling of the above exception, another exception occurred:
self = <prac_po1.testcases.test_contacts.TestContact object at 0x10bdaf640>
def test_addcontact1(self):
"""
添加联系人
:return:
"""
# mock 联系人姓名和电话号码
name = ContactInfo.get_name()
phonenum = ContactInfo.get_phonenum()
result = self.main.goto_addresslist(). \
goto_addmember_page().click_addmember_menual(). \
edit_member(name, phonenum).get_text()
test_contacts.py:50:
…/page/address_list_page.py:17: in goto_addmember_page
self.swipe_find(“添加成员”).click()
…/base/base_page.py:94: in swipe_find
self.swipe_up()
…/base/base_page.py:82: in swipe_up
self.driver.swipe(start_x, start_y, end_x, end_y, duration)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/extensions/action_helpers.py:164: in swipe
actions.perform()
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/common/action_chains.py:79: in perform
self.w3c_actions.perform()
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/common/actions/action_builder.py:88: in perform
self.driver.execute(Command.W3C_ACTIONS, enc)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:430: in execute
self.error_handler.check_response(response)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:30: in check_response
raise wde
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:26: in check_response
super().check_response(response)
self = <appium.webdriver.errorhandler.MobileErrorHandler object at 0x10bdebfa0>
response = {‘status’: 404, ‘value’: ‘{“value”:{“error”:“unknown method”,“message”:“Method has not yet been implemented”,“stacktra…rator/runtime.js:136:37)\n at \n at process._tickCallback (internal/process/next_tick.js:188:7)”}}’}
def check_response(self, response: Dict[str, Any]) -> None:
"""
Checks that a JSON response from the WebDriver does not have an error.
:Args:
- response - The JSON response from the WebDriver server as a dictionary
object.
:Raises: If the response contains an error message.
"""
status = response.get('status', None)
if not status or status == ErrorCode.SUCCESS:
return
value = None
message = response.get("message", "")
screen: str = response.get("screen", "")
stacktrace = None
if isinstance(status, int):
value_json = response.get('value', None)
if value_json and isinstance(value_json, str):
import json
try:
value = json.loads(value_json)
if len(value.keys()) == 1:
value = value['value']
status = value.get('error', None)
if not status:
status = value.get("status", ErrorCode.UNKNOWN_ERROR)
message = value.get("value") or value.get("message")
if not isinstance(message, str):
value = message
message = message.get('message')
else:
message = value.get('message', None)
except ValueError:
pass
exception_class: Type[WebDriverException]
if status in ErrorCode.NO_SUCH_ELEMENT:
exception_class = NoSuchElementException
elif status in ErrorCode.NO_SUCH_FRAME:
exception_class = NoSuchFrameException
elif status in ErrorCode.NO_SUCH_SHADOW_ROOT:
exception_class = NoSuchShadowRootException
elif status in ErrorCode.NO_SUCH_WINDOW:
exception_class = NoSuchWindowException
elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
exception_class = StaleElementReferenceException
elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
exception_class = ElementNotVisibleException
elif status in ErrorCode.INVALID_ELEMENT_STATE:
exception_class = InvalidElementStateException
elif status in ErrorCode.INVALID_SELECTOR \
or status in ErrorCode.INVALID_XPATH_SELECTOR \
or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
exception_class = InvalidSelectorException
elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
exception_class = ElementNotSelectableException
elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE:
exception_class = ElementNotInteractableException
elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
exception_class = InvalidCookieDomainException
elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
exception_class = UnableToSetCookieException
elif status in ErrorCode.TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.SCRIPT_TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.UNKNOWN_ERROR:
exception_class = WebDriverException
elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
exception_class = UnexpectedAlertPresentException
elif status in ErrorCode.NO_ALERT_OPEN:
exception_class = NoAlertPresentException
elif status in ErrorCode.IME_NOT_AVAILABLE:
exception_class = ImeNotAvailableException
elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
exception_class = ImeActivationFailedException
elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
exception_class = MoveTargetOutOfBoundsException
elif status in ErrorCode.JAVASCRIPT_ERROR:
exception_class = JavascriptException
elif status in ErrorCode.SESSION_NOT_CREATED:
exception_class = SessionNotCreatedException
elif status in ErrorCode.INVALID_ARGUMENT:
exception_class = InvalidArgumentException
elif status in ErrorCode.NO_SUCH_COOKIE:
exception_class = NoSuchCookieException
elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN:
exception_class = ScreenshotException
elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED:
exception_class = ElementClickInterceptedException
elif status in ErrorCode.INSECURE_CERTIFICATE:
exception_class = InsecureCertificateException
elif status in ErrorCode.INVALID_COORDINATES:
exception_class = InvalidCoordinatesException
elif status in ErrorCode.INVALID_SESSION_ID:
exception_class = InvalidSessionIdException
elif status in ErrorCode.UNKNOWN_METHOD:
exception_class = UnknownMethodException
else:
exception_class = WebDriverException
if not value:
value = response['value']
if isinstance(value, str):
raise exception_class(value)
if message == "" and 'message' in value:
message = value['message']
screen = None # type: ignore[assignment]
if 'screen' in value:
screen = value['screen']
stacktrace = None
st_value = value.get('stackTrace') or value.get('stacktrace')
if st_value:
if isinstance(st_value, str):
stacktrace = st_value.split('\n')
else:
stacktrace = []
try:
for frame in st_value:
line = self._value_or_default(frame, 'lineNumber', '')
file = self._value_or_default(frame, 'fileName', '<anonymous>')
if line:
file = "%s:%s" % (file, line)
meth = self._value_or_default(frame, 'methodName', '<anonymous>')
if 'className' in frame:
meth = "%s.%s" % (frame['className'], meth)
msg = " at %s (%s)"
msg = msg % (meth, file)
stacktrace.append(msg)
except TypeError:
pass
if exception_class == UnexpectedAlertPresentException:
alert_text = None
if 'data' in value:
alert_text = value['data'].get('text')
elif 'alert' in value:
alert_text = value['alert'].get('text')
raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here
raise exception_class(message, screen, stacktrace)
E selenium.common.exceptions.WebDriverException: Message: Method has not yet been implemented
E Stacktrace:
E NotYetImplementedError: Method has not yet been implemented
E at AndroidDriver.executeCommand$ (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/lib/basedriver/driver.js:249:13)
E at tryCatch (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
E at GeneratorFunctionPrototype.invoke [as _invoke] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
E at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js21)
E at invoke (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
E at enqueueResult (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:185:17)
E at new Promise ()
E at new F (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/core-js/library/modules/$.export.js:30:36)
E at AsyncIterator.enqueue (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:184:12)
E at AsyncIterator.prototype.(anonymous function) [as next] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js21)
E at Object.runtime.async (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:209:12)
E at AndroidDriver.executeCommand (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-base-driver/build/lib/basedriver/driver.js:271:34)
E at AppiumDriver.executeCommand$ (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/lib/appium.js:377:50)
E at tryCatch (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
E at GeneratorFunctionPrototype.invoke [as _invoke] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
E at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js21)
E at GeneratorFunctionPrototype.invoke (/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
E at
E at process._tickCallback (internal/process/next_tick.js:188:7)
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py:247: WebDriverException
环境
==========设备信息==========
UUID:e89e3e30b7e55aa680d0a1941884a235
模拟器版本:1.9.58
系统版本:macOS 10.14.6(18G9323)
机器型号:MacBookPro15,2
Appium v1.8.1