...">

Polymer unit test: dom-repeat not showing when "ready" is called

I have the following unit test for my custom polymer component:

<head>
  <meta charset="UTF-8">
  <title>survey</title>

  <script src="../bower_components/webcomponentsjs/webcomponents.js"></script>
  <script src="/web-component-tester/browser.js"></script>
  <script src="../bower_components/test-fixture/test-fixture-mocha.js"></script>

  <link rel="import" href="../bower_components/polymer/polymer.html">
  <link rel="import" href="../bower_components/test-fixture/test-fixture.html">
  <link rel="import" href="../bower_components/iron-test-helpers/iron-test-helpers.html">
  <link rel="import" href="../views/components/survey.html">

</head>

<body>
  <test-fixture id="Network">
    <template>
      <survey></survey>
    </template>
  </test-fixture>
  <script>
    describe('<survey>', function() {
      var survey;


      describe('network', function() {
        beforeEach(function(done) {
          survey = fixture('Network');
        })
        it('should work', function() {
          expect(survey.$.dog).to.exist;
        });

      });
    });
  </script>
      

Run codeHide result


And the following custom polymer component survey

:

<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="survey">
<template>
  <h3 class="text-center">Tell us about yourself!</h3>
  <div class="form-group">
    <label>I'm a...</label>
    <array-selector id="imaSelector" items="{{ima}}" selected="{{imaSelected}}" multi toggle></array-selector>
    <template is="dom-repeat" id="imaList" items="{{ima}}">
      <div class="checkbox">
        <paper-checkbox id="{{item.id}}" on-iron-change="toggleIma">{{item.name}}</paper-checkbox>
      </div>
    </template>
  </div>
</template>
</dom-module>
<script>
  Polymer({
    is: 'survey',
    properties: {
      ima: {
        type: Array,
        value: function() {
          return [ {
            name: 'House Cat',
            id: 'houseCat'
          }, {
            name: 'Basic Dog',
            id: 'dog'
          }, {
            name: 'Swimming Fish',
            id: 'fish'
          }];
        }
      },
    
    },
    toggleIma: function(e) {
      var item = this.$.imaList.itemForElement(e.target);
      if (item) {
        this.$.imaSelector.select(item.id);
      }
    }

  })
</script>
      

Run codeHide result


This test will fail because the local dom is not initialized due to the fact that I am using the element dom-repeat

.

How do I want until the local dom is marked?

+3


source to share


3 answers


There are two parts. Waiting for asynchronous rendering and searching for node.

For rendering: Either listen for an event dom-change

from the template dom-repeat

, or call a method render()

on dom-repeat

to force synchronous rendering.

In unit tests, you probably just want to call render()

.



To find the node - this.$

only statically created elements are filled in (not, for example, elements from the template dom-if

or dom-repeat

) as described in the docs . This is a common source of confusion.

You can use a convenience method this.$$

to request a local DOM element using a selector, so you can do something like this:

survey.$.imaList.render();
expect(survey.$$(#dog)).to.exist;

      

+2


source


You can return Promise

instead of expecting something immediately:

it('should work', function() {
    return expect(survey.$.dog).should.eventually.exist();
});

      



See http://mochajs.org/#asynchronous-code for details .

+1


source


This seems like a Polymer problem. The problem is that I was trying to use a selector this.$

to refer to dynamically generated nodes. However, the docs docs explicitly state that it this.$

will only include statically generated nodes and not dynamically created nodes.

See the note in this link. This is for version 0.5, but I assume it is the same in version 1.0. If there are any other known solutions than those mentioned in the link, I'd love to hear them.

https://www.polymer-project.org/0.5/docs/polymer/polymer.html#automatic-node-finding

Pay attention to the final solution, it looks something like this:

  
describe('network', function() {
  beforeEach(function(done) {
    survey = fixture('Network');
    flush(function(){
        done()
    });
  })
  it('should work', function() {
    expect(survey.querySelector('#dog')).to.exist;
  });
});
      

Run codeHide result


Please note that it is flush()

required to ensure loading dom. https://www.polymer-project.org/0.5/articles/unit-testing-elements.html#wct-specific-helpers

+1


source







All Articles