Run tests with logs capturing

Below you can find information on how to run tests with automatic system or appium logs capturing

Prerequisites

  • Existing native application with the Biometric authentication.
  • The app is installed on a device.
  • The tests are using Appium framework.
  • Access key is generated.

Step 1: Add capability to the Appium session configuration

We have the specific capabilities for enable of the automatic log(s) capturing during an Appium test session.
You can use both of them simultaneously or individually.
Below you can find an example for popular programming languages.

System log:

  private BaseOptions<? extends MutableCapabilities> generateOptionsForDevice(String platformName,String deviceSerial) {
        BaseOptions<? extends MutableCapabilities> options = platformName.equalsIgnoreCase(MobilePlatform.ANDROID) ?
                new UiAutomator2Options() : new XCUITestOptions();
        options.setCapability("udid", udid);
        options.setCapability("mobitru:collectDeviceLogs", true);
        ...
        return options;
    }
// The example is for WebdriverIO framework
...

exports.config = {
    runner: 'local',
    protocol: 'https',
    hostname: `@app.mobitru.com`,
    ....
    capabilities: [{
        platformName: 'Android',
        'appium:automationName': 'UIAutomator2',
        'appium:udid': '28101FDH3009BP',
        ....
        'mobitru:collectDeviceLogs': true,
    }],
    ....
};
import pytest

@pytest.fixture(scope="function")
def driver():
    """Fixture to set up and tear down the Appium driver."""
    options = {
        "platformName": "Android",
        "automationName": "UIAutomator2",
        "udid": "28101FDH3009BP",
        ....
        "mobitru:collectDeviceLogs": True
    }
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Support.UI;


        [SetUp]
        public void Setup()
        {
            var appiumOptions = new AppiumOptions();

            appiumOptions.AutomationName = "UIAutomator2";
            appiumOptions.AddAdditionalAppiumOption("udid", "28101FDH3009BP");
            ....
            appiumOptions.AddAdditionalAppiumOption("mobitru:collectDeviceLogs", true);
        }

Appium log:

 private BaseOptions<? extends MutableCapabilities> generateOptionsForDevice(String platformName,String deviceSerial) {
        BaseOptions<? extends MutableCapabilities> options = platformName.equalsIgnoreCase(MobilePlatform.ANDROID) ?
                new UiAutomator2Options() : new XCUITestOptions();
        options.setCapability("udid", udid);
        options.setCapability("mobitru:collectAppiumLogs", true);
        ...
        return options;
    }
// The example is for WebdriverIO framework
...

exports.config = {
    runner: 'local',
    protocol: 'https',
    hostname: `@app.mobitru.com`,
    ....
    capabilities: [{
        platformName: 'Android',
        'appium:automationName': 'UIAutomator2',
        'appium:udid': '28101FDH3009BP',
        ....
        'mobitru:collectAppiumLogs': true,
    }],
    ....
};
import pytest

@pytest.fixture(scope="function")
def driver():
    """Fixture to set up and tear down the Appium driver."""
    options = {
        "platformName": "Android",
        "automationName": "UIAutomator2",
        "udid": "28101FDH3009BP",
        ....
        "mobitru:collectAppiumLogs": True
    }
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Support.UI;


        [SetUp]
        public void Setup()
        {
            var appiumOptions = new AppiumOptions();

            appiumOptions.AutomationName = "UIAutomator2";
            appiumOptions.AddAdditionalAppiumOption("udid", "28101FDH3009BP");
            ....
            appiumOptions.AddAdditionalAppiumOption("mobitru:collectAppiumLogs", true);
        }

Step 2: Run tests and store an Appium session ID

The Mobitru will start the logs capturing immediately after initiating a new Appium session.
However, you need to store the Appium session ID in order to download logs after finish of the tests execution.
Below you can find an example for different programming languages and the Appium lib.

public void startDriver(BaseOptions<? extends MutableCapabilities> options) {
        url = new URL(format("https://%s:%s@app.mobitru.com/wd/hub",  "<BILLING_UNIT>", "<ACCESS_KEY>"));
        driver = new AppiumDriver(url, options)
        String sessionId = driver.getSessionId().toString();
        ...

    }
// The example is for WebdriverIO framework
...

let sessionid;

exports.config = {
    runner: 'local',
    protocol: 'https',
    hostname: `@app.mobitru.com`,
    ....
    capabilities: [{
        platformName: 'Android',
        'appium:automationName': 'UIAutomator2',
        ....
    }],
    afterTest: async function (test, context, {error, result, duration, passed, retries}) {
        sessionid = browser.sessionId;
    },
};
import pytest
from appium import webdriver

PROJECT_NAME = "<TEAM_CODE>"
ACCESS_KEY = "mobitru_ak_...."
APPIUM_HUB = "app.mobitru.com"

@pytest.fixture(scope="function")
def driver():
    """Fixture to set up and tear down the Appium driver."""
    options = {
        "platformName": "Android",
        "automationName": "UIAutomator2",
       ...
    }

    driver = webdriver.Remote(
        command_executor=f"https://{PROJECT_NAME}:{ACCESS_KEY}@{APPIUM_HUB}/wd/hub",
        desired_capabilities=options
    )

    yield driver

    session_id = driver.session_id
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Support.UI;

const string ProjectName = "<TEAM_CODE>";
const string AccessKey = "mobitru_ak_...";
const string AppiumHost = "app.mobitru.com";


private AndroidDriver driver;

         [SetUp]
        public void Setup()
        {
            var appiumOptions = new AppiumOptions();

            appiumOptions.AutomationName = "UIAutomator2";
            ....

            driver = new AndroidDriver(new Uri($"{appiumHubUrl}"), appiumOptions);
        }
        
        [TearDown]
        public void TearDown()
        {
            string sessionId = driver?.SessionId.ToString();
            driver?.Quit();
        }

Step 3: Download logs after finish of the execution

You can download captured logs after finish of the tests execution.
In Mobitru we have specific APIs for that and you can find all details here.
Important note: once Appium session is finished it could take some time to prepare the log file for downloading.
Below you can find an example for popular programming languages:

// Rest-assured library is using here https://rest-assured.io/
 
public String downloadDeviceLog(String appiumSessionId) {
        return RestAssured.
                given().
                baseUri("https://app.mobitru.com/billing/unit/"+
                      <TEAM_ACCOUNT_NAME>
                      +"/automation/api").
                auth().oauth2(<ACCESS_KEY>).
                when().
                get("appium/{id}/device-log", appiumSessionId).
                then().
                statusCode(HTTP_OK).
                extract().
                body().asString();
}

public String downloadAppiumLog(String appiumSessionId) {
        return RestAssured.
                given().
                baseUri("https://app.mobitru.com/billing/unit/"+
                      <TEAM_ACCOUNT_NAME>
                      +"/automation/api").
                auth().oauth2(<ACCESS_KEY>).
                when().
                get("appium/{id}/appium-log", appiumSessionId).
                then().
                statusCode(HTTP_OK).
                extract().
                body().asString();
}
// The example is for WebdriverIO framework
const KEY = 'mobitru_ak_....';
const BILLING_UNIT = '<TEAM_CODE>';
const APPIUM_HUB = 'app.mobitru.com';

const axios = require('axios');
let sessionid;

exports.config = {
    runner: 'local',
    protocol: 'https',
    hostname: `@app.mobitru.com`,
     ....
    maxInstances: 1,
    capabilities: [{
        platformName: 'Android',
        'appium:automationName': 'UIAutomator2',
.....
        'mobitru:collectDeviceLogs': true,
        'mobitru:collectAppiumLogs': true
    }],
    afterTest: async function (test, context, {error, result, duration, passed, retries}) {
        sessionid = browser.sessionId;
    },
    afterSession: async function (config, capabilities, specs) {
        async function doRequest(sessionId, apiPath) {
            return new Promise(function (resolve, reject) {
                const url = `https://${APPIUM_HUB}/billing/unit/${BILLING_UNIT}/automation/api/appium/${sessionId}/${apiPath}`;
                const headers = {
                    "Authorization": `Bearer ${KEY}`
                };
                return axios.get(url, {headers}).then(response => {
                    // Check if the request is successful
                    if (response.status === 200) {
                        resolve(response.data); // Extract and return the response body as a string
                    } else {
                        // Throw an error if status code is not HTTP 200
                        reject(new Error(`Failed to download ${apiPath} log. Status code: ${response.status}`));
                    }
                });
            })
        }

        let deviceLog = await doRequest(sessionid, "device-log")
        let appiumLog = await doRequest(sessionid, "appium-log")
        console.log(deviceLog)
        console.log(appiumLog)
    },
};
import pytest
import requests
from appium import webdriver

PROJECT_NAME = "<TEAM_CODE>"
ACCESS_KEY = "mobitru_ak_...."
APPIUM_HUB = "app.mobitru.com"

@pytest.fixture(scope="function")
def driver():
    """Fixture to set up and tear down the Appium driver."""
    options = {
        "platformName": "Android",
        "automationName": "UIAutomator2",
       ...
    }

    driver = webdriver.Remote(
        command_executor=f"https://{PROJECT_NAME}:{ACCESS_KEY}@{APPIUM_HUB}/wd/hub",
        desired_capabilities=options
    )

    yield driver
    session_id = driver.session_id
       # Teardown
    driver.quit()
    
    download_all_logs(session_id)
    
def download_all_logs(session_id):
    device_log = download_log("device-log", session_id)
    appium_log = download_log("appium-log", session_id)
    print(device_log)
    print(appium_log)

def download_log(log_api_path, appium_session_id):
    url = f"https://{APPIUM_HUB}/billing/unit/{PROJECT_NAME}/automation/api/appium/{appium_session_id}/{log_api_path}"
    headers = {
        "Authorization": f"Bearer {ACCESS_KEY}"
    }

    # Perform the GET request
    response = requests.get(url, headers=headers)

    # Check if the request was successful
    if response.status_code == 200:
        return response.text  # Extract and return the response body as a string
    else:
        raise Exception(
            f"Failed to download {log_api_path} log. Status code: {response.status_code}, Response: {response.text}")
    
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Support.UI;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;


const string ProjectName = "<TEAM_CODE>";
const string AccessKey = "mobitru_ak_...";
const string AppiumHost = "app.mobitru.com";

private AndroidDriver driver;

         [SetUp]
        public void Setup()
        {
            var appiumOptions = new AppiumOptions();

            appiumOptions.AutomationName = "UIAutomator2";
            ....

            driver = new AndroidDriver(new Uri($"{appiumHubUrl}"), appiumOptions);
        }
        
        [TearDown]
        public void TearDown()
        {
            string sessionId = driver?.SessionId.ToString();
            driver?.Quit();
            DownloadAllLogs(sessionId);
        }
        
        private void DownloadAllLogs(string sessionId)
        {

            string deviceLog = DownloadLog("device-log", sessionId);
            string appiumLog = DownloadLog("appium-log", sessionId);

            // Print the logs
            Console.WriteLine(deviceLog);
            Console.WriteLine(appiumLog);

        }

        private string DownloadLog(string logApiPath, string appiumSessionId)
        {
            string url = $"https://{AppiumHost}/billing/unit/{ProjectName}/automation/api/appium/{appiumSessionId}/{logApiPath}";

            using (var httpClient = new HttpClient())
            {
                // Set the Authorization header
                httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessKey}");

                // Perform the GET request
                HttpResponseMessage response = httpClient.GetAsync(url).Result;

                // Check if the request was successful
                if (response.IsSuccessStatusCode)
                {
                    return response.Content.ReadAsStringAsync().Result; // Extract and return the response body as a string
                }
                else
                {
                    throw new Exception(
                        $"Failed to download {logApiPath} log. Status code: {response.StatusCode}, Response: {response.Content.ReadAsStringAsync().Result}");
                }
            }
        }        

Scroll to Top