blob: 5d075a880163bc055ac94185f5ee98e7394fa20d [file] [log] [blame]
// 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 = '&nbsp;';
goog.testing.dom.assertHtmlContentsMatch(
'&nbsp;', 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);
}