If javascript updates the classList of an element, it does not clear the computedStyles cache for that and related elements.
This effect is shown if an element is hidden by a click handler from one of its descendants.
toggletest.html:
<!DOCTYPE html>
<html>
<head>
<style>
#togglable.hidden {
display: none;
}
</style>
</head>
<body>
<div id="togglable" class="x">
<button onclick="getElementById('togglable').classList.toggle('hidden')">X</button>
</div>
</body>
</html>
ToggleTest.java:
@Test
public void testToggle() throws Exception {
WebClient wc = new WebClient();
HtmlPage page = wc.getPage("file:toggletest.html");
HtmlElement button = page.querySelector("button");
button.click();
assertFalse("Should be hidden", button.isDisplayed());
wc.close();
}
In a browser, clicking on the "x" correctly hides the whole div. In HtmlUnit, the test fails with "java.lang.AssertionError: Should be hidden"
The issue seems to be that ...classList.toggle(...) calls DOMTokenList.toggle(...), which in turn calls (indirectly) DOMTokenList.updateAttribute(...). If the attribute already exists, this calls DomAttr.setValue(...), which triggers no further DOM change event handlers. If the class="x" is removed entirely, this will instead call domNode.setAttributeNode(...), which does trigger an attribute change event, resulting in a computed styles cache clear and a successful unittest.
Tested on HtmlUnit 2.33
If javascript updates the classList of an element, it does not clear the computedStyles cache for that and related elements.
This effect is shown if an element is hidden by a click handler from one of its descendants.
toggletest.html:ToggleTest.java:In a browser, clicking on the "x" correctly hides the whole div. In HtmlUnit, the test fails with "java.lang.AssertionError: Should be hidden"
The issue seems to be that
...classList.toggle(...)callsDOMTokenList.toggle(...), which in turn calls (indirectly)DOMTokenList.updateAttribute(...). If the attribute already exists, this callsDomAttr.setValue(...), which triggers no further DOM change event handlers. If theclass="x"is removed entirely, this will instead calldomNode.setAttributeNode(...), which does trigger an attribute change event, resulting in a computed styles cache clear and a successful unittest.Tested on HtmlUnit 2.33