-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathext_locator.py
More file actions
203 lines (159 loc) · 5.27 KB
/
ext_locator.py
File metadata and controls
203 lines (159 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import logging
from typing import List, Optional, TYPE_CHECKING
from playwright.sync_api import Locator
if TYPE_CHECKING:
from ext_page import ExtPage
logger = logging.getLogger(__name__)
class ExtLocator:
"""扩展定位器类"""
def __init__(self, ext_page: 'ExtPage', locator: Locator, selectors: List[str]):
self.ext_page = ext_page
self.locator = locator
self.selectors = selectors
def ext_locator(self, selector: str) -> 'ExtLocator':
"""创建子定位器
Args:
selector: CSS 选择器
Returns:
ExtLocator 实例
"""
new_locator = self.locator.locator(selector)
new_selectors = self.selectors + [selector]
return ExtLocator(self.ext_page, new_locator, new_selectors)
def exists(self) -> bool:
"""检查元素是否存在
Returns:
元素是否存在
"""
try:
count = self.locator.count()
return count > 0
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] count error: {e}")
return False
def must_inner_text(self) -> str:
"""获取元素的内部文本
Returns:
内部文本
"""
if not self.exists():
return ""
try:
text = self.locator.inner_text()
return text.strip()
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] inner text error: {e}")
return ""
def must_text_content(self) -> str:
"""获取元素的文本内容
Returns:
文本内容
"""
if not self.exists():
return ""
try:
text = self.locator.text_content()
return text.strip()
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] text content error: {e}")
return ""
def must_get_attribute(self, attr: str) -> str:
"""获取元素的属性值
Args:
attr: 属性名
Returns:
属性值
"""
if not self.exists():
return ""
try:
text = self.locator.get_attribute(attr)
if text is None:
return ""
return text.strip()
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] get attribute error: {e}")
return ""
def ext_all(self) -> List['ExtLocator']:
"""获取所有匹配的元素
Returns:
ExtLocator 列表
"""
if not self.exists():
return []
try:
all_locators = self.locator.all()
return [ExtLocator(self.ext_page, loc, self.selectors) for loc in all_locators]
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] all error: {e}")
return []
def must_all_inner_texts(self) -> List[str]:
"""获取所有匹配元素的内部文本
Returns:
内部文本列表
"""
all_locators = self.ext_all()
return [loc.must_inner_text() for loc in all_locators]
def must_all_text_contents(self) -> List[str]:
"""获取所有匹配元素的文本内容
Returns:
文本内容列表
"""
all_locators = self.ext_all()
return [loc.must_text_content() for loc in all_locators]
def must_all_get_attributes(self, attr: str) -> List[str]:
"""获取所有匹配元素的属性值
Args:
attr: 属性名
Returns:
属性值列表
"""
all_locators = self.ext_all()
return [loc.must_get_attribute(attr) for loc in all_locators]
def must_click(self):
"""点击元素"""
self.check_suspend()
try:
self.locator.click()
except Exception as e:
logger.error(f"locator[{self._get_selector_path()}] click error: {e}")
raise
def has_class(self, class_name: str) -> bool:
"""检查元素是否包含指定的 class
Args:
class_name: 类名
Returns:
是否包含该类名
"""
cls = self.must_get_attribute("class")
if not cls:
return False
if " " in cls:
classes = cls.split()
return class_name in classes
return cls == class_name
def get_selectors(self) -> List[str]:
"""获取选择器列表
Returns:
选择器列表
"""
return self.selectors
def suspend(self):
"""暂停定位器操作"""
self.ext_page.suspended = True
def continue_locator(self):
"""继续定位器操作"""
self.ext_page.suspended = False
def check_suspend(self):
"""检查是否需要暂停"""
while self.ext_page.suspended:
self.ext_page.random_wait_middle()
def _get_selector_path(self) -> str:
"""获取选择器路径字符串
Returns:
选择器路径字符串
"""
return " ".join(self.selectors)
def __getattr__(self, name):
"""代理到 Playwright Locator"""
return getattr(self.locator, name)