| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import time
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
- from selenium.webdriver.common.keys import Keys
- class BasePage:
- def __init__(self, driver):
- self.driver = driver
- self.wait = WebDriverWait(driver, 20) # 增加默认等待时间
- self.short_wait = WebDriverWait(driver, 5) # 添加短等待
- self.long_wait = WebDriverWait(driver, 30) # 添加长等待
-
- def find_element(self, by, locator, timeout=None, check_visibility=True):
- """等待并查找单个元素"""
- wait = WebDriverWait(self.driver, timeout) if timeout else self.wait
- try:
- if check_visibility:
- return wait.until(EC.visibility_of_element_located((by, locator)))
- else:
- return wait.until(EC.presence_of_element_located((by, locator)))
- except:
- # 如果找不到元素,打印页面状态
- print("页面状态:", self.get_page_state())
- raise
-
- def find_element_directly(self, by, locator):
- """直接查找元素,不等待"""
- return self.driver.find_element(by, locator)
-
- def find_clickable_element(self, by, locator, timeout=None):
- """等待并查找可点击元素"""
- wait = WebDriverWait(self.driver, timeout) if timeout else self.wait
- try:
- return wait.until(EC.element_to_be_clickable((by, locator)))
- except:
- # 如果找不到元素,打印页面状态
- print("页面状态:", self.get_page_state())
- raise
-
- def get_page_state(self):
- """获取页面状态信息"""
- try:
- return {
- 'url': self.driver.current_url,
- 'ready_state': self.driver.execute_script('return document.readyState'),
- 'is_iframe': len(self.driver.find_elements(by='tag name', value='iframe')) > 0,
- 'page_source_length': len(self.driver.page_source)
- }
- except Exception as e:
- return f"获取页面状态失败: {str(e)}"
-
- def safe_click(self, element):
- """安全点击元素,如果普通点击失败则使用JS点击"""
- try:
- self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
- time.sleep(1)
- element.click()
- except Exception as e:
- print(f"常规点击失败,尝试JS点击: {str(e)}")
- self.driver.execute_script("arguments[0].click();", element)
-
- def safe_send_keys(self, element, text):
- """
- 安全输入文本,支持emoji
- 使用分段输入的方式,确保emoji字符能够正确输入
- """
- try:
- element.clear()
- # 先点击确保焦点
- element.click()
- time.sleep(0.5)
-
- # 使用clipboard.js来处理复制粘贴
- self.driver.execute_script("""
- if (!window.clipboardJS) {
- window.clipboardJS = true;
- var script = document.createElement('script');
- script.src = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js';
- document.head.appendChild(script);
- }
- """)
- time.sleep(1) # 等待脚本加载
-
- # 创建临时输入区域并复制文本
- self.driver.execute_script("""
- // 创建临时textarea
- var textarea = document.createElement('textarea');
- textarea.value = arguments[0];
- textarea.style.position = 'fixed';
- textarea.style.opacity = '0';
- document.body.appendChild(textarea);
- // 选择文本
- textarea.select();
- // 复制
- document.execCommand('copy');
- // 清理
- document.body.removeChild(textarea);
- """, text)
-
- # 模拟粘贴操作
- element.send_keys(Keys.CONTROL + 'v') # Windows
- time.sleep(0.5)
-
- except Exception as e:
- print(f"复杂输入方式失败,尝试直接输入: {str(e)}")
- try:
- # 如果复杂方式失败,回退到直接输入
- element.clear()
- element.send_keys(text)
- except Exception as e2:
- print(f"所有输入方式都失败: {str(e2)}")
- raise
- def __init__(self, driver):
- self.driver = driver
- self.wait = WebDriverWait(driver, 10)
-
- def find_element(self, by, locator):
- """等待并查找单个元素"""
- return self.wait.until(EC.presence_of_element_located((by, locator)))
-
- def find_element_directly(self, by, locator):
- """等待并查找多个元素"""
- return self.driver.find_element(by, locator)
-
- def find_clickable_element(self, by, locator):
- """等待并查找可点击元素"""
- return self.wait.until(EC.element_to_be_clickable((by, locator)))
-
- def safe_click(self, element):
- """安全点击元素,如果普通点击失败则使用JS点击"""
- try:
- self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
- time.sleep(1)
- element.click()
- except Exception as e:
- print(f"常规点击失败,尝试JS点击: {str(e)}")
- self.driver.execute_script("arguments[0].click();", element)
-
- def safe_send_keys(self, element, text):
- """
- 安全输入文本,支持emoji
- 使用分段输入的方式,确保emoji字符能够正确输入
- """
- try:
- element.clear()
- # 先点击确保焦点
- element.click()
- time.sleep(0.5)
-
- # 使用clipboard.js来处理复制粘贴
- self.driver.execute_script("""
- if (!window.clipboardJS) {
- window.clipboardJS = true;
- var script = document.createElement('script');
- script.src = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js';
- document.head.appendChild(script);
- }
- """)
- time.sleep(1) # 等待脚本加载
-
- # 创建临时输入区域并复制文本
- self.driver.execute_script("""
- // 创建临时textarea
- var textarea = document.createElement('textarea');
- textarea.value = arguments[0];
- textarea.style.position = 'fixed';
- textarea.style.opacity = '0';
- document.body.appendChild(textarea);
- // 选择文本
- textarea.select();
- // 复制
- document.execCommand('copy');
- // 清理
- document.body.removeChild(textarea);
- """, text)
-
- # 模拟粘贴操作
- element.send_keys(Keys.CONTROL + 'v') # Windows
- time.sleep(0.5)
-
- except Exception as e:
- print(f"复杂输入方式失败,尝试直接输入: {str(e)}")
- try:
- # 如果复杂方式失败,回退到直接输入
- element.clear()
- element.send_keys(text)
- except Exception as e2:
- print(f"所有输入方式都失败: {str(e2)}")
- raise
|