如何手动加载聚合物元素

时间:2014-06-24 09:37:04

标签: javascript unit-testing polymer

我正在尝试将Mocha / Chai / Karma连接到我们的测试框架。我几乎到了那里,使用聚合物单元测试指南作为基础。我想要更简单的东西,只需要一个tests.js脚本并使用一个凉亭组件vca-tests。这就是`tests.js的样子:

(function() {
  'user strict';
  elementSuite('vca-colour-picker', function() {
    test('setting the web value should be reflected in the RGB values', function(done) {
      this.set(function(element) {
        element.web = '#FFCC88';
      }).then(function(element) {
        assert.equal(element.r, 255);
        assert.equal(element.g, 204);
        assert.equal(element.b, 136);
      });
    });
  });
}());

所以我写了一个Mocha测试跑者:

<!doctype html>
<html>
  <head>
    <title>VCA Element Test Runner</title>
    <meta charset="UTF-8">

    <!-- Load in the frameworks we need -->
    <script src="../platform/platform.js"></script>
    <link rel="import" href="../polymer/polymer.html">
    <link rel="import" href="vca-tests.html">
  </head>
  <body>
    <div id="mocha"></div>
  </body>
</html>

elementSuite函数在组件中从存储库的路径加载到<iframe>。由于bower的工作方式,我需要修改导入的位置。从vca-test.html文件夹中加载bower_components

<!-- Test frameworks -->
<link rel="stylesheet" href="../mocha/mocha.css" />
<script src="../mocha/mocha.js"></script>
<script src="../chai/chai.js"></script>

<!-- Perform some set up -->
<script>
(function() {
  'use strict';
  var iframe,
      documents = {};

  function elementImport(suite, name, done) {
    if (this.status === 200) {
      var i,
          doc = iframe.contentDocument,
          link = doc.createElement('link'),
          win = iframe.contentWindow,
          head = doc.getElementsByTagName('head')[0],
          body = doc.body,
          origin = window.location.origin,
          links = this.response.querySelectorAll('link[rel="import"]'),
          element = this.response.querySelector('polymer-element');

      // Fix up the import paths as they will be referencing the root path and we
      // need the relative to the bower components (which is where we are now)
      for (i = 0; i < links.length; ++i) {
        links[i].href = links[i].href.replace(origin, '..');
        doc.adoptNode(links[i]);
        head.appendChild(links[i]);
      }

      // Make sure polymer is fired up
      doc.addEventListener('polymer-ready', function() {

// --------------------------------------------------------------------------
// At this point we have loaded all of the dependent components of the
// component to test but we still need to be able to create instances
// of the component. The below code will work, but because it is loaded
// to the root of the repository all the dependencies will fail with 404s

        /*/ Import the rest of the component
        link.rel = 'import';
        link.href = '../../' + name + '.html';
        link.import = this.response;
        head.appendChild(link);/**/

// --------------------------------------------------------------------------
        // Create the element
        suite.ctx.element = doc.createElement(name);
        body.appendChild(suite.ctx.element);

        // Tell mocha that we are done
        done();
      }, false);
    }
  }

  function elementLoad(name, done) {
    var xhr = new XMLHttpRequest(),
        path = '../../' + name + '.html';
    xhr.open('GET', path, true);
    xhr.responseType = 'document';
    xhr.onload = elementImport.bind(xhr, this, name, done);
    xhr.send();
  }

  function elementSetup(name, done) {
    iframe = document.createElement('iframe');
    iframe.style.cssText = /*'position: absolute;left:-10000em;*/'width:768px;height:1024px';
    iframe.onload = elementLoad.bind(this, name, done);
    iframe.src = 'iframe.html';
    document.body.appendChild(iframe);

    // Provide convience functions
    this.ctx.set = function(callback) {
      callback.call(this, this.element);
      Platform.flush();
      return this;
    };
    this.ctx.then = function(callback) {
      setTimeout(function() {
        callback.call(this, this.element);
        this.test.callback();
      }.bind(this), 50);
      return this;
    };
  }

  function elementTeardown() {
//    document.body.removeChild(iframe);
  }

  // This is what the tests.js script uses to register an element to test
  window.elementSuite = function(name, tests) {
    suite(name, function() {
      setup(elementSetup.bind(this, name));
      teardown(elementTeardown);
      tests();
    });
  }

  // We use chai as our assertion framework
  window.assert = chai.assert;

  // Mocha runs our tests
  mocha.setup({ui: 'tdd', slow: 1000, timeout: 5000});
}());
</script>

<!-- Load in the test script -->
<script src="../../tests.js"></script>

<!-- Run the tests -->
<script>
mocha.run();
</script>

所以我的问题归结为:如何XHR包含polymer-element的HTML文档,但更改基础href以便我的相对bower组件加载? < / p>

当加载<link rel="import">以使元素可用时,聚合物似乎有些神奇。

1 个答案:

答案 0 :(得分:2)

编辑:HTML导入不支持规范中的data:text/html,因此在使用polyfill时工作。

它是否使用了可怕的猴子补丁:

// Do a local import
link.rel = 'import';
link.href = 'data:text/html,' + encodeURIComponent(component);

// Monkey Patch Polymer, to fake the location of the 'import'
if (iframe.contentWindow.HTMLImports && !iframe.contentWindow.HTMLImports.useNative) {
  var hi = iframe.contentWindow.HTMLImports,
      importLoader = hi.importLoader,
      receive = importLoader.receive,
      origin = iframe.src.substr(0, iframe.src.lastIndexOf('/', iframe.src.lastIndexOf('/') - 1));
  importLoader.receive = function(args) {
    if (arguments[0] === link.href) {
      var i, redirected = [];
      for (i = 0; i < arguments.length; ++i) {
        redirected.push(arguments[i]);
      }
      redirected.push(origin + '/' + name + '/' + name + '.html');
      receive.apply(this, redirected);
    } else {
      receive.apply(this, arguments);
    }
  }
}

// Add the link now that we are monkey patched
doc.head.appendChild(link);

HTMLImports在撰写本文时没有正确处理数据URI。目前还不确定如何为项目编写补丁。

相关问题