Thursday, May 16, 2013

Getting Started BDDing Dart HTML Workflows

‹prev | My Chain | next›

Now that I have a beautiful Dart test suite for ICE Code Editor, I would like to try driving a little UI workflow.

For my first test, I write something that is decidedly not behavior driving. I check for the presence of a button:
  group("main toolbar", (){
    setUp(()=> new Full(enable_javascript_mode: false));
    tearDown(()=> document.query('#ice').remove());

    test("it has a menu button", (){
      var buttons = document.queryAll('button');
      expect(buttons.any((e)=> e.text=='☰'), isTrue);
    });
  });
In other words, when the full screen editor first starts up, there should be a menu button available.

I am not going to test for location or z-index or any formatting here. I will visually inspect that they exist. It might be nice if Dart supported something like a visible getter, but perhaps that is something for a library. Anyhow I will get the toolbar in place, then I will write another test to drive some UI behavior.

But first, I need to get the test passing:
FAIL: main toolbar it has a menu button 
  Expected: true
       but: was <false>.
I make that pass by modifying the Full class to attach a toolbar on construction. And, I have the toolbar create the menu button:
class Full {
  Full({enable_javascript_mode: true}) {
    // ...
    _attachToolbar();
  }

  _attachToolbar() {
    var el = new Element.html('<div class=ice-toolbar>');
    el.style
      ..position = 'absolute'
      ..top = '10px'
      ..right = '20px'
      ..zIndex = '999';

    _attachMenuButton(el);

    document.body.nodes.add(el);
  }

  _attachMenuButton(parent) {
    var el = new Element.html('<button>☰');
    parent.children.add(el);
  }
}
That gets my first test passing:
PASS: main toolbar it has a menu button
Now, I am ready to write my first UI workflow test—nothing fancy, just that clicking this button brings up the menu that includes a “Help” item:
    test("clicking the menu button brings up the menu", (){
      var menu_button = queryAll('button').
        firstWhere((e)=> e.text=='☰');

      menu_button.click();
      var menu = queryAll('li').
        firstWhere((e)=> e.text.contains('Help'));

      expect(menu, isNotNull);
    });
And make it pass with:
  toggleMenu() {
    var el = new Element.html('<ul class=ice-menu>');
    document.body.children.add(el);

    el.style
      ..position = 'absolute'
      ..right = '17px'
      ..top = '55px'
      ..zIndex = '999';

    el.children
      ..add(new Element.html('<li>New</li>'))
      ..add(new Element.html('<li>Open</li>'))
      ..add(new Element.html('<li>Save</li>'))
      ..add(new Element.html('<li>Make a Copy</li>'))
      ..add(new Element.html('<li>Share</li>'))
      ..add(new Element.html('<li>Download</li>'))
      ..add(new Element.html('<li>Help</li>'));
  }
That was easy!

My #pairwithme, Srdjan Pejic, and I spend the rest of the evening building out a few of those menu elements—BDDing as much as possible along the way. So far, I have to say that I really like driving UI changes like this. It will be interesting to see if my happiness level remains high as the UI (and complexity) grows.


Day #753

No comments:

Post a Comment