Модульное тестирование динамически визуализируемых элементов в Polymer

Обзор

Элементы DOM, которые динамически визуализируются в dom-if, dom-repeat <templates>, кажутся рендерингом асинхронно, что делает модульное тестирование немного болезненным.


Полимерный компонент

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

Тест

  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;
  });

Почему это кажется неудачным:

При нажатии кнопки, которая запускает dom-if/dom-repeat, элементы не отображаются в синхронном порядке.

  • dom-if и последующие/вложенные dom-repeat отображаются асинхронно.

  • Что еще хуже, сам button получает свой класс вычисляемым/связанным образом (обратите внимание на class$= на button).

Итак, вопрос сводится к следующему:

Можно ли принудительно отобразить dom-if, dom-repeat и вычисляемую привязку класса в синхронном порядке после того, как я имитирую нажатие на кнопку, которая активирует все 3 из эти условия?


Примечания:

  • Я использую официальный WCT Polymer в качестве тестовой системы.
  • Я также использую chai-jquery.
  • Я также использовал Polymer.dom.flush(), но он все еще не смылся.
  • Я знаю, что вместо этого я могу использовать chai-as-promised.js, но это усложняет мои тесты для таких тривиальных вопросов, как этот, поэтому я хотел бы избежать этого.

person nicholaswmin    schedule 29.12.2015    source источник


Ответы (1)


Вместо использования Polymer.dom.flush() попробуйте использовать функцию flush, которую WCT помещает в окно. Теоретически это поставит в очередь функцию обратного вызова, которая будет выполняться после рендеринга шаблона.

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();
    }
});

Важно отметить: асинхронные тесты требуют, чтобы функция done была передана в обратный вызов теста, и требуют, чтобы done вызывался после того, как ваши условия были оценены.

person Dogs    schedule 30.12.2015
comment
бинго - спасибо, но чем это сильно отличается от использования setTimeout() в тестах? Как я смогу продолжить следующие тесты, которые зависят от этого? - person nicholaswmin; 30.12.2015
comment
Убедитесь сами: github.com/ Polymer/web-component-tester/blob/ В большинстве случаев нет никакой реальной разницы по сравнению с простым использованием setTimeout с аргументом 0. Однако причина, по которой вы хотели бы использовать window.flush вместо setTimeout, заключается в следующем. что в будущих версиях web-component-tester реализация флеша может измениться, чтобы стать умнее и/или более полезной. - person Dogs; 30.12.2015
comment
И что касается следующих тестов, эти тесты не будут выполняться до тех пор, пока предыдущий тест либо не вызовет функцию завершения, либо не завершится ошибкой из-за утверждения, либо из-за тайм-аута. - person Dogs; 30.12.2015