1 # !/user/bin/env python3
2 # -*- coding:utf-8 -*-
3
4 from selenium.webdriver.remote.webdriver import WebElement
5 from selenium.webdriver.remote.webdriver import WebDriver
6 from selenium.webdriver.common.by import By
7 from selenium.webdriver.support.wait import WebDriverWait
8 from selenium.webdriver.support import expected_conditions as EC
9 from selenium.webdriver.common.keys import Keys
10 from selenium.webdriver.common.action_chains import ActionChains
11 import logging
12 import time
13 import os
14 import datetime
15 import select
16 import random
17
18 from common.dir_config import screenshot_dir
19
20
21 class BasePage:
22 def __init__(self, driver):
23 self.driver = driver
24
25 # 等待元素可见
26 def wait_ele_visible(self, loc, img_desc, timeout=30, frequency=0.5):
27 """
28
29 :param loc: 元素定位
30 :param img_desc: 图片描述名称
31 :param timeout: 时间
32 :param frequency:
33 :return:
34 """
35 start = datetime.datetime.now()
36 try:
37 WebDriverWait(self.driver, timeout, frequency).until(EC.visibility_of_element_located(loc))
38 except:
39 logging.exception("等待元素{}可见,失败!".format(loc))
40 self.save_web_screenshot(img_desc)
41 raise
42 else:
43 end = datetime.datetime.now()
44 logging.info("等待 {} 元素 {} 可见成功。耗时:{}".format(img_desc, loc, end - start))
45
46 # 等待元素存在
47 def wait_ele_exist(self, loc, img_desc, timeout=30, frequency=0.5):
48 start = datetime.datetime.now()
49 try:
50 WebDriverWait(self.driver, timeout, frequency).until(EC.presence_of_element_located(loc))
51 except:
52 logging.exception("等待元素{}可见,失败!".format(loc))
53 self.save_web_screenshot(img_desc)
54 raise
55 else:
56 end = datetime.datetime.now()
57 logging.info("等待 {} 元素 {} 可见成功。耗时:{}".format(img_desc, loc, end - start))
58
59 # 实现网页截图操作
60 def save_web_screenshot(self, img_description):
61 # 页面_功能_时间.png
62 now = time.strftime("%Y-%m-%d %H_%M_%S")
63 filepath = "{}_{}.png".format(img_description, now)
64 try:
65 self.driver.save_screenshot(screenshot_dir + "/" + filepath)
66 logging.info("网页截图成功。图片存储在:{}".format(screenshot_dir + "/" + filepath))
67 except:
68 logging.exception("网页截屏失败!")
69 raise
70
71 #
72 def del_readonly(self, ele):
73 eles = self.driver.find_element(*ele)
74 self.driver.execute_script('arguments[0].removeAttribute(\"readonly\")', eles) # 删除元素d下面 readonly属性
75
76 # 查找元素
77 def get_element(self, loc, img_desc, find_all=False):
78 """
79
80 :param loc: 元组,元素表达式
81 :param img_desc: 截图命名
82 :param find_all: 是否匹配全部
83 :return: WebElement对象。当find_all为true,返回列表
84 """
85 try:
86 if find_all is True:
87 ele = self.driver.find_elements(*loc)
88 else:
89 ele = self.driver.find_element(*loc)
90 except:
91 logging.exception("查找 {} 元素 {} 失败!".format(img_desc, loc))
92 self.save_web_screenshot(img_desc)
93 raise
94 else:
95 return ele
96
97 # 元素可以是通过元素定位查找,也可以是直接是webElement对象。
98 def _deal_element(self, loc, img_desc, timeout=30, frequency=0.5, wait_type="visible"):
99 # 先等待可见,再查找元素
100 if isinstance(loc, tuple): # 元素定位表达式类型
101 if wait_type == "visible": # 等待元素可见
102 self.wait_ele_visible(loc, img_desc, timeout, frequency)
103 else: # 等待元素存在
104 self.wait_ele_exist(loc, img_desc, timeout, frequency)
105 return self.get_element(loc, img_desc)
106 elif isinstance(loc, WebElement): # WebElement对象
107 return loc
108 else:
109 logging.error("参数loc: {} 即不是元组,也不是WebElement对象,无法根据此参数找到元素。".format(loc))
110 raise
111
112 # 点击元素
113 def click_element(self, loc, img_desc, timeout=30, frequency=0.5):
114 ele = self._deal_element(loc, img_desc, timeout, frequency)
115 time.sleep(1)
116 try:
117 ele.click()
118 except:
119 logging.exception("点击 {} 元素 {} 失败!".format(img_desc, loc))
120 self.save_web_screenshot(img_desc)
121 raise
122
123 # 双击元素
124 def double_click_element(self, loc, img_desc, timeout=30, frequency=0.5):
125 ele = self._deal_element(loc, img_desc, timeout, frequency)
126 try:
127 ActionChains(driver=self.driver).double_click(ele).perform()
128 except:
129 logging.exception("双击 {} 元素 {} 失败!".format(img_desc, loc))
130 self.save_web_screenshot(img_desc)
131 raise
132
133 # 清除文本元素
134 def clean_element_text(self, loc, img_desc):
135 ele = self.driver.find_element(*loc)
136 try:
137 ele.send_keys(Keys.CONTROL, "a")
138 ele.send_keys(Keys.DELETE)
139 except:
140 # 日志
141 logging.exception("清除 {} 元素 的文本 {} 失败!".format(img_desc, loc))
142 # 截图
143 self.save_web_screenshot(img_desc)
144 raise
145
146 # 文本输入
147 def input_text(self, loc, value, img_desc, timeout=30, frequency=0.5):
148 ele = self._deal_element(loc, img_desc, timeout, frequency)
149 try:
150 ele.send_keys(value)
151 except:
152 logging.exception("在 {} 元素 {} 上输入文本值:{} 失败!".format(img_desc, loc, value))
153 self.save_web_screenshot(img_desc)
154 raise
155
156 # 下拉菜单
157 def select_element(self, loc, img_desc):
158 # ele = self._deal_element(loc, img_desc, timeout, frequency)
159 ele = self.driver.find_element(*loc)
160 # 操作
161 try:
162 ActionChains(self.driver).move_to_element(ele).click(ele).perform()
163
164 except:
165 logging.exception("滑动到 {} 元素 {} 失败!".format(img_desc, loc))
166 self.save_web_screenshot(img_desc)
167 raise
168
169 def scroll_up_down(self, img_desc):
170 time.sleep(1)
171 # ele = self._deal_element(loc, img_desc, timeout, frequency)
172 # 操作
173 try:
174 # self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight); ")
175 self.driver.execute_script("window.scrollTo(0, 650); ")
176 logging.info("滑动到 {} 元素 成功!".format(img_desc))
177 except:
178 logging.exception("滑动到 {} 元素 失败!".format(img_desc))
179 self.save_web_screenshot(img_desc)
180 raise
181 time.sleep(1)
182
183 def scroll_down(self, img_desc):
184 # ele = self._deal_element(loc, img_desc, timeout, frequency)
185 try:
186 self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight); ")
187 logging.info("滑动到 {} 元素 成功!".format(img_desc))
188 except:
189 # 日志
190 logging.exception("滑动到 {} 元素 失败!".format(img_desc))
191 # 截图
192 self.save_web_screenshot(img_desc)
193 raise # 抛出异常,让用例识别到异常将用例状态为失败。
194 time.sleep(1)
195
196 def scroll_mouse_to_location(self,loc):
197 logging.info("正在准备滚动屏幕到目标元素{}".format(loc))
198 try:
199 self.driver.execute_script("arguments[0].scrollIntoView();", self.driver.find_element(*loc))
200 # logging.info("滚动到目标元素{}成功".format(loc))
201 except:
202 self.save_web_screenshot("滚动到{}截图".format(loc))
203 logging.exception("滚动到目标元素{}失败".format(loc))
204 raise
205
206 # 获取元素的属性值
207 def get_element_attribute(self, loc, attr_name, img_desc, timeout=30, frequency=0.5):
208 ele = self._deal_element(loc, img_desc, timeout, frequency, wait_type="precence")
209 try:
210 attr_value = ele.get_attribute(attr_name)
211 except:
212 logging.exception("获取 {} 元素 {} 的属性 {} 失败!".format(img_desc, loc, attr_name))
213 self.save_web_screenshot(img_desc)
214 raise
215 else:
216 return attr_value
217
218 # 获取元素的文本值。
219 def get_text(self, loc, img_desc, timeout=30, frequency=0.5,wait_type="visible"):
220 ele = self._deal_element(loc, img_desc, timeout, frequency, wait_type)
221 try:
222 text = ele.text
223 return text
224 except:
225 logging.exception("获取 {} 元素 {} 的文本失败!".format(img_desc, loc))
226 self.save_web_screenshot(img_desc)
227 raise
228
229 # 获取隐藏元素的文本值。
230 def get_hide_text(self, loc, img_desc, timeout=30, frequency=0.5):
231 ele = self._deal_element(loc, img_desc, timeout, frequency, wait_type="precence")
232 try:
233 text = ele.get_attribute("textContent")
234 except:
235 logging.exception("获取 {} 元素 {} 的文本失败!".format(img_desc, loc))
236 self.save_web_screenshot(img_desc)
237 raise
238 else:
239 logging.info("获取 {} 元素 {} 的文本值为:{}".format(img_desc, loc, text))
240 return text
241
242 # Alert是否存在
243 def alert_is_present(self, timeout=30, frequency=1):
244 logging.info("正在准备判断 alert 是否出现")
245 try:
246 WebDriverWait(self.driver, timeout, frequency).until(EC.alert_is_present())
247 logging.info("alert 弹框已经出现")
248 except:
249 logging.exception("alert弹框没有出现")
250
251 # Alert处理
252 def deal_alter(self, value="1"): # driver.switch_to.alert.accept()
253 logging.info("正在准备处理alert弹框")
254 try:
255 if value == "1":
256 text = self.driver.switch_to.alert.text
257 self.driver.switch_to.alert.accept()
258 logging.info("alert接受成功")
259 return text
260 else:
261 self.driver.switch_to.alert.dismiss()
262 logging.info("alert 取消接收")
263 except:
264 logging.exception("alert弹框处理失败")
265 raise
266
267 # def get_select_options_list(self,loc):
268 # select = self.driver.find_elements(*loc)
269 # try:
270 # option_list = select.options
271 # print(option_list)
272 # index = random.randint(1,len(option_list)-1)
273 # print("随机数字为",index)
274 # # loc = '//label[text()="地址"]/following-sibling::div[1]/div[1]/div[2]/p[{}]'.format(index)
275 # # return loc
276 # except:
277 # logging.exception("获取随机元素对象失败!")
278 # raise