简体   繁体   English

聚合物2.0:在Chrome的测试中未呈现的子组件

[英]Polymer 2.0: Sub-components not rendered in tests on Chrome

I've got a simple Polymer component using 2 different components. 我有一个使用2个不同组件的简单Polymer组件。 When used on page, everything works fine but when I run tests, they fail on Chrome only. 当在页面上使用时,一切正常,但是当我运行测试时,它们仅在Chrome上失败。 Contents of sub-components moment-element and duration-view are not rendered. 未呈现子组件moment-elementduration-view的内容。

<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/moment-element/moment-element.html">
<link rel="import" href="../duration-view/duration-view.html">

<dom-module id="issue-row">
    <template>
        <li>
            [[issue]]
            <moment-element datetime="[[startDate]]" output-format="[[startDateFormat]]"></moment-element>
            -
            <moment-element datetime="[[endDate]]" output-format="[[endDateFormat]]"></moment-element>
            <duration-view date-from="[[startDate]]" date-to="[[endDate]]"></duration-view>
        </li>
    </template>

    <script>
        class IssueRow extends Polymer.Element {
            static get is() { return 'issue-row'; }
            static get properties() {
                return {
                    issue : String,
                    startDate : String,
                    endDate : String,
                    startDateFormat : {
                        type : String,
                        value : 'D.MM HH:mm'
                    },
                    endDateFormat : {
                        type : String,
                        value : 'HH:mm'
                    }
                };
            }
        }

        window.customElements.define(IssueRow.is, IssueRow);
    </script>
</dom-module>
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/moment-element/moment-import.html">
<link rel="import" href="moment-duration-format-import.html">

<dom-module id="duration-view">
    <template>
        some static content which is not rendered.
        [[formattedDuration]]
    </template>

    <script>
        class DurationView extends Polymer.Element {
            static get is() { return 'duration-view'; }
            static get properties() {
                return {
                    format : {
                        type : String,
                        value : "hh:mm"
                    },
                    duration : {
                        type : String,
                        value : '00:00:00'
                    },
                    dateFrom : String,
                    dateTo : String,
                    formattedDuration : {
                        type : String,
                        notify : true
                    }
                };
            }
            static get observers() {
                return ['_computeDuration(duration, dateFrom, dateTo, format)']
            }
            _computeDuration(duration, dateFrom, dateTo, format) {
                console.log(duration, dateFrom, dateTo, format);
                var output;
                if (dateFrom && dateTo) {
                    var from = moment(dateFrom);
                    var to = moment(dateTo);
                    if (!from.isValid() || !to.isValid()) {
                        this.set('formattedDuration', 'Invalid date');
                        return;
                    }
                    output = moment.duration(to.diff(from), 'ms');
                } else {
                    output = moment.duration(duration);
                }
                this.set('formattedDuration', output.format(format, {trim: false}));
            }
        }

        window.customElements.define(DurationView.is, DurationView);
    </script>
</dom-module>
  <test-fixture id="BasicTestFixture">
    <template>
      <issue-row issue="PR-493" start-date="2017-05-18 11:00" end-date="2017-05-18 14:30"></issue-row>
    </template>
  </test-fixture>

  <script>
      suite('issue-row', function () {

        test('displays issue number, dates and duration', function () {
          var element = fixture('BasicTestFixture');
          var elementShadowRoot = element.shadowRoot;
          var elementText = elementShadowRoot.textContent;
          expect(elementText).to.have.string("PR-493");
          expect(elementText).to.have.string("18.05");
          expect(elementText).to.have.string("11:00");
          expect(elementText).to.have.string("14:30");
          expect(elementText).to.have.string("3:30");
        });

      });
  </script>

I've got assertion error on second expect call: 我在第二个expect调用上有断言错误:

Error: expected '\n        \n            PR-493\n            \n            -\n            \n            \n        \n    ' to contain '18.05'
  Context.<anonymous> at issue-row_test.html:32

console.log in _computeDuration outputs only default values (or empty) when testing on chrome. 在chrome上进行测试时, _computeDuration console.log _computeDuration输出默认值(或为空)。

This works fine on Firefox and fails on Chrome. 在Firefox上运行正常,而在Chrome上运行失败。 Test results: 检测结果:

chrome 58 (5/0/1)                       firefox 53 (6/0/0)

The problem is a misunderstanding of shadow DOM concept. 问题是对影子DOM概念的误解。 Elements are rendered but they are not showing in standard DOM traversal. 元素已呈现,但未在标准DOM遍历中显示。 In this particular case, textContent , innerHTML and outerHTML properties ignore shadow elements. 在这种情况下, textContentinnerHTMLouterHTML属性会忽略阴影元素。 It worked on Firefox because it lacks shadow DOM support and it renders everything in standard DOM tree. 它可以在Firefox上运行,因为它缺少影子DOM支持,并且可以在标准DOM树中呈现所有内容。

I made a simple tool for testing contents of nested components: 我做了一个简单的工具来测试嵌套组件的内容:

window.deep = function (element) {
    return {
        textContent : (function () {
            if (element.nodeType === Node.TEXT_NODE) {
                return element.textContent;
            }
            var children;
            if (element.shadowRoot) {
                children = element.shadowRoot.childNodes;
            } else {
                children = element.childNodes;
            }
            var content = [];
            for (var i in children) {
                content.push(deep(children[i]).textContent);
            }
            return content.join('');
        })()
    }
}

Feel free to use this concept if you need to. 如果需要,请随意使用此概念。 Usage: deep(fixture('fixtureId')).textContent 用法: deep(fixture('fixtureId')).textContent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular 2,不渲染动态组件的子组件 - Angular 2, sub-components of dynamic component are not rendered 使用带有 props 的子组件动态反应 - React dynamically using sub-components with props 使用动态子组件对组件进行反应 - React Component with dynamic Sub-Components 如何正确地将一个组件的代码拆分为多个子组件? - How to properly split the code of a component into sub-components? 棱角分明。 如何在外部定义点击,不包括子组件? - Angular. How to define a click outside, excluding sub-components? 使用Bulma和Angular 5创建选项卡并调用子组件 - Creating Tabs and calling sub-components with Bulma and Angular 5 改变React状态的最佳方法 <App /> 基于子组件的级别 - Best way to change React state at <App /> level based on sub-components Material UI如何使用整个组件的一种主要通用样式设置子组件的外部样式 - Material UI How to set external styles for sub-components with one main common style for the entire component 在使用Jest单元测试React组件时如何模拟子组件 - How to mock out sub-components when unit testing a React component with Jest 当React / Flux中有多个小的可重复子组件时,如何管理组件渲染 - How to manage component rendering when there are several small, repeatable sub-components in React/Flux
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM