[karma-server]: TypeError: Cannot read property 'range' of undefined - Angular Unit Testing in CI environment
Asked Answered
P

7

23

Our CI/CD pipelines stopped working on the "ng test" job and fails with the following error message:

[karma-server]: TypeError: Cannot read property 'range' of undefined
    at handleRangeHeaders (/builds/......../node_modules/webpack-dev-middleware/lib/util.js:131:21)
    at processRequest (/builds/......../node_modules/webpack-dev-middleware/lib/middleware.js:98:19)
    at ready (/builds/......./node_modules/webpack-dev-middleware/lib/util.js:53:12)
    at handleRequest (/builds/........../node_modules/webpack-dev-middleware/lib/util.js:182:5)
    at /builds/............/node_modules/webpack-dev-middleware/lib/middleware.js:64:7
    at new Promise (<anonymous>)
    at middleware (/builds/........../node_modules/webpack-dev-middleware/lib/middleware.js:63:12)

Added periods to sub out some specific repo names

We've never had this error before and it worked fine previously. Also oddly enough, it works perfectly when I run it locally. But when the GitLab runners execute it, it fails. Any help would be appreciated. Thanks!

Palpitant answered 9/11, 2020 at 13:33 Comment(2)
It looks like your CI/CD might be type-scanning your node_modules; do you have an "exclude": [ "*/node_modules/" ] in your tsconfig.json?Viniculture
Unfortunately, I tried that but still results in the same error. Thanks though!Palpitant
P
40

Was able to figure it out. We were using node:latest in our .gitlab-ci.yml file and whatever that was pulling down was causing an issue. (It looked to be version 15). So instead of node:latest, we set it to node:14.

Palpitant answered 10/11, 2020 at 13:17 Comment(7)
I can confirm that my tests stopped working with node v15.2.0Ultrasonics
Same for me. Thanks for sharing your solution.Tiffinytiffy
also here @v15.3.0Methacrylate
having the same issue with v14.15.2. Switching to v14.15.1 works.Lymphangitis
Had this same issue, 14.15.3 is working for me.Incised
My solution was similar. I deleted the node_modules directory in my project, changed the version of node to an older on (16.13.0) and installed the node_modules again via npm install and the tests worked again!Coltin
node version 14.15.1 worked for meFonville
G
10

I had similar issue after migration to ESLint my project.

I got rid of tsconfig.app.json and tsconfig.spec.json.

Neither of the Node.JS version didn't solve the problem but somehow I found this post https://ievgen.de/2020/11/17/angular-tests-fail-docker/ which is basically saying to add the following line into your karma.conf.js:

proxies: {
  '/assets/': '/base/src/assets/'
},

This solve my problem :-)

Granada answered 27/3, 2021 at 8:28 Comment(0)
R
7

If you do not want to change your global node version, you can install a local version and run that instead. This way you will get absolute control over what you are running, regardless of the system you are running on.

yarn add node@^14.15.0 --dev
// package.json
{
  "scripts": {
    "test": "node_modules/node/bin/node node_modules/.bin/ng test"
  }
}

Hope this helps a little! 🙂

Rossi answered 3/12, 2020 at 14:33 Comment(0)
S
5

It's indeed an issue with karma on node v15. Looks like (for now) it will not be fixed, so downgrading to v14 is the solution: https://github.com/karma-runner/karma/issues/3571

Schmo answered 22/11, 2020 at 9:23 Comment(0)
C
5

TL;DR

  • In html use relative paths starting with assets/.... In component based CSS use relative paths going one level up: ../assets/...
  • Never, and I mean never use asset paths starting with a slash like /assets this will break your code in some cases
  • Follow the advice below for configuring karma.conf.js because karma does not serve assets and currently karma 5.1.1 with webpack 4.44.2 or some plugin of it crashes with OPs error above

Post Mortem (3)

I deleted my first post mortem twice now, because it was broken and lead me to a post mortem (3) :D

Two things are important: You need to tweak the karma.conf.js as explained in the this SO thread.

Add

    proxies: {
      '/assets/': '/base/src/assets/'
      '/Every-single-image-from-css.png': '/base/src/assets/what-ever-the-path-is/Every-single-image-from-css.png'
    },
    files: [
      { pattern: './src/assets/**', watched: false, included: false, nocache: false, served: true }
    ],

in the config.set({ part, and yes, keep /base/src/assets even if base is nowhere to be found. The second part is the file pattern you need to currently make things work with relative paths. The third part is actually the second entry in the proxies array: List every single resource accessed from css individually :/

Important

ng preprocesses paths somehow strange, the code above will result in your assets referenced from CSS will be duplicated and lying around in root once ng build completes. Very ugly but I don't know a solution to this except using images only from html, which gets processed correctly. The thing I noticed ng serve flattens all urls. So even a css file looking like this

.my-img{
  background: url('../assets/deeply/nested/logo.png');
}

will be served as /logo.png from the built-in webserver. I checked this while looking at the website produced by ng serve and inspecting network calls.

What ever this behaviour is, ng test will die because of this unless you do specify every single image in the proxies part. Using the first proxies entry, e.g. /assets/ is fun but works only when you would use absolute paths from assets, which you should not but is also used, when you reference images from within html, so keep it!

As the ng compilation flattens the urls, this proxy wont work for css references since even in ng test the images from css will be requested from root as /logo.png (stripped of their path). Unfortunately proxies does not support wildcards, otherwise one could write things like /*.png` to something. But currently listing all entries separately seems to be the solution.

Why using absolute paths in assets is a stupid idea

My first result was to actually recommend to use path like /assets/foo.png. Doing this, only the mentioned proxies entry is necessary (but it had to look a bit different). Now I thought i was ok, because ng serve worked, ng test worked and even ng build worked.

But things went south when I wanted to deploy my angular app into a subdirectory. If you do this, I was unable to find any way, meddling around with ng build --base-href '..' and mixing also some --deploy-url into it to make things work.

When you use absolute paths to your assets, never expect to make things work in a subdirectory.

So you might be lucky using my "broken" approach in some instances but I kid you not, you are very likely to save some time following the excellent advise from @programmerinprogress which I repeated above.

Concretion answered 17/12, 2020 at 19:23 Comment(3)
Had this error with a single spec file for an Angular component. It was driving me crazy as all other specs ran fine. Found this post and commented out the <img> element that uses assets in the template and the spec ran successfully. Thank you!!!!Incised
Had this error and all I did was altered the karma.conf.js as per SO Post, as you mentioned it was a much more elegant solution without changing the url paths in the CSSJoiejoin
thanks for sharing and updating the post! it is really helpful!Kana
S
2

This issue will happen if you use node:latest and also for node:14, this is because it happens for v14.15.2. As mentioned in the above answers, you should use node:14.15.1 and the issue will go away.

Saadi answered 17/12, 2020 at 10:21 Comment(0)
G
0

Try to add: browsers: ['Chrome'] to karma.conf.js

Gazehound answered 30/9, 2022 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.