CSS: Make the reliableTrDimensions support test work with Bootstrap CSS
[jquery.git] / Gruntfile.js
blob11260d350fcf2d807b1a46334e0a05b65b480ce5
1 "use strict";
3 module.exports = function( grunt ) {
4         function readOptionalJSON( filepath ) {
5                 const stripJSONComments = require( "strip-json-comments" );
6                 let data = {};
7                 try {
8                         data = JSON.parse( stripJSONComments(
9                                 fs.readFileSync( filepath, { encoding: "utf8" } )
10                         ) );
11                 } catch ( e ) {}
12                 return data;
13         }
15         const fs = require( "fs" );
16         const gzip = require( "gzip-js" );
17         const nodeV14OrNewer = !/^v1[0-3]\./.test( process.version );
18         const nodeV17OrNewer = !/^v1[0-6]\./.test( process.version );
19         const customBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
21         // Support: Node.js <14
22         // Skip running tasks that dropped support for Node.js 10 or 12
23         // in this Node version.
24         function runIfNewNode( task ) {
25                 return nodeV14OrNewer ? task : "print_old_node_message:" + task;
26         }
28         if ( nodeV14OrNewer ) {
29                 const playwright = require( "playwright-webkit" );
30                 process.env.WEBKIT_HEADLESS_BIN = playwright.webkit.executablePath();
31         }
33         if ( !grunt.option( "filename" ) ) {
34                 grunt.option( "filename", "jquery.js" );
35         }
37         grunt.initConfig( {
38                 pkg: grunt.file.readJSON( "package.json" ),
39                 dst: readOptionalJSON( "dist/.destination.json" ),
40                 compare_size: {
41                         files: [ "dist/jquery.js", "dist/jquery.min.js" ],
42                         options: {
43                                 compress: {
44                                         gz: function( contents ) {
45                                                 return gzip.zip( contents, {} ).length;
46                                         }
47                                 },
48                                 cache: "build/.sizecache.json"
49                         }
50                 },
51                 babel: {
52                         options: {
53                                 sourceMap: "inline",
54                                 retainLines: true,
55                                 plugins: [ "@babel/transform-for-of" ]
56                         },
57                         tests: {
58                                 files: {
59                                         "test/data/core/jquery-iterability-transpiled.js":
60                                                 "test/data/core/jquery-iterability-transpiled-es6.js"
61                                 }
62                         }
63                 },
64                 build: {
65                         all: {
66                                 dest: "dist/jquery.js",
67                                 minimum: [
68                                         "core"
69                                 ],
71                                 // Exclude specified modules if the module matching the key is removed
72                                 removeWith: {
73                                         ajax: [ "manipulation/_evalUrl", "deprecated/ajax-event-alias" ],
74                                         callbacks: [ "deferred" ],
75                                         css: [ "effects", "dimensions", "offset" ],
76                                         "css/showHide": [ "effects" ],
77                                         deferred: {
78                                                 remove: [ "ajax", "effects", "queue", "core/ready" ],
79                                                 include: [ "core/ready-no-deferred" ]
80                                         },
81                                         event: [ "deprecated/ajax-event-alias", "deprecated/event" ],
82                                         selector: [ "css/hiddenVisibleSelectors", "effects/animatedSelector" ]
83                                 }
84                         }
85                 },
86                 npmcopy: {
87                         all: {
88                                 options: {
89                                         destPrefix: "external"
90                                 },
91                                 files: {
92                                         "bootstrap/bootstrap.css": "bootstrap/dist/css/bootstrap.css",
93                                         "bootstrap/bootstrap.min.css": "bootstrap/dist/css/bootstrap.min.css",
94                                         "bootstrap/bootstrap.min.css.map": "bootstrap/dist/css/bootstrap.min.css.map",
96                                         "core-js-bundle/core-js-bundle.js": "core-js-bundle/minified.js",
97                                         "core-js-bundle/LICENSE": "core-js-bundle/LICENSE",
99                                         "npo/npo.js": "native-promise-only/lib/npo.src.js",
101                                         "qunit/qunit.js": "qunit/qunit/qunit.js",
102                                         "qunit/qunit.css": "qunit/qunit/qunit.css",
103                                         "qunit/LICENSE.txt": "qunit/LICENSE.txt",
105                                         "requirejs/require.js": "requirejs/require.js",
107                                         "sinon/sinon.js": "sinon/pkg/sinon.js",
108                                         "sinon/LICENSE.txt": "sinon/LICENSE"
109                                 }
110                         }
111                 },
112                 jsonlint: {
113                         pkg: {
114                                 src: [ "package.json" ]
115                         }
116                 },
117                 eslint: {
118                         options: {
119                                 maxWarnings: 0
120                         },
122                         // We have to explicitly declare "src" property otherwise "newer"
123                         // task wouldn't work properly :/
124                         dist: {
125                                 src: [ "dist/jquery.js", "dist/jquery.min.js" ]
126                         },
127                         dev: {
128                                 src: [
129                                         "src/**/*.js",
130                                         "Gruntfile.js",
131                                         "test/**/*.js",
132                                         "build/**/*.js",
134                                         // Ignore files from .eslintignore
135                                         // See https://github.com/sindresorhus/grunt-eslint/issues/119
136                                         ...fs
137                                                 .readFileSync( `${ __dirname }/.eslintignore`, "utf-8" )
138                                                 .split( "\n" )
139                                                 .filter( filePath => filePath )
140                                                 .map( filePath => filePath[ 0 ] === "!" ?
141                                                         filePath.slice( 1 ) :
142                                                         `!${ filePath }`
143                                                 ),
145                                         // Explicitly ignore `dist/` as it could be unignored by
146                                         // the above `.eslintignore` parsing.
147                                         "!dist/**/*.js"
148                                 ]
149                         }
150                 },
151                 testswarm: {
152                         tests: [
154                                 // A special module with basic tests, meant for not fully
155                                 // supported environments like jsdom. We run it everywhere,
156                                 // though, to make sure tests are not broken.
157                                 "basic",
159                                 "ajax",
160                                 "animation",
161                                 "attributes",
162                                 "callbacks",
163                                 "core",
164                                 "css",
165                                 "data",
166                                 "deferred",
167                                 "deprecated",
168                                 "dimensions",
169                                 "effects",
170                                 "event",
171                                 "manipulation",
172                                 "offset",
173                                 "queue",
174                                 "selector",
175                                 "serialize",
176                                 "support",
177                                 "traversing",
178                                 "tween"
179                         ]
180                 },
181                 karma: {
182                         options: {
183                                 customContextFile: "test/karma.context.html",
184                                 customDebugFile: "test/karma.debug.html",
185                                 customLaunchers: {
186                                         ChromeHeadlessNoSandbox: {
187                                                 base: "ChromeHeadless",
188                                                 flags: [ "--no-sandbox" ]
189                                         }
190                                 },
191                                 frameworks: [ "qunit" ],
192                                 middleware: [ "mockserver" ],
193                                 plugins: [
194                                         "karma-*",
195                                         {
196                                                 "middleware:mockserver": [
197                                                         "factory",
198                                                         require( "./test/middleware-mockserver.js" )
199                                                 ]
200                                         }
201                                 ],
202                                 client: {
203                                         qunit: {
205                                                 // We're running `QUnit.start()` ourselves via `loadTests()`
206                                                 // in test/jquery.js
207                                                 autostart: false
208                                         }
209                                 },
210                                 files: [
211                                         "test/data/jquery-1.9.1.js",
212                                         "external/sinon/sinon.js",
213                                         "external/npo/npo.js",
214                                         "external/requirejs/require.js",
215                                         "test/data/testinit.js",
217                                         "test/jquery.js",
219                                         {
220                                                 pattern: "dist/jquery.*",
221                                                 included: false,
222                                                 served: true,
223                                                 nocache: true
224                                         },
225                                         {
226                                                 pattern: "src/**",
227                                                 type: "module",
228                                                 included: false,
229                                                 served: true,
230                                                 nocache: true
231                                         },
232                                         { pattern: "external/**", included: false, served: true },
233                                         {
234                                                 pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
235                                                 included: false,
236                                                 served: true,
237                                                 nocache: true
238                                         }
239                                 ],
240                                 reporters: [ "dots" ],
241                                 autoWatch: false,
243                                 // 2 minutes; has to be longer than QUnit.config.testTimeout
244                                 browserNoActivityTimeout: 120e3,
246                                 concurrency: 3,
247                                 captureTimeout: 20 * 1000,
248                                 singleRun: true
249                         },
250                         main: {
251                                 browsers: customBrowsers ||
252                                         [ "ChromeHeadless", "FirefoxHeadless", "WebkitHeadless" ]
253                         },
254                         esmodules: {
255                                 browsers: customBrowsers || [ "ChromeHeadless" ],
256                                 options: {
257                                         client: {
258                                                 qunit: {
260                                                         // We're running `QUnit.start()` ourselves via `loadTests()`
261                                                         // in test/jquery.js
262                                                         autostart: false,
264                                                         esmodules: true
265                                                 }
266                                         }
267                                 }
268                         },
270                         jsdom: {
271                                 options: {
272                                         files: [
273                                                 "test/data/jquery-1.9.1.js",
274                                                 "test/data/testinit-jsdom.js",
276                                                 // We don't support various loading methods like esmodules,
277                                                 // choosing a version etc. for jsdom.
278                                                 "dist/jquery.js",
280                                                 // A partial replacement for testinit.js#loadTests()
281                                                 "test/data/testrunner.js",
283                                                 // jsdom only runs basic tests
284                                                 "test/unit/basic.js",
286                                                 {
287                                                         pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
288                                                         included: false,
289                                                         served: true
290                                                 }
291                                         ]
292                                 },
293                                 browsers: [ "jsdom" ]
294                         },
296                         // To debug tests with Karma:
297                         // 1. Run 'grunt karma:chrome-debug' or 'grunt karma:firefox-debug'
298                         //    (any karma subtask that has singleRun=false)
299                         // 2. Press "Debug" in the opened browser window to start
300                         //    the tests. Unlike the other karma tasks, the debug task will
301                         //    keep the browser window open.
302                         "chrome-debug": {
303                                 browsers: [ "Chrome" ],
304                                 singleRun: false
305                         },
306                         "firefox-debug": {
307                                 browsers: [ "Firefox" ],
308                                 singleRun: false
309                         },
310                         "ie-debug": {
311                                 browsers: [ "IE" ],
312                                 singleRun: false
313                         }
314                 },
315                 watch: {
316                         files: [ "<%= eslint.dev.src %>" ],
317                         tasks: [ "dev" ]
318                 },
319                 minify: {
320                         all: {
321                                 files: {
322                                         "dist/<%= grunt.option('filename').replace('.js', '.min.js') %>":
323                                                 "dist/<%= grunt.option('filename') %>"
324                                 },
325                                 options: {
326                                         sourceMap: {
327                                                 filename: "dist/<%= grunt.option('filename').replace('.js', '.min.map') %>",
329                                                 // The map's `files` & `sources` property are set incorrectly, fix
330                                                 // them via overrides from the task config.
331                                                 // See https://github.com/swc-project/swc/issues/7588#issuecomment-1624345254
332                                                 overrides: {
333                                                         file: "jquery.min.js",
334                                                         sources: [
335                                                                 "jquery.js"
336                                                         ]
337                                                 }
338                                         },
339                                         swc: {
340                                                 format: {
341                                                         ecma: 5,
342                                                         asciiOnly: true,
343                                                         comments: false,
344                                                         preamble: "/*! jQuery v4.0.0-pre | " +
345                                                                 "(c) OpenJS Foundation and other contributors | " +
346                                                                 "jquery.org/license */\n"
347                                                 },
348                                                 compress: {
349                                                         ecma: 5,
350                                                         hoist_funs: false,
351                                                         loops: false
352                                                 },
353                                                 mangle: true
354                                         }
355                                 }
356                         }
357                 }
358         } );
360         // Load grunt tasks from NPM packages
361         require( "load-grunt-tasks" )( grunt, {
362                 pattern: nodeV14OrNewer ? [ "grunt-*" ] : [ "grunt-*", "!grunt-eslint" ]
363         } );
365         // Integrate jQuery specific tasks
366         grunt.loadTasks( "build/tasks" );
368         grunt.registerTask( "print_old_node_message", ( ...args ) => {
369                 var task = args.join( ":" );
370                 grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." );
371         } );
373         grunt.registerTask( "print_jsdom_message", () => {
374                 grunt.log.writeln( "Node.js 17 or newer detected, skipping jsdom tests..." );
375         } );
377         grunt.registerTask( "lint", [
378                 "jsonlint",
380                 // Running the full eslint task without breaking it down to targets
381                 // would run the dist target first which would point to errors in the built
382                 // file, making it harder to fix them. We want to check the built file only
383                 // if we already know the source files pass the linter.
384                 runIfNewNode( "eslint:dev" ),
385                 runIfNewNode( "eslint:dist" )
386         ] );
388         grunt.registerTask( "lint:newer", [
389                 "newer:jsonlint",
391                 // Don't replace it with just the task; see the above comment.
392                 runIfNewNode( "newer:eslint:dev" ),
393                 runIfNewNode( "newer:eslint:dist" )
394         ] );
396         grunt.registerTask( "test:fast", runIfNewNode( "node_smoke_tests" ) );
397         grunt.registerTask( "test:slow", [
398                 runIfNewNode( "promises_aplus_tests" ),
400                 // Support: Node.js 17+
401                 // jsdom fails to connect to the Karma server in Node 17+.
402                 // Until we figure out a fix, skip jsdom tests there.
403                 nodeV17OrNewer ? "print_jsdom_message" : runIfNewNode( "karma:jsdom" )
404         ] );
406         grunt.registerTask( "test:prepare", [
407                 "npmcopy",
408                 "qunit_fixture",
409                 "babel:tests"
410         ] );
412         grunt.registerTask( "test", [
413                 "test:prepare",
414                 "test:fast",
415                 "test:slow"
416         ] );
418         grunt.registerTask( "dev", [
419                 "build:*:*",
420                 runIfNewNode( "newer:eslint:dev" ),
421                 "newer:minify",
422                 "remove_map_comment",
423                 "dist:*",
424                 "qunit_fixture",
425                 "compare_size"
426         ] );
428         grunt.registerTask( "default", [
429                 runIfNewNode( "eslint:dev" ),
430                 "build:*:*",
431                 "minify",
432                 "remove_map_comment",
433                 "dist:*",
434                 "test:prepare",
435                 runIfNewNode( "eslint:dist" ),
436                 "test:fast",
437                 "compare_size"
438         ] );