PolymerElements / test-fixture

21 stars 14 forks source link

Can't get data bound fixtures to work with v3.0.0-rc.1 #47

Open pghalliday opened 7 years ago

pghalliday commented 7 years ago

Description

I tried to do the same as I did in Polymer 1.x with test-fixture v1.1.2, using the is="dom-template" attribute on my template and also tried using dom-bind as documented here https://www.polymer-project.org/2.0/docs/devguide/templates#dom-bind

But I cannot get data bound fixtures to work with a fresh polymer-2-application using test-fixture v3.0.0-rc.1

I suspect I'm doing something wrong :s

Expected outcome

Bound attributes are rendered with bound data

Actual outcome

Bound attributes are not rendered with bound data

Steps to reproduce

To a fresh polymer-2-application generated with polymer-cli v0.18.0-pre.13 (installs text-fixture v3.0.0-rc.1) add the following simple component as src/text.html

<link rel="import" href="../../../bower_components/polymer/polymer.html">

<dom-module id="my-text">
  <template>
    <div id="text">[[text]]</div>
  </template>
  <script>
    class MyText extends Polymer.Element {
      static get is() {
        return 'my-text';
      }

      static get properties() {
        return {
          text: String,
        };
      }
    }
    customElements.define(MyText.is, MyText);
  </script>
</dom-module>

And the following test as test/text.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">

    <title>my-list test</title>

    <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
    <script src="../../web-component-tester/browser.js"></script>

    <link rel="import" href="../src/text.html">
  </head>
  <body>
    <test-fixture id="myText">
      <template is="dom-template">
        <my-text text="[[text]]"></my-text>
      </template>
    </test-fixture>
    <script>
      describe('my-text', function() {
        var myText;

        beforeEach(function(done) {
          myText = fixture('myText', {
            text: 'hello'
          });
          flush(done);
        });

        it('should display the text', function() {
          expect(myText.root.querySelector('#text').textContent).to.eql('hello');
        });
      });
    </script>
  </body>
</html>

Then run polymer test or wct, etc

The test fails with:

expected '[[text]]' to deeply equal 'hello'
  Context.<anonymous> at text.html:32

NB. The equivalent test with an equivalent polymer 1.x component succeeds

I also got this error in the console

test-fixture.html:296 test-fixture#myText "was given a model to stamp, but the template is not of a bindable type"
stamp @ test-fixture.html:296
createFrom @ test-fixture.html:200
(anonymous) @ test-fixture.html:176
forElements @ test-fixture.html:277
create @ test-fixture.html:174
fixture @ stub.js:3
(anonymous) @ VM528 text.html:25
callFnAsync @ mocha.js:4470
Runnable.run @ mocha.js:4420
next @ mocha.js:4801
(anonymous) @ mocha.js:4831
timeslice @ mocha.js:82

Browsers Affected

Aside

I also tried with the dom-bind element like this

    <test-fixture id="myText">
      <dom-bind>
        <template>
          <my-text text="[[text]]"></my-text>
        </template>
      </dom-bind>
    </test-fixture>

But that fails in both Polymer 1.x and the Polymer 2 RC with the following error

Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
     HTMLElement.<anonymous> at /components/test-fixture/test-fixture.html:271
     HTMLElement.forElements at /components/test-fixture/test-fixture.html:277
  HTMLElement.removeElements at /components/test-fixture/test-fixture.html:270
          HTMLElement.create at /components/test-fixture/test-fixture.html:172
         Context.<anonymous> at text.html:27
jmorille commented 7 years ago

I trying to migrate some polymer 1 to polymer 2 and I have the same bug the following test working before migration to Polymer 2 with test-fixture#3.0.0-rc.1

<test-fixture id="ChangedPropertyTestFixture">
    <template is="dom-template">
        <my-text   url="{{url}}"></my-text>
    </template>
</test-fixture>
test('setting a property on the element works', function () {
    // Create a test fixture
    var element = fixture('ChangedPropertyTestFixture', {url: '/FiveElements/air'}); 
    assert.equal(element.url, '/FiveElements/air');
 });

with the current error

 expected '{{url}}' to equal '/FiveElements/air'

with the current log in console

'was given a model to stamp, but the template is not of a bindable type'

in reference of the code of test-fixture that test if (fixtureTemplate.stamp)

    stamp: function (fixtureTemplate, model) {
      var stamped;
      // Check if we are dealing with a "stampable" `<template>`. This is a
      // vaguely defined special case of a `<template>` that is a custom
      // element with a public `stamp` method that implements some manner of
      // data binding.
      if (fixtureTemplate.stamp) {
        stamped = fixtureTemplate.stamp(model);
        // We leak Polymer specifics a little; if there is an element `root`, we
        // want that to be returned.
        stamped = stamped.root || stamped;

      // Otherwise, we fall back to standard HTML templates, which do not have
      // any sort of binding support.
      } else {
        if (model) {
          console.warn(this, 'was given a model to stamp, but the template is not of a bindable type');
        }

question: need to still use is="dom-template" with fixture with model ?

*NB*: This regression is a big probem for migrate to polymer 2 if the unit testing not fulling working**

ppeou commented 7 years ago

Hello, I am facing same issue. Any help resolving this issue is greatly appreciated.

srsudar commented 7 years ago

I've tried both a bare <template is="dom-template"> and one wrapped with <dom-bind>, and I see the same errors as @pghalliday .

srsudar commented 7 years ago

Messing around with this some more, I remain confused. There are a lot of things that confuse me writing Polymer apps, including wct and polymer-cli versions. I've forked test-fixture and have tried to write a test that requires data binding. Thus far I've failed, but I'm not at all sure this isn't due to a Polymer/WCT version issue that eludes me.

Nevertheless, what I describe below is odd and might help someone who knows more than I do.

I've added a test case like the following in test/test-fixture.html:

DOM:

  <test-fixture id="DataBindingFixture">
    <dom-bind>
      <template is="dom-template">
        <div id="stamp-me">
          {{textValue}}
        </div>
      </template>
    </dom-bind>
  </test-fixture>

Test:

    describe('for a dom with a bound template', function () {
      var el;
      let model = {
        textValue: 'I should be stamped',
      };

      beforeEach(function () {
        debugger; // lets you step in and see the removeChild() problem
        el = dataBindingFixture.create(model);
      });

      it('div text should be stamped', function () {
        var div = document.getElementById('stamp-me');
        expect(document.getElementById('stamp-me').innerText)
          .to.equal(model.textValue);
      });
    });

That test fails with the Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. error reported above. Omitting the <dom-bind> element just causes the test to fail at the assert statement.

What really boggles my mind about this is that when I step through the code, the element that supposedly is not a child certainly looks like it is a child. This console screenshot is taken with the debugger on the line:

this.removeChild(element);

Looking at this and element, it certainly looks like element is a child. What is really strange is that, after manually invoking removeChild(element) and seeing the error that element is not a child, inspecting this again still indicates that element is a child! Very odd.

screen shot 2017-07-02 at 10 19 38 pm

pdesjardins90 commented 7 years ago

@cdata (Please file a bug re: data-bound templates. ) that was already filed I guess

MrMcGibblets commented 7 years ago

Was the bug mentioned above filed? if so can it be linked to this one, please?

pdesjardins90 commented 7 years ago

It was just a discussion on twitter that resulted in me opening an issue, but this issue was exactly what we were talking about

MrMcGibblets commented 7 years ago

ah ok, so no movement as of yet.

Thanks

ErikGrimes commented 6 years ago

To workaround the issue, wrap the <test-fixture> in a <dom-bind>.

<dom-bind>
   <test-fixture>
       <template>
            <paper-icon-button icon="[[icon]]"></paper-icon-button>
       </template>
   </test-fixture>
</dom-bind>

Then update the bound data using the DomBind.set.

document.querySelector('dom-bind').set('icon','clear');
ansreng commented 6 years ago

@ErikGrimes your solution doesn't seem to work for me.

Any new comments from the developers?

pdesjardins90 commented 6 years ago

For everyone's information, type-extension elements (<.. is="...">) doesn't work anymore in Polymer 2 (see the what's new section), so that's why \