5
votes

I am tetsing a template driven form in angular, just testing not validating it. I have read that it can be done using a viewChild property but it seems to not work for me.

I create a reference like this in my one of my forms label:

<label #ref  id=.. class=...>

And now in my component I do this:

@ViewChild('ref') ref:ElementRef;

So, I suppose I created a valiable of type ElementRef that is viewChild of my input. So now I can use ref in my tests.

Inside my tests I do this:

let ref: HTMLElement:

it(....=>
{
ref = fixture.debugElement.query(By.css('ref')).nativeElement;
fixture.detectChanges();
expect(ref.innerHTML)toContain('Name');// or whatever
}

)

Now consider that the test, html and component files are separated from one another.

I still get errors of nativeElemnt property cannot be read. eventhough I have imported ElemntRef.

Is this the right way to access the DOM elemnts?? Or this viewChild doesnt make a referece to my label??

And again can I use the ID to access the form elements? What I have read they use a reference with #.

Thanks!!

1
You can use elementRef to access the native element. - Kunal Mukherjee
Post your answer and I will vote it if it works for me - Tester
In my experience you don't use the unit tests to validate that the DOM is displaying the correct values. Your test should validate that your component is setting the correct properties/events for itself and then use something like selenium to test that the DOM is working as you expected. if you couple them closely like this in your unit tests then any changes to the DOM/UI will cause you to edit a lot of your tests. - Simply Ged
Again I do not need validation of teh form. Just to test that a element exists, an input for example. That it sends the correct data. How can I access it??? - Tester

1 Answers

5
votes

For direct access to DOM in Angular you can make judicious use of ElementRef

However Direct access to DOM elements is not a good practice because it leaves you vulnerable to XSS attacks.


Your AppComponent

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

@Component({
    selector: 'my-app'
})
export class AppComponent implements ngOnInit {

constructor(private _elementRef : ElementRef) { }

ngOnInit(): void
{
  this.ModifyDOMElement();
}

 ModifyDOMElement() : void
 { 
   //Do whatever you wish with the DOM element.
   let domElement = this._elementRef.nativeElement.querySelector(`#someID`);
 } 
}

Your HTML

<p id="someID"></p>