ti-appium
Version:
An Appium wrapper to test Titanium applications
191 lines (167 loc) • 5.49 kB
JavaScript
;
const
path = require('path'),
fs = require('fs-extra'),
Mocha = require('mocha'),
output = require('./output.js');
/**
* @class Mocha_Helper
* @desc
* Used for pulling in test files, and launching a Mocha test suite.
*/
class Mocha_Helper {
/**
* Goes through the passed directory, and extracts any tests that match the
* regular expression.
*
* @param {String} dir - The directory to search
*/
static collectTests(dir) {
return new Promise((resolve, reject) => {
output.debug('Fetching test files');
// Our container for all the test files to be run
let tests = [];
try {
output.debug(`Searching in ${dir} for tests`);
// Iterate through each file within the test directory
fs.readdirSync(dir).forEach(file => {
// Only use actual test files, ignore everything else
if (file.match(/.+\.test\.js/g)) {
let filePath = path.join(dir, file);
tests.push(filePath);
}
});
} catch (err) {
reject(err);
}
output.debug(`Found ${tests.length} test file(s)`);
return resolve(tests);
});
}
/**
* Runs through the Mocha tests outlined in device_config.js
*
* @param {Array} testFiles - An array of test files for Mocha to run
* @param {String} modRoot - The path to the root of the project being tested
* @param {Object} opts - Optional Arguments
* @param {Int} opts.timeout - Timeout threshold for Mocha tests
* @param {Int} opts.slow - Slow threshold for Mocha tests
*/
static run(testFiles, modRoot, { timeout = 60000, slow = 30000 } = {}) {
return new Promise((resolve, reject) => {
// Have to clear cache so that Mocha will run the same tests twice, solution taken from here https://github.com/mochajs/mocha/issues/995#issuecomment-261752316
Object.keys(require.cache).forEach((file) => {
delete require.cache[file];
});
// Get the current date time, to label the test run in a unique manner
const
moment = require('moment-timezone'),
time = moment().format('DD-MM-YY_HH꞉mm:ss');
// Create the labels
const
outDir = path.join(modRoot, 'Reports'),
outFile = path.join(outDir, `${time}.xml`);
// Make sure our result location exists
fs.ensureFileSync(outFile);
output.debug(`Putting Jenkins results in ${time}.xml`);
// Create the new Mocha instance
let mocha = new Mocha({
fullTrace: false,
useColors: true,
timeout: timeout,
slow: slow,
reporter: 'mocha-jenkins-reporter',
reporterOptions: {
junit_report_name: time,
junit_report_path: outFile,
junit_report_stack: 1
}
});
// If tests are numbered, ensure they're executed in the correct order
let collator = new Intl.Collator(undefined, {
numeric: true,
sensitivity: 'base'
});
testFiles.sort(collator.compare);
// Add all of the test files one by one
testFiles.forEach(file => {
mocha.addFile(file);
});
let tests = [];
output.debug('Handing off to Mocha for testing');
// Run the supplied test files
try {
mocha.run(() => {
output.debug('Tests complete, exiting Mocha');
resolve(tests);
})
.on('test end', data => {
try {
// Attempt to pull the name of the ticket using the file path of the test
let
test,
fileName = path.basename(data.file),
index = tests.indexOf(tests.find(x => x.fileName === fileName));
if (data.pending === true) {
// Check if the ticket is already in the array
if (index >= 0) {
// Add the skip message onto the object
tests[index].errors.push(data.title.replace(/\\/g, '').replace(/"/g, '\'').replace(/\n/, ''));
} else {
// If a ticket object isn't already in the array, create it
test = {
state: 3,
name: data.title,
fileName: fileName,
errors: [ data.title.replace(/\\/g, '').replace(/"/g, '\'').replace(/\n/, '') ]
};
}
} else if (data.state === 'passed') {
// Check if the ticket is already in the array
if (index >= 0) {
// Change the state of the test to a pass if it was previously skipped
if (tests[index].state === 3) {
tests[index].state = 1;
}
} else {
// Create a new ticket object if one doesn't exist
test = {
state: 1,
name: data.title,
fileName: fileName,
errors: []
};
}
} else if (data.state === 'failed') {
// Create a message to be attatched to the ticket
let failMessage = `[TEST STEP] ${data.title.replace(/"/g, '\'')}\\n[RESULT] ${data.err.message.replace(/\\/g, '').replace(/"/g, '\'').replace(/\n/, '')}`;
// Check if the ticket is already in the array
if (index >= 0) {
// Change the state of the test to a failure
tests[index].state = 2;
// Add the error into the array
tests[index].errors.push(failMessage);
} else {
// Create a new ticket object if one doesn't exist
test = {
state: 2,
name: data.title,
fileName: fileName,
errors: [ failMessage ]
};
}
}
if (test) {
tests.push(test);
}
} catch (err) {
output.debug(err);
}
});
} catch (err) {
reject(`Issue on Mocha run: ${err}`);
}
});
}
}
module.exports = Mocha_Helper;