| /** |
| * @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'], |
| |
| |
| // 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'], |
| } |
| } |
| }); |
| }; |