Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"browser" to "application" test builder regression: assets not found #29872

Closed
1 task
Klaster1 opened this issue Mar 18, 2025 · 5 comments · Fixed by #29923
Closed
1 task

"browser" to "application" test builder regression: assets not found #29872

Klaster1 opened this issue Mar 18, 2025 · 5 comments · Fixed by #29923
Labels
needs: repro steps We cannot reproduce the issue with the information given

Comments

@Klaster1
Copy link

Klaster1 commented Mar 18, 2025

Command

test

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

Discovered while evaluating if "application" karma builder is ready for my project. On the latest Angular version - 19.2.3 - when switching "@angular-devkit/build-angular:karma" mode from "browser" to "application", my tests lose the ability to load assets. I presume the assets are still served, but couldn't figure out what's the new path is. In the "browser" setup, the assets load perfectly fine from the same path as in the full application.

Test builder configuration:

"test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "include": ["**/*.spec.ts"],
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "builderMode": "browser",
            "assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "**/testing/*.png",
                "input": "src/app/",
                "output": "/test-images/"
              }
            ],
            "styles": ["src/styles.scss"],
            "stylePreprocessorOptions": {
              "includePaths": ["src/styles", "node_modules/"]
            },
            "scripts": []
          }
        },

Minimal Reproduction

Have a component that uses Mat Icon SVG icons.

My icon initializer:

export const iconsAppInitializer = provideAppInitializer(() => {
  const iconRegistry = inject(MatIconRegistry);
  const sanitizer = inject(DomSanitizer);
  iconRegistry.addSvgIconResolver((name, namespace: string) => {
    // Namespaces: "ggcc", "material-filled", "material-outlined", "material-symbols-outlined"
    return sanitizer.bypassSecurityTrustResourceUrl(`assets/images/icons/${namespace}/${name}.icon.svg`);
  });
});

Author a test for the component.

To load icons in the test, provide these:

  iconsAppInitializer,
  provideHttpClient(withInterceptorsFromDi()),

Run the test, i.e. ng test --browsers=ChromiumHeadless --include=**/page-signin.component.spec.ts.

Exception or Error

Node.js version v23.6.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/previous-releases/.
Initial chunk files                   | Names                              |  Raw size
chunk-GW4D6KLC.js                     | -                                  |   2.95 MB | 
spec-alerting-shell.component.spec.js | spec-alerting-shell.component.spec |   2.49 MB | 
polyfills.js                          | polyfills                          | 979.40 kB | 
styles.css                            | styles                             | 391.17 kB | 
test_main.js                          | test_main                          | 348.92 kB | 
chunk-ZMU26DRM.js                     | -                                  |   4.67 kB | 
jasmine-cleanup-0.js                  | jasmine-cleanup-0                  | 519 bytes | 

                                      | Initial total                      |   7.17 MB

Lazy chunk files                      | Names                              |  Raw size
chunk-T3M3URMI.js                     | driver-min                         |  75.70 kB | 

Application bundle generation complete. [18.867 seconds]

Watch mode enabled. Watching for file changes...
Ignoring framework "@angular-devkit/build-angular" from karma config file because it's not compatible with the application builder.
18 03 2025 10:28:57.390:WARN [karma]: No captured browser, open http://localhost:9876/
18 03 2025 10:28:57.403:INFO [karma-server]: Karma v6.4.4 server started at http://localhost:9876/
18 03 2025 10:28:57.403:INFO [launcher]: Launching browsers ChromiumHeadless with concurrency unlimited
18 03 2025 10:28:57.412:INFO [launcher]: Starting browser ChromiumHeadless
18 03 2025 10:28:58.006:INFO [Chrome Headless 130.0.0.0 (Windows 10)]: Connected on socket uXz_a1SARC2o7PHOAAAB with id 74125878
Chrome Headless 130.0.0.0 (Windows 10): Executed 0 of 6 SUCCESS (0 secs / 0 secs)
ERROR: 'ERROR', Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
    at Object.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/@angular/material/fesm2022/icon.mjs:990:40)
    at ConsumerObserver.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:99:25)
    at SafeSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at SafeSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
Chrome Headless 130.0.0.0 (Windows 10): Executed 0 of 6 SUCCESS (0 secs / 0 secs)
ERROR: 'ERROR', Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
    at Object.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/@angular/material/fesm2022/icon.mjs:990:40)
    at ConsumerObserver.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:99:25)
    at SafeSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at SafeSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
Chrome Headless 130.0.0.0 (Windows 10): Executed 2 of 6 SUCCESS (0 secs / 0.43 secs)                                                                                                                                                                                                                                                                                                                             
ERROR: 'ERROR', Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found                                                                                                                                                                                                                                    
Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
    at Object.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/@angular/material/fesm2022/icon.mjs:990:40)
    at ConsumerObserver.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:99:25)
    at SafeSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at SafeSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
Chrome Headless 130.0.0.0 (Windows 10): Executed 2 of 6 SUCCESS (0 secs / 0.43 secs)
ERROR: 'ERROR', Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
Error: Error retrieving icon ggcc:alerting-alt! Http failure response for http://localhost:9876/assets/images/icons/ggcc/alerting-alt.icon.svg: 404 Not Found
    at Object.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/@angular/material/fesm2022/icon.mjs:990:40)
    at ConsumerObserver.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:99:25)
    at SafeSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at SafeSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
    at OperatorSubscriber.error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:37:12)
    at OperatorSubscriber._error (http://localhost:9876/base/frontend/dist/test-out/209eb165-3ba5-4460-b14d-910838e8c199/node_modules/rxjs/dist/esm/internal/Subscriber.js:60:24)
Chrome Headless 130.0.0.0 (Windows 10): Executed 6 of 6 SUCCESS (0.473 secs / 0.466 secs)
TOTAL: 6 SUCCESS
TOTAL: 6 SUCCESS

Your Environment

Node.js version v23.6.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/previous-releases/.

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 19.2.3
Node: 23.6.0 (Unsupported)
Package Manager: npm 10.9.2
OS: win32 x64

Angular: 19.2.2
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1902.3
@angular-devkit/build-angular   19.2.3
@angular-devkit/core            19.2.3 (cli-only)
@angular-devkit/schematics      19.2.3
@angular/cdk                    19.0.4
@angular/cli                    19.2.3
@angular/material               19.0.4
@schematics/angular             19.2.3
rxjs                            7.8.1
typescript                      5.6.3
zone.js                         0.15.0

Warning: The current version of Node (23.6.0) is not supported by Angular.

Anything else relevant?

Test runner output in "browser" mode:

Node.js version v23.6.0 detected.
Odd numbered Node.js versions will not enter LTS status and should not be used for production. For more information, please see https://nodejs.org/en/about/previous-releases/.
✔ Browser application bundle generation complete.
18 03 2025 10:41:28.959:WARN [karma]: No captured browser, open http://localhost:9876/
18 03 2025 10:41:28.976:INFO [karma-server]: Karma v6.4.4 server started at http://localhost:9876/
18 03 2025 10:41:28.977:INFO [launcher]: Launching browsers ChromiumHeadless with concurrency unlimited
18 03 2025 10:41:28.989:INFO [launcher]: Starting browser ChromiumHeadless
18 03 2025 10:41:29.606:INFO [Chrome Headless 130.0.0.0 (Windows 10)]: Connected on socket tRQToaI5nACCag2oAAAB with id 69138295
Chrome Headless 130.0.0.0 (Windows 10): Executed 4 of 14 SUCCESS (0 secs / 0.207 secs)
18 03 2025 10:41:31.238:WARN [web-server]: 404: /_karma_webpack_/assets/images/open-id-logos/light/foo.svg
Chrome Headless 130.0.0.0 (Windows 10): Executed 6 of 14 SUCCESS (0 secs / 0.235 secs)
Chrome Headless 130.0.0.0 (Windows 10) Sign in page component Shows provider links icons for the Light theme FAILED
        Expected 'assets/images/open-id-logos/light/foo.svg' to be 'assets/images/open-id-logos/light/1foo.svg'.
            at <Jasmine>
            at UserContext.<anonymous> (src/app/public/page-signin/page-signin.component.spec.ts:99:84)
            at Generator.next (<anonymous>)
            at asyncGeneratorStep (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1)
            at _next (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:17:1)
Chrome Headless 130.0.0.0 (Windows 10): Executed 11 of 14 (1 FAILED) (0 secs / 0.313 secs)
Chrome Headless 130.0.0.0 (Windows 10) Sign in page component Shows provider links icons for the Light theme FAILED
        Expected 'assets/images/open-id-logos/light/foo.svg' to be 'assets/images/open-id-logos/light/1foo.svg'.
            at <Jasmine>
            at UserContext.<anonymous> (src/app/public/page-signin/page-signin.component.spec.ts:99:84)
            at Generator.next (<anonymous>)
            at asyncGeneratorStep (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1)
            at _next (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:17:1)
Chrome Headless 130.0.0.0 (Windows 10): Executed 13 of 14 (1 FAILED) (0 secs / 0.333 secs)
Chrome Headless 130.0.0.0 (Windows 10): Executed 14 of 14 (1 FAILED) (0.354 secs / 0.342 secs)
TOTAL: 1 FAILED, 13 SUCCESS
TOTAL: 1 FAILED, 13 SUCCESS
@clydin
Copy link
Member

clydin commented Mar 19, 2025

Unfortunately, we are unable to reproduce the problem as described.
If possible, could you create a minimal reproduction based on a newly generated project?
The issue may be project directory structure related and a runnable reproduction will aid in additional investigation.

@clydin clydin added the needs: repro steps We cannot reproduce the issue with the information given label Mar 19, 2025
@Klaster1
Copy link
Author

Absolutely, should have done from the start. Give me several days.

@jr01
Copy link

jr01 commented Mar 20, 2025

I ran into the same problem (assets not being served by Karma with the new application builder) while converting our project. I can reproduce it on a new/clean Angular 19.2.4 project. And I also found a workaround.

Minimal steps to reproduce:

  • Create a new Angular 19.2.4 project: ng new myproject

  • Create a folder /folderwithassets with a file image.png in it

  • Modify angular.json to have it serve some that asset folder and set the builderMode application for the test.

     	...
     		"assets": [
               {
                 "glob": "**/*",
                 "input": "public"
               },
               {
                 "glob": "**/*",
                 "input": "/folderwithassets",
                 "output": "/assets/"
               }
     	...
         "test": {
           "builder": "@angular-devkit/build-angular:karma",
           "options": {
             "builderMode": "application",
     	  ...
     	  "assets": [
               ...
               {
                 "glob": "**/*",
                 "input": "/folderwithassets",
                 "output": "/assets/"
               },
     		
  • Replace contents of app.component.html

    <img src="/assets/image.png" />
  • Run the application and verify the image is shown: npm start

  • Run the tests npm test - yes it fails because we changed the content - ignore that. LOOK in the Chrome console and notice: GET http://localhost:9876/assets/image.png 404 (Not Found)

  • Use ng g config karma to generate the karma.conf.js and add a workaround to it:

        frameworks: ['jasmine', '@angular-devkit/build-angular', 'fixAssets'],
        plugins: [
          require('karma-jasmine'),
          require('karma-chrome-launcher'),
          require('karma-jasmine-html-reporter'),
          require('karma-coverage'),
          require('@angular-devkit/build-angular/plugins/karma'),
          {
            'framework:fixAssets': ['factory', function(config) {
              const assetPattern = {
                pattern: `${config.basePath}/assets/**/*`,
                included: false,
                served: true,
                watched: false
              };
              config.files.push(assetPattern);
    
              config.proxies['/assets/'] = '/base/assets/';
            }]
          }
  • Run the tests again npm test - yes it still fails as expected - ignore that. LOOK in the Chrome console and notice nothing. 😄

@clydin
Copy link
Member

clydin commented Mar 24, 2025

@jr01 That asset configuration does not work with a build either. This is due to the input value (/folderwithassets) which is looking for assets in the root of the file system and not within the project. Removing the leading / causes both the build and test to execute as expected.

@jr01
Copy link

jr01 commented Mar 24, 2025

@clydin not completely sure what you mean, but the assets in that root folder are copied to test-out and thus I would expect them to be served. In my project its actually assets from an installed npm package using "input": "./node_modules/@vismaux/vud/dist/img" that are copied to test-out, but don't get served.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs: repro steps We cannot reproduce the issue with the information given
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants