feat: add in-reader search and restructure documentation

- Add RDEPUBReaderSearchBarView with animated show/hide, keyword
  navigation, and match counting integrated into the reader controller
- Restructure docs: replace scattered design docs with consolidated
  BUSINESS_LOGIC.md and UML_CLASS_DIAGRAMS.md; update ARCHITECTURE.md
- Add SearchTests and FanrenParseTimeTest; enhance LargeBookOnDemandTests
- Add scripts/run_ui_regression.sh and summarize_ui_results.py for
  automated UI test execution and reporting

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-06-05 17:34:50 +08:00
co-authored by Claude Opus 4.7
parent d20196ee34
commit 0e7c0577e3
37 changed files with 4941 additions and 7621 deletions
@@ -0,0 +1,54 @@
import XCTest
final class FanrenParseTimeTest: XCTestCase {
private let app = XCUIApplication()
override func setUpWithError() throws {
continueAfterFailure = false
}
///
func testFanrenParseTime() throws {
let cpuCount = ProcessInfo.processInfo.activeProcessorCount
print("[Fanren] 开始测试 - 设备CPU核心数: \(cpuCount)")
// 使
app.launchAndOpenSampleBook(
bookTitleQuery: "凡人修仙传",
resetsReaderState: true,
concurrency: cpuCount,
clearsCache: true
)
//
app.waitForReader(timeout: 20)
//
_ = app.waitForDemoReaderState(timeout: 30, description: "首屏加载") { state in
state.mode == "bookPageMap" && (state.page ?? 0) >= 1
}
print("[Fanren] 首屏加载完成")
// parseMs > 0
let completed = app.waitForDemoReaderState(timeout: 900, description: "后台解析完成") { state in
(state.parseMs ?? 0) > 0
}
let parseMs = completed.parseMs ?? 0
let concurrency = completed.parseConcurrency ?? 0
print("[Fanren] ---- 测试结果 ----")
print("[Fanren] 后台解析耗时: \(parseMs)ms")
print("[Fanren] 并发数: \(concurrency)")
print("[Fanren] CPU核心数: \(cpuCount)")
//
XCTAssertGreaterThan(parseMs, 0, "parseMs应大于0")
//
app.showReaderChromeIfNeeded()
if app.buttons[IDs.readerBack].waitForExistence(timeout: 5) {
app.buttons[IDs.readerBack].tap()
}
}
}