1
1
mirror of https://github.com/KenanZhu/AutoLibrary.git synced 2026-06-18 15:33:03 +08:00

refactor(pages): 拆分 _dialogs 为独立组件文件,解耦 Service 构造函数,消除 PageObject 重复逻辑

- 将 _dialogs.py 拆分为 pages/components/ 下的独立文件,Overlay 基类同步移入
- CaptchaHandler / RecordChecker 构造函数不再持有 PageObject,改为方法参数注入
- LoginPage.login() 直接接收 auto_captcha 参数,简化 captcha_solver 调用链
- SeatMapOverlay.selectSeat 引入两层查找:先按 ID 直查,失败后遍历匹配
- 移除 ReserveView 中与 Dialog/Overlay 重复的方法(selectSeat、getAvailableTimeOptions)
- AutoLibPages 拆分 __initPagesServices / __initPagesFlows
- 修复 RecordsView.MORE_BTN 选择器被错误 snake_case 化(more_btn → moreBtn)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 13:41:55 +08:00
parent 2226e8ac90
commit a6bc103c73
19 changed files with 608 additions and 580 deletions
+2 -67
View File
@@ -15,12 +15,11 @@ from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.common.exceptions import (
ElementNotInteractableException,
NoSuchElementException,
StaleElementReferenceException,
TimeoutException,
)
from pages._dialogs import SeatMapOverlay, ReserveResultDialog
from pages.components.SeatMapOverlay import SeatMapOverlay
from pages.components.ReserveResultDialog import ReserveResultDialog
class ReserveView:
@@ -40,17 +39,8 @@ class ReserveView:
FIND_ROOM_BTN = (By.ID, "findRoom")
ROOM_BTN_FMT = "room_{room}"
SEAT_LAYOUT = (By.ID, "seatLayout")
SEAT_ITEMS = (By.CSS_SELECTOR, "li[id^='seat_']")
RESERVE_BTN = (By.ID, "reserveBtn")
START_TIME_OPTS = (By.CSS_SELECTOR, "#startTime ul li a")
END_TIME_OPTS = (By.CSS_SELECTOR, "#endTime ul li a")
RESULT_DIALOG = (By.CLASS_NAME, "layoutSeat")
RESULT_TITLE = (By.CSS_SELECTOR, ".layoutSeat dt")
RESULT_DETAIL = (By.CSS_SELECTOR, ".layoutSeat dd")
FLOOR_MAP = {"2": "二层", "3": "三层", "4": "四层", "5": "五层"}
ROOM_MAP = {
"1": "二层内环", "2": "二层西区", "3": "三层内环", "4": "三层外环",
@@ -138,41 +128,6 @@ class ReserveView:
return SeatMapOverlay(self._driver)
def selectSeat(
self,
seat_id: str,
) -> str | None:
try:
WebDriverWait(self._driver, 2).until(
EC.presence_of_element_located(self.SEAT_LAYOUT)
)
WebDriverWait(self._driver, 2).until(
EC.presence_of_all_elements_located(self.SEAT_ITEMS)
)
except TimeoutException:
return None
except Exception:
return None
try:
all_seats = self._driver.find_elements(*self.SEAT_ITEMS)
seat_id_upper = seat_id.lstrip('0').upper()
for seat in all_seats:
if not seat_id_upper == seat.text.lstrip('0'):
continue
seat_link = seat.find_element(By.TAG_NAME, "a")
WebDriverWait(self._driver, 2).until(
EC.element_to_be_clickable(seat_link)
)
seat_link.click()
return seat_link.get_attribute("title")
return None
except (NoSuchElementException, TimeoutException,
StaleElementReferenceException, ElementNotInteractableException):
return None
except Exception:
return None
def submitReserve(
self,
) -> bool:
@@ -193,26 +148,6 @@ class ReserveView:
return ReserveResultDialog(self._driver)
def getAvailableTimeOptions(
self,
time_id: str,
) -> list:
try:
WebDriverWait(self._driver, 2).until(
EC.presence_of_all_elements_located(
(By.CSS_SELECTOR, f"#{time_id} ul li a")
)
)
except TimeoutException:
return []
except Exception:
return []
return self._driver.find_elements(
By.CSS_SELECTOR,
f"#{time_id} ul li a",
)
def refresh(
self,
) -> None: