1. 如何封裝page
- 實現(xiàn)通用的page方法,對常用自動化做封裝
- 管理各種driver
- 減少每個page對appium,selenium等庫的依賴
2. 自動化行為封裝
3. BasePage構(gòu)成
- 類的屬性:各個元素的定位
- 類的方法:各個元素的操作方法
4. 優(yōu)點
- 當(dāng)某頁面元素發(fā)生變化,只需要修改頁面中的元素的定位,不需修改測試用例
- 提高代碼重用性,結(jié)構(gòu)更加清晰
- 測試用例發(fā)生變化,只需修改少數(shù)頁面對象
5. BasePage示例
# -*- coding: utf-8 -*-#
# -----------------------
# Name: demo
# Description: 封裝所有頁面的公共方法
# Author: sofi
# Date: 2019-11-05
# -----------------------
import os
import time
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from Common.read_yaml_tool import ReadYamlTool
from Common.path_tool import screenshot_path
from Common.read_config_tool import ReadConfigTool
class BasePage:
def __init__(self, apk_name):
# 初始化webdriver
if apk_name == 'client':
self.readConf = ReadConfigTool('apk_client_info.ini')
self.host = self.readConf.get_option_value('Client_DeviceConf', 'remoteHost')
self.desired_cap = self.readConf.get_conf_dump_dict()['Client_DeviceConf']
elif apk_name == 'launcher':
self.readConf = ReadConfigTool('apk_launcher_info.ini')
self.host = self.readConf.get_option_value('Launcher_DeviceConf', 'remoteHost')
self.desired_cap = self.readConf.get_conf_dump_dict()['Launcher_DeviceConf']
try:
self.driver = webdriver.Remote(self.host, self.desired_cap)
# 隱式等待10秒
self.driver.implicitly_wait(10)
print('當(dāng)前activity:{}'.format(self.driver.current_activity))
self.driver.wait_activity('com.sudiyi.apps.launcher.IndexActivity',10)
# 返回driver
# return self.driver
except Exception as e:
print('[ERROR]-生成DRIVER失敗..原因:{}'.format(e))
'''====================================元素定位函數(shù)===================================='''
def find_element(self, pagename, elename):
'''
查找元素
:param pagename:頁面名稱
:param elename: 元素名稱
:return:
'''
#讀取元素信息
ele_info = self.get_ele_info(pagename,elename)
# print(ele_info[0])
if ele_info[0] == 'By.ID':
BY_KEY = By.ID
elif ele_info[0] == 'By.XPATH':
BY_KEY = By.XPATH
elif ele_info[0] == 'By.NAME':
BY_KEY = By.NAME
elif ele_info[0] == 'By.CLASS_NAME':
BY_KEY = By.CLASS_NAME
elif ele_info[0] == 'By.CSS_SELECTOR':
BY_KEY = By.CSS_SELECTOR
BY_VALUE = ele_info[1]
ele_info = (BY_KEY,BY_VALUE)
try:
# if 'id' in elename:
# ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_id(ele_info))
#
#
# elif 'name' in elename:
# ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_name(ele_info))
#
# elif 'class_name' in elename:
# ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_class_name(ele_info))
#
# elif 'xpath' in elename:
# ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_xpath(ele_info))
#
# elif 'accessbility' in elename:
# ele = WebDriverWait(self.driver, 10).until(lambda x: x.find_element_by_accessibility_id(ele_info))
WebDriverWait(self.driver, 10,1).until(EC.presence_of_element_located(ele_info))
loc = self.driver.find_element(*ele_info)
print(loc)
return loc
except Exception as e:
print('[ERROR]-查找元素{}失敗,具體原因:{}'.format(elename, e))
def check_ele_is_show(self,pagename,elename):
'''
檢查元素是否顯示
:param page: 頁面名稱
:param elename: 元素名稱
:return:
'''
if self.find_element(pagename,elename):
return True
else:
return False
'''====================================元素操作函數(shù)===================================='''
def click_element(self,pagename,elename):
try:
#點擊頁面元素
ele = self.find_element(pagename,elename)
ele.click()
except Exception as e:
print('[ERROR]-點擊頁面元素{}失敗,原因:{}'.format(elename,e))
def click_one_of_elements(self,pagename,elename,index):
'''
點擊元素集中的某一個元素
:param pagename:
:param elename:
:param index: 元素下標(biāo)
:return:
'''
try:
elements = self.find_elements(pagename,elename)
ele = elements[index]
ele.click()
except Exception as e:
print('[ERROR]-點擊頁面元素{}失敗,原因:{}'.format(elename, e))
def long_press_element(self,pagename,elename,duration=1000):
'''
長按元素
:param pagename:
:param elename:
:return:
'''
try:
ele = self.find_element(pagename,elename)
TouchAction(self.driver).long_press(ele,duration).perform()
except Exception as e:
print('[ERROR]-長按頁面元素{}失敗,原因:{}'.format(elename, e))
def clear_element(self,pagename,elename):
try:
#元素清空
ele = self.find_element(pagename,elename)
ele.clear()
except Exception as e:
print('[ERROR]-清空頁面元素{}失敗,原因:{}'.format(elename,e))
def sendkeys(self,pagename,elename,content, clear_first=True, click_first=True):
try:
#輸入元素信息
ele = self.find_element(pagename,elename)
if click_first:
ele.click()
if clear_first:
ele.clear()
ele.send_keys(content)
except Exception as e:
print('[ERROR]-輸入信息失敗,原因:{}'.format(elename,e))
def is_toast_exist(self, text):
'''is toast exist, return True or False
:Agrs:
- driver - 傳driver
- text - 頁面上看到的文本內(nèi)容
- timeout - 最大超時時間,默認(rèn)30s
- poll_frequency - 間隔查詢時間,默認(rèn)0.5s查詢一次
:Usage:
is_toast_exist(driver, "看到的內(nèi)容")
'''
try:
toast_loc = (By.XPATH, ".//*[contains(@text,'%s')]" % text)
WebDriverWait(self.driver, 20, 0.01).until(EC.presence_of_element_located(toast_loc))
return True
except Exception as e:
print(e)
return False
def tap_element(self,pagename,elename_x,elename_y,msec):
'''
:param pagename:
:param elename_x: 橫坐標(biāo)
:param elename_y: 縱坐標(biāo)
:param msec:點擊頻率
:return:
'''
x = self.get_ele_info(pagename,elename_x)
y = self.get_ele_info(pagename, elename_y)
self.driver.tap([x, y], msec)
def get_element_size(self,pagename,elename):
'''
獲取元素的大小
:param pagename:
:param elename:
:return:
'''
element_size = self.find_element(pagename,elename).size
element_width = element_size.get('width')
element_height = element_size.get('height')
return element_width, element_height
def get_window_size(self):
size = self.driver.get_window_size()
width = size['width']
height = size['height']
return width,height
def swipe_screen(self,start_x,start_y,end_x,end_y,msec):
'''
滑動屏幕
:param start_x: 元素左上方的x坐標(biāo)
:param start_y: 元素左上方的y坐標(biāo)
:param end_x: 元素右下方的x坐標(biāo)
:param end_y: 元素右下方的y坐標(biāo)
:param msec: 滑動頻率,毫秒為單位,一般設(shè)置500-1000毫秒比較合適。
'''
self.driver.swipe(start_x,start_y,end_x,end_y,duration=msec)
def swipe_right(self,start_x=0.1,end_x=0.9,duration=2000):
'''向右滑動'''
x = self.get_window_size()[0]
y = self.get_window_size()[1]
x1 = int(x*start_x)
x2 = int(x*end_x)
y1 = int(y * 0.5)
y2 = int(y * 0.5)
self.swipe_screen(x1,y1,x2,y2,duration)
def swipe_left(self,start_x=0.9,end_x=0.1,duration=2000):
'''向左滑動'''
x = self.get_window_size()[0]
y = self.get_window_size()[1]
x1 = int(x * start_x)
x2 = int(x * end_x)
y1 = int(y * 0.5)
y2 = int(y * 0.5)
self.swipe_screen(x1, y1, x2, y2, duration)
def swipe_up(self,start_y=0.9,end_y=0.1,duration=2000):
'''向上滑動'''
x = self.get_window_size()[0]
y = self.get_window_size()[1]
x1 = int(x * 0.5)
x2 = int(x * 0.5)
y1 = int(y * start_y)
y2 = int(y * end_y)
self.swipe_screen(x1, y1, x2, y2, duration)
def swipe_down(self,start_y=0.1,end_y=0.9,duration=2000):
'''向下滑動'''
x = self.get_window_size()[0]
y = self.get_window_size()[1]
x1 = int(x * 0.5)
x2 = int(x * 0.5)
y1 = int(y * start_y)
y2 = int(y * end_y)
self.swipe_screen(x1, y1, x2, y2, duration)
def get_element_location(self,pagename,elename):
'''
獲取元素位置
:param pagename:
:param elename:
:return:
'''
element_pos = self.find_element(pagename,elename).location
element_x = element_pos.get('x')
element_y = element_pos.get('y')
return element_x, element_y
'''====================================模擬按鍵函數(shù)===================================='''
def press_HomeButton(self):
'''按下Home鍵'''
self.driver.press_keycode('3')
def press_BackButton(self):
'''按下返回鍵'''
self.driver.press_keycode('4')
def press_SearchButton(self):
'''按下搜索鍵'''
self.driver.press_keycode('84')
def press_EnterButton(self):
'''按下回車鍵'''
self.driver.press_keycode('66')
def press_DelButton(self):
'''按下刪除鍵'''
self.driver.press_keycode('67')
'''====================================截圖操作函數(shù)===================================='''
def _nowtime(self):
nowtime = time.strftime('%Y%m%d_%H%M%S')
return nowtime
def take_screenshot(self,filename):
'''
:param filename:文件名
:return:
'''
try:
nowtime = self._nowtime()
file_path = os.path.join(screenshot_path,'{}_{}.png'.format(filename,nowtime))
self.driver.get_screenshot_as_file(file_path)
except Exception as e:
print('[ERROR]-截圖失敗,原因:{}'.format(e))
'''====================================頁面操作函數(shù)===================================='''
def switch_to_webview(self):
'''切換到webview'''
for i in range(1):
print(self.driver.contexts)
time.sleep(1)
# WebDriverWait(self.driver,20).until(expected_conditions.visibility_of_element_located((By.ID)))
webview = self.driver.contexts[-1]
# print(webview)
# #切換到webview
self.driver.switch_to.context(webview)
def switch_to_native_view(self):
# 切換到nativeview
self.driver.switch_to.context(self.driver.contexts[0])
def get_ele_info(self,pagename,elename):
'''
讀取元素信息
:param page: 頁面名稱
:param elename: 元素名稱
:return:
'''
read_yaml = ReadYamlTool('ElementsData', pagename)
ele_info = read_yaml.get_yaml_all_items(elename)
return ele_info
def quit_driver(self):
self.driver.quit()
if __name__ == '__main__':
tool = BasePage('launcher')
# print(tool.find_element('HomePage.yaml', 'ele_btn1_id'))
# tool.find_elements('HomePage.yaml', 'ele_btn1_id','ele_btn2_id')
# tool.find_element('HomePage.yaml', 'ele_btn1_id')