nicholaswmin
nicholaswmin

Reputation: 22949

Unit testing dynamically-rendered elements in Polymer

Overview

DOM elements that are dynamically-rendered within dom-if, dom-repeat <templates> seem to be rendered asynchronously thus making unit-testing a bit of a pain.


The Polymer Component

template(is='dom-if', if='{{!defaultPrintAll}}')
  template(is='dom-repeat', items='{{_pageBucketItems}}')
    button(type='button', class$='{{_computeDefaultClass(item)}}', on-tap='_togglePageClick') {{item}}

The Test

  test("Clicking 'Export All' to off, reveals board-selection tiles", function() {
    $("#export-pdf-checkbox-all").siblings(".checkbox").trigger("click");
    Polymer.dom.flush()
    expect($(".board-range__button")).to.be.visible;
  });

Why it seems to fail:

When clicking a button which triggers the dom-if/dom-repeat the elements don't render in a synchronous order.

So the question boils down to this:

Is it possible to force render the dom-if, dom-repeat, and the computed-binding of the class in a synchronous order after I simulate the click to the button which activates all 3 of those conditions?


Notes:

Upvotes: 7

Views: 3487

Answers (1)

Dogs
Dogs

Reputation: 3157

Rather than using Polymer.dom.flush(), try using the flush function that WCT puts on the window. This will enqueue a callback function to be executed, in theory, after the template has rendered.

test("Clicking 'Export All' to off, reveals board-selection tiles", function(done) {
    $("#export-pdf-checkbox-all").siblings(".checkbox").trigger("click");
    flush(function () {
        expect($(".board-range__button")).to.be.visible;
        done();
    }
});

Important to notice: Asynchronous tests require the done function to be passed into the test callback, and require done to be called after your conditions have been evaluated.

Upvotes: 8

Related Questions