Karma-webpack does not download AngularJS package

I recently started the transition with a custom gulp script that was used to handle all sorts of things in webpack. I am working on the fact that the translation, integration and maintenance of the client application in the browser works fine.

Now that I used gulp to run my karma tests complete with the app.js file, the gulp script first linked the app.js file and then put it in the dist folder. This file will then be used by karma to run tests against it. My gulp test task will also keep track of any changes to the test file or to modify the package file and restart the tests based on this.

With webpack, I understand that dist / app.js is in memory and not written to disk (at least the way I configured it). The problem is that apparently my linked application (which gets great using webpack-dev-server --open ) for some reason does not load with karma, and I cannot figure out what the missing part of the puzzle is .

This is what my folder structure looks like (I left only the simplest things that may be relevant to the problem):

 package.json webpack.config.js karma.conf.js src/ --app/ ----[other files/subfolders] ----app.ts ----index.ts --boot.ts --index.html tests/ --common/ ----services/ ------account.service.spec.js 

This is my webpack.config.js

 var path = require("path"); const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); module.exports = { context: path.join(__dirname), entry: "./src/boot.ts", plugins: [ new webpack.HotModuleReplacementPlugin(), new ForkTsCheckerWebpackPlugin(), new CleanWebpackPlugin(["dist"]), new HtmlWebpackPlugin({ template: "./src/index.html" }) ], module: { rules: [ { test: /\.scss$/, use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "sass-loader" }] }, { test: /\.tsx?$/, use: [{ loader: "ts-loader", options: { transpileOnly: true, exclude: /node_modules/ } }] }, { test: /\.html$/, loaders: "html-loader", options: { attrs: [":data-src"], minimize: true } } ] }, resolve: { extensions: [".tsx", ".ts", ".js"], alias: { "common": path.resolve(__dirname, "src/app/common"), "common/*": path.resolve(__dirname, "src/app/common/*"), "modules": path.resolve(__dirname, "src/app/modules"), "modules/*": path.resolve(__dirname, "src/app/modules/*"), } }, output: { filename: "app.js", path: path.resolve(__dirname, "dist") }, devtool: "inline-source-map", devServer: { historyApiFallback: true, hot: false, contentBase: path.resolve(__dirname, "dist") } }; 

This is my karma.conf.js

 const webpackConfig = require("./webpack.config"); module.exports = function (config) { config.set({ frameworks: ["jasmine"], files: [ "node_modules/angular/angular.js", "node_modules/angular-mocks/angular-mocks.js", "dist/app.js", // not sure about this "tests/common/*.spec.js", "tests/common/**/*.spec.js" ], preprocessors: { "dist/app.js": ["webpack", "sourcemap"], // not sure about this either "tests/common/*.spec.js": ["webpack", "sourcemap"], "tests/common/**/*.spec.js": ["webpack", "sourcemap"] }, webpack: webpackConfig, webpackMiddleware: { noInfo: true, stats: { chunks: false } }, reporters: ["progress", "coverage"], // , "teamcity"], coverageReporter: { dir: "coverage", reporters: [ { type: "html", subdir: "html" }, { type: "text-summary" } ] }, port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: [ "PhantomJS" //"Chrome" ], singleRun: false, concurrency: Infinity, browserNoActivityTimeout: 100000 }); }; 

This is boot.ts, which is basically the entry point to the application:

 import * as app from "./app/app"; import "./styles/app.scss"; // This never gets written to the console // so I know it never gets loaded by karma console.log("I NEVER OUTPUT TO CONSOLE"); 

This is the app.ts application (which then links to something below:

 import * as ng from "angular"; import * as _ from "lodash"; import "@uirouter/angularjs"; import "angular-cookies"; import "angular-material" import "angular-local-storage"; import "angular-sanitize"; import "angular-messages"; import "angular-file-saver"; import "angular-loading-bar"; import "satellizer"; export * from "./index"; import * as Module from "common/module"; import * as AuthModule from "modules/auth/module"; import * as UserModule from "modules/user/module"; import { MyAppConfig } from "./app.config"; import { MyAppRun } from "./app.run"; export default ng.module("MyApp", [ "ngCookies", "ngSanitize", "ngMessages", "ngFileSaver", "LocalStorageModule", "ui.router", "ngMaterial", "satellizer", "angular-loading-bar", Module.name, AuthModule.name, UserModule.name ]) .config(MyAppConfig) .run(MyAppRun); 

And finally, this is account.service.spec.js

 describe("Account service", function () { // SETUP var _AccountService; beforeEach(angular.mock.module("MyApp.Common")); beforeEach(angular.mock.inject(function (_AccountService_) { // CODE NEVER GETS IN HERE EITHER console.log("I NEVER OUTPUT TO CONSOLE"); _AccountService = _AccountService_; })); function expectValidPassword(result) { expect(result).toEqual({ minCharacters: true, lowercase: true, uppercase: true, digits: true, isValid: true }); } // TESTS describe(".validatePassword()", function () { describe("on valid password", function () { it("returns valid true state", function () { expectValidPassword(_AccountService.validatePassword("asdfASDF123")); expectValidPassword(_AccountService.validatePassword("as#dfAS!DF123%")); expectValidPassword(_AccountService.validatePassword("aA1234%$2")); expectValidPassword(_AccountService.validatePassword(" YYyy22!@ ")); expectValidPassword(_AccountService.validatePassword("Ma#38Hr$")); expectValidPassword(_AccountService.validatePassword("aA1\"#$%(#/$\"#$/(=/#$=!\")(\")(")); }) }); }); }); 

And this is the result of starting karma start

 > npm test > myapp@1.0.0 test E:\projects\Whatever > karma start clean-webpack-plugin: E:\projects\Whatever\dist has been removed. Starting type checking service... Using 1 worker with 2048MB memory limit 31 10 2017 21:47:23.372:WARN [watcher]: Pattern "E:/projects/Whatever/dist/app.js" does not match any file. 31 10 2017 21:47:23.376:WARN [watcher]: Pattern "E:/projects/Whatever/tests/common/*.spec.js" does not match any file. ts-loader: Using typescript@2.4.2 and E:\projects\Whatever\tsconfig.json No type errors found Version: typescript 2.4.2 Time: 2468ms 31 10 2017 21:47:31.991:WARN [karma]: No captured browser, open http://localhost:9876/ 31 10 2017 21:47:32.004:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/ 31 10 2017 21:47:32.004:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency 31 10 2017 21:47:32.010:INFO [launcher]: Starting browser PhantomJS 31 10 2017 21:47:35.142:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket PT-pno0eF3hlcdNEAAAA with id 71358105 PhantomJS 2.1.1 (Windows 8 0.0.0) Account service .validatePassword() on valid password returns valid true state FAILED forEach@node _modules/angular/angular.js:410:24 loadModules@node _modules/angular/angular.js:4917:12 createInjector@node _modules/angular/angular.js:4839:30 WorkFn@node _modules/angular-mocks/angular-mocks.js:3172:60 loaded@http ://localhost:9876/context.js:162:17 node_modules/angular/angular.js:4958:53 TypeError: undefined is not an object (evaluating '_AccountService.validatePassword') in tests/common/services/account.service.spec.js (line 742) webpack:///tests/common/services/account.service.spec.js:27:0 <- tests/common/services/account.service.spec.js:742:44 loaded@http ://localhost:9876/context.js:162:17 PhantomJS 2.1.1 (Windows 8 0.0.0) Account service .validatePassword() on valid amount of characters returns minCharacters true FAILED forEach@node _modules/angular/angular.js:410:24 loadModules@node _modules/angular/angular.js:4917:12 createInjector@node _modules/angular/angular.js:4839:30 WorkFn@node _modules/angular-mocks/angular-mocks.js:3172:60 node_modules/angular/angular.js:4958:53 TypeError: undefined is not an object (evaluating '_AccountService.validatePassword') in tests/common/services/account.service.spec.js (line 753) webpack:///tests/common/services/account.service.spec.js:38:0 <- tests/common/services/account.service.spec.js:753:37 PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 2 of 2 (2 FAILED) ERROR (0.017 secs / 0.015 secs) 

Pay attention to a few places where I left console.logs, which never start. As I know, the application does not load. It is also a fact that jasmine cannot introduce the service that I want to test.

I use:

 karma v1.7.1 karma-webpack v2.0.5 webpack v3.3.0 

Any ideas? What am I doing wrong? I get the impression that my webpack.config.js should bundle my AngularJS / TS application and then essentially feed it karma, but for some reason this does not work. Or do I have a fundamental misconception about how this should work?

Thanks.

I extracted some files in a simple application and put it on github so that the problem can be easily reproduced.

 npm install # install deps npm run serve:dev # run the app - works npm run test # run karma tests - doesn't work 

Edit:

I managed to run the tests by replacing:

 "dist/app.js" 

in setting up karma with

 "src/boot.ts" 

but it will not reduce or load / import the rest of the application. Then I tried to import only the class that I want to check for the specification, but then I could not make fun of any DI-injected services that the class I'm testing is using. Anyway, I pretty much gave up on this at this stage and stopped trying to figure out how to do this by moving to ang2 +.

+5
source share
1 answer

I ran into a similar problem when transferring my AngularJS project project from Grunt to Webpack and tried two different approaches.

1. Webpack and Karma as two separate processes. I did an npm-script with running webpack and karma in parallel. It looked like

 "dev-build": "webpack --config webpack/development.js", "dev-test": "karma start test/karma.development.conf.js", "test": "concurrently --kill-others --raw \"npm run dev-build\" \"npm run dev-test\"" 

Instead of concurrently you can do something else, npm-run-all or even & . In this configuration, Karma had no material in Webpack, she just looked at the folder. / temp to create the distribution and worked autonomously, restarting itself every time the tests or distribution were changed. Webpack was launched in dev mode (via the "dev-build" script), it looked at the folder. / src and compiled the distribution into a folder. / temp. When he updated. / temp, Karma started testing again.

This worked despite the problems of the first karma. Karma started the tests before the first Webpack compilation was completed. This is not critical. Also, playing with the restartOnFileChange setting might help ... Perhaps there is another good workaround. I did not finish this story, I switched to option 2, which, in my opinion, is suitable for Webpack-way a little more than just described.

2. Karma is the only process that uses Webpack. I refused the folder. / temp and decided that for dev-mode all operations should be in memory. Dev-mode Webpack received the following settings (./webpack/development.js):

 entry: { 'ui-scroll': path.resolve(__dirname, '../src/ui-scroll.js') }, output: { filename: '[name].js' }, // + path to ./dist in prod devtool: 'inline-source-map', // 'source-map' in prod compressing: false, watch: true 

Dev-mode Karma (./test/karma.development.conf.js):

 files: [ // external libs // tests specs '../src/ui-scroll.js' // ../dist in prod ], preprocessors: { // no preprocessors in prod '../src/ui-scroll.js': ['webpack', 'sourcemap'] }, webpack: require('../webpack/development.js'), // no webpack in prod autoWatch: true, keepalive: true, singleRun: false 

It also required installing two npm packages: karma-webpack and karma-sourcemap-loader . The first option looks more familiar after Grunt / gulp, but it is simpler, shorter and more stable.

+1
source

Source: https://habr.com/ru/post/1273031/


All Articles