feat(reader): 增强阅读器功能与 UI 测试支持
- 新增字体选择(系统/宋体/圆体/等宽)与暗色图片柔化配置 - 文本选择改为自定义手势+操作栏(拷贝/高亮/批注) - 添加 accessibilityIdentifier 支持自动化 UI 测试 - 新增 UITests 覆盖阅读器打开/关闭、工具栏、设置面板、批注等 - 添加 Demo 测试用 EPUB 书源(宝山辽墓材料与释读) - 新增文档:UI 自动化测试、功能开发计划、阅读器规划
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import XCTest
|
||||
|
||||
final class DisplayTypeTests: XCTestCase {
|
||||
private let app = XCUIApplication()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testOpenWithPageCurl() {
|
||||
app.launchAndOpenSampleBook(displayType: "pagecurl")
|
||||
app.waitForReader()
|
||||
}
|
||||
|
||||
func testOpenWithHorizontalScroll() {
|
||||
app.launchAndOpenSampleBook(displayType: "scroll")
|
||||
app.waitForReader()
|
||||
app.waitForReaderState(containing: "display=horizontalScroll")
|
||||
}
|
||||
|
||||
func testOpenWithVerticalScroll() {
|
||||
app.launchAndOpenSampleBook(displayType: "vertical")
|
||||
app.waitForReader()
|
||||
app.waitForReaderState(containing: "display=verticalScroll")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import XCTest
|
||||
|
||||
final class ReaderAnnotationTests: XCTestCase {
|
||||
private let app = XCUIApplication()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testSelectionMenuCreatesHighlight() {
|
||||
app.launchAndOpenSampleBook(pageNumber: 2)
|
||||
app.waitForReader()
|
||||
|
||||
let content = app.textViews[IDs.readerSelectionText].firstMatch
|
||||
XCTAssertTrue(content.waitForExistence(timeout: 5), "阅读内容区域未出现")
|
||||
|
||||
let start = content.coordinate(withNormalizedOffset: CGVector(dx: 0.35, dy: 0.42))
|
||||
let end = content.coordinate(withNormalizedOffset: CGVector(dx: 0.68, dy: 0.42))
|
||||
start.press(forDuration: 0.6, thenDragTo: end)
|
||||
|
||||
app.waitForReaderState(containing: "selection=1", timeout: 5)
|
||||
|
||||
let highlightMenuItem = app.menuItems["高亮"]
|
||||
let highlightButton = app.buttons["高亮"]
|
||||
let highlightActionButton = app.buttons[IDs.readerSelectionHighlight]
|
||||
if highlightMenuItem.waitForExistence(timeout: 3) {
|
||||
highlightMenuItem.tap()
|
||||
} else if highlightActionButton.waitForExistence(timeout: 3) {
|
||||
highlightActionButton.tap()
|
||||
} else {
|
||||
XCTAssertTrue(highlightButton.waitForExistence(timeout: 3), "选中文本后未出现高亮菜单")
|
||||
highlightButton.tap()
|
||||
}
|
||||
|
||||
app.waitForReaderState(containing: "highlights=1", timeout: 8)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import XCTest
|
||||
|
||||
final class ReaderOpenCloseTests: XCTestCase {
|
||||
private let app = XCUIApplication()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testBookListShowsSampleBooks() {
|
||||
app.launch()
|
||||
XCTAssertTrue(app.tables[IDs.demoBooksTable].waitForExistence(timeout: 5))
|
||||
XCTAssertTrue(app.cells[IDs.demoBook(0)].waitForExistence(timeout: 5))
|
||||
}
|
||||
|
||||
func testLaunchArgumentOpensReader() {
|
||||
app.launchAndOpenSampleBook()
|
||||
app.waitForReader()
|
||||
app.showReaderChromeIfNeeded()
|
||||
XCTAssertTrue(app.staticTexts[IDs.readerTitle].waitForExistence(timeout: 5))
|
||||
}
|
||||
|
||||
func testBackButtonReturnsToBookList() {
|
||||
app.launchAndOpenSampleBook()
|
||||
app.waitForReader()
|
||||
app.showReaderChromeIfNeeded()
|
||||
XCTAssertTrue(app.buttons[IDs.readerBack].waitForExistence(timeout: 5))
|
||||
app.buttons[IDs.readerBack].tap()
|
||||
XCTAssertTrue(app.tables[IDs.demoBooksTable].waitForExistence(timeout: 5))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import XCTest
|
||||
|
||||
final class ReaderToolbarTests: XCTestCase {
|
||||
private let app = XCUIApplication()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testTapCenterShowsToolbars() {
|
||||
app.launchAndOpenSampleBook()
|
||||
app.waitForReader()
|
||||
|
||||
app.showReaderChromeIfNeeded()
|
||||
|
||||
XCTAssertTrue(app.otherElements[IDs.readerTopToolbar].waitForExistence(timeout: 5))
|
||||
XCTAssertTrue(app.otherElements[IDs.readerBottomToolbar].waitForExistence(timeout: 5))
|
||||
XCTAssertTrue(app.buttons[IDs.readerBack].exists)
|
||||
XCTAssertTrue(app.buttons[IDs.readerSettings].exists)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import XCTest
|
||||
|
||||
final class SettingsPanelTests: XCTestCase {
|
||||
private let app = XCUIApplication()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testOpenChangeFontAndCloseSettings() {
|
||||
app.launchAndOpenSampleBook()
|
||||
app.waitForReader()
|
||||
app.showReaderChromeIfNeeded()
|
||||
|
||||
XCTAssertTrue(app.buttons[IDs.readerSettings].waitForExistence(timeout: 5))
|
||||
app.buttons[IDs.readerSettings].tap()
|
||||
|
||||
XCTAssertTrue(app.scrollViews[IDs.settingsScroll].waitForExistence(timeout: 5))
|
||||
let fontValue = app.staticTexts[IDs.settingsFontValue]
|
||||
XCTAssertTrue(fontValue.waitForExistence(timeout: 3))
|
||||
let before = fontValue.label
|
||||
|
||||
app.buttons[IDs.settingsFontIncrease].tap()
|
||||
XCTAssertNotEqual(before, fontValue.label)
|
||||
|
||||
app.buttons[IDs.settingsFontDecrease].tap()
|
||||
let fontChoice = app.segmentedControls[IDs.settingsFontChoice]
|
||||
XCTAssertTrue(fontChoice.waitForExistence(timeout: 3))
|
||||
fontChoice.buttons["宋体"].tap()
|
||||
|
||||
let darkTheme = app.buttons[IDs.settingsTheme(5)]
|
||||
XCTAssertTrue(darkTheme.waitForExistence(timeout: 3))
|
||||
darkTheme.tap()
|
||||
|
||||
app.buttons[IDs.settingsDone].tap()
|
||||
XCTAssertTrue(app.buttons[IDs.readerBack].waitForExistence(timeout: 5))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user