看过一些Page Object
的封装,做的都不彻底,在这里分享下我的做法
class URLHome(object):
@By.id("delay", ctx="web")
def delay_btn(self): pass
@By.id("schema", ctx="web")
def schema_btn(self): pass
class AndroidLoadingViewPage(object):
@By.id("com.**.android.webview.test:id/host")
def host_input_box(self): pass
@By.id("com.**.android.webview.test:id/path")
def path_input_box(self): pass
class IOSLoadingViewPage(object):
@By.id("loadingViewHostTextField")
def host_input_box(self): pass
@By.id("loadingViewPathField")
def path_input_box(self): pass
class Operates(object):
def __init__(self, platform, wd):
self.platform = platform
self.wd = wd
if platform == "Android":
self.url_home = URLHome()
self.loading_view_page = AndroidLoadingViewPage()
else:
self.url_home = URLHome()
self.loading_view_page = IOSLoadingViewPage()
def set_loading_style(self, host, path=None, style=1):
self.home.set_loading_view().click()
self.loading_view_page.host_input_box().clear().send_keys(host)
这样做的好处是,以后如果页面元素修改了,直接改page
中的元素就好,如果页面操作行为修改了,那就改操作相关的类,从而实现真正的解耦。
具体怎么实现的呢
class By(object):
wd = None
@classmethod
def set_wd(cls, wd):
cls.wd = wd
@classmethod
def id(cls, id, ctx="native"):
def decorator(func):
def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
source = cls.wd.page_source
if id in source:
if ctx == "web":
return cls.wd.find_element_by_id(id)
if "com." in id:
return cls.wd.find_element_by_id(id)
else:
return cls.wd.find_element_by_accessibility_id(id)
else:
time.sleep(2)
return cls.wd.find_element_by_id(id)
except Exception as e:
raise Exception("当前id:" + id + "\n" + str(e))
return wrapper
return decorator
一个简单的装饰器就行了。而且一个@By.id
可以同时识别android native
,ios native
,h5
上的元素,用起来简单明了。