import XCTest final class ConfigurableWindowTests: XCTestCase { private let app = XCUIApplication() private let largeBookQuery = "凡人修仙传" override func setUpWithError() throws { continueAfterFailure = false } func testWindowSize5PreloadsMoreChapters() throws { app.launchAndOpenSampleBook(bookTitleQuery: largeBookQuery, resetsReaderState: true, windowSize: 5) app.waitForReader(timeout: 20) let state = app.waitForDemoReaderState(timeout: 15, description: "window=5 预加载更多章节") { state in state.mode == "bookPageMap" && state.knownChapters != nil } XCTAssertEqual(state.windowSize, 5, "windowSize 应为 5") XCTAssertTrue((state.knownChapters ?? 0) >= 3, "window=5 首开应至少预加载 3 章(当前章 + 相邻),实际=\(state.knownChapters ?? 0)") XCTAssertTrue(app.otherElements[IDs.readerContent].waitForExistence(timeout: 5), "window=5 首开应可阅读") } func testWindowSize3MinimumWorks() throws { app.launchAndOpenSampleBook(bookTitleQuery: largeBookQuery, resetsReaderState: true, windowSize: 3) app.waitForReader(timeout: 20) let state = app.waitForDemoReaderState(timeout: 15, description: "window=3 最小窗口") { state in state.mode == "bookPageMap" && state.knownChapters != nil } XCTAssertEqual(state.windowSize, 3, "windowSize 应为 3") XCTAssertTrue(app.otherElements[IDs.readerContent].waitForExistence(timeout: 5), "window=3 应可阅读") } func testWindowSize15MaximumWorks() throws { app.launchAndOpenSampleBook(bookTitleQuery: largeBookQuery, resetsReaderState: true, windowSize: 15) app.waitForReader(timeout: 20) let state = app.waitForDemoReaderState(timeout: 15, description: "window=15 最大窗口") { state in state.mode == "bookPageMap" && state.knownChapters != nil } XCTAssertEqual(state.windowSize, 15, "windowSize 应为 15") XCTAssertTrue((state.knownChapters ?? 0) >= 3, "window=15 首开应预加载多章") XCTAssertTrue(app.otherElements[IDs.readerContent].waitForExistence(timeout: 5), "window=15 应可阅读") } func testWindowSize5ChapterNavigationSmooth() throws { app.launchAndOpenSampleBook(bookTitleQuery: largeBookQuery, resetsReaderState: true, windowSize: 5) app.waitForReader(timeout: 20) _ = app.waitForDemoReaderState(timeout: 15, description: "等待首章加载") { state in state.mode == "bookPageMap" && (state.page ?? 0) >= 1 } let paging = app.collectionViews[IDs.readerPaging] XCTAssertTrue(paging.waitForExistence(timeout: 5), "分页视图不存在") // 快速连续翻页,window=5 应该有更多章在缓存中 for _ in 0..<6 { paging.swipeLeft() RunLoop.current.run(until: Date().addingTimeInterval(0.3)) } let afterSwipe = app.currentDemoReaderState() XCTAssertNotNil(afterSwipe, "翻页后应能读取状态") XCTAssertTrue((afterSwipe?.page ?? 0) > 1, "连续翻页后页码应推进") } func testEvenWindowSizeRoundsUp() throws { // 传 4 应被归一化为 5 app.launchAndOpenSampleBook(bookTitleQuery: largeBookQuery, resetsReaderState: true, windowSize: 4) app.waitForReader(timeout: 20) let state = app.waitForDemoReaderState(timeout: 15, description: "偶数窗口向上取奇") { state in state.mode == "bookPageMap" && state.windowSize != nil } XCTAssertEqual(state.windowSize, 5, "windowSize=4 应被归一化为 5") } }