/** * @license * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const runUnderBazel = !!process.env["RUNFILES_DIR"]; const path = require('path'); function getModulesDir() { if(runUnderBazel) { // Run under bazel return [ `external/ui_npm/node_modules`, `external/ui_dev_npm/node_modules` ]; } // Run from intellij or npm run test:kdebug return [ path.join(__dirname, 'app/node_modules'), path.join(__dirname, 'node_modules'), ]; } function getUiDevNpmFilePath(importPath) { if(runUnderBazel) { return `external/ui_dev_npm/node_modules/${importPath}`; } else { return `polygerrit-ui/node_modules/${importPath}` } } function runInIde() { // A simple detection of IDE. // Default browserNoActivityTimeout is 30 seconds. An IDE usually // runs karma in background and send commands when a user wants to // execute test. If interval between user executed tests is bigger than // browserNoActivityTimeout, the IDE reports error and doesn't restart // server. // We want to increase browserNoActivityTimeout when tests run in IDE. // Wd don't want to increase it in other cases, oterhise hanging tests // can slow down CI. return !runUnderBazel && process.argv.some(arg => arg.toLowerCase().contains('intellij')); } module.exports = function(config) { const localDirName = path.resolve(__dirname, '../.ts-out/polygerrit-ui/app'); const rootDir = runUnderBazel ? 'polygerrit-ui/app/_pg_with_tests_out/' : localDirName + '/'; const testFilesLocationPattern = `${rootDir}**/!(template_test_srcs)/`; // Use --test-files to specify pattern for a test files. // It can be just a file name, without a path: // --test-files async-foreach-behavior_test.js // If you specify --test-files without pattern, it gets true value // In this case we ill run all tests (usefull for package.json "debugtest" // script) const testFilesPattern = (typeof config.testFiles == 'string') ? testFilesLocationPattern + config.testFiles : testFilesLocationPattern + '*_test.js'; // Special patch for grep parameters (see details in the grep-patch-karam.js) const additionalFiles = runUnderBazel ? [] : ['polygerrit-ui/grep-patch-karma.js']; config.set({ browserNoActivityTimeout: runInIde ? 60 * 60 * 1000 : 30 * 1000, // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '../', plugins: [ // Do not use karma-* to load all installed plugin // This can lead to unexpected behavior under bazel // if you forget to add a plugin in a bazel rule. require.resolve('@open-wc/karma-esm'), 'karma-mocha', 'karma-chrome-launcher', 'karma-mocha-reporter', ], // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['mocha', 'esm'], // list of files / patterns to load in the browser files: [ ...additionalFiles, getUiDevNpmFilePath('source-map-support/browser-source-map-support.js'), getUiDevNpmFilePath('accessibility-developer-tools/dist/js/axs_testing.js'), getUiDevNpmFilePath('sinon/pkg/sinon.js'), { pattern: testFilesPattern, type: 'module' }, ], esm: { nodeResolve: { // By default, it tries to use page.mjs file instead of page.js // when importing 'page/page', so we shouldn't use .mjs extension // in node resolve. // The .ts extension is required to display source code in browser // (otherwise esm plugin crashes) extensions: ['.js', '.ts'], }, moduleDirs: getModulesDir(), // Bazel and yarn uses symlinks for files. // preserveSymlinks is necessary for correct modules paths resolving preserveSymlinks: true, // By default, esm-dev-server uses 'auto' compatibility mode. // In the 'auto' mode it incorrectly applies polyfills and // breaks tests in some browser versions // (for example, Chrome 69 on gerrit-ci). compatibility: 'none', plugins: [ { resolveImport(importSpecifier) { // esm-dev-server interprets .ts files as .js files and // tries to replace all module imports with relative/absolute // paths. In most cases this works correctly. However if // a ts file imports type from .d.ts and there is no // associated .js file then the esm-dev-server responds with // 500 error. // For example the following import .ts file causes problem // import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces'; // To avoid problems, we don't resolve imports in .ts files // and instead always return original path if (importSpecifier.context.originalUrl.endsWith(".ts")) { return importSpecifier.source; } return undefined; } }, { transform(context) { if (context.path.endsWith('/node_modules/page/page.js')) { const orignalBody = context.body; // Can't import page.js directly, because this is undefined. // Replace it with window // The same replace exists in server.go // Rollup makes this replacement automatically const transformedBody = orignalBody.replace( '}(this, (function () { \'use strict\';', '}(window, (function () { \'use strict\';' ); if(orignalBody.length === transformedBody.length) { console.error('The page.js was updated. Please update transform accordingly'); process.exit(1); } return {body: transformedBody}; } }, } ] }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['mocha'], mochaReporter: { showDiff: true }, // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: false, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ["CustomChromeHeadless"], browserForDebugging: "CustomChromeHeadlessWithDebugPort", // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: true, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity, client: { mocha: { ui: 'tdd', timeout: 5000, } }, customLaunchers: { // Based on https://developers.google.com/web/updates/2017/06/headless-karma-mocha-chai "CustomChromeHeadless": { base: 'ChromeHeadless', flags: ['--disable-translate', '--disable-extensions'], }, "ChromeDev": { base: 'Chrome', flags: ['--disable-extensions', ' --auto-open-devtools-for-tabs'], }, "CustomChromeHeadlessWithDebugPort": { base: 'CustomChromeHeadless', flags: ['--remote-debugging-port=9222'], } } }); };