angular: By.css() query does not find SVG elements

I’m submitting a …

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior Currently, the By.css() query function seems not to be able to find SVG elements in the DOM.

Expected behavior It is expected that the By.css() query function returns the HTML element as a result, no matter of what kind the element is (div or span or svg or …).

Minimal reproduction of the problem with instructions In one of my components, I do have an SVG element which looks similar to:

<svg class="button__icon" viewBox="0 0 64 64" *ngIf="showIcon()">
    <path d="..."></path>
</svg>

Then, within my unit test, I want to query for this SVG element in order to check whether it gets displayed or not, depending on the result of showIcon(). To do so, I’ve tried to use Angular testing tools, resulting in the following code:

const iconElement: SVGElement | null =
    testComponentFixture.debugElement.query( By.css( '.button__icon' ) );
expect( iconElement ).not.toBeNull(); // Check that element exists

However, it turns out that the iconElement is always null - By.css() seems to not be able to find the SVG element, in this specific case by a given class name.

Is there any reason why this isn’t working, or is this behaviour intentional / by design? The docs don’t reveal any specifics regarding this case.

What is the motivation / use case for changing the behavior? The By.css() query function should work consistently, with all kinds of HTML elements, without any workaround needed.

Workaround As described right here, using the following code instead works just fine:

const iconElement: SVGElement | null =
      testComponentFixture.debugElement.nativeElement.querySelector( '.button__icon' );

Please tell us about your environment: Angular CLI 1.0.0-RC.1, Visual Studio Code on a Windows 7 machine

  • Angular version: 2.4.9 (latest at the moment)

  • Browser: Karma & PhantomJS

  • Language: TypeScript

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 6
  • Comments: 16 (3 by maintainers)

Commits related to this issue

Most upvoted comments

As it seems many people are still encountering this issue, I’m re-opening it. We should, however, create a new reproduction for this, e.g. a Plunkr or on StackBlitz.

Still an issue with Angular 5.2.1

Are you guys planning to do something about it? Bug been opened since March. Can we get an update?

Thanks.

Another workaround, since nothing else seemed to work for me:

    const svg = fixture.nativeElement.firstChild; // adjusted template for svg to be the only child element
    // bars = fixture.debugElement.queryAll(By.css('rect[class=bar]')); // nothing
    // bars = fixture.debugElement.nativeElement.querySelector('rect.bar'); // empty
    bars = svg.getElementsByClassName('bar'); // finds bars!

Confirming here also, that it’s an issue with Angular 5.0.0.

I want this fixed, too, but in the meantime I have been working around it by using debugElement.nativeElement.querySelector()

fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
const textElement: HTMLElement = fixture.debugElement.nativeElement.querySelector('.myClass');
expect(textElement.textContent).toBe('hello world!');