A lightweight Swift package for automating scroll operations in UICollectionView and UIScrollView during UI tests.
XCScrollHelper uses accessibility identifiers to locate target elements and performs precise, programmatic scrolling, making it ideal for UI test automation on iOS.
demo-scroll.mp4
- Scroll to any cell, section header, or section footer in a
UICollectionView - Scroll to any subview inside a
UIScrollView - Supports 6 scroll positions:
top,bottom,leading,trailing,centerX,centerY - Custom padding support for fine-tuned scroll positioning
- File-based communication between UI test runner and app process
- Built-in retry logic for reliable element discovery
XCScrollTestHelper— ready-to-use helper for UI test targets
- iOS 15.0+
- Swift 5.9+
Add XCScrollHelper to your project via Xcode:
- Go to File > Add Package Dependencies...
- Enter the repository URL
- Add
XCScrollHelperto both your app target and UI test target
Or add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/Trendyol/XCScrollHelper.git", from: "1.0.0")
]Start the automation observer in your app's launch sequence (e.g., AppDelegate):
import XCScrollHelper
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UITestAutomationObserver.shared.start() // UICollectionView scrolling
UITestAutomationObserver.shared.startForScrollView() // UIScrollView scrolling
return true
}import XCTest
import XCScrollHelper
final class MyUITests: XCTestCase {
private let app = XCUIApplication()
private let scrollHelper = XCScrollTestHelper.shared
override func setUp() {
super.setUp()
app.launch()
}
func test_scrollToDistantCell() {
// Scroll to a cell by its accessibility identifier
let result = scrollHelper.scrollToCell(
elementIdentifier: "cell_3_20",
in: "myCollectionView"
)
XCTAssertTrue(result.isSuccess, result.message ?? "Scroll failed")
// The cell is now visible — interact with it
let cell = app.collectionViews["myCollectionView"].cells["cell_3_20"]
XCTAssertTrue(cell.isHittable)
cell.tap()
}
func test_scrollToSectionHeader() {
let result = scrollHelper.scrollToCell(
elementIdentifier: "header_5",
in: "myCollectionView",
position: .top,
type: .elementKindSectionHeader
)
XCTAssertTrue(result.isSuccess)
}
func test_scrollInsideScrollView() {
let result = scrollHelper.scrollToView(
targetIdentifier: "item_30",
in: "myScrollView"
)
XCTAssertTrue(result.isSuccess)
}
}- UI test calls
XCScrollTestHelper.shared.scrollToCell(...)or.scrollToView(...) - Helper writes a
CollectionViewScrollArgument/ScrollViewScrollArgumentsJSON to/tmp/UITestAutomation.json - App's
FileMonitordetects the file change and decodes the JSON ComponentScrollHelperorScrollViewScrollHelperperforms the scroll- App writes
UITestAutomationResult(success/failure + message) back to the file - Test helper polls the file, decodes the result, and returns it
| Position | Description |
|---|---|
.top |
Element's top edge aligns with the collection view's top |
.bottom |
Element's bottom edge aligns with the collection view's bottom |
.leading |
Element's leading edge aligns (horizontal collections) |
.trailing |
Element's trailing edge aligns (horizontal collections) |
.centerX |
Center the element horizontally |
.centerY |
Center the element vertically |
| Type | Description |
|---|---|
.elementKindCell |
Regular collection view cell |
.elementKindSectionHeader |
Section header supplementary view |
.elementKindSectionFooter |
Section footer supplementary view |
// CollectionView — scroll to cell, header, or footer
XCScrollTestHelper.shared.scrollToCell(
elementIdentifier: "cell_id",
in: "collectionView_id",
position: .top, // default: .top
type: .elementKindCell, // default: .elementKindCell
padding: 0, // default: 0
animated: true // default: true
) -> UITestAutomationResult
// ScrollView — scroll to any subview
XCScrollTestHelper.shared.scrollToView(
targetIdentifier: "view_id",
in: "scrollView_id",
animated: true // default: true
) -> UITestAutomationResultUITestAutomationObserver.shared.start() // Start listening for CollectionView commands
UITestAutomationObserver.shared.startForScrollView() // Start listening for ScrollView commandsXCScrollHelper is available under the MIT license. See the LICENSE file for more info.