435 lines
15 KiB
JavaScript
435 lines
15 KiB
JavaScript
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
goog.provide('goog.testing.domTest');
|
|
goog.setTestOnly('goog.testing.domTest');
|
|
|
|
goog.require('goog.dom');
|
|
goog.require('goog.dom.TagName');
|
|
goog.require('goog.testing.dom');
|
|
goog.require('goog.testing.jsunit');
|
|
goog.require('goog.userAgent');
|
|
|
|
var root;
|
|
function setUpPage() {
|
|
root = goog.dom.getElement('root');
|
|
}
|
|
|
|
function setUp() {
|
|
root.innerHTML = '';
|
|
}
|
|
|
|
function testFindNode() {
|
|
// Test the easiest case.
|
|
root.innerHTML = 'a<br>b';
|
|
assertEquals(goog.testing.dom.findTextNode('a', root), root.firstChild);
|
|
assertEquals(goog.testing.dom.findTextNode('b', root), root.lastChild);
|
|
assertNull(goog.testing.dom.findTextNode('c', root));
|
|
}
|
|
|
|
function testFindNodeDuplicate() {
|
|
// Test duplicate.
|
|
root.innerHTML = 'c<br>c';
|
|
assertEquals('Should return first duplicate',
|
|
goog.testing.dom.findTextNode('c', root), root.firstChild);
|
|
}
|
|
|
|
function findNodeWithHierarchy() {
|
|
// Test a more complicated hierarchy.
|
|
root.innerHTML = '<div>a<p>b<span>c</span>d</p>e</div>';
|
|
assertEquals(goog.dom.TagName.DIV,
|
|
goog.testing.dom.findTextNode('a', root).parentNode.tagName);
|
|
assertEquals(goog.dom.TagName.P,
|
|
goog.testing.dom.findTextNode('b', root).parentNode.tagName);
|
|
assertEquals(goog.dom.TagName.SPAN,
|
|
goog.testing.dom.findTextNode('c', root).parentNode.tagName);
|
|
assertEquals(goog.dom.TagName.P,
|
|
goog.testing.dom.findTextNode('d', root).parentNode.tagName);
|
|
assertEquals(goog.dom.TagName.DIV,
|
|
goog.testing.dom.findTextNode('e', root).parentNode.tagName);
|
|
}
|
|
|
|
function setUpAssertHtmlMatches() {
|
|
var tag1, tag2;
|
|
if (goog.userAgent.IE) {
|
|
tag1 = goog.dom.TagName.DIV;
|
|
} else if (goog.userAgent.WEBKIT) {
|
|
tag1 = goog.dom.TagName.P;
|
|
tag2 = goog.dom.TagName.BR;
|
|
} else if (goog.userAgent.GECKO) {
|
|
tag1 = goog.dom.TagName.SPAN;
|
|
tag2 = goog.dom.TagName.BR;
|
|
}
|
|
|
|
var parent = goog.dom.createDom(goog.dom.TagName.DIV);
|
|
root.appendChild(parent);
|
|
parent.style.fontSize = '2em';
|
|
parent.style.display = 'none';
|
|
if (!goog.userAgent.WEBKIT) {
|
|
parent.appendChild(goog.dom.createTextNode('NonWebKitText'));
|
|
}
|
|
|
|
if (tag1) {
|
|
var e1 = goog.dom.createDom(tag1);
|
|
parent.appendChild(e1);
|
|
parent = e1;
|
|
}
|
|
if (tag2) {
|
|
parent.appendChild(goog.dom.createDom(tag2));
|
|
}
|
|
parent.appendChild(goog.dom.createTextNode('Text'));
|
|
if (goog.userAgent.WEBKIT) {
|
|
root.firstChild.appendChild(goog.dom.createTextNode('WebKitText'));
|
|
}
|
|
}
|
|
|
|
function testAssertHtmlContentsMatch() {
|
|
setUpAssertHtmlMatches();
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div style="display: none; font-size: 2em">' +
|
|
'[[!WEBKIT]]NonWebKitText<div class="IE"><p class="WEBKIT">' +
|
|
'<span class="GECKO"><br class="GECKO WEBKIT">Text</span></p></div>' +
|
|
'</div>[[WEBKIT]]WebKitText',
|
|
root);
|
|
}
|
|
|
|
function testAssertHtmlMismatchText() {
|
|
setUpAssertHtmlMatches();
|
|
|
|
var e = assertThrows('Should fail due to mismatched text', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div style="display: none; font-size: 2em">' +
|
|
'[[IE GECKO]]NonWebKitText<div class="IE"><p class="WEBKIT">' +
|
|
'<span class="GECKO"><br class="GECKO WEBKIT">Bad</span></p></div>' +
|
|
'</div>[[WEBKIT]]Extra',
|
|
root);
|
|
});
|
|
assertContains('Text should match', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchTag() {
|
|
setUpAssertHtmlMatches();
|
|
|
|
var e = assertThrows('Should fail due to mismatched tag', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<span style="display: none; font-size: 2em">' +
|
|
'[[IE GECKO]]NonWebKitText<div class="IE"><p class="WEBKIT">' +
|
|
'<span class="GECKO"><br class="GECKO WEBKIT">Text</span></p></div>' +
|
|
'</span>[[WEBKIT]]Extra',
|
|
root);
|
|
});
|
|
assertContains('Tag names should match', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchStyle() {
|
|
setUpAssertHtmlMatches();
|
|
|
|
var e = assertThrows('Should fail due to mismatched style', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div style="display: none; font-size: 3em">' +
|
|
'[[IE GECKO]]NonWebKitText<div class="IE"><p class="WEBKIT">' +
|
|
'<span class="GECKO"><br class="GECKO WEBKIT">Text</span></p></div>' +
|
|
'</div>[[WEBKIT]]Extra',
|
|
root);
|
|
});
|
|
assertContains('Should have same styles', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchOptionalText() {
|
|
setUpAssertHtmlMatches();
|
|
|
|
var e = assertThrows('Should fail due to mismatched text', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div style="display: none; font-size: 2em">' +
|
|
'[[IE GECKO]]Bad<div class="IE"><p class="WEBKIT">' +
|
|
'<span class="GECKO"><br class="GECKO WEBKIT">Text</span></p></div>' +
|
|
'</div>[[WEBKIT]]Bad',
|
|
root);
|
|
});
|
|
assertContains('Text should match', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchExtraActualAfterText() {
|
|
root.innerHTML = '<div>abc</div>def';
|
|
|
|
var e = assertThrows('Should fail due to extra actual nodes', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch('<div>abc</div>', root);
|
|
});
|
|
assertContains('Finished expected HTML before', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchExtraActualAfterElement() {
|
|
root.innerHTML = '<br>def';
|
|
|
|
var e = assertThrows('Should fail due to extra actual nodes', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch('<br>', root);
|
|
});
|
|
assertContains('Finished expected HTML before', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithSplitTextNodes() {
|
|
root.appendChild(goog.dom.createTextNode('1'));
|
|
root.appendChild(goog.dom.createTextNode('2'));
|
|
root.appendChild(goog.dom.createTextNode('3'));
|
|
goog.testing.dom.assertHtmlContentsMatch('123', root);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithDifferentlyOrderedAttributes() {
|
|
root.innerHTML = '<div foo="a" bar="b" class="className"></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div bar="b" class="className" foo="a"></div>', root, true);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWithDifferentNumberOfAttributes() {
|
|
root.innerHTML = '<div foo="a" bar="b"></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div foo="a"></div>', root, true);
|
|
});
|
|
assertContains('Unexpected attribute with name bar in element', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWithDifferentAttributeNames() {
|
|
root.innerHTML = '<div foo="a" bar="b"></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div foo="a" baz="b"></div>', root, true);
|
|
});
|
|
assertContains('Expected to find attribute with name baz', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWithDifferentClassNames() {
|
|
root.innerHTML = '<div class="className1"></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div class="className2"></div>', root, true);
|
|
});
|
|
assertContains(
|
|
'Expected class was: className2, but actual class was: className1',
|
|
e.message);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithClassNameAndUserAgentSpecified() {
|
|
root.innerHTML =
|
|
'<div>' + (goog.userAgent.GECKO ? '<div class="foo"></div>' : '') +
|
|
'</div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div><div class="foo GECKO"></div></div>',
|
|
root, true);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithClassesInDifferentOrder() {
|
|
root.innerHTML = '<div class="class1 class2"></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div class="class2 class1"></div>', root, true);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWithDifferentAttributeValues() {
|
|
root.innerHTML = '<div foo="b" bar="a"></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div foo="a" bar="a"></div>', root, true);
|
|
});
|
|
assertContains('Expected attribute foo has a different value', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWhenStrictAttributesIsFalse() {
|
|
root.innerHTML = '<div foo="a" bar="b"></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<div foo="a"></div>', root);
|
|
}
|
|
|
|
function testAssertHtmlMatchesForMethodsAttribute() {
|
|
root.innerHTML = '<a methods="get"></a>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<a></a>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<a methods="get"></a>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<a methods="get"></a>', root,
|
|
true);
|
|
}
|
|
|
|
function testAssertHtmlMatchesForMethodsAttribute() {
|
|
root.innerHTML = '<input></input>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<input></input>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<input></input>', root, true);
|
|
}
|
|
|
|
function testAssertHtmlMatchesForIdAttribute() {
|
|
root.innerHTML = '<div id="foo"></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<div></div>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<div id="foo"></div>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<div id="foo"></div>', root,
|
|
true);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWhenIdIsNotSpecified() {
|
|
root.innerHTML = '<div id="someId"></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<div></div>', root);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWhenIdIsNotSpecified() {
|
|
root.innerHTML = '<div id="someId"></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch('<div></div>', root, true);
|
|
});
|
|
assertContains('Unexpected attribute with name id in element', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMismatchWhenIdIsSpecified() {
|
|
root.innerHTML = '<div></div>';
|
|
|
|
var e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch('<div id="someId"></div>', root);
|
|
});
|
|
assertContains('Expected to find attribute with name id, in element',
|
|
e.message);
|
|
|
|
e = assertThrows(function() {
|
|
goog.testing.dom.assertHtmlContentsMatch('<div id="someId"></div>', root,
|
|
true);
|
|
});
|
|
assertContains('Expected to find attribute with name id, in element',
|
|
e.message);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWhenIdIsEmpty() {
|
|
root.innerHTML = '<div></div>';
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch('<div></div>', root);
|
|
goog.testing.dom.assertHtmlContentsMatch('<div></div>', root, true);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithDisabledAttribute() {
|
|
var disabledShortest = '<input disabled="disabled">';
|
|
var disabledShort = '<input disabled="">';
|
|
var disabledLong = '<input disabled="disabled">';
|
|
var enabled = '<input>';
|
|
|
|
root.innerHTML = disabledLong;
|
|
goog.testing.dom.assertHtmlContentsMatch(disabledShortest, root, true);
|
|
goog.testing.dom.assertHtmlContentsMatch(disabledShort, root, true);
|
|
goog.testing.dom.assertHtmlContentsMatch(disabledLong, root, true);
|
|
|
|
|
|
var e = assertThrows('Should fail due to mismatched text', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(enabled, root, true);
|
|
});
|
|
// Attribute value mismatch in IE.
|
|
// Unexpected attribute error in other browsers.
|
|
assertContains('disabled', e.message);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithCheckedAttribute() {
|
|
var checkedShortest = '<input type="radio" name="x" checked="checked">';
|
|
var checkedShort = '<input type="radio" name="x" checked="">';
|
|
var checkedLong = '<input type="radio" name="x" checked="checked">';
|
|
var unchecked = '<input type="radio" name="x">';
|
|
|
|
root.innerHTML = checkedLong;
|
|
goog.testing.dom.assertHtmlContentsMatch(checkedShortest, root, true);
|
|
goog.testing.dom.assertHtmlContentsMatch(checkedShort, root, true);
|
|
goog.testing.dom.assertHtmlContentsMatch(checkedLong, root, true);
|
|
if (!goog.userAgent.IE) {
|
|
// CHECKED attribute is ignored because it's among BAD_IE_ATTRIBUTES_.
|
|
var e = assertThrows('Should fail due to mismatched text', function() {
|
|
goog.testing.dom.assertHtmlContentsMatch(unchecked, root, true);
|
|
});
|
|
assertContains('Unexpected attribute with name checked', e.message);
|
|
}
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithWhitespace() {
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createTextNode(' A '));
|
|
goog.testing.dom.assertHtmlContentsMatch(' A ', root);
|
|
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createTextNode(' A '));
|
|
root.appendChild(goog.dom.createDom('span', null, ' B '));
|
|
root.appendChild(goog.dom.createTextNode(' C '));
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
' A <span> B </span> C ', root);
|
|
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createTextNode(' A'));
|
|
root.appendChild(goog.dom.createDom('span', null, ' B'));
|
|
root.appendChild(goog.dom.createTextNode(' C'));
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
' A<span> B</span> C', root);
|
|
}
|
|
|
|
function testAssertHtmlMatchesWithWhitespaceAndNesting() {
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createDom('div', null,
|
|
goog.dom.createDom('b', null, ' A '),
|
|
goog.dom.createDom('b', null, ' B ')));
|
|
root.appendChild(goog.dom.createDom('div', null,
|
|
goog.dom.createDom('b', null, ' C '),
|
|
goog.dom.createDom('b', null, ' D ')));
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div><b> A </b><b> B </b></div>' +
|
|
'<div><b> C </b><b> D </b></div>', root);
|
|
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createDom('b', null,
|
|
goog.dom.createDom('b', null,
|
|
goog.dom.createDom('b', null, ' A '))));
|
|
root.appendChild(goog.dom.createDom('b', null, ' B '));
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<b><b><b> A </b></b></b><b> B </b>', root);
|
|
|
|
root.innerHTML = '';
|
|
root.appendChild(goog.dom.createDom('div', null,
|
|
goog.dom.createDom('b', null,
|
|
goog.dom.createDom('b', null, ' A '))));
|
|
root.appendChild(goog.dom.createDom('b', null, ' B '));
|
|
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
'<div><b><b> A </b></b></div><b> B </b>', root);
|
|
|
|
root.innerHTML = ' ';
|
|
goog.testing.dom.assertHtmlContentsMatch(
|
|
' ', root);
|
|
}
|
|
|
|
function testAssertHtmlMatches() {
|
|
// Since assertHtmlMatches is based on assertHtmlContentsMatch, we leave the
|
|
// majority of edge case testing to the above. Here we just do a sanity
|
|
// check.
|
|
goog.testing.dom.assertHtmlMatches('<div>abc</div>', '<div>abc</div>');
|
|
goog.testing.dom.assertHtmlMatches('<div>abc</div>', '<div>abc</div> ');
|
|
goog.testing.dom.assertHtmlMatches(
|
|
'<div style="font-size: 1px; color: red">abc</div>',
|
|
'<div style="color: red; font-size: 1px;;">abc</div>');
|
|
|
|
var e = assertThrows('Should fail due to mismatched text', function() {
|
|
goog.testing.dom.assertHtmlMatches('<div>abc</div>', '<div>abd</div>');
|
|
});
|
|
assertContains('Text should match', e.message);
|
|
}
|