189 lines
6.8 KiB
JavaScript
189 lines
6.8 KiB
JavaScript
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2014-2019 (original work) Open Assessment Technlogies SA
|
|
*
|
|
*/
|
|
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { URL } = require('url');
|
|
|
|
/**
|
|
* Main configuration to run tests
|
|
*
|
|
* grunt connect:test qunit:extension --extension=taoQtiTest
|
|
* grunt connect:test qunit:single --text=/taoQtiTest/views/js/test/runner/qti/test.html
|
|
*
|
|
* @param {Object} grunt - grunt instance
|
|
* @returns {void}
|
|
*/
|
|
module.exports = function(grunt) {
|
|
|
|
const root = grunt.option('root');
|
|
const testPort = grunt.option('testPort');
|
|
const testUrl = grunt.option('testUrl');
|
|
const livereloadPort = grunt.option('livereloadPort');
|
|
const reportOutput = grunt.option('reports');
|
|
const ext = require(`${root}/tao/views/build/tasks/helpers/extensions`)(grunt, root);
|
|
const baseUrl = `http://${testUrl}:${testPort}`;
|
|
const testRunners = `${root}/tao/views/js/test/**/test.html`;
|
|
|
|
|
|
//extract unit tests from FS to URL
|
|
const extractTests = function extractTests(){
|
|
return grunt.file.expand([testRunners]).map(function(testPath){
|
|
return testPath.replace(root, baseUrl);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Creates a namespace from the test url (the reports needs namspaces)
|
|
* For example :
|
|
* From 'http://127.0.0.1:8082/tao/views/js/test/core/eventifier/test.html'
|
|
* To 'tao.core.eventifier'
|
|
* Expecting the following URL pattern '${baseUrl}/${extensionName}/views/js/test/${path}/test.html'
|
|
*
|
|
* @param {String} url - the URl of the test
|
|
* @param {String} [joinWith=.] - the glue character for the namespace, replacing the slashes
|
|
* @param {String} [suffix] - namespace suffix
|
|
* @returns {String} the test namespace
|
|
*/
|
|
const testUrlToNamespace = function testUrlToNamespace(url = '', joinWith = '.', suffix) {
|
|
|
|
const namespaceChunks = path.dirname(new URL(url).pathname)
|
|
.replace('views/js/test', '')
|
|
.split('/')
|
|
.filter( entry => !!entry );
|
|
|
|
if(suffix){
|
|
namespaceChunks.push(suffix);
|
|
}
|
|
return namespaceChunks.join(joinWith);
|
|
};
|
|
|
|
grunt.config.merge({
|
|
|
|
qunit : {
|
|
|
|
//global options
|
|
options : {
|
|
inject: './config/chrome-bridge.js',
|
|
timeout: 30000,
|
|
puppeteer : {
|
|
ignoreHTTPSErrors: true,
|
|
timeout: 30000,
|
|
args: [ '--no-sandbox', '--disable-gpu', '--disable-popup-blocking' , '--autoplay-policy=no-user-gesture-required'],
|
|
defaultViewport: {
|
|
width: 1280,
|
|
height: 720,
|
|
deviceScaleFactor: 1
|
|
}
|
|
}
|
|
},
|
|
|
|
//run a single test (requires the options test=${testUrl})
|
|
single : {
|
|
options : {
|
|
console: true,
|
|
urls: [baseUrl + grunt.option('test')]
|
|
}
|
|
},
|
|
|
|
//tests for the tao extension
|
|
taotest : {
|
|
options : {
|
|
console : true,
|
|
urls : extractTests()
|
|
}
|
|
}
|
|
},
|
|
|
|
//convert QUnit report to JUnit reports for Jenkins
|
|
'qunit_junit' : {
|
|
options : {
|
|
dest : reportOutput,
|
|
fileNamer : url => testUrlToNamespace(url, '-'),
|
|
classNamer : (moduleName, url) => {
|
|
//moduleName is a sentence so make it camelcase
|
|
const moduleNameSuffix = moduleName
|
|
.toLowerCase()
|
|
.replace(/ (.)/g, (fullMatch,firstMatch) => firstMatch.toUpperCase() );
|
|
|
|
return testUrlToNamespace(url, '.', moduleNameSuffix);
|
|
}
|
|
}
|
|
},
|
|
|
|
//starts a static web server to serve assets for tests and the requirejs config
|
|
connect : {
|
|
options: {
|
|
protocol : 'http',
|
|
hostname : testUrl,
|
|
port: testPort,
|
|
base: root,
|
|
middleware: function(connect, options, middlewares) {
|
|
const rjsConfig = require('../config/requirejs.build.json');
|
|
rjsConfig.baseUrl = `${baseUrl}/tao/views/js`;
|
|
ext.getExtensions().forEach(function(extension){
|
|
rjsConfig.paths[extension] = `../../../${extension}/views/js`;
|
|
rjsConfig.paths[`${extension}Css`] = `../../../${extension}/views/css`;
|
|
});
|
|
|
|
const extraPaths = ext.getExtensionsExtraPaths();
|
|
rjsConfig.paths = {...rjsConfig.paths, ...extraPaths};
|
|
|
|
// inject a mock for the requirejs config
|
|
middlewares.unshift(function(req, res, next) {
|
|
if (/\/tao\/ClientConfig\/config/.test(req.url)){
|
|
res.writeHead(200, { 'Content-Type' : 'application/javascript'});
|
|
return res.end(`require.config(${JSON.stringify(rjsConfig)})`);
|
|
}
|
|
return next();
|
|
});
|
|
|
|
//allow post requests
|
|
middlewares.unshift(function(req, res, next) {
|
|
if (req.method.toLowerCase() === 'post') {
|
|
const filepath = path.join(options.base[0], req.url);
|
|
if (fs.existsSync(filepath)) {
|
|
fs.createReadStream(filepath).pipe(res);
|
|
return;
|
|
}
|
|
}
|
|
return next();
|
|
});
|
|
|
|
return middlewares;
|
|
}
|
|
},
|
|
test : {
|
|
options : {
|
|
livereload: false
|
|
}
|
|
},
|
|
dev : {
|
|
options : {
|
|
livereload: livereloadPort
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// test task
|
|
grunt.registerTask('taotest', ['qunit:taotest']);
|
|
};
|