import webdriverio from 'webdriverio';
import GboxSDK from "gbox-sdk";
const gboxSDK = new GboxSDK({
apiKey: process.env["GBOX_API_KEY"] // This is the default and can be omitted
});
async function main() {
const box = await gboxSDK.create({ type: "android" });
const { url, defaultOption } = await box.appiumURL();
console.log("Appium connection URL:", url);
// Connect to Appium with defaultOption from backend
console.log("Connecting to Appium server...");
const ac = await remote(defaultOption);
console.log("β
Successfully connected to Appium server");
console.log("Session ID:", ac.sessionId);
try {
// Get current page XML layout
console.log("Fetching XML layout...");
const xmlLayout = await ac.getPageSource();
console.log("β
XML layout fetched successfully!");
console.log("XML length:", xmlLayout.length, "characters");
// Display a preview of the XML (first 500 characters)
console.log("\n--- XML Layout Preview (first 500 chars) ---");
console.log(xmlLayout.substring(0, 500) + "...\n");
// Save XML to file for easier viewing
const outputDir = path.join(__dirname, "output");
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const filename = `layout_${timestamp}.xml`;
const filepath = path.join(outputDir, filename);
fs.writeFileSync(filepath, xmlLayout, "utf-8");
console.log(`π XML layout saved to: ${filepath}`);
// Optional: Parse and display some basic info
const elementMatches = xmlLayout.match(/<[\w.-]+/g);
if (elementMatches) {
const elementSet = new Set(elementMatches.map(e => e.substring(1)));
const uniqueElements = Array.from(elementSet);
console.log("\n--- UI Elements Found ---");
console.log("Total elements:", elementMatches.length);
console.log("Unique element types:", uniqueElements.length);
console.log("Element types:", uniqueElements.slice(0, 10).join(", "), "...");
}
} catch (error) {
console.error(
"β Error fetching XML layout:",
error instanceof Error ? error.message : String(error)
);
} finally {
console.log("\nClosing session...");
await ac.deleteSession();
console.log("Session closed.");
}
}
main()import os
from appium import webdriver
from gbox_sdk import GboxSDK
# Initialize GboxSDK (synchronous API)
gbox_sdk = GboxSDK(
api_key=os.environ.get("GBOX_API_KEY") # This is the default and can be omitted
)
def main():
# Create a box (synchronous)
box = gbox_sdk.create(type="android")
# Get Appium connection URL (synchronous)
result = box.appium_url()
url = result["url"]
default_option = result["default_option"]
print("Appium connection URL:", url)
# Connect to Appium with defaultOption from backend
print("Connecting to Appium server...")
driver = webdriver.Remote(
command_executor=url,
desired_capabilities=default_option["capabilities"]
)
print("β
Successfully connected to Appium server")
print("Session ID:", driver.session_id)
try:
# Get current page XML layout
print("Fetching XML layout...")
xml_layout = driver.page_source
print("β
XML layout fetched successfully!")
print("XML length:", len(xml_layout), "characters")
# Display a preview of the XML (first 500 characters)
print("\n--- XML Layout Preview (first 500 chars) ---")
print(xml_layout[:500] + "...\n")
# Save XML to file for easier viewing
import os
from datetime import datetime
output_dir = os.path.join(os.path.dirname(__file__), "output")
if not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True)
timestamp = datetime.now().isoformat().replace(":", "-").replace(".", "-")
filename = f"layout_{timestamp}.xml"
filepath = os.path.join(output_dir, filename)
with open(filepath, "w", encoding="utf-8") as f:
f.write(xml_layout)
print(f"π XML layout saved to: {filepath}")
# Optional: Parse and display some basic info
import re
element_matches = re.findall(r'<[\w.-]+', xml_layout)
if element_matches:
element_set = set(e[1:] for e in element_matches)
unique_elements = list(element_set)
print("\n--- UI Elements Found ---")
print("Total elements:", len(element_matches))
print("Unique element types:", len(unique_elements))
print("Element types:", ", ".join(unique_elements[:10]), "...")
except Exception as error:
print(f"β Error fetching XML layout: {str(error)}")
finally:
print("\nClosing session...")
driver.quit()
print("Session closed.")
if __name__ == "__main__":
main()curl --request POST \
--url https://gbox.ai/api/v1/boxes/{boxId}/android/connect-url/appium \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expiresIn": "120m"
}
'{
"url": "https://gbox.ai/api/share/v1/proxy/tmp_token123/appium",
"udid": "emulator-5554",
"defaultOption": {
"protocol": "https",
"hostname": "gbox.ai",
"port": 443,
"path": "/api/share/v1/proxy/tmp_token123/appium",
"capabilities": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "emulator-5554",
"appium:deviceName": "emulator-5554"
}
},
"logLevel": "error"
}Appium Connection
Generate a pre-signed proxy URL for Appium server of a running Android box.
import webdriverio from 'webdriverio';
import GboxSDK from "gbox-sdk";
const gboxSDK = new GboxSDK({
apiKey: process.env["GBOX_API_KEY"] // This is the default and can be omitted
});
async function main() {
const box = await gboxSDK.create({ type: "android" });
const { url, defaultOption } = await box.appiumURL();
console.log("Appium connection URL:", url);
// Connect to Appium with defaultOption from backend
console.log("Connecting to Appium server...");
const ac = await remote(defaultOption);
console.log("β
Successfully connected to Appium server");
console.log("Session ID:", ac.sessionId);
try {
// Get current page XML layout
console.log("Fetching XML layout...");
const xmlLayout = await ac.getPageSource();
console.log("β
XML layout fetched successfully!");
console.log("XML length:", xmlLayout.length, "characters");
// Display a preview of the XML (first 500 characters)
console.log("\n--- XML Layout Preview (first 500 chars) ---");
console.log(xmlLayout.substring(0, 500) + "...\n");
// Save XML to file for easier viewing
const outputDir = path.join(__dirname, "output");
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const filename = `layout_${timestamp}.xml`;
const filepath = path.join(outputDir, filename);
fs.writeFileSync(filepath, xmlLayout, "utf-8");
console.log(`π XML layout saved to: ${filepath}`);
// Optional: Parse and display some basic info
const elementMatches = xmlLayout.match(/<[\w.-]+/g);
if (elementMatches) {
const elementSet = new Set(elementMatches.map(e => e.substring(1)));
const uniqueElements = Array.from(elementSet);
console.log("\n--- UI Elements Found ---");
console.log("Total elements:", elementMatches.length);
console.log("Unique element types:", uniqueElements.length);
console.log("Element types:", uniqueElements.slice(0, 10).join(", "), "...");
}
} catch (error) {
console.error(
"β Error fetching XML layout:",
error instanceof Error ? error.message : String(error)
);
} finally {
console.log("\nClosing session...");
await ac.deleteSession();
console.log("Session closed.");
}
}
main()import os
from appium import webdriver
from gbox_sdk import GboxSDK
# Initialize GboxSDK (synchronous API)
gbox_sdk = GboxSDK(
api_key=os.environ.get("GBOX_API_KEY") # This is the default and can be omitted
)
def main():
# Create a box (synchronous)
box = gbox_sdk.create(type="android")
# Get Appium connection URL (synchronous)
result = box.appium_url()
url = result["url"]
default_option = result["default_option"]
print("Appium connection URL:", url)
# Connect to Appium with defaultOption from backend
print("Connecting to Appium server...")
driver = webdriver.Remote(
command_executor=url,
desired_capabilities=default_option["capabilities"]
)
print("β
Successfully connected to Appium server")
print("Session ID:", driver.session_id)
try:
# Get current page XML layout
print("Fetching XML layout...")
xml_layout = driver.page_source
print("β
XML layout fetched successfully!")
print("XML length:", len(xml_layout), "characters")
# Display a preview of the XML (first 500 characters)
print("\n--- XML Layout Preview (first 500 chars) ---")
print(xml_layout[:500] + "...\n")
# Save XML to file for easier viewing
import os
from datetime import datetime
output_dir = os.path.join(os.path.dirname(__file__), "output")
if not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True)
timestamp = datetime.now().isoformat().replace(":", "-").replace(".", "-")
filename = f"layout_{timestamp}.xml"
filepath = os.path.join(output_dir, filename)
with open(filepath, "w", encoding="utf-8") as f:
f.write(xml_layout)
print(f"π XML layout saved to: {filepath}")
# Optional: Parse and display some basic info
import re
element_matches = re.findall(r'<[\w.-]+', xml_layout)
if element_matches:
element_set = set(e[1:] for e in element_matches)
unique_elements = list(element_set)
print("\n--- UI Elements Found ---")
print("Total elements:", len(element_matches))
print("Unique element types:", len(unique_elements))
print("Element types:", ", ".join(unique_elements[:10]), "...")
except Exception as error:
print(f"β Error fetching XML layout: {str(error)}")
finally:
print("\nClosing session...")
driver.quit()
print("Session closed.")
if __name__ == "__main__":
main()curl --request POST \
--url https://gbox.ai/api/v1/boxes/{boxId}/android/connect-url/appium \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expiresIn": "120m"
}
'{
"url": "https://gbox.ai/api/share/v1/proxy/tmp_token123/appium",
"udid": "emulator-5554",
"defaultOption": {
"protocol": "https",
"hostname": "gbox.ai",
"port": 443,
"path": "/api/share/v1/proxy/tmp_token123/appium",
"capabilities": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "emulator-5554",
"appium:deviceName": "emulator-5554"
}
},
"logLevel": "error"
}Authorizations
Enter your API Key in the format: Bearer . Get it from https://gbox.ai
Path Parameters
Box ID
"c9bdc193-b54b-4ddb-a035-5ac0c598d32d"
Body
Generate Appium connection URL
Generate Appium connection url
The Appium connection url will be alive for the given duration
Supported time units: ms (milliseconds), s (seconds), m (minutes), h (hours) Example formats: "500ms", "30s", "5m", "1h" Default: 120m
"120m"
Response
Appium connection information
Appium connection information
Appium connection URL
"https://gbox.ai/api/share/v1/proxy/tmp_token123/appium"
Device UDID for Appium connection
"emulator-5554"
A ready-to-use default WebdriverIO remote options object
Show child attributes
Show child attributes
{
"protocol": "https",
"hostname": "gbox.ai",
"port": 443,
"path": "/api/share/v1/proxy/tmp_token123/appium",
"capabilities": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "emulator-5554",
"appium:deviceName": "emulator-5554"
}
}
Log level for WebdriverIO/Appium client
trace, debug, info, warn, error, silent "error"
Was this page helpful?