Skip to content

Latest commit

 

History

History
45 lines (28 loc) · 3.85 KB

File metadata and controls

45 lines (28 loc) · 3.85 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Purpose

Example project showing how to drive a remote Appium session on the TestingBot cloud device grid from Robot Framework to run native mobile app tests. It is intentionally small — one suite (test.robot) plus two Python helper libraries.

Running tests

PYTHONPATH must include the repo root so Robot Framework can import the local Python libraries (AppOptions.py, TestingBot.py) as libraries named AppOptions / TestingBot.

pip install -r requirements.txt
export TB_KEY=<key>
export TB_SECRET=<secret>
PYTHONPATH=$PYTHONPATH:. robot \
  --variable PLATFORM:Android \
  --variable VERSION:14.0 \
  --variable DEVICE:Pixel.* \
  --variable APP:https://testingbot.com/appium/sample.apk \
  test.robot

Run a single test case: add --test "Simple App Test" (or -t) to the robot invocation.

TB_KEY / TB_SECRET are read from os.environ inside TestingBot.pydo not pass them via --variable or embed them in the remote URL, or they will leak into log.html / output.xml. The four --variable args (PLATFORM, VERSION, DEVICE, APP) are required — the suite references them with no defaults. CI (.github/workflows/test-python.yml) injects TB_KEY/TB_SECRET via the job's env: block from GitHub secrets.

Architecture

The suite is three pieces that plug together via Robot Framework's Library imports:

  • test.robot — declares AppiumLibrary, AppOptions, and TestingBot as libraries. Test Setup calls Get App Options to get an Appium platform-specific *Options object (e.g. UiAutomator2Options / XCUITestOptions), attaches W3C + Appium capabilities and a tb:options dict (TestingBot-specific metadata like build name) via Call Method ... set_capability, then hands the configured options off to Open Testingbot App. The suite never references credentials.

  • AppOptions.py — factory returning UiAutomator2Options / XCUITestOptions based on the PLATFORM variable. Keeping this in Python (rather than Robot keywords) is deliberate: the test needs a real Appium options object to call set_capability on.

  • TestingBot.py — owns all TestingBot/credential concerns. Reads TB_KEY/TB_SECRET from os.environ, builds a selenium.webdriver.remote.client_config.ClientConfig with basic auth, and creates the remote Appium driver via appium.webdriver.Remote(...). It then registers the driver in the running AppiumLibrary instance's _cache — this both avoids URL-embedded credentials (which would be logged) and means subsequent AppiumLibrary keywords (Wait Until Page Contains Element, Click Element, …) just work. Report Testingbot Status then reaches into the running AppiumLibrary instance for the live session_id and PUTs pass/fail to api.testingbot.com/v1/tests/<session_id>. This only works while the app session is still open, which is why it runs before Close Application in the teardown.

Note: AppiumLibrary's own Open Application keyword also creates the driver, but only accepts capability kwargs and would require embedding credentials in the remote URL. Registering our own driver in appium._cache is the escape hatch that keeps credentials out of the URL and the logs.

When changing capabilities or adding platform-specific flags, edit test.robot (capabilities) or AppOptions.py (options object construction) — don't try to do it purely in Robot syntax. If you need to change how the driver is created or how auth is handled, that all lives in TestingBot.py:open_testingbot_app — keep credentials out of test.robot and out of Robot variables.

Ignorable artifacts

log.html, report.html, output.xml, .pabotsuitenames, and pabot_results/ are generated by robot/pabot runs and should not be committed or treated as source.