Define a UI selector once, resolve it on every platform (Android, iOS, iPadOS, Windows, web).
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crosslocator-0.2.0.tar.gz.
File metadata
- Download URL: crosslocator-0.2.0.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8fe534088357caf956451af334c394756bcbb595e0adfa3658e1e9fbc83b858
|
|
| MD5 |
5a1c4757bde49cea585277fd06b94cd3
|
|
| BLAKE2b-256 |
018fed37c5616a136d2cab390a9483e082fc4899e907c702a32d7c868c0b1501
|
File details
Details for the file crosslocator-0.2.0-py3-none-any.whl.
File metadata
- Download URL: crosslocator-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d222c6a5ddbeabd984002548530b01ab74979779fa8e5d815db255ba0baae0d6
|
|
| MD5 |
f4bfbfe3eae2fbb59f10325b538b5351
|
|
| BLAKE2b-256 |
ae6080b40b1351f09072a0f03774874c51f80c972efe5c84b7a9c05f73c04855
|