我有一个包含不同HTML元素的文本的页面,我想要一种快速验证文本的方法。
使用jasmine和jasmine-query加载HTML并测试DOM。
例如,我想验证此HTML中的文本
<table id="users">
<thead>
<tr>
<td>user</td>
<td>permissions</td>
<td>last seen</td>
</tr>
</thead>
<tbody>
<tr>
<td>Darren</td>
<td>testuser,customer</td>
<td>today</td>
</tr>
<tr>
<td>Hillary</td>
<td>administrator</td>
<td>yesterday</td>
</tr>
</tbody>
</table>
让我们说我想验证表中的每一行都包含正确的文本。 茉莉花测试文件:
it('should find correct text in table', function () {
expect( $('#users').find('tbody tr').first() ).toContainText('Darren testuser,customer today');
expect( $('#users').find('tbody tr').last() ).toContainText('Hillary administrator yesterday');
});
我将失败:
Testexample:: should find correct text in table: failed
Expected '<tr>
<td>Darren</td>
<td>testuser,customer</td>
<td>today</td>
</tr>' to contain text 'Darren testuser,customer today'. (1)
Expected '<tr>
<td>Hillary</td>
<td>administrator</td>
<td>yesterday</td>
</tr>' to contain text 'Hillary administrator yesterday'. (2)
1 spec in 0.283s.
>> 2 failures
另一个实验是使用jQuery.text()来提取,然后因为所有的空格而仍然有错误:
it('should find correct text in table with jQuery.text()', function () {
expect( $('#users').find('tbody tr').first().text() ).toContain('Darren testuser,customer today');
expect( $('#users').find('tbody tr').last().text() ).toContain('Hillary administrator yesterday');
});
给出了这个失败:
Testexample:: should find correct text in table with jQuery.text(): failed
Expected '
Darren
testuser,customer
today
' to contain 'Darren testuser,customer today'. (1)
Expected '
Hillary
administrator
yesterday
' to contain 'Hillary administrator yesterday'. (2)
1 spec in 0.291s.
>> 2 failures
Capybara(用于ruby)有一种标准化文本的方法,这样我总能看到HTML的合理文本表示。我如何以简单的方式规范化空白,以便我可以进行这样的验证?
(我不希望像'你不应该跨html元素测试'这样的答案......因为这是问题的前提。实际上我喜欢在几个元素之间做出断言:它是可读的,简短的,快速的查看是否有工作。当我从外向内测试时也非常必要)
答案 0 :(得分:3)
我经常在我的项目中添加这样的内容:
String.prototype.normalizeSpace = function() {
return this.replace(/\s\s+/g, ' ');
}
因此,在.text()
之后您可以添加对.normalizeSpace()
答案 1 :(得分:2)
感谢Tobias的回答,我最终改进了并编写了自己的自定义匹配器。现在我可以写:
expect( $('#users').find('tbody tr').first() ).toHaveNormalizedText('Darren testuser,customer today');
匹配代码 - 在我的describe()场景的beforeEach()块中添加:
this.addMatchers({
toHaveNormalizedText: function(expected) {
var actualText = $.trim(this.actual.text()).replace(/\s+/g, ' ');
var result = actualText === expected;
if( result) return result;
//rest is only if it fails
var notText = this.isNot ? " not" : "";
var charcodes = [];
for(var i=0; i<actualText.length; i++){
charcodes.push(actualText.charCodeAt(i));
if(i>23) break;
}
this.message = function () {return 'Expected "' + actualText + notText + '" to match "'+expected+'"\n\nFirst 25 charcodes:\n'+charcodes;};
return result;
}
});
关于此的一些注释。这是实际的替代品:
$.trim(this.actual.text()).replace(/\s+/g, ' ');
$ .trim()对我的html结构非常重要,它在text()字符串的开头包含空格。
this.message = function () {return 'Expected "' + actualText + notText + '" to match "'+expected+'"\n\nFirst 25 charcodes:\n'+charcodes;};
this.message
是jasmine的自定义错误消息。这个字符串在出错时输出这样的字符串:
failed
Expected "Darren testuser,customer todaiiy" to match "Darren testuser,customer today"
First 25 charcodes:
68,97,114,114,101,110,32,116,101,115,116,117,115,101,114,44,99,117,115,116,111,109,101,114,32 (1)
我决定添加charcodes,因为有一点我的charcodes 10(换行符)和32(空格)有问题。
答案 2 :(得分:1)
对于Jasmine v2,我写了这个:
jasmine.addMatchers({
toHaveTrimText: function() {
return {
compare: function(actual, expected) {
var actualText = $(actual).text().trim();
var result = {
pass: actualText === expected,
message: 'Expected "' + actualText + '" to match "' + expected + '"'
}
return result;
}
}
}
});