How to export a summary of mabl test results to a CSV using Node

You can use the following Node.js script example with the mabl Reporting API batch results endpoint to retrieve a set of test run results and transform them into a CSV format.

Setup

To execute the example script you’ll need Node.js installed, which is available for all major platforms here.

With Node.js installed, you also need to install the axios library to communicate with APIs like the mabl Reporting API. From the command line, in a directory where you want to create this script, you can install the axios library using npm, which comes with Node.js:

npm install [email protected] --save

Sample script

Save the following script as index.js in the same directory where you installed axios. You can edit the TEST_RUN_FIELDS list in the script if you do not want all fields in the CSV output or want to change their order.

const axios = require('axios');
const process = require('process');
const fs = require('fs');

// Check correct number of arguments and provide usage help
if (process.argv.length < 5 || process.argv.length > 6) {
  console.error('Usage: node index.js WORKSPACE_ID MABL_API_KEY OUTPUT_FILE [API_QUERY_PARAMS]');
  process.exit(1);
}

const WORKSPACE_ID = process.argv[2];
const MABL_API_KEY = process.argv[3];
const OUTPUT_FILE = process.argv[4];
const QUERY_PARAMS = process.argv[5];

let MABL_ENDPOINT_URL = `https://api.mabl.com/results/workspace/${WORKSPACE_ID}/testRuns?${QUERY_PARAMS || ''}`;

// Ordered fields to extract from each test run
const TEST_RUN_FIELDS = [
  'application_id',
  'application_name',
  'environment_id',
  'environment_name',
  'initial_url',
  'scenario_name',
  'browser',
  'browser_version',
  'execution_runner_type',
  'plan_id',
  'plan_name',
  'plan_run_id',
  'test_id',
  'test_version',
  'test_name',
  'test_type',
  'branch',
  'test_run_id',
  'test_run_app_url',
  'is_ad_hoc_run',
  'failure_category',
  'start_time',
  'end_time',
  'run_time',
  'status',
  'success',
  'trigger_type',
  'triggering_deployment_event_id',
  'emulation_mode',
  'metrics.cumulative_speed_index',
  'metrics.cumulative_api_response_time',
  'metrics.accessibility_rule_violations.critical',
  'metrics.accessibility_rule_violations.serious',
  'metrics.accessibility_rule_violations.moderate',
  'metrics.accessibility_rule_violations.minor',
];

function getField(object, field) {
  return field
    .split('.')
    .reduce((currentObject, currentField) =>  currentObject === undefined || currentObject === null ? undefined : currentObject[currentField], object);
}

async function getRunResults(cursor) {
  let url = MABL_ENDPOINT_URL;
  if (cursor !== undefined) {
    url += `&cursor=${cursor}`;
  }
  console.log(`Fetching results with cursor=${cursor}`);
  const response = await axios.get(url, {
    auth: {
      username: 'key',
      password: MABL_API_KEY,
    }
  });
  if (!response.data) {
    console.error(`No data returned from mabl API; full response: ${JSON.stringify(response)}`);
  }
  return response.data;
}

function getResultFields(results) {
  return results.map(result => {
    return TEST_RUN_FIELDS
      .map(field => escapeValue(getField(result, field)));
  });
}

function escapeValue(value) {
  if (value === undefined) {
    return '';
  }
  if (typeof value === 'string') {
    return value.replace(/,/g, '_');
  }
  return value;
}

function resultRowsToCsv(results) {
  return results
    .map(row => row.join(','))
    .join('\n') + '\n';
}

async function getAllRunResults() {
  let cursor;
  const outStream = fs.createWriteStream(OUTPUT_FILE);
  outStream.write(resultRowsToCsv([TEST_RUN_FIELDS]));
  do {
    const data = await getRunResults(cursor);
    if (data) {
      cursor = data.cursor;
      const results = getResultFields(data.test_results || []);
      outStream.write(resultRowsToCsv(results));
    } else {
      break;
    }
  } while (cursor !== undefined);
  outStream.end();
}

getAllRunResults().catch(console.error);

Running the script

The index.js script can be called from the command line to retrieve results from the mabl Reporting API and save them to a CSV file:

node index.js <WORKSPACE_ID> <API_KEY> <OUT_FILE> <QUERY_PARAMETER_STRING>

The index.js script takes the following arguments:

  • <WORKSPACE_ID>: replace <WORKSPACE_ID> below with your workspace ID
  • <API_KEY>: have a workspace owner create or use an existing mabl Viewer API key and replace <API_KEY> with the key secret.
  • <OUT_FILE>: replace <OUT_FILE> with the output file name, such as results.csv
  • <QUERY_PARAMETER_STRING>: use this optional argument to filter your results.

See the API documentation for the batch run results endpoint to find available query parameters and create an appropriate query parameter string to replace <QUERY_PARAMETER_STRING>.

For example, to specify all runs within a time range, use https://www.epochconverter.com/ to get the desired start and end timestamp in milliseconds and use them with in a query parameter string as follows: earliest_run_start_time=1677506400000&latest_run_start_time=1677592800000