| /** |
| * @license |
| * Copyright 2020 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| const runUnderBazel = !!process.env["RUNFILES_DIR"]; |
| const path = require("path"); |
| |
| function getModulesDir() { |
| if (runUnderBazel) { |
| // Run under bazel |
| return [ |
| `external/plugins_npm/node_modules`, |
| `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) { |
| let root = config.root; |
| if (!root) { |
| console.warn(`--root argument not set. Falling back to __dirname.`); |
| root = path.resolve(__dirname) + "/"; |
| } |
| // 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 will run all tests (usefull for package.json "debugtest" |
| // script) |
| // We will convert a .ts argument to .js and fill in .js if no extension is |
| // given. |
| let filePattern; |
| if (typeof config.testFiles === "string") { |
| if (config.testFiles.endsWith(".ts")) { |
| filePattern = |
| config.testFiles.substr(0, config.testFiles.lastIndexOf(".")) + ".js"; |
| } else if (config.testFiles.endsWith(".js")) { |
| filePattern = config.testFiles; |
| } else { |
| filePattern = config.testFiles + ".js"; |
| } |
| } else { |
| filePattern = "*_test.js"; |
| } |
| const testFilesPattern = root + "**/" + filePattern; |
| |
| console.info(`Karma test file pattern: ${testFilesPattern}`); |
| // 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" |
| ), |
| { |
| pattern: getUiDevNpmFilePath("@open-wc/semantic-dom-diff/index.js"), |
| type: "module", |
| }, |
| { |
| pattern: getUiDevNpmFilePath("@open-wc/testing-helpers/index.js"), |
| type: "module", |
| }, |
| 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, |
| }, |
| |
| // Listen on localhost so it either listens to ipv4 |
| // or ipv6. Some OS's default to ipv6 for localhost |
| // and others ipv4. |
| // Nodejs 17 changed the behaviour from prefering ipv4 to |
| // using the OS settings. |
| // The default is 127.0.0.1 thus if localhost is on ipv6 only |
| // it'll fail to connect to the karma server. |
| // See https://github.com/karma-runner/karma/blob/e17698f950af83bf2b3edc540d2a3e1fb73cba59/lib/utils/dns-utils.js#L3 |
| listenAddress: "localhost", |
| |
| // 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"], |
| }, |
| }, |
| }); |
| }; |