From 989ebcbb62f87e0b28758ffda8ec2d732fdf0cdc Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 7 Jul 2019 12:17:37 +0200 Subject: [PATCH] fix(ivy): inconsistent value returned by DebugNode.context (#31442) Fixes Ivy's return value for `DebugNode.context` not being consistent for the case where there is both a structural directive and a component on a node. In `ViewEngine` the instance of the component would be returned, whereas in Ivy the context of the directive is returned. Also adds a couple of extra test cases for how `DebugNode.context` deals with directives. This PR resolves FW-1343. PR Close #31442 --- packages/core/src/debug/debug_node.ts | 4 +- packages/core/test/debug/debug_node_spec.ts | 45 +++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/core/src/debug/debug_node.ts b/packages/core/src/debug/debug_node.ts index 61f138ee6c..adeb75ee15 100644 --- a/packages/core/src/debug/debug_node.ts +++ b/packages/core/src/debug/debug_node.ts @@ -220,7 +220,9 @@ class DebugNode__POST_R3__ implements DebugNode { return nativeElement && (getComponent(nativeElement as Element) || getViewComponent(nativeElement)); } - get context(): any { return getContext(this.nativeNode as Element); } + get context(): any { + return getComponent(this.nativeNode as Element) || getContext(this.nativeNode as Element); + } get listeners(): DebugEventListener[] { return getListeners(this.nativeNode as Element).filter(isBrowserEvents); diff --git a/packages/core/test/debug/debug_node_spec.ts b/packages/core/test/debug/debug_node_spec.ts index 4f318f0b1a..2aa6814343 100644 --- a/packages/core/test/debug/debug_node_spec.ts +++ b/packages/core/test/debug/debug_node_spec.ts @@ -7,6 +7,7 @@ */ +import {CommonModule, NgIfContext} from '@angular/common'; import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; @@ -644,6 +645,50 @@ class TestCmptWithPropBindings { }); }); + describe('context on DebugNode', () => { + it('should return component associated with the node if both a structural directive and a component match the node', + () => { + @Component({selector: 'example-component', template: ''}) + class ExampleComponent { + } + + TestBed.configureTestingModule( + {imports: [CommonModule], declarations: [ExampleComponent]}); + TestBed.overrideTemplate( + TestApp, ''); + + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + const debugNode = fixture.debugElement.query(By.directive(ExampleComponent)); + + expect(debugNode.context instanceof ExampleComponent).toBe(true); + }); + + it('should return structural directive context if there is a structural directive on the node', + () => { + TestBed.configureTestingModule({imports: [CommonModule]}); + TestBed.overrideTemplate(TestApp, ''); + + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + const debugNode = fixture.debugElement.query(By.css('span')); + + expect(debugNode.context instanceof NgIfContext).toBe(true); + }); + + it('should return the containing component if there is no structural directive or component on the node', + () => { + TestBed.configureTestingModule({declarations: [MyDir]}); + TestBed.overrideTemplate(TestApp, ''); + + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + const debugNode = fixture.debugElement.query(By.directive(MyDir)); + + expect(debugNode.context instanceof TestApp).toBe(true); + }); + }); + it('should be able to query for elements that are not in the same DOM tree anymore', () => { fixture = TestBed.createComponent(SimpleContentComp); fixture.detectChanges();