【问题标题】:Angular: debugElement query doesn't find the element but jQuery doesAngular:debugElement 查询没有找到元素,但 jQuery 找到了
【发布时间】:2018-06-28 23:20:59
【问题描述】:

我一直在忍受这个。 我正在使用第三方列表框小部件(jqx-listbox)并尝试对其进行测试。在ng serve 下一切正常,甚至查看 Chrome 中的 Karma 输出,我可以看到整个 UI、列表框和项目,这是我想要测试的。

问题是在测试中查询元素:

let openListbox = fixture.debugElement.query(By.css('.jqx-listitem-element')); 返回 null,而如果我在该行设置断点,并在 Chrome 控制台$('.jqx-listitem-element) 中使用 jQuery,则返回 DOM 元素!

如果我将测试中的查找更改为模板中定义的元素 (<jqxlistbox>),如下所示:let openListbox = fixture.debugElement.query(By.css('jqxlistbox')),这将返回 debugElement,我什至可以在该元素的本机元素内部进行检查断点并看到它里面有东西,但无论我尝试了什么(返回该元素然后对其进行查询),我似乎无法更深入地查询对象,所以我的测试一直失败。

我也尝试过使用 fakeAsyncfixture.whenStable,但这似乎完全被跳过(或者它永远不会稳定)。

这是小部件在运行时生成的渲染模板代码(这是我要检查的最里面的跨度)

<jqxlistbox _ngcontent-c0="" class="" style="" ng-reflect-attr-display-member="message" ng-reflect-attr-source="[object Object]"
  ng-reflect-attr-value-member="errorType" ng-reflect-attr-width="100%">
  <div class="ng-tns-c0-0 jqx-listbox jqx-reset jqx-rc-all jqx-widget jqx-widget-content jqx-disableselect" id="jqxWidgete238403f0fb8"
    style="width: 100%; height: 200px;" aria-multiselectable="false" role="listbox" tabindex="1">
    <div style="-webkit-appearance: none; background: transparent; outline: none; width:100%; height: 100%; align:left; border: 0px; padding: 0px; margin: 0px; left: 0px; top: 0px; valign:top; position: relative;">
      <div style="-webkit-appearance: none; border: none; background: transparent; outline: none; width:100%; height: 100%; padding: 0px; margin: 0px; align:left; left: 0px; top: 0px; valign:top; position: relative;">
        <div id="listBoxContentjqxWidgete238403f0fb8" style="-webkit-appearance: none; background: transparent; outline: none; border: none; padding: 0px; overflow: hidden; margin: 0px; left: 0px; top: 0px; position: absolute; width: 328px; height: 198px;">
          <div style="outline: none 0px; overflow: hidden; width: 329px; position: relative; height: 404px;">
            <div role="option" id="listitem0jqxWidgete238403f0fb8" class="jqx-listitem-element" style="height: 24px; top: 0px; left: 0px;"
              aria-selected="true">
              <span style="white-space: pre; display: block; visibility: inherit; width: 318px;" class="jqx-listitem-state-normal jqx-item jqx-rc-all jqx-listitem-state-selected jqx-fill-state-pressed">Open hard error</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</jqxlistbox>

编辑 我可以得到外部元素,它的 innerText 是那个跨度的文本:“打开硬错误”,但这只是因为它是整个元素中唯一的文本节点。

使用这个测试代码,第一个断言通过,第二个断言失败,出现“无法读取 null 的属性 nativeElement”的错误,这对我来说太奇怪了,因为如果它可以找到 innerText,那么它就拥有整个 DOM 元素.我想知道查询查询返回的 DebugElement 是否有问题?:

fixture.detectChanges();
let openListbox = fixture.debugElement.query(By.css('#open jqxlistbox'));
expect(openListbox.nativeElement.innerText).toContain('Open hard error', 'item in listbox');

fixture.detectChanges();

let openListboxItem: HTMLElement = openListbox.query(By.css('span')).nativeElement;
expect(openListboxItem.textContent).toBe('Open hard error', 'item in listbox');

【问题讨论】:

    标签: angular unit-testing integration-testing jqxwidgets


    【解决方案1】:

    我有一种感觉,您的 jqx-listitem-element 正在根据提供给 jqxlistbox 的一些数据进行渲染。为了访问那些依赖于数据的子元素,您需要在组件“初始化”之后查询它们(通过调用fixture.detectChanges)。

    所以,试试以下方法:

    let openListBox = fixture.debugElement.query(By.css('jqxlistbox'));
    fixture.detectChanges();
    let listItems = fixture.debugElement.queryAll(By.css('.jqx-listitem-element'));
    

    这将初始化组件,导致 jqxlistbox 注册它的数据并呈现它的子列表项,然后您可以使用上述 sn-p 中的第二行 queryAll 查询这些列表项。


    根据第一条评论和附加信息进行编辑:

    我想知道查询查询返回的 DebugElement 是否有问题?

    查询 DebugElement 并没有错,您所做的在语法上是正确的。您应该能够使用我在此答案的第一个版本中添加的代码。我认为这可能与您如何填充这些列表项有关。检查您的模拟数据/提供者。我看不到你的整个spec,所以我无法在那里进行故障排除。

    【讨论】:

    • 是的,这是我尝试的第一件事,在那里乱扔了更多detectChanges,包括你建议的地方,但第二个查询仍然返回 null。使用测试期间呈现的 HTML 更新我的原始帖子。现在,我确实发现我可以使用openListBox.innerText,因为在这种情况下,唯一的文本节点在那个范围内,但感觉不对;我应该能够到达那个 DOM 节点。
    • 我在有角度的材料表行方面遇到了类似的问题。会对答案非常感兴趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多