poium
poium copied to clipboard
execut_script() TypeError:Object of type Element is not json serializable
申明一个元素 class xxPage(Page): xxbtn = Element(xpath="~~~~~") 在测试类中: class TestXX: def test_xxpage(browser): page = xxPage(broeser) page.execut_script("arguments[0].click()", page.xxbtn) 在selenium 中都可以通过 driver.execut_script("arguments[0].click()", xxbtn) 执行,但是poium 报错TypeError:Object of type Element is not json serializable,是什么问题呢?
原因(应该是这样)
page.execute_script("arguments[0].click()", page.xxbtn)
Element类是描述符类,走的是__get__
方法,返回self
(应该是当前实例),并不是elem
(元素),所以报错了
看page_objects.py 130行
class Element(object):
"""
Returns an element object
"""
def __init__(self, timeout=5, describe="undefined", index=0, **kwargs):
self.timeout = timeout
self.index = index
self.desc = describe
if not kwargs:
raise ValueError("Please specify a locator")
if len(kwargs) > 1:
raise ValueError("Please specify only one locator")
self.kwargs = kwargs
self.k, self.v = next(iter(kwargs.items()))
if self.k not in LOCATOR_LIST.keys():
raise FindElementTypesError("Element positioning of type '{}' is not supported.".format(self.k))
def __get__(self, instance, owner):
if instance is None:
return None
Browser.driver = instance.driver
return self
def __set__(self, instance, value):
self.__get__(instance, instance.__class__)
self.send_keys(value)
...
def __get_element(self, by, value):
"""
Judge element positioning way, and returns the element.
"""
# selenium
if by == "id_":
self.__find_element((By.ID, value))
elem = Browser.driver.find_elements_by_id(value)[self.index]
elif by == "name":
self.__find_element((By.NAME, value))
elem = Browser.driver.find_elements_by_name(value)[self.index]
elif by == "class_name":
self.__find_element((By.CLASS_NAME, value))
elem = Browser.driver.find_elements_by_class_name(value)[self.index]
elif by == "tag":
self.__find_element((By.TAG_NAME, value))
elem = Browser.driver.find_elements_by_tag_name(value)[self.index]
elif by == "link_text":
self.__find_element((By.LINK_TEXT, value))
elem = Browser.driver.find_elements_by_link_text(value)[self.index]
elif by == "partial_link_text":
self.__find_element((By.PARTIAL_LINK_TEXT, value))
elem = Browser.driver.find_elements_by_partial_link_text(value)[self.index]
elif by == "xpath":
self.__find_element((By.XPATH, value))
elem = Browser.driver.find_elements_by_xpath(value)[self.index]
elif by == "css":
self.__find_element((By.CSS_SELECTOR, value))
elem = Browser.driver.find_elements_by_css_selector(value)[self.index]
# appium
elif by == "ios_uiautomation":
self.__find_element((MobileBy.IOS_UIAUTOMATION, value))
elem = Browser.driver.find_elements_by_ios_uiautomation(value)[self.index]
elif by == "ios_predicate":
self.__find_element((MobileBy.IOS_PREDICATE, value))
elem = Browser.driver.find_elements_by_ios_predicate(value)[self.index]
elif by == "ios_class_chain":
self.__find_element((MobileBy.IOS_CLASS_CHAIN, value))
elem = Browser.driver.find_elements_by_ios_class_chain(value)[self.index]
elif by == "android_uiautomator":
self.__find_element((MobileBy.ANDROID_UIAUTOMATOR, value))
elem = Browser.driver.find_elements_by_android_uiautomator(value)[self.index]
elif by == "android_viewtag":
self.__find_element((MobileBy.ANDROID_VIEWTAG, value))
elem = Browser.driver.find_elements_by_android_viewtag(value)[self.index]
elif by == "android_data_matcher":
self.__find_element((MobileBy.ANDROID_DATA_MATCHER, value))
elem = Browser.driver.find_elements_by_android_data_matcher(value)[self.index]
elif by == "accessibility_id":
self.__find_element((MobileBy.ACCESSIBILITY_ID, value))
elem = Browser.driver.find_elements_by_accessibility_id(value)[self.index]
elif by == "android_view_matcher":
self.__find_element((MobileBy.ANDROID_VIEW_MATCHER, value))
elem = Browser.driver.find_elements_by_android_view_matcher(value)[self.index]
elif by == "windows_uiautomation":
self.__find_element((MobileBy.WINDOWS_UI_AUTOMATION, value))
elem = Browser.driver.find_elements_by_windows_uiautomation(value)[self.index]
elif by == "image":
self.__find_element((MobileBy.IMAGE, value))
elem = Browser.driver.find_elements_by_image(value)[self.index]
elif by == "custom":
self.__find_element((MobileBy.CUSTOM, value))
elem = Browser.driver.find_elements_by_custom(value)[self.index]
else:
raise FindElementTypesError(
"Please enter the correct targeting elements")
if Browser.show is True:
try:
style_red = 'arguments[0].style.border="2px solid #FF0000"'
style_blue = 'arguments[0].style.border="2px solid #00FF00"'
style_null = 'arguments[0].style.border=""'
for _ in range(2):
Browser.driver.execute_script(style_red, elem)
sleep(0.1)
Browser.driver.execute_script(style_blue, elem)
sleep(0.1)
Browser.driver.execute_script(style_blue, elem)
sleep(0.5)
Browser.driver.execute_script(style_null, elem)
except WebDriverException:
pass
return elem
...
其实__elements()
返回的才是page.execute_script("arguments[0].click()", elems)
应该接受的参数
但虫师大佬把这个方法私有化了,不能在外部调用了(如果有误我道歉)
我的处理方法是
"""
InheritElement.py
"""
from poium.config import Browser
from poium.common import logging
from poium import Element
class InheritElement(Element):
def click_js(self):
Browser.driver.execute_script("arguments[0].click();", self._Element__get_element(self.k, self.v))
logging.info("🖱 click element by click_js: {}".format(self.desc))
我的处理方法是再封装一层类,强制调用私有方法(但这种做法不是很符合规范)