Sunday, March 16, 2014

Input Testing of Polymers (Dart)


It really bothers me that I cannot test text input in Dart Polymer elements. Last night, I was unable to dynamically generate text events to simulate someone typing into an <input> field that is doubly data bound with the header:



In my tests, I tried multiple ways to get text events to fire such that the header should have been updated—all without success. I explicitly set the value of the <input> field:
      var input = el.shadowRoot.query('input');
      input.value = 'Bob';
I sent TextEvent events to the <input>:
      var input = el.shadowRoot.query('input');
      var e = new TextEvent('textInput', data: 'Bob');
      input.dispatchEvent(e);
I even tried sending KeyEvent objects to custom event streams:
      var input = el.shadowRoot.query('input');
      KeyEvent.keyUpEvent.forTarget(input)
        ..add(new KeyEvent('keyup', charCode: 66))
        ..add(new KeyEvent('keyup', charCode: 111))
        ..add(new KeyEvent('keyup', charCode: 98));
I even waited for the events to propagate:
  group("typing", (){
    setUp((){
      // Try to generate input events here ...
      var completer = new Completer();
      new Timer(new Duration(milliseconds: 100), (){ completer.complete(); });
      return completer.future;
    });
    test((){ /* ... */ });
All for naught.

In the end, I think it best to update the attribute directly to trick the Polymer element into thinking that a change has occurred. The only way that I can do that is to update the attribute in question directly:
  group("typing", (){
    setUp((){
      el.your_name = "Bob";

      /* None of the following work :( */

      // var input = el.shadowRoot.query('input');
      // input.value = 'Bob';
      // input.click();

      // input.dispatchEvent(new CustomEvent('keyup'));
      // el.fire('change', toNode: input, detail: 'foo');

      // el.notifyPropertyChange(#your_name, '', 'Bob');

      // var change = new Event.eventType('HTMLEvents', 'change');
      // input.dispatchEvent(change);

      // var e = new TextEvent('textInput', data: 'Bob');
      // input.dispatchEvent(e);

      // KeyEvent.keyUpEvent.forTarget(input)
      //   ..add(new KeyEvent('keyup', charCode: 66))
      //   ..add(new KeyEvent('keyup', charCode: 111))
      //   ..add(new KeyEvent('keyup', charCode: 98));
      // print(input.value);

      var completer = new Completer();
      new Timer(new Duration(milliseconds: 100), completer.complete);
      return completer.future;
    });

    test('says a friendly hello', (){
      var h2 = el.$['hello'];
      expect(h2.text, 'Hello Bob');
    });
  });
That is a bummer. But at least I have something in the way of a test. Hopefully some day in the not too distant future there will be better ways to trigger keyboard input in Dart. For now, it is time to move on to more fertile ground.


Day #5

No comments:

Post a Comment