diff --git a/packages/core/src/debug/debug_node.ts b/packages/core/src/debug/debug_node.ts index f4ecc218c2..e8547d8783 100644 --- a/packages/core/src/debug/debug_node.ts +++ b/packages/core/src/debug/debug_node.ts @@ -638,14 +638,19 @@ function getDebugNode__PRE_R3__(nativeNode: any): DebugNode|null { return _nativeNodeToDebugNode.get(nativeNode) || null; } +const NG_DEBUG_PROPERTY = '__ng_debug__'; + export function getDebugNode__POST_R3__(nativeNode: Element): DebugElement__POST_R3__; export function getDebugNode__POST_R3__(nativeNode: Node): DebugNode__POST_R3__; export function getDebugNode__POST_R3__(nativeNode: null): null; export function getDebugNode__POST_R3__(nativeNode: any): DebugNode|null { if (nativeNode instanceof Node) { - return nativeNode.nodeType == Node.ELEMENT_NODE ? - new DebugElement__POST_R3__(nativeNode as Element) : - new DebugNode__POST_R3__(nativeNode); + if (!(nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY))) { + (nativeNode as any)[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ? + new DebugElement__POST_R3__(nativeNode as Element) : + new DebugNode__POST_R3__(nativeNode); + } + return (nativeNode as any)[NG_DEBUG_PROPERTY]; } return null; } @@ -678,9 +683,9 @@ export interface Predicate { (value: T): boolean; } /** * @publicApi */ -export const DebugNode: {new (...args: any[]): DebugNode} = DebugNode__PRE_R3__ as any; +export const DebugNode: {new (...args: any[]): DebugNode} = DebugNode__PRE_R3__; /** * @publicApi */ -export const DebugElement: {new (...args: any[]): DebugElement} = DebugElement__PRE_R3__ as any; +export const DebugElement: {new (...args: any[]): DebugElement} = DebugElement__PRE_R3__; diff --git a/packages/core/test/debug/debug_node_spec.ts b/packages/core/test/debug/debug_node_spec.ts index ac3773b873..b45cb43031 100644 --- a/packages/core/test/debug/debug_node_spec.ts +++ b/packages/core/test/debug/debug_node_spec.ts @@ -7,7 +7,7 @@ */ -import {Component, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; +import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; @@ -678,5 +678,22 @@ class TestCmptWithPropBindings { expect(divB.nativeElement.getAttribute('id')).toBe('b'); }); + it('should be an instance of DebugNode', () => { + fixture = TestBed.createComponent(ParentComp); + fixture.detectChanges(); + expect(fixture.debugElement).toBeAnInstanceOf(DebugNode); + }); + + it('should return the same element when queried twice', () => { + fixture = TestBed.createComponent(ParentComp); + fixture.detectChanges(); + + const childTestElsFirst = fixture.debugElement.queryAll(By.css('child-comp')); + const childTestElsSecond = fixture.debugElement.queryAll(By.css('child-comp')); + + expect(childTestElsFirst.length).toBe(1); + expect(childTestElsSecond[0]).toBe(childTestElsFirst[0]); + }); + }); }