title: Testing window resize on Angular directive - window dimensions undefined after resize event
body: <p>I have a directive that changes height of the text within element on window resize:</p>
  
  <pre class="lang-ts prettyprint-override"><code>import {Directive, ElementRef, Renderer2, HostListener} from '@angular/core';
  
  
  @Directive({selector: '[fittext]'})
  export class FittextDirective {
  
    constructor(private element: ElementRef, private renderer: Renderer2) { }
  
    public changeFontSize(): void {
      const htmlElement: HTMLElement = this.element.nativeElement;
      const elemDims = htmlElement.getBoundingClientRect();
      const height = elemDims.height;
      // Set new font size on element
      this.renderer.setStyle(htmlElement, 'font-size', `${height / 2}px`);
    }
  
    @HostListener('window:resize')
    public onResize(): void {
      this.changeFontSize();
    }
  
  }
  </code></pre>
  
  <p>And I'm trying to test it using custom wrapper component and by dispatching resize event on window.</p>
  
  <pre class="lang-ts prettyprint-override"><code>import { async, ComponentFixture, TestBed } from '@angular/core/testing';
  import { FittextDirective } from './fittext.directive';
  import { Component, ViewChild, ElementRef } from '@angular/core';
  import { By } from '@angular/platform-browser';
  
  
  @Component({
    template: `
      &lt;div #div fittext&gt;{{ text }}&lt;/div&gt;
      &lt;style&gt;
        div {
          height: 100vh;
          width: 100vw;
          font-size: 100%;
        }
      &lt;/style&gt;
    `
  })
  class TestComponent {
    @ViewChild('div') div: ElementRef;
    public text: string = 'This is test string';
  }
  
  
  describe('FittextDirective', () =&gt; {
    let component: TestComponent;
    let fixture: ComponentFixture&lt;TestComponent&gt;;
  
    beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [
          TestComponent,
          FittextDirective
        ]
      }).compileComponents();
    }));
  
    beforeEach(() =&gt; {
      fixture = TestBed.createComponent(TestComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });
  
    fit('should trigger on resize', () =&gt; {
      const {height, width} = component.div.nativeElement.getBoundingClientRect();
      const fontSize = component.div.nativeElement.style.fontSize;
      window.dispatchEvent(new Event('resize'));
      fixture.detectChanges()
  
      const resizedElement = fixture.debugElement.query(By.directive(FittextDirective));
      const {newHeight, newWidth} = resizedElement.nativeElement.getBoundingClientRect();
      const newFontSize = resizedElement.nativeElement.style.fontSize;
  
      expect(newHeight).not.toEqual(height);
      expect(newWidth).not.toEqual(width);
      expect(newFontSize).not.toEqual(fontSize);
    });
  });
  </code></pre>
  
  <p>However, tests report font sizes to be <code>''</code>, and height and width after resize (i.e. <code>newHeight</code> and <code>newWidth</code>) to be <code>undefined</code>. Why is the font size an empty string, even though the font should be sized to match the div? And why are the height and width after window resize undefined? I'm using headless chrome for testing so I can't use <code>window.resizeTo(width, height)</code> method.</p>
  
  <p><strong>Edit 1:</strong> After suggestion by <code>Alex K</code> I've changed <code>newHeight</code> and <code>newWidth</code> to:</p>
  
  <pre class="lang-ts prettyprint-override"><code>const newHeight = resizedElement.nativeElement.getBoundingClientRect().height;
  const newWidth = resizedElement.nativeElement.getBoundingClientRect().width;
  </code></pre>
  
  <p>However, it seems that after resize event, that windows is not resized (I get the error <code>Expected 600 not to equal 600.</code> and <code>Expected 785 not to equal 785.</code>). I've also changed the style between tags, to style in the component attribute i.e. <code>styles</code> attribute, but still, the <code>fontSize</code> is reported to be <code>''</code> (or any style for that matter).</p>
  
  <p><strong>Edit 2:</strong> For some strange reason styles can only be fetched using <code>window.getComputedStyle()</code> (see <a href="https://stackoverflow.com/questions/42349088/angular2-unit-testing-why-nativeelement-has-empty-cssstyledeclaration">this</a>). Now, I get the size of the font, but it does not change after resize.</p>
  
  <pre class="lang-ts prettyprint-override"><code>const styles = window.getComputedStyle(element.nativeElement);
  const fontSize = styles.fontSize;
  ...
  const newStyles = window.getComputedStyle(resizedElement.nativeElement);
  const newFontSize = newStyles.fontSize;
  </code></pre>
  
  <p><strong>Edit 3:</strong> As suggested, I've faked dimensions with <code>spyOn</code>, however, this does not resize fonts.</p>
  
  <pre class="lang-ts prettyprint-override"><code>spyOn(component.div.nativeElement, 'getBoundingClientRect')
    .and.returnValue({height: height / 2, width: width / 2});
  
  window.dispatchEvent(new Event('resize'));
  fixture.detectChanges()
  </code></pre>