2 module.exports = function ( grunt ) {
3 grunt.loadNpmTasks( 'grunt-banana-checker' );
4 grunt.loadNpmTasks( 'grunt-contrib-copy' );
5 grunt.loadNpmTasks( 'grunt-eslint' );
6 grunt.loadNpmTasks( 'grunt-karma' );
7 grunt.loadNpmTasks( 'grunt-stylelint' );
9 const fs = require( 'fs' );
10 const path = require( 'path' );
11 const wgServer = process.env.MW_SERVER;
12 const wgScriptPath = process.env.MW_SCRIPT_PATH;
13 const karmaProxy = {};
15 let qunitPattern = wgServer + wgScriptPath + '/index.php?title=Special:JavaScriptTest/qunit/export';
17 // "MediaWiki" for core, or extension/skin name (e.g. "GrowthExperiments")
18 const qunitComponent = grunt.option( 'qunit-component' );
19 const qunitWatch = grunt.option( 'qunit-watch' ) || false;
20 const qunitWatchFiles = [];
21 if ( qunitComponent ) {
22 let qunitWatchSourcePattern;
23 let qunitWatchTestPattern;
24 qunitPattern = qunitPattern + '&component=' + qunitComponent;
26 // Special-case MediaWiki core.
27 if ( qunitComponent === 'MediaWiki' ) {
28 qunitWatchTestPattern = 'tests/qunit/**/*.js';
29 qunitWatchSourcePattern = 'resources/**/*.js';
34 basePath = 'extensions';
35 // eslint-disable-next-line security/detect-non-literal-fs-filename
36 settingsJson = fs.readFileSync(
37 path.resolve( __dirname + '/' + basePath + '/' + qunitComponent + '/extension.json' )
41 // eslint-disable-next-line security/detect-non-literal-fs-filename
42 settingsJson = fs.readFileSync(
43 path.resolve( __dirname + '/' + basePath + '/' + qunitComponent + '/skin.json' )
46 settingsJson = JSON.parse( settingsJson );
47 qunitWatchSourcePattern =
48 path.resolve( __dirname + '/' + basePath + '/' + qunitComponent + '/' + settingsJson.ResourceFileModulePaths.localBasePath + '/**/*.js' );
49 qunitWatchTestPattern = path.resolve( __dirname + '/' + basePath + '/' + qunitComponent + '/tests/qunit/**/*.js' );
51 qunitWatchFiles.push( {
52 pattern: qunitWatchSourcePattern,
58 qunitWatchFiles.push( {
59 pattern: qunitWatchTestPattern,
68 karmaProxy[ wgScriptPath ] = {
69 target: wgServer + wgScriptPath,
76 extensions: [ '.js', '.json', '.vue' ],
78 fix: grunt.option( 'fix' )
84 requireLowerCase: false,
85 disallowBlankTranslations: false
87 core: 'languages/i18n/',
88 exif: 'languages/i18n/exif/',
89 api: 'includes/api/i18n/',
90 rest: 'includes/Rest/i18n/',
91 installer: 'includes/installer/i18n/',
92 paramvalidator: 'includes/libs/ParamValidator/i18n/'
96 reportNeedlessDisables: true
98 resources: 'resources/src/**/*.{css,less,vue}',
99 config: 'mw-config/**/*.css'
103 '.{stylelintrc,eslintrc}.json',
105 '!{extensions,node_modules,skins,vendor}/**'
113 base: 'ChromeHeadless',
114 // Chrome requires --no-sandbox in Docker/CI.
115 // WMF CI images expose CHROMIUM_FLAGS which sets that.
116 flags: process.env.CHROMIUM_FLAGS ? ( process.env.CHROMIUM_FLAGS || '' ).split( ' ' ) : []
121 pattern: qunitPattern,
126 }, ...qunitWatchFiles ],
127 logLevel: ( process.env.ZUUL_PROJECT ? 'DEBUG' : 'INFO' ),
128 frameworks: [ 'qunit' ],
129 reporters: [ 'mocha' ],
130 singleRun: !qunitWatch,
131 autoWatch: qunitWatch,
132 // Some tests in extensions don't yield for more than the default 10s (T89075)
133 browserNoActivityTimeout: 60 * 1000,
134 // Karma requires Same-Origin (or CORS) by default since v1.1.1
135 // for better stacktraces. But we load the first request from wgServer
136 crossOriginAttribute: false
139 browsers: [ 'ChromeCustom' ]
142 browsers: [ 'FirefoxHeadless' ]
147 src: 'resources/**/*',
148 dest: 'docs/js/modules',
150 rename: function ( dest, src ) {
151 return require( 'path' ).join( dest, src.replace( 'resources/', '' ) );
157 grunt.registerTask( 'assert-mw-env', function () {
159 if ( !process.env.MW_SERVER ) {
160 grunt.log.error( 'Environment variable MW_SERVER must be set.\n' +
161 'Set this like $wgServer, e.g. "http://localhost"'
165 if ( !process.env.MW_SCRIPT_PATH ) {
166 grunt.log.error( 'Environment variable MW_SCRIPT_PATH must be set.\n' +
167 'Set this like $wgScriptPath, e.g. "/w"' );
173 grunt.registerTask( 'lint', [ 'eslint', 'banana', 'stylelint' ] );
174 grunt.registerTask( 'qunit', [ 'assert-mw-env', 'karma:main' ] );