Run the sample web app visual test

Step 1: Setup environment

Requirements

  • Npm tool
  • WebdriverIO framework
  • Access key
    • You can generate an Access key using the following instruction – Access key
  • Billing unit
    • The billing unit is your team’s unique identifier, or just the word “personal” in the case of an individual account.
      More information can be found here.

Step 2: Prepare the test configuration

After setup up the environment, you need to prepare the test configuration

const KEY = 'mobitru_ak....';
const BILLING_UNIT = '<TEAM_CODE>';

const credentials = `${BILLING_UNIT}:${KEY}`;
const encodedCredentials = Buffer.from(credentials).toString('base64');

exports.config = {
    runner: 'local',
    protocol: 'https',
    hostname: `@app.mobitru.com`,
    headers: {
        Authorization: `Basic ${encodedCredentials}`
    },
    path: '/wd/hub',
    logLevel: 'debug',
    port: 443,
    specs: ['./test/specs/**/web-appium-demo.js'], // Path to your test file.
    maxInstances: 1,
    capabilities: [{
        platformName: 'iOS',
        'appium:automationName': 'XCUITest',
        'appium:platformVersion': '18.2',    // specific device capabilities
        'appium:browserName': 'safari',
        'appium:deviceName': 'IPHONE iPhone17,1',
    }],
    bail: 0,
    waitForTimeout: 10000, // Default timeout for wait commands
    connectionRetryTimeout: 120000,
    connectionRetryCount: 3,
    framework: 'mocha',
    reporters: ['allure'],
    mochaOpts: {
        ui: 'bdd',
        timeout: 60000
    }
};

Step 3: Add the interaction with visual testing API

After setup up the environment, you need to add the interaction with the visual testing API:

const axios = require('axios');
const FormData = require("form-data");

class VisualTestingAPI {
    constructor(baseUrl, apiKey) {
        this.baseUrl = baseUrl;
        this.apiKey = apiKey;

        // Initialize an Axios instance
        this.http = axios.create({
            baseURL: this.baseUrl,
            headers: {
                Authorization: `Bearer ${this.apiKey}`,
                "Content-Type": "application/json",
            },
        });
    }


    async createBuild(inputData) {
        const response = await this.http.post("/builds", inputData);
        if (response.status === 200) {
            return response.data; // VisualBuildData object
        } else {
            console.log(`Unexpected status code: ${response.status}`);
        }
    }

    async finishBuild(buildId) {
        const response = await this.http.post(`/builds/${buildId}/finish`);
        if (response.status === 200) {
            console.log("Build finished successfully!");
        } else {
            console.log(`Unexpected status code: ${response.status}`);
        }
    }

    async submitSnapshot(driver, buildId, visualBuildInputData) {
        const response = await this.http.post(
            `/builds/${buildId}/snapshots`,
            visualBuildInputData,
            {
                headers: {
                    Authorization: `Bearer ${this.apiKey}`,
                    'Content-Type': 'multipart/form-data'
                },
            }
        );
        if (response.status === 201) {
            return response.data; // VisualBuildData object
        } else {
            console.log(`Unexpected status code: ${response.status}`);
        }
    }
}

Step 4: Run sample test

After setup up the environment and integrating the visual testing API, you can run your first web visual test

const assert = require('assert');
const axios = require('axios');
const fs = require('fs');
const tmp = require('tmp');
const path = require('path');
const FormData = require("form-data");

const API_KEY = 'mobitru_ak....';
const BILLING_UNIT = '<TEAM_CODE>';
const VISUAL_TESTING_API_HOST = 'visual.mobitru.com';
const VISUAL_TESTING_API_BASE_URL = `https://${VISUAL_TESTING_API_HOST}/billing/unit/${BILLING_UNIT}/api/v1`;


const visualTestingApi = new VisualTestingAPI(VISUAL_TESTING_API_BASE_URL, API_KEY);

describe('Appium Demo Test', () => {
    const OPEN_URL = 'https://mobitru.com/';
    const VISUAL_TEST_NAME = "visual js appium web demo";
    const DEFAULT_WAIT_TIMEOUT_MS = 10000;
    let visualBuildData;

    before(async () => {
        const buildInput = {
            name: "Build 1",
            project: "JS iOS Web Automation Demo",
            branch: "main"
        };
        visualBuildData = await visualTestingApi.createBuild(buildInput);
        console.log("Build Created:", visualBuildData);
        // Maximize the window for testing (if supported)
        await browser.setTimeout({ pageLoad: 30000, implicit: 3000 });
    });

    it('should navigate to Mobitru and verify the page loads correctly', async () => {
        // Navigate to the URL
        await browser.url(OPEN_URL);

        // Wait for the Mobitru main page to load
        const demoButton = await $('button[class*="demo"]');
        await demoButton.waitForDisplayed({ timeout: DEFAULT_WAIT_TIMEOUT_MS });

        // Verify the current URL
        const currentUrl = await browser.getUrl();
        assert.strictEqual(currentUrl, OPEN_URL, 'The current URL is incorrect.');

        await submitSnapshot(driver, 'after_open', VISUAL_TEST_NAME, visualBuildData, visualTestingApi);
    });

    after(async () => {
        await visualTestingApi.finishBuild(visualBuildData.id);
    });
});


async function submitSnapshot(driver, name, testName, visualBuildData, visualTestingApi) {
    //save screenshot
    const tmpFile = tmp.fileSync({postfix: '.png'});
    const tmpFilePath = tmpFile.name;
    await driver.saveScreenshot(tmpFilePath);

    const formData = new FormData();
    formData.append("name", name);
    formData.append("testName", testName);
    formData.append("suiteName", visualBuildData.projectName);
    formData.append("device", driver.capabilities["appium:udid"]);
    formData.append("image", fs.createReadStream(tmpFilePath), {
        filename: path.basename(tmpFilePath),
        contentType: 'image/png'
    });

    await visualTestingApi.submitSnapshot(driver, visualBuildData.id, formData);
}
Scroll to Top