Friday, April 25, 2014

Dynamically Generating Polymer Definitions (not working)


In my ongoing efforts to test angular-bind-polymer, I would like to define test Polymer definition right inside the tests. Currently, I have to define the template and class definition in separate files, then import them into the Karma Jasmine test setup:
var script = document.createElement("script");
script.src = "/base/bower_components/platform/platform.js";
document.getElementsByTagName("head")[0].appendChild(script);

var link = document.createElement("link");
link.rel = "import";
link.href = "/base/test/x-double.html";
document.getElementsByTagName("head")[0].appendChild(link);
// ...
As limitations go, this is hardly severe—heck it may even be appropriate in this case. Still, I would like to know that I can generate custom Polymer element definitions on the fly if I need them.

When I first tried this, it failed badly. Or at least it seemed to. I say “seemed to” because I tried to do too much at the time. I tried to do this, dynamically add the custom element to the page, and test things—all in one night. It went badly. Now that I have a handle on testing and dynamically adding custom elements to the DOM, perhaps dynamically defining element will just work?

To answer that question, I start SMALL. Despite the awful pain of the other night, my first instinct remains to just copy the test Polymer element in its entirety into JavaScript strings that can be appended to the test DOM. I resist that first instinct and instead start by commenting out the link to the Polymer library from the Polymer definition:
<!-- <link rel="import" href="../bower_components/polymer/polymer.html"> -->
<polymer-element name="x-double" attributes="in out">
  <template></template>
  <script>
    Polymer("x-double", { /* ... */ });
  </script>
</polymer-element>
With that, my test fails:
Chrome 34.0.1847 (Linux) Double binding works FAILED
        timeout: timed out after 5000 msec waiting for something to happen
I can restore it to green by dynamically linking to the Polymer library after doing the same for the platform in the test setup:
var script = document.createElement("script");
script.src = "/base/bower_components/platform/platform.js";
document.getElementsByTagName("head")[0].appendChild(script);

var link = document.createElement("link");
link.rel = "import";
link.href = "/base/test/x-double.html";
document.getElementsByTagName("head")[0].appendChild(link);

var link = document.createElement("link");
link.rel = 'import';
link.href = "/base/bower_components/polymer/polymer.html";
document.getElementsByTagName("head")[0].appendChild(link);
That is some progress over the night before, but I still need to dynamically define the element and backing class. I try:
var double_el = document.createElement('polymer-element');
double_el.setAttribute('name', 'x-double');
double_el.setAttribute('attributes', 'in out');
double_el.innerHTML = '  <template></template>\n<script>\n'
                  + '    Polymer("x-double", { /* ... */  });\n'
                  + '  </script>\n';

document.body.appendChild(double_el);
Sadly, that does not work. I am not getting any errors, the test just fails as if the <x-double> element is undefined:
Expected null to equal '84'.
Error: Expected null to equal '84'.
    at new jasmine.ExpectationResult (http://localhost:9876/absolute/home/chris/local/node-v0.10.20/lib/node_modules/karma-jasmine/lib/jasmine.js:114:32)
Unfortunately, this has me stumped for tonight.

I try adding the dynamically generated <polymer-element> definition at the top the document <body>. I try adding it to the document <head>. I even try adding the definition after the polymer-ready event. But my test always fails as if my definition is completely ignored.

So it would seem that there is some magic necessary to get Polymer elements that are dynamically added to the document. I am happy to have made some progress tonight with the dynamic import of the Polymer library. Hopefully tomorrow I can figure out how to get the dynamic Polymer element definition working—either by reading other tests or the Polymer code itself.




Day #45

No comments:

Post a Comment