### Enable and Start Docker Service Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Enables the Docker service to start on boot and starts the service immediately. ```bash systemctl enable docker systemctl start docker ``` -------------------------------- ### Start Local Development Instance CLI Source: https://context7.com/devicefarmer/stf/llms.txt Use `stf local` to start all STF processes for development. RethinkDB must be running. Options include specifying public IP, device serials, ports, and authentication secrets. ```bash # Minimal local start (devices auto-discovered via ADB) stf local ``` ```bash # With public IP for access from other machines on the network stf local --public-ip 192.168.1.50 ``` ```bash # Restrict to specific device serials (prevents duplicate-device issues with adb connect) stf local 0123456789ABCDEF FEDCBA9876543210 ``` ```bash # Full example with custom ports and OAuth secret stf local \ --public-ip 192.168.1.50 \ --port 7100 \ --adb-host 127.0.0.1 \ --adb-port 5037 \ --auth-secret "change-me-in-production" \ --rethinkdb-host 127.0.0.1 ``` ```bash # Override via environment variables before first run: export STF_ADMIN_NAME="Admin" export STF_ADMIN_EMAIL="admin@mycompany.com" export STF_ROOT_GROUP_NAME="Lab" stf local ``` -------------------------------- ### Install Docker and Git Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Installs Docker and Git packages using pacman on Arch Linux. ```bash pacman -Sy pacman -S docker git ``` -------------------------------- ### Initialize Swagger Client for STF API (Node.js) Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Set up the Swagger client to interact with the STF API. This example shows both non-Promise and Promise-based initialization, including authorization setup. ```javascript var Swagger = require('swagger-client'); var SWAGGER_URL = 'https://stf.example.org/api/v1/swagger.json'; var AUTH_TOKEN = 'xx-xxxx-xx'; // Without Promise var client = new Swagger({ url: SWAGGER_URL , authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } , success: function() { client.user.getUser(function(user) { console.log(user.obj) }) } }); // Using Promise var clientWithPromise = new Swagger({ url: SWAGGER_URL , usePromise: true , authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } }) clientWithPromise.then(function(api) { api.user.getUser() .then(function(res) { console.log(res.obj.user.email) // vishal@example.com }) }) ``` -------------------------------- ### Start STF Local Development Server Source: https://github.com/devicefarmer/stf/blob/master/README.md Launches the STF local development server. This command starts all required processes and a mock login implementation. Ensure RethinkDB is running first. ```bash stf local ``` -------------------------------- ### Run Local STF Instance Source: https://github.com/devicefarmer/stf/blob/master/TESTING.md Start a local instance of STF. Ensure it is fully functional and devices are discovered before running tests. ```bash ./bin/stf local ``` -------------------------------- ### Install PhantomJS for Unit Tests Source: https://github.com/devicefarmer/stf/blob/master/TESTING.md Install PhantomJS using Homebrew, a dependency for running unit tests. ```bash brew install phantomjs ``` -------------------------------- ### Install STF via NPM Source: https://github.com/devicefarmer/stf/blob/master/README.md Install the STF package globally using NPM. This command should be run after all system requirements are met. ```bash npm install -g @devicefarmer/stf ``` -------------------------------- ### Install Homebrew Dependencies on macOS Source: https://github.com/devicefarmer/stf/blob/master/README.md Use Homebrew to install the necessary dependencies for STF on macOS. Ensure these are installed before proceeding with STF setup. ```bash brew install rethinkdb graphicsmagick zeromq protobuf yasm pkg-config cmake ``` -------------------------------- ### Run RethinkDB Source: https://github.com/devicefarmer/stf/blob/master/TESTING.md Start the RethinkDB database, a prerequisite for running STF. ```bash rethinkdb ``` -------------------------------- ### Reserve Device with Node.js Client Source: https://context7.com/devicefarmer/stf/llms.txt Node.js example for reserving a device, including error handling for failed reservations. ```javascript // Node.js — reserve device with error handling client.then(function(api) { return api.user.addUserDevice({ device: { serial: 'AAAA000001', timeout: 900000 } }) }).then(function(res) { if (!res.obj.success) { throw new Error(res.obj.description) } console.log('Reserved:', res.obj.description) // Reserved: Device successfully added }).catch(function(err) { console.error('Failed to reserve device:', err.message) }) ``` -------------------------------- ### Node.js: Reserve, Connect Remotely, and Disconnect Source: https://context7.com/devicefarmer/stf/llms.txt Comprehensive Node.js example demonstrating device reservation, remote ADB connection, and subsequent cleanup operations. ```javascript // Node.js — reserve, connect remotely, then clean up client.then(function(api) { return api.user.addUserDevice({ device: { serial: 'AAAA000001', timeout: 600000 } }) .then(function(res) { if (!res.obj.success) throw new Error(res.obj.description) return api.user.remoteConnectUserDeviceBySerial({ serial: 'AAAA000001' }) }) .then(function(res) { if (!res.obj.success) throw new Error(res.obj.description) console.log('ADB address:', res.obj.remoteConnectUrl) // ADB address: 192.168.1.100:16829 // Run your adb commands here ... return api.user.remoteDisconnectUserDeviceBySerial({ serial: 'AAAA000001' }) }) .then(function() { return api.user.deleteUserDeviceBySerial({ serial: 'AAAA000001' }) }) .then(function(res) { console.log(res.obj.description) // Device successfully removed }) }).catch(console.error) ``` -------------------------------- ### Enable and Start Nightly Publish Timer Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Enables the systemd timer for automatically publishing the 'latest' Docker image nightly and starts the timer. ```bash systemctl enable stf-armv7l-publish-latest.timer systemctl start stf-armv7l-publish-latest.timer ``` -------------------------------- ### Authentication Example Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Demonstrates how to authenticate API requests using an OAuth 2.0 Bearer token with cURL and Node.js. ```APIDOC ## Authentication STF uses OAuth 2.0 for authentication. In order to use the API, you will first need to generate an access token. Access tokens can be easily generated from the STF UI. Just go to the **Settings** tab and generate a new access token in **Keys** section. Don't forget to save this token somewhere, you will not be able to see it again. The access token must be included in every request. ### Using cURL: ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/user ``` ### Using Node.js: ```js var Swagger = require('swagger-client'); var SWAGGER_URL = 'https://stf.example.org/api/v1/swagger.json'; var AUTH_TOKEN = 'xx-xxxx-xx'; // Without Promise var client = new Swagger({ url: SWAGGER_URL , authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } , success: function() { client.user.getUser(function(user) { console.log(user.obj) }) } }); // Using Promise var clientWithPromise = new Swagger({ url: SWAGGER_URL , usePromise: true , authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } }) clientWithPromise.then(function(api) { api.user.getUser() .then(function(res) { console.log(res.obj.user.email) // vishal@example.com }) }) ``` ``` -------------------------------- ### Node.js - List devices accessible by the current user Source: https://context7.com/devicefarmer/stf/llms.txt Example of listing devices using the Swagger client in Node.js, filtering for available devices. ```APIDOC ```js // Node.js — list devices accessible by the current user client.then(function(api) { return api.devices.getDevices({ fields: 'serial,present,ready,using,owner' }) }).then(function(res) { var available = res.obj.devices.filter(function(d) { return d.present && d.ready && !d.using && !d.owner }) console.log('Available devices:', available.map(function(d) { return d.serial })) // Available devices: [ 'AAAA000001', 'DDDD000004' ] }).catch(console.error) ``` ``` -------------------------------- ### Start STF with Public IP Access Source: https://github.com/devicefarmer/stf/blob/master/README.md Use this command for quick testing if you need to access STF from other machines on your network. Replace `` with your actual internal IP address. ```bash stf local --public-ip ``` -------------------------------- ### Node.js - Check device availability before reserving Source: https://context7.com/devicefarmer/stf/llms.txt Example of checking a specific device's availability using the Swagger client in Node.js before attempting to reserve it. ```APIDOC ```js // Node.js — check device availability before reserving client.then(function(api) { return api.devices.getDeviceBySerial({ serial: 'AAAA000001', fields: 'serial,present,ready,using,owner' }) }).then(function(res) { var d = res.obj.device if (d.present && d.ready && !d.using && !d.owner) { console.log('Device', d.serial, 'is available') } else { console.log('Device not available:', JSON.stringify(d)) } }).catch(console.error) ``` ``` -------------------------------- ### Node.js - Initialize Swagger client with Bearer auth Source: https://context7.com/devicefarmer/stf/llms.txt Example of initializing a Swagger client in Node.js to interact with the STF API, including setting up Bearer token authentication. ```APIDOC ```js // Node.js — initialize Swagger client with Bearer auth var Swagger = require('swagger-client') var SWAGGER_URL = 'https://stf.example.org/api/v1/swagger.json' var AUTH_TOKEN = 'xx-xxxx-xx' var client = new Swagger({ url: SWAGGER_URL, usePromise: true, authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } }) client.then(function(api) { return api.user.getUser() }).then(function(res) { console.log(res.obj.user.email) // alice@example.com }).catch(console.error) ``` ``` -------------------------------- ### Enable and Start Docker Cleanup Timer Source: https://github.com/devicefarmer/stf/blob/master/docker/extras/README.md Enable and start the systemd timer to schedule the daily cleanup of dangling Docker images. This ensures the cleanup runs automatically. ```bash systemctl enable --now docker-cleanup-dangling-images.timer ``` -------------------------------- ### GET /devices Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Lists all STF devices, including those that are disconnected or inaccessible. ```APIDOC ## GET /devices List **all** STF devices (including disconnected or otherwise inaccessible devices). ### Method GET ### Endpoint /api/v1/devices ### Request Example ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/devices ``` ### Response #### Success Response (200) - **devices** (array) - A list of device objects. ### Response Example ```json { "devices": [ { "serial": "xxxx", "using": false, "ready": true }, { "serial": "yyyy", "using": false, "ready": true } ] } ``` ### Node.js Example ```js clientWithPromise.then(function(api) { api.devices.getDevices() .then(function(res) { console.log(res.obj.devices.length) // 50 }) }) // OR clientWithPromise.then(function(api) { api.devices.getDevices({fields: 'serial,using,ready'}) .then(function(res) { console.log(res.obj.devices) // [ { serial: 'xxxx', using: false, ready: true }, // { serial: 'yyyy', using: false, ready: true }] }) }) ``` ``` -------------------------------- ### Create Booking/Partition Group Source: https://context7.com/devicefarmer/stf/llms.txt Creates a device-reservation group with specified properties like name, class, start time, and stop time. ```APIDOC ## POST /api/v1/groups — Create a booking/partition group ### Description Creates a device-reservation group (transient booking or origin partition). The `class` field controls recurrence; `startTime`/`stopTime` follow RFC 3339. ### Method POST ### Endpoint /api/v1/groups ### Parameters #### Request Body - **name** (string) - Required - The name of the group. - **class** (string) - Required - The recurrence class (e.g., `once`). - **startTime** (string) - Required - The start time in RFC 3339 format. - **stopTime** (string) - Required - The stop time in RFC 3339 format. - **state** (string) - Optional - The initial state of the group (e.g., `ready`). ### Request Example ```json { "name": "nightly-regression", "class": "once", "startTime": "2025-06-01T02:00:00Z", "stopTime": "2025-06-01T03:00:00Z", "state": "ready" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **group** (object) - Details of the created group. - **id** (string) - The unique identifier of the group. - **name** (string) - The name of the group. - **class** (string) - The recurrence class of the group. - **state** (string) - The state of the group. - **startTime** (string) - The start time of the group. - **stopTime** (string) - The stop time of the group. #### Response Example ```json { "success": true, "group": { "id": "abc123", "name": "nightly-regression", "class": "once", "state": "ready", "startTime": "2025-06-01T02:00:00.000Z", "stopTime": "2025-06-01T03:00:00.000Z" } } ``` ``` -------------------------------- ### GET /user/devices Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Returns a list of devices currently being used by the authenticated user. ```APIDOC ## GET /user/devices ### Description Returns a list of devices currently being used by the authenticated user. ### Method GET ### Endpoint /api/v1/user/devices ### Request Example ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/user/devices ``` ### Response Example ```json { "obj": { "devices": [ { "serial": "xxxx", "using": true, "ready": true } ] } } ``` ``` -------------------------------- ### Initialize RethinkDB with a password Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md This command initializes a RethinkDB instance with a specified password, which can then be used to secure your database cluster. This is an alternative to setting the password via the admin interface after the service starts. ```bash docker run --rm -v /srv/rethinkdb:/data rethinkdb:2.3 rethinkdb --initial-password yourBrandNewKey ``` -------------------------------- ### Initialize Swagger Client with Bearer Authentication (Node.js) Source: https://context7.com/devicefarmer/stf/llms.txt Initialize a Swagger client for interacting with the STF API using Node.js. This example demonstrates setting up Bearer token authentication for API requests. ```javascript // Node.js — initialize Swagger client with Bearer auth var Swagger = require('swagger-client') var SWAGGER_URL = 'https://stf.example.org/api/v1/swagger.json' var AUTH_TOKEN = 'xx-xxxx-xx' var client = new Swagger({ url: SWAGGER_URL, usePromise: true, authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } }) client.then(function(api) { return api.user.getUser() }).then(function(res) { console.log(res.obj.user.email) // alice@example.com }).catch(console.error) ``` -------------------------------- ### Deploy STF with SAML 2.0 Authentication Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md Configure STF to use SAML 2.0 for authentication, compatible with identity providers like Okta. This setup requires specifying the identity provider's URLs and certificate path. The Service Provider metadata is accessible at `/auth/saml/metadata`. ```ini [Unit] Description=STF SAML 2.0 auth After=docker.service Requires=docker.service [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull devicefarmer/stf:latest ExecStartPre=-/usr/bin/docker kill %p-%i ExecStartPre=-/usr/bin/docker rm %p-%i ExecStart=/usr/bin/docker run --rm \ --name %p-%i \ -v /srv/ssl/id_provider.cert:/etc/id_provider.cert:ro \ -e "SECRET=YOUR_SESSION_SECRET_HERE" \ -e "SAML_ID_PROVIDER_ENTRY_POINT_URL=YOUR_ID_PROVIDER_ENTRY_POINT" \ -e "SAML_ID_PROVIDER_ISSUER=YOUR_ID_PROVIDER_ISSUER" \ -e "SAML_ID_PROVIDER_CALLBACK_URL=YOUR_ID_PROVIDER_CALLBACK_URL" \ -e "SAML_ID_PROVIDER_CERT_PATH=/etc/id_provider.cert" \ -p %i:3000 \ devicefarmer/stf:latest \ stf auth-saml2 --port 3000 \ --app-url https://stf.example.org/ ExecStop=-/usr/bin/docker stop -t 10 %p-%i ``` -------------------------------- ### Get Device Count with Node.js Swagger Client Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Fetch the total number of STF devices available using the Swagger client. This example demonstrates calling the `getDevices` method and accessing the response object. ```javascript clientWithPromise.then(function(api) { api.devices.getDevices() .then(function(res) { console.log(res.obj.devices.length) // 50 }) }) ``` -------------------------------- ### Full Shell Workflow: Reserve, ADB Connect, Release Device Source: https://context7.com/devicefarmer/stf/llms.txt This script demonstrates the complete device lifecycle using `curl` and `jq`. Ensure STF_URL, STF_TOKEN, and DEVICE_SERIAL environment variables are set. ```bash #!/usr/bin/env bash set -euo pipefail STF_URL="${STF_URL:?set STF_URL}" STF_TOKEN="${STF_TOKEN:?set STF_TOKEN}" DEVICE_SERIAL="${DEVICE_SERIAL:?set DEVICE_SERIAL}" AUTH=(-H "Authorization: Bearer $STF_TOKEN") # 1. Reserve device add=$(curl -sf -X POST "${AUTH[@]}" -H "Content-Type: application/json" --data "{\"serial\":\"$DEVICE_SERIAL\",\"timeout\":900000}" "$STF_URL/api/v1/user/devices") [[ $(echo "$add" | jq -r .success) == "true" ]] || { echo "Reserve failed: $(echo "$add" | jq -r .description)"; exit 1; } echo "Reserved $DEVICE_SERIAL" # 2. Enable remote ADB connect=$(curl -sf -X POST "${AUTH[@]}" "$STF_URL/api/v1/user/devices/$DEVICE_SERIAL/remoteConnect") [[ $(echo "$connect" | jq -r .success) == "true" ]] || { echo "Remote connect failed"; exit 1; } ADB_URL=$(echo "$connect" | jq -r .remoteConnectUrl) # adb connect "$ADB_URL" echo "ADB connected at $ADB_URL" # 3. Run tests / automation # adb -s "$ADB_URL" shell getprop ro.product.model # 4. Disconnect ADB curl -sf -X DELETE "${AUTH[@]}" "$STF_URL/api/v1/user/devices/$DEVICE_SERIAL/remoteConnect" > /dev/null # 5. Release device curl -sf -X DELETE "${AUTH[@]}" "$STF_URL/api/v1/user/devices/$DEVICE_SERIAL" > /dev/null echo "Released $DEVICE_SERIAL" ``` -------------------------------- ### STF Nginx Service Unit Configuration Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md Systemd unit file to manage the STF Nginx load balancer as a Docker container. It includes service dependencies, environment setup, and Docker execution commands for starting and stopping the Nginx container. ```ini [Unit] Description=STF nginx public load balancer After=docker.service Requires=docker.service ConditionPathExists=/srv/ssl/stf.example.org.crt ConditionPathExists=/srv/ssl/stf.example.org.key ConditionPathExists=/srv/ssl/dhparam.pem ConditionPathExists=/srv/nginx/nginx.conf [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull nginx:1.17.4 ExecStartPre=-/usr/bin/docker kill %p ExecStartPre=-/usr/bin/docker rm %p ExecStart=/usr/bin/docker run --rm \ --name %p \ --net host \ -v /srv/ssl/stf.example.org.crt:/etc/nginx/ssl/cert.pem:ro \ -v /srv/ssl/stf.example.org.key:/etc/nginx/ssl/cert.key:ro \ -v /srv/ssl/dhparam.pem:/etc/nginx/ssl/dhparam.pem:ro \ -v /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx:1.17.4 \ nginx ExecStop=/usr/bin/docker stop -t 2 %p ``` -------------------------------- ### Fetch Project Dependencies Source: https://github.com/devicefarmer/stf/blob/master/README.md After cloning the repository and ensuring all system requirements are met, run this command to fetch all NPM and Bower modules required for STF. ```bash npm install ``` -------------------------------- ### Initialize or Migrate Database CLI Source: https://context7.com/devicefarmer/stf/llms.txt Run `stf migrate` after `stf local` to apply schema migrations or update built-in objects. Always back up RethinkDB before running. ```bash # Apply pending database migrations stf migrate ``` ```bash # Change admin identity (stop STF first, set env vars, then migrate) STF_ADMIN_NAME="NewAdmin" STF_ADMIN_EMAIL="newadmin@example.com" stf migrate ``` -------------------------------- ### GET /api/v1/devices/{serial} — Get a single device Source: https://context7.com/devicefarmer/stf/llms.txt Retrieves detailed information for a specific device identified by its serial number. Supports filtering by fields. ```APIDOC ## GET /api/v1/devices/{serial} — Get a single device Returns full details for a specific device identified by its serial number. Supports `fields` query parameter. ### Method GET ### Endpoint /api/v1/devices/{serial} ### Parameters #### Path Parameters - **serial** (string) - Required - The serial number of the device. #### Query Parameters - **fields** (string) - Optional - Comma-separated list of attributes to return. ### Request Example (curl) ```bash curl -s \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ "https://stf.example.org/api/v1/devices/AAAA000001?fields=serial,model,version,using,ready,present" | jq . ``` ### Response Example (Success) ```json { "success": true, "device": { "serial": "AAAA000001", "model": "Pixel 6", "version": "13", "using": false, "ready": true, "present": true } } ``` ``` -------------------------------- ### GET /user Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieves information about the currently authenticated user. ```APIDOC ## GET /user Returns information about yourself (the authenticated user). ### Method GET ### Endpoint /api/v1/user ### Request Example ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/user ``` ### Response #### Success Response (200) - **user** (object) - An object containing the authenticated user's details. ### Response Example ```json { "user": { "email": "vishal@example.com" } } ``` ### Node.js Example ```js clientWithPromise.then(function(api) { api.user.getUser() .then(function(res) { console.log(res.obj.user.email) // vishal@example.com }) }) ``` ``` -------------------------------- ### GET /devices/{serial} Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieves detailed information about a specific STF device identified by its serial number. ```APIDOC ## GET /devices/{serial} Returns information about a specific device. ### Method GET ### Endpoint /api/v1/devices/{serial} ### Parameters #### Path Parameters - **serial** (string) - Required - The serial number of the device to retrieve. ### Request Example ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/devices/xxxxxxxxx ``` ### Response #### Success Response (200) - **device** (object) - An object containing the device's details. ### Response Example ```json { "device": { "serial": "xxxx", "using": false, "ready": true } } ``` ### Node.js Example ```js clientWithPromise.then(function(api) { api.devices.getDeviceBySerial({serial: 'xxxx'}) .then(function(res) { console.log(res.obj.device.serial) // xxxx }) }) // OR clientWithPromise.then(function(api) { api.devices.getDeviceBySerial({serial: 'xxxx', fields: 'serial,using,ready'}) .then(function(res) { console.log(res.obj.device) // { serial: 'xxxx', using: false, ready: true } }) }) ``` ``` -------------------------------- ### Update npmjs Package Coordinates Source: https://github.com/devicefarmer/stf/blob/master/README.md Change the npmjs package coordinates to install the package from the new @devicefarmer scope. ```bash npm install -g stf to npm install -g @devicefarmer/stf ``` -------------------------------- ### Create Docker Build User Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Creates a system user named 'stf-armv7l' with a home directory and adds it to the 'docker' group. ```bash useradd --system --create-home -G docker stf-armv7l ``` -------------------------------- ### Manual Docker Image Build for ARMv7l Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Builds the STF Docker image for ARMv7l architecture. Ensure you are in the repository root and on an ARMv7l machine. ```bash ARCH=armhf docker/armv7l/mkimage-alpine.sh docker build -f docker/armv7l/Dockerfile -t openstf/stf-armv7l:latest . ``` -------------------------------- ### Create User API (Admin Only) Source: https://context7.com/devicefarmer/stf/llms.txt This admin-only endpoint creates a user account directly in the database. Requires administrator privileges. ```bash curl -s -X POST \ -H "Authorization: Bearer ADMIN-TOKEN-HERE" \ "https://stf.example.org/api/v1/users/bob@example.com?name=Bob" | jq . ``` -------------------------------- ### Add Device to STF via Bash Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Adds a device to the user's STF session using environment variables for configuration. Requires jq to parse JSON responses. ```bash #!/usr/bin/env bash set -euxo pipefail if [ "$DEVICE_SERIAL" == "" ]; then echo "Please specify device serial using ENV['DEVICE_SERIAL']" exit 1 fi if [ "$STF_URL" == "" ]; then echo "Please specify stf url using ENV['STF_URL']" exit 1 fi if [ "$STF_TOKEN" == "" ]; then echo "Please specify stf token using using ENV['STF_TOKEN']" exit 1 fi function add_device { response=$(curl -X POST -H "Content-Type: application/json" \ -H "Authorization: Bearer $STF_TOKEN" \ --data "{\"serial\": \"$DEVICE_SERIAL\"}" $STF_URL/api/v1/user/devices) success=$(echo "$response" | jq .success | tr -d '"') description=$(echo "$response" | jq .description | tr -d '"') if [ "$success" != "true" ]; then echo "Failed because $description" exit 1 fi echo "Device $DEVICE_SERIAL added successfully" } ``` -------------------------------- ### Manually Trigger Docker Cleanup Job Source: https://github.com/devicefarmer/stf/blob/master/docker/extras/README.md Manually start the Docker cleanup job. This is useful for immediate cleanup or testing the functionality. ```bash systemctl start docker-cleanup-dangling-images ``` -------------------------------- ### Get Device By Serial (Node.js SDK) Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieves details of a specific device using its serial number via the Node.js SDK. ```APIDOC ## GET /api/v1/devices/{serial} ### Description Retrieves information about a specific device identified by its serial number. ### Method GET ### Endpoint /api/v1/devices/{serial} ### Parameters #### Path Parameters - **serial** (string) - Required - The serial number of the device. #### Query Parameters - **fields** (string) - Optional - Comma-separated list of fields to include in the response. ### Response #### Success Response (200) - **device** (object) - An object containing device details. - **serial** (string) - The serial number of the device. - **present** (boolean) - Indicates if the device is currently connected. - **ready** (boolean) - Indicates if the device is ready for use. - **using** (boolean) - Indicates if the device is currently in use. - **owner** (string) - The owner of the device, if any. ``` -------------------------------- ### Create Booking/Partition Group Source: https://context7.com/devicefarmer/stf/llms.txt Creates a device reservation group, which can be a transient booking or an origin partition. The `class` field determines recurrence, and `startTime`/`stopTime` use RFC 3339 format. ```bash # Create a once-off booking group valid for 1 hour from now curl -s -X POST \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ -H "Content-Type: application/json" \ --data '{ "name": "nightly-regression", "class": "once", "startTime": "2025-06-01T02:00:00Z", "stopTime": "2025-06-01T03:00:00Z", "state": "ready" }' \ https://stf.example.org/api/v1/groups | jq . ``` -------------------------------- ### Deploy STF Mock Authentication Service Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md This systemd service unit deploys the mock authentication provider for STF. It requires Docker and pulls the STF image. Ensure the `--app-url` is correctly set in the `stf-app` unit. ```ini [Unit] Description=STF mock auth After=docker.service Requires=docker.service [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull devicefarmer/stf:latest ExecStartPre=-/usr/bin/docker kill %p-%i ExecStartPre=-/usr/bin/docker rm %p-%i ExecStart=/usr/bin/docker run --rm \ --name %p-%i \ -e "SECRET=YOUR_SESSION_SECRET_HERE" \ -p %i:3000 \ devicefarmer/stf:latest \ stf auth-mock --port 3000 \ --app-url https://stf.example.org/ ExecStop=-/usr/bin/docker stop -t 10 %p-%i ``` -------------------------------- ### Get User Devices (Node.js SDK) Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieves a list of devices currently associated with the user's session via the Node.js SDK. ```APIDOC ## GET /api/v1/user/devices (SDK) ### Description Fetches the list of devices currently managed by the user's session. ### Method GET ### Endpoint /api/v1/user/devices ### Parameters #### Query Parameters - **serial** (string) - Optional - Filters the list to a specific device serial. - **fields** (string) - Optional - Comma-separated list of fields to include for each device. ``` -------------------------------- ### Get Specific Device Info with cURL Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieve detailed information for a single STF device using its serial number. Requires authentication. ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/devices/xxxxxxxxx ``` -------------------------------- ### Remote Connect to Device via Bash Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Establishes a remote connection to a specified device using STF API and ADB. Requires environment variables for configuration. ```bash function remote_connect { response=$(curl -X POST \ -H "Authorization: Bearer $STF_TOKEN" \ $STF_URL/api/v1/user/devices/$DEVICE_SERIAL/remoteConnect) success=$(echo "$response" | jq .success | tr -d '"') description=$(echo "$response" | jq .description | tr -d '"') if [ "$success" != "true" ]; then echo "Failed because $description" exit 1 fi remote_connect_url=$(echo "$response" | jq .remoteConnectUrl | tr -d '"') adb connect $remote_connect_url echo "Device $DEVICE_SERIAL remote connected successfully" } ``` -------------------------------- ### List All Devices with cURL and jq Source: https://context7.com/devicefarmer/stf/llms.txt Retrieve a list of all devices registered in STF, including disconnected and offline ones. Supports filtering fields and targeting specific device types. The output is pretty-printed using jq. ```bash # List all devices, pretty-printed, selecting three fields only curl -s \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ "https://stf.example.org/api/v1/devices?fields=serial,using,ready" | jq . ``` -------------------------------- ### GET /api/v1/devices — List all devices Source: https://context7.com/devicefarmer/stf/llms.txt Retrieves a list of all devices registered in STF, including disconnected and offline devices. Supports filtering by fields and target. ```APIDOC ## GET /api/v1/devices — List all devices Returns every device registered in STF, including disconnected and offline ones. Supports a `fields` query parameter (comma-separated) to limit returned attributes, and a `target` parameter (`user`, `bookable`, `standard`, `origin`, `standardizable`). ### Method GET ### Endpoint /api/v1/devices ### Query Parameters - **fields** (string) - Optional - Comma-separated list of attributes to return. - **target** (string) - Optional - Filters devices by target type (e.g., `user`, `bookable`). ### Request Example (curl) ```bash curl -s \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ "https://stf.example.org/api/v1/devices?fields=serial,using,ready" | jq . ``` ### Response Example (Success) ```json { "success": true, "devices": [ { "serial": "AAAA000001", "using": false, "ready": true }, { "serial": "BBBB000002", "using": true, "ready": true }, { "serial": "CCCC000003", "using": false, "ready": false } ] } ``` ``` -------------------------------- ### Run Translation Process Source: https://github.com/devicefarmer/stf/blob/master/README.md Execute the Gulp task to manage translation files. This command converts Jade to HTML, extracts translatable strings, pushes them to Transifex, pulls translations, and compiles them to JSON. ```bash gulp translate ``` -------------------------------- ### Add Device Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Adds a device to the user's account in STF. ```APIDOC ## POST /api/v1/user/devices ### Description Adds a device to the user's account. ### Method POST ### Endpoint /api/v1/user/devices ### Parameters #### Request Body - **serial** (string) - Required - The serial number of the device to add. ### Request Example ```json { "serial": "DEVICE_SERIAL" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **description** (string) - Provides a message about the outcome of the operation. ``` -------------------------------- ### Get Specific Device Info with cURL Source: https://context7.com/devicefarmer/stf/llms.txt Retrieve detailed information for a specific device using its serial number. The `fields` query parameter can be used to limit the returned attributes. ```bash # Retrieve specific device info curl -s \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ "https://stf.example.org/api/v1/devices/AAAA000001?fields=serial,model,version,using,ready,present" | jq . ``` -------------------------------- ### Get Specific Device Fields by Serial with Node.js Swagger Client Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieve specific fields for a single STF device by its serial number. This allows for a more targeted data retrieval. ```javascript // OR clientWithPromise.then(function(api) { api.devices.getDeviceBySerial({serial: 'xxxx', fields: 'serial,using,ready'}) .then(function(res) { console.log(res.obj.device) // { serial: 'xxxx', using: false, ready: true } }) }) ``` -------------------------------- ### Login to Docker Registry Source: https://github.com/devicefarmer/stf/blob/master/docker/armv7l/README.md Logs into the Docker registry. This is required before pushing built images. ```bash docker login ``` -------------------------------- ### Connect to Device and Get Remote Debug URL with Node.js Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Connects to a device using the STF API and retrieves its remote debug URL. Requires the 'swagger-client' package and authentication token. ```javascript // stf-connect.js var Swagger = require('swagger-client'); var SWAGGER_URL = 'https://stf.example.org/api/v1/swagger.json'; var AUTH_TOKEN = 'xx-xxxx-xx'; // Using Promise var client = new Swagger({ url: SWAGGER_URL , usePromise: true , authorizations: { accessTokenAuth: new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + AUTH_TOKEN, 'header') } }) var serial = process.argv.slice(2)[0] client.then(function(api) { return api.devices.getDeviceBySerial({ serial: serial , fields: 'serial,present,ready,using,owner' }).then(function(res) { // check if device can be added or not var device = res.obj.device if (!device.present || !device.ready || device.using || device.owner) { console.log('Device is not available') return } // add device to user return api.user.addUserDevice({ device: { serial: device.serial , timeout: 900000 } }).then(function(res) { if (!res.obj.success) { console.log('Could not add device') return } // get remote connect url return api.user.remoteConnectUserDeviceBySerial({ serial: device.serial }).then(function(res) { console.log(res.obj.remoteConnectUrl) }) }) }) }) ``` ```bash node stf-connect.js xxxx # $PROVIDR_IP:16829 ``` -------------------------------- ### Run Unit Tests with Gulp Source: https://github.com/devicefarmer/stf/blob/master/TESTING.md Execute unit tests using Gulp and Karma. ```bash gulp karma ``` -------------------------------- ### Get Specific Device Info by Serial with Node.js Swagger Client Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Fetch details for a specific STF device by its serial number. Demonstrates calling `getDeviceBySerial` and accessing the device object. ```javascript clientWithPromise.then(function(api) { api.devices.getDeviceBySerial({serial: 'xxxx'}) .then(function(res) { console.log(res.obj.device.serial) // xxxx }) }) ``` -------------------------------- ### List User Devices (cURL) Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Use this endpoint to retrieve a list of devices currently in use by the authenticated user. Requires an Authorization header. ```bash GET /api/v1/user/devices ``` ```bash curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/user/devices ``` -------------------------------- ### Configure RethinkDB.service for STF Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md This unit sets up a RethinkDB instance, suitable for development or single-server deployments. It configures Docker to run RethinkDB with specified cache size and network settings. Ensure to update the RethinkDB version and AUTHKEY for production environments. ```ini [Unit] Description=RethinkDB After=docker.service Requires=docker.service [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull rethinkdb:2.3 ExecStartPre=-/usr/bin/docker kill %p ExecStartPre=-/usr/bin/docker rm %p ExecStartPre=/bin/mkdir -p /srv/rethinkdb ExecStartPre=/usr/bin/chattr -R +C /srv/rethinkdb ExecStart=/usr/bin/docker run --rm \ --name %p \ -v /srv/rethinkdb:/data \ -e "AUTHKEY=YOUR_RETHINKDB_AUTH_KEY_HERE_IF_ANY" \ --net host \ rethinkdb:2.3 \ rethinkdb --bind all \ --cache-size 8192 \ --no-update-check ExecStop=-/usr/bin/docker stop -t 10 %p ``` -------------------------------- ### Get Authenticated User Email with Node.js Swagger Client Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Fetch the email address of the authenticated user using the Swagger client. This demonstrates calling the `getUser` method and accessing nested response properties. ```javascript clientWithPromise.then(function(api) { api.user.getUser() .then(function(res) { console.log(res.obj.user.email) // vishal@example.com }) }) ``` -------------------------------- ### Get Specific Device Fields with Node.js Swagger Client Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Retrieve a list of STF devices, specifying only the desired fields (e.g., 'serial', 'using', 'ready'). This optimizes the response by reducing data transfer. ```javascript // OR clientWithPromise.then(function(api) { api.devices.getDevices({fields: 'serial,using,ready'}) .then(function(res) { console.log(res.obj.devices) // [ { serial: 'xxxx', using: false, ready: true }, // { serial: 'yyyy', using: false, ready: true }] }) }) ``` -------------------------------- ### Deploy STF Application Service Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md Use this systemd service unit to run the main STF application. It requires the rethinkdb proxy and pulls the latest Docker image. Configure the exposed port and authentication URL as needed. ```ini [Unit] Description=STF app After=rethinkdb-proxy-28015.service BindsTo=rethinkdb-proxy-28015.service [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull devicefarmer/stf:latest ExecStartPre=-/usr/bin/docker kill %p-%i ExecStartPre=-/usr/bin/docker rm %p-%i ExecStart=/usr/bin/docker run --rm \ --name %p-%i \ --link rethinkdb-proxy-28015:rethinkdb \ -e "SECRET=YOUR_SESSION_SECRET_HERE" \ -p %i:3000 \ devicefarmer/stf:latest \ stf app --port 3000 \ --auth-url https://stf.example.org/auth/mock/ \ --websocket-url wss://stf.example.org/ ExecStop=-/usr/bin/docker stop -t 10 %p-%i ``` -------------------------------- ### Authenticate and Get User Profile with cURL Source: https://context7.com/devicefarmer/stf/llms.txt Verify authentication by passing a Bearer token in the Authorization header and retrieve the current user's profile information. Requires a valid token generated from the STF UI. ```bash # Verify authentication and retrieve current user profile curl -s \ -H "Authorization: Bearer YOUR-TOKEN-HERE" \ https://stf.example.org/api/v1/user | jq . ``` -------------------------------- ### Pretty Print API Output with jq Source: https://github.com/devicefarmer/stf/blob/master/doc/API.md Use the `jq` command-line tool to format JSON API responses for better readability. This is useful for inspecting large or complex data structures. ```sh curl -H "Authorization: Bearer YOUR-TOKEN-HERE" https://stf.example.org/api/v1/devices | jq . ``` -------------------------------- ### STF S3 Storage Service Unit Source: https://github.com/devicefarmer/stf/blob/master/doc/DEPLOYMENT.md Configure this template systemd unit to store STF data like screenshots and APKs in Amazon S3. Requires AWS credentials and S3 bucket setup. This unit replaces the temporary storage unit. ```ini [Unit] Description=STF s3 storage After=docker.service Requires=docker.service [Service] EnvironmentFile=/etc/environment TimeoutStartSec=0 Restart=always ExecStartPre=/usr/bin/docker pull devicefarmer/stf:latest ExecStartPre=-/usr/bin/docker kill %p-%i ExecStartPre=-/usr/bin/docker rm %p-%i ExecStart=/usr/bin/docker run --rm \ --name %p-%i \ -p %i:3000 \ devicefarmer/stf:latest \ stf storage-s3 --port 3000 \ --bucket YOUR_S3_BUCKET_NAME_HERE \ --profile YOUR_AWS_CREDENTIALS_PROFILE \ --endpoint YOUR_BUCKET_ENDPOING_HERE ExecStop=-/usr/bin/docker stop -t 10 %p-%i ```