Tuesday, November 26, 2013

No Joy with Karma with Polymer.dart


While writing the testing chapter in Patterns in Polymer, I found myself putting the Karma test runner section entirely inside a ifdef:js block of text. This got me to thinking. I really like Karma. I really like Dart. Can the two of them get along? Can Karma go in both the Dart and JavaScript versions of the book?

Well, there is one way to find out...

I already have a couple of tests written in Dart's unittest. There is a karma-dart testing framework definition. Maybe that'll just work. I start by installing the plugin via node.js's npm:
$ npm install karma-dart --save-dev
I start with the same karma.conf.js that I have been using for my JavaScript Polymer, but I change the framework (to dart-unittest) and the list of files to be used:
    // ...
    // frameworks to use
    frameworks: ['dart-unittest'],

    // list of files / patterns to load in the browser
    files: [
      'test/*.dart',
      {pattern: '**/*.dart', watched: true, included: false, served: true}
      // 'packages/browser/dart.js',
      // 'packages/browser/interop.js'
    ],
    // ...
I am not sure about those two browser package dependencies, so I leave them commented out at first. But when I run Karma and attach Dartium to http://localhost:9876, I find that I need those after all:
...
Error: ENOENT, no such file or directory '/home/chris/repos/polymer-book/play/bootstrap-panels/dart/packages/js/js.dart'
    at Object.fs.openSync (fs.js:427:18)
    at Object.fs.readFileSync (fs.js:284:15)
...
Since I do not need these in my Polymer code, I add them as additional development dependencies in my Dart Pub pubspec.yaml:
name: pricing_panels
dependencies:
  polymer: any
dev_dependencies:
  unittest: any
  browser: any
  js: any
After a pub get, I restart my Karma server and try again in Dartium.

I no longer have errors about the js package. Now both of my tests are run and both fail with similar error messages:
Test failed: Caught The null object does not have a getter 'text'.

NoSuchMethodError : method not found: 'text'
Receiver: null
Arguments: [] 
This is failing because nothing is importing my Polymer.dart element definitions. Without them, my custom <pricing-plan> elements have no shadow DOM, causing tests that probe the shadow DOM to fail:
      expect(
        query('pricing-plan').shadowRoot.text,
        contains('Plan')
      );
In my non-Karma test, I simply imported these elements in the test context page:
<head>
  <!-- Load component(s) -->
  <link rel="import" href="packages/pricing_panels/pricing-plans.html">
  <link rel="import" href="packages/pricing_panels/pricing-plan.html">
  <script type="application/dart" src="test.dart"></script>
</head>
That will not work here, so I have manually add them in my test:
importPolymerElements(list) {
  list.forEach((definition) {
    var link = new LinkElement()
      ..rel = "import"
      ..href = "/packages/pricing_panels/${definition}";
    query('head').append(link);
  });
}

main() {
  importPolymerElements(['pricing-plans.html', 'pricing-plan.html']);
  // tests here..
}
Unfortunately, that does not work. I am still left with a distinct lack of shadow DOM on my custom Polymer elements. Furthermore, I am seeing Dartium errors like:
URL must be imported by main Dart script: pricing_plans.dart 
URL must be imported by main Dart script: pricing_plan.dart 
I am unsure what I might be doing that would cause Karma / unittest / Dartium to attempt to load these script files outside the context of my existing main() entry point that is running my test and Polymer.

Stumped, I call it a night. I may or may not revisit this. It is probably sufficient to Grunt a content_shell test run, which I may try tomorrow (hopefully with more luck).


Day #947

No comments:

Post a Comment