这是我的财产声明:
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>
我正在尝试获取ID为:before
的{{1}}伪元素,但WCT无法找到它,并且测试套件中的#icon
等同于{{ 1}}。
我做错了什么?
答案 0 :(得分:1)
更新 问题已更新,其中包含test-fixture
的完整代码,其中显示了根本原因。
正如你在自己的回答中所说:
- 我有两个模板标签,因此它不知道要定位哪个元素。
醇>
仅此就是问题的原因,而伪元素实际上与它无关。您会发现,如果您从test-fixture
中删除其中一个模板,那么您的原始代码就会起作用(并且会比您现在拥有的IMO更清晰)。
test-fixture
应该只包含一个 template
,并将自定义元素的固定状态作为测试的基线(最常见的分母)。在这种情况下,该基线是单个size-icon
,但似乎您为每个可能的测试用例添加template
,但该设置应该在测试脚本中真正发生,如下所示: / p>
<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
元素仅在sizeName
不是undefined
时标记为空。绑定评估类似于that of computed bindings(即使未针对非计算绑定明确说明):
在定义所有相关属性(
!=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 ""; }
}
}
});
答案 1 :(得分:0)
我解决了这个问题。我使用':before'元素来填充#icon
范围的内容。在尝试选择它时,我遇到了两个问题:
以下是我用来正确选择和测试伪元素的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的一部分。