How to Display Rendered Component with Karma Test Runner?
Asked Answered
P

2

8

I have created a new angular app v13 using cli with the defaults. I replaced the app.component.html file to display 4 images. This loads in the browser fine doing npm start. When I run npm test and run the test that checks for the existence of these images (using a class selector) the test passes but I don't see the images in the Karma chrome browser window. Using devtools I see they are loaded.

In general, how do I get the component dom to display on Karma Chrome page?

EDIT: Here's some code

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'flopbuster_basics';
}

app.component.css

.fit-picture {
    width: 250px;
}

app.component.html

<div class="posters">
  <span class="poster">
    <img class="fit-picture" src="assets/images/posters/cloudy.jpg" alt="Cloudy With a Chance of Meatballs">
  </span>
  <span class="poster">
    <img class="fit-picture" src="assets/images/posters/luca.jpg" alt="Luca">
  </span>
  <span class="poster">
    <img class="fit-picture" src="assets/images/posters/peanuts.jpg" alt="The Peanuts Movie">
  </span>
  <span class="poster">
    <img class="fit-picture" src="assets/images/posters/zootopia.jpg" alt="Zootopia">
  </span>
</div>

app.component.spec.ts

import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'flopbuster_basics'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('flopbuster_basics');
  });

  it('should display the movie posters of 4 movie flops', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelectorAll('.poster').length).toBe(4);
  });
});

karma.conf.js

// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      jasmine: {
        // you can add configuration options for Jasmine here
        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
        // for example, you can disable the random execution with `random: false`
        // or set a specific seed with `seed: 4321`
      },
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    jasmineHtmlReporter: {
      suppressAll: true // removes the duplicated traces
    },
    coverageReporter: {
      dir: require('path').join(__dirname, './coverage/flopbuster_basics'),
      subdir: '.',
      reporters: [
        { type: 'html' },
        { type: 'text-summary' }
      ]
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    restartOnFileChange: true,
    files: [
      {pattern: 'src/assets/images/posters/*.jpg', watched: false, included: false, served: true, nocache: false}

    ]
  });
};

package.json

{
  "name": "flopbuster-basics",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~13.2.0",
    "@angular/common": "~13.2.0",
    "@angular/compiler": "~13.2.0",
    "@angular/core": "~13.2.0",
    "@angular/forms": "~13.2.0",
    "@angular/platform-browser": "~13.2.0",
    "@angular/platform-browser-dynamic": "~13.2.0",
    "@angular/router": "~13.2.0",
    "rxjs": "~7.5.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.2.5",
    "@angular/cli": "~13.2.5",
    "@angular/compiler-cli": "~13.2.0",
    "@types/jasmine": "~3.10.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~4.0.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.1.0",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.5.2"
  }
}

The rendered page Rendered page

But here is the test output in Karma

karma output in chrome

And using DevTools I see the images are getting loaded loaded images

Pastoralize answered 26/2, 2022 at 22:31 Comment(0)
D
12

I had the same issue and I resolved it by modifying the project's test.ts file to pass ModuleTeardownOptions to getTestBed().initTestEnvironment() with a value of { teardown: { destroyAfterEach: false }}, like this:

getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting(),
  // Set destroyAfterEach to false:
  { teardown: { destroyAfterEach: false }}
);

You can either pass the options to TestBed.configureTestingModule() for any specific test case(s), or globally via TestBed.initTestEnvironment() like in the example above.

Devotion answered 28/6, 2022 at 14:30 Comment(3)
Also, it's worth mentioning that if you don't have test.ts, you need to create it, add it as "main" to angular.json and to "files" in tsconfig.spec.jsonWile
I have the same issue, in test.ts it is the same. and the component not appeared into karma test runner. any another solutions??Alvy
hi @NsdHSO, same issue with my tests, using Angular15, and the UI components render in a blink of eye while tests are being run, but aren't displayed along with test results in karma browser at all to us to refer. Any solution?Pretense
B
0

I think there is some misunderstanding of how the Karma test runner works. What it does is check your test code against the application code, and in its browser window it displays what passes or fails.

What it does not do is render your application. Unit tests are meant to test pieces of code (components, functions etc) in isolation as opposed to an application as a whole. In other words, if you add a child component to your testbed and test that, it will not actually mount nor be part of app.component or some other parent component.

If you do want to test your application as a whole and/or see what and how it renders, you should look for and end-to-end test suite. Angular has a built-in one (haven't tried it myself) or you could look for one of many other options. I personally would recommend Cypress.

Balsa answered 12/6, 2024 at 9:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.