1

这是我的财产声明:

  properties: {

    size: {
      type: String,
      value: ''
    }, 

    sizeName: {
      type: String,
      value: ''
    }
  }

我的 CSS:

<style>
  :root {
    --width: 20px;
    --height: 20px;
    --border-color: black;
    --font-size: 16px;
  }
  :host {
    display: inline-block;
    box-sizing: border-box;
    height: var(--height);
    width: var(--width);
  }
  #icon {
    position: relative;
    display: block;
    width: var(--width);
    height: var(--height);
    border-radius: 50%;
    border: 1px solid var(--border-color);
    font-size: var(--font-size);
    @apply(--size-icon);
  }
  #icon:before {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 100%;
    content: '?';
    text-align: center;
    @apply(--size-icon--before);
  }
  #icon.small:before {content: 's';}
  #icon.medium:before {content: 'm';}
  #icon.large:before {content: 'l';}

  #name {
    font-size: var(--font-size);
    @apply(--size-name);
  }

  .hidden {
    display: none;
  }
</style>

我有一个测试夹具如下:

<test-fixture id="hasWrongSize">
  <template>
    <size-icon size="asdf"></size-icon>
  </template>
  <template>
    <size-icon size=""></size-icon>
  </template>
</test-fixture>

使用如下测试套件:

  suite('when no icon size or incorrect icon size is provided', function() {
    var el;
    setup(function() {
      el = fixture('hasWrongSize');
    });
    test('when the "size" property is incorrect the inner html equals "?"', function(done) {
      flush(function() {
        var domEl = Polymer.dom(el.root).querySelector('#icon:before');
        expect(domEl.innerHTML).to.equal('?');
        done();
      });
    });
  });

自定义元素的Local DOM如下:

<template>
  <template is="dom-if" if="{{ !sizeName }}">
    <span id="icon" class$="{{size}}"></span>
  </template>
  <span id="name">{{ sizeName }}</span>
</template>

我正在尝试获取:beforeID 为的伪元素,#icon但 WCT 无法找到它,并且domEl在测试套件中等同于null.

我究竟做错了什么?

4

2 回答 2

1

更新 问题已更新以包含 的完整代码test-fixture,这揭示了根本原因。

正如您在自己的回答中指出的那样:

  1. 我有两个模板标签,所以它不知道要定位哪个元素。

仅此一项就是您的问题的原因,而伪元素实际上与它无关。您会发现,如果您从 中删除其中一个模板test-fixture,您的原始代码就会起作用(并且会比您现在拥有的 IMO 更干净)。

test-fixture应该只包含一个 具有固定状态的template自定义元素作为测试的基线(最常见的分母)。在这种情况下,该基线是 single size-icon,但似乎您正在template为每个可能的测试用例添加一个,但该设置应该真正发生在测试脚本中,如下所示:

<test-fixture id="basic">
  <template>
    <size-icon></size-icon>
  </template>
</test-fixture>

<script>
  suite('size-icon', function() {
    var el;

    setup(function() {
      el = fixture('basic');
    });

    function expectIconEquals(done, contents) {
      flush(function() {
        var domEl = Polymer.dom(el.root).querySelector('#icon');
        expect(domEl.innerHTML).to.equal(contents);
        done();
      });
    }

    test('when the "size" property is empty, the inner html equals "?"', function(done) {
      el.size = "";
      expectIconEquals(done, '?');
    });

    test('when the "size" property is invalid, the inner html equals "?"', function(done) {
      el.size = "asdf";
      expectIconEquals(done, '?');
    });

    test('when the "size" property is valid, the inner html equals "<some valid content>"', function(done) {
      el.size = "12%";
      expectIconEquals(done, '<some valid content>');
    });
  });
</script>

回答原始问题:

在您的代码中,该元素仅在不是并且为空span#icon时才被标记。绑定评估类似于计算绑定的评估(即使对于非计算绑定没有明确说明):sizeNameundefined

在定义所有相关属性之前,不会调用计算函数(!=undefined)。因此,每个依赖属性都应该在属性中定义一个默认值(或者初始化为非undefined值),以确保计算函数值。

要解决此问题,sizeName请在刷新模板之前在测试中设置为空字符串。

suite('when no icon size or incorrect icon size is provided', function() {
  var el;
  setup(function() {
    el = fixture('hasWrongSize');
  });
  test('when the "size" property is incorrect the inner html equals "?"', function(done) {

    // #icon exists only when sizeName is empty string
    el.sizeName = "";

    flush(function() {
      var domEl = Polymer.dom(el.root).querySelector('#icon');
      expect(domEl).to.not.be.null;
      expect(domEl.innerHTML).to.equal('?');
      done();
    });
  });
});

sizeName或者,您可以在您的内部初始化dom-module

Polymer({
  is: 'size-icon',
  properties: {
    sizeName: {
      type: String,
      value: function() { return ""; }
    }
  }
});
于 2016-05-27T20:51:17.360 回答
1

我解决了这个问题。我使用 ':before' 元素来填充#icon跨度的内容。在尝试选择它时,我遇到了两个问题:

  1. 我有两个模板标签,所以它不知道要定位哪个元素。
  2. 我错误地选择了一个伪元素。

这是我用来正确选择和测试content伪元素属性的代码。

  var getBeforeText = function(el) {
    return window.getComputedStyle(
      getIcon(el), ':before'
    ).getPropertyValue('content').replace(/"/g, "").replace(/'/g, "");
  };

  var getIcon = function(el) {
    return Polymer.dom(el.root).querySelector('#icon');
  };

  suite('when no icon size or incorrect icon size is provided', function() {
    var el;
    setup(function() {
      el = fixture('hasWrongSize');
    });
    test('when the "size" property is incorrect the inner html equals "?"', function(done) {
      flush(function() {
        expect(getBeforeText(el)).to.equal('?');
        done();
      });
    });
  });

伪元素不能用纯 JS 直接选择,因为它们不是 DOM 的一部分。

于 2016-06-01T13:33:55.687 回答