blob: ddf302fbc49f077f6f279d2c5f13e24676d44c20 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function() {
TestRunner.addResult(`Tests that pseudo elements and their styles are handled properly.\n`);
await TestRunner.loadModule('elements_test_runner');
await TestRunner.showPanel('elements');
await TestRunner.loadHTML(`
<style>
#inspected::target-text {
color: green;
}
#inspected::spelling-error {
color: orange;
}
#inspected::grammar-error {
color: teal;
}
#inspected {
display: list-item;
}
#inspected::marker {
content: "MARKER";
}
#inspected:before, .some-other-selector {
content: "BEFORE";
}
#inspected:after {
content: "AFTER";
}
</style>
<style>
#empty {
display: list-item;
}
#empty::marker {
content: "EmptyMarker";
}
#empty::before {
content: "EmptyBefore";
}
#empty::after {
content: "EmptyAfter";
}
</style>
<div id="container">
<div id="inspected">Text</div>
<div id="empty"></div>
</div>
`);
await TestRunner.evaluateInPagePromise(`
function removeLastRule()
{
document.styleSheets[0].deleteRule(document.styleSheets[0].cssRules.length - 1);
}
function addAfterRule()
{
document.styleSheets[0].addRule("#inspected:after", "content: \\"AFTER\\"");
}
function addBeforeRule()
{
document.styleSheets[0].addRule("#inspected:before", "content: \\"BEFORE\\"");
}
function addMarkerRule()
{
document.styleSheets[0].addRule("#inspected", "display: list-item");
document.styleSheets[0].addRule("#inspected::marker", "content: \\"MARKER\\"");
}
function modifyTextContent()
{
document.getElementById("inspected").textContent = "bar";
}
function clearTextContent()
{
document.getElementById("inspected").textContent = "";
}
function removeNode()
{
document.getElementById("inspected").remove();
}
`);
var containerNode;
var inspectedNode;
TestRunner.runTestSuite([
function dumpOriginalTree(next) {
ElementsTestRunner.expandElementsTree(callback);
function callback() {
containerNode = ElementsTestRunner.expandedNodeWithId('container');
inspectedNode = ElementsTestRunner.expandedNodeWithId('inspected');
TestRunner.addResult('Original elements tree:');
ElementsTestRunner.dumpElementsTree(containerNode);
next();
}
},
function dumpNormalNodeStyles(next) {
selectNodeAndDumpStyles('inspected', '', next);
},
function dumpBeforeStyles(next) {
selectNodeAndDumpStyles('inspected', 'before', next);
},
function dumpAfterStyles(next) {
selectNodeAndDumpStyles('inspected', 'after', next);
},
function dumpMarkerStyles(next) {
selectNodeAndDumpStyles('inspected', 'marker', next);
},
function removeAfter(next) {
executeAndDumpTree('removeLastRule()', SDK.DOMModel.Events.NodeRemoved, next);
},
function removeBefore(next) {
executeAndDumpTree('removeLastRule()', SDK.DOMModel.Events.NodeRemoved, next);
},
function removeMarker(next) {
executeAndDumpTree('removeLastRule(); removeLastRule()', SDK.DOMModel.Events.NodeRemoved, next);
},
function addAfter(next) {
executeAndDumpTree('addAfterRule()', SDK.DOMModel.Events.NodeInserted, expandAndDumpTree.bind(this, next));
},
function addBefore(next) {
executeAndDumpTree('addBeforeRule()', SDK.DOMModel.Events.NodeInserted, next);
},
function addMarker(next) {
executeAndDumpTree('addMarkerRule()', SDK.DOMModel.Events.NodeInserted, next);
},
function modifyTextContent(next) {
executeAndDumpTree('modifyTextContent()', SDK.DOMModel.Events.NodeInserted, next);
},
function clearTextContent(next) {
executeAndDumpTree('clearTextContent()', SDK.DOMModel.Events.NodeRemoved, next);
},
function removeNodeAndCheckPseudoElementsUnbound(next) {
var inspectedBefore = inspectedNode.beforePseudoElement();
var inspectedAfter = inspectedNode.afterPseudoElement();
var inspectedMarker = inspectedNode.markerPseudoElement();
executeAndDumpTree('removeNode()', SDK.DOMModel.Events.NodeRemoved, callback);
function callback() {
TestRunner.addResult(
'inspected:before DOMNode in DOMAgent: ' + !!(TestRunner.domModel.nodeForId(inspectedBefore.id)));
TestRunner.addResult(
'inspected:after DOMNode in DOMAgent: ' + !!(TestRunner.domModel.nodeForId(inspectedAfter.id)));
TestRunner.addResult(
'inspected::marker DOMNode in DOMAgent: ' + !!(TestRunner.domModel.nodeForId(inspectedMarker.id)));
next();
}
}
]);
function executeAndDumpTree(pageFunction, eventName, next) {
TestRunner.domModel.addEventListener(eventName, domCallback, this);
TestRunner.evaluateInPage(pageFunction);
function domCallback() {
TestRunner.domModel.removeEventListener(eventName, domCallback, this);
ElementsTestRunner.firstElementsTreeOutline().addEventListener(
Elements.ElementsTreeOutline.Events.ElementsTreeUpdated, treeCallback, this);
}
function treeCallback() {
ElementsTestRunner.firstElementsTreeOutline().removeEventListener(
Elements.ElementsTreeOutline.Events.ElementsTreeUpdated, treeCallback, this);
ElementsTestRunner.dumpElementsTree(containerNode);
next();
}
}
function expandAndDumpTree(next) {
TestRunner.addResult('== Expanding: ==');
ElementsTestRunner.expandElementsTree(callback);
function callback() {
ElementsTestRunner.dumpElementsTree(containerNode);
next();
}
}
function selectNodeAndDumpStyles(id, pseudoTypeName, callback) {
if (pseudoTypeName)
ElementsTestRunner.selectPseudoElementAndWaitForStyles('inspected', pseudoTypeName, stylesCallback);
else
ElementsTestRunner.selectNodeAndWaitForStyles('inspected', stylesCallback);
async function stylesCallback() {
await ElementsTestRunner.dumpSelectedElementStyles(true, false, false, true);
callback();
}
}
})();