crosslocator
Define a UI selector once. Resolve it on every platform.
Cross-platform test automation means maintaining the same element for Android,
iOS, iPadOS, Windows and the web. Most teams end up either duplicating selectors
or scattering if platform == ... branches through their page objects.
crosslocator lets you declare a selector once, per platform, and resolves
the right one at runtime — from pure Python (Appium), Robot Framework, or any
other framework. It only routes selector strings; it never wraps your driver.
from crosslocator import Locator
ADD_PATIENT = Locator(
android="accessibility_id=add_patient",
ios="add_patient",
windows='//Button[@Name="Add"]',
default="id=add",
)
ADD_PATIENT.for_platform("ios") # -> "add_patient"
Installation
pip install crosslocator
Zero runtime dependencies.
Why
- One source of truth per element — no duplicated selectors, no platform
if/else. - Framework-agnostic — Appium in plain Python, Robot Framework, or anything else.
- Sensible fallbacks — iPad inherits from iOS, and a shared
defaultcovers the rest. - Typed and dependency-free.
Quick start (Python)
from crosslocator import Locator, set_current_platform
ADD_PATIENT = Locator(
android="accessibility_id=add_patient",
ios="add_patient",
windows='//Button[@Name="Add"]',
)
set_current_platform("android") # usually done once, at session start
ADD_PATIENT.resolve() # -> "accessibility_id=add_patient"
Robot Framework
*** Settings ***
Library crosslocator.robot.CrossLocator
Variables locators.py # ADD_PATIENT defined as a Locator here
*** Test Cases ***
Open Add Patient
Set Current Platform android
${selector}= Resolve Locator ${ADD_PATIENT}
# -> pass ${selector} to AppiumLibrary / Browser as usual
How the platform is resolved
resolve() determines the current platform in this order:
- an explicit
set_current_platform(...) - the
CROSSLOCATOR_PLATFORMenvironment variable - a registered provider — typically an Appium session (see below)
Automatic platform detection (Appium)
Let crosslocator read the platform straight from a live Appium session, so you
never call set_current_platform by hand.
Python (Appium-Python-Client):
from crosslocator import use_appium
use_appium(driver) # your Appium webdriver
LOGIN_BUTTON.resolve() # platform detected from the session capabilities
Robot Framework (AppiumLibrary):
Open Application ${REMOTE_URL} platformName=Android ...
Use Appium Session
${selector}= Resolve Locator ${LOGIN_BUTTON}
iPad is detected from the session device name and resolves to iPad selectors (falling back to iOS when none are defined).
Fallback rules
ipad→ falls back toioswhen no iPad-specific selector is set- any platform → falls back to
default - nothing found →
LocatorNotFound
Examples
Runnable examples (no device needed) live in the examples/ folder —
a login screen resolved across Android, iOS, iPadOS and Windows, plus a Robot
Framework suite.
Roadmap
- v0.1: the core
Locatortype, platform resolution, Robot Framework keywords. - v0.2 (current): automatic platform detection from a live Appium session.
- Next: Playwright/Browser helpers, and declarative loading of whole screens from YAML/dict.
Issues and contributions are welcome.
License
MIT © 2026 Julien Becheny
Release files for crosslocator 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crosslocator-0.2.0.tar.gz | 8.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crosslocator-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.4 kB
Release files / crosslocator-0.2.0.tar.gz
| Download URL | crosslocator-0.2.0.tar.gz |
|---|---|
| Size | 8.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8fe534088357caf956451af334c394756bcbb595e0adfa3658e1e9fbc83b858
|
|
BLAKE2b-256 checksum How to use checksums |
018fed37c5616a136d2cab390a9483e082fc4899e907c702a32d7c868c0b1501
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Release files / crosslocator-0.2.0-py3-none-any.whl
| Download URL | crosslocator-0.2.0-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d222c6a5ddbeabd984002548530b01ab74979779fa8e5d815db255ba0baae0d6
|
|
BLAKE2b-256 checksum How to use checksums |
ae6080b40b1351f09072a0f03774874c51f80c972efe5c84b7a9c05f73c04855
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|