зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644428 - Added tests to verify Compatiblity Panel reacting to DOM mutations r=daisuke,mtigley
The tests cover the following test cases: * Dynamic addition of inline style * Dynamic change of classlist - addition and removal of class * Inline style change via the rule-view * Dynamic addition of nodes with issues * Dynamic addition of nodes whose children have issues * Dynamic removal of node with issue * Dynamic removal of node whose children have issue Differential Revision: https://phabricator.services.mozilla.com/D81443
This commit is contained in:
Родитель
6a6c70267a
Коммит
30282112dd
|
@ -10,6 +10,10 @@ support-files =
|
|||
!/devtools/client/shared/test/test-actor.js
|
||||
|
||||
[browser_compatibility_css-property_issue.js]
|
||||
[browser_compatibility_dynamic_js-attribute-change.js]
|
||||
[browser_compatibility_dynamic_js-dom-change.js]
|
||||
[browser_compatibility_dynamic_markup-dom-change.js]
|
||||
[browser_compatibility_dynamic_ruleview-attribute-change.js]
|
||||
[browser_compatibility_event_document-reload.js]
|
||||
[browser_compatibility_event_panel-select.js]
|
||||
[browser_compatibility_event_rule-change.js]
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MDNCompatibility = require("devtools/shared/compatibility/MDNCompatibility");
|
||||
|
||||
const {
|
||||
COMPATIBILITY_UPDATE_NODE_COMPLETE,
|
||||
} = require("devtools/client/inspector/compatibility/actions/index");
|
||||
|
||||
// Test the behavior rules are dynamically added
|
||||
|
||||
const ISSUE_CURSOR = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY,
|
||||
property: "cursor",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/cursor",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const ISSUE_HYPHENS = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY_ALIASES,
|
||||
aliases: ["hyphens"],
|
||||
property: "hyphens",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/hyphens",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const TEST_URI = `
|
||||
<style>
|
||||
.issue {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="test"></div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
info("Testing dynamic style change using JavaScript");
|
||||
const tab = await addTab(
|
||||
"data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)
|
||||
);
|
||||
|
||||
const {
|
||||
allElementsPane,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
} = await openCompatibilityView();
|
||||
|
||||
info("Testing inline style change due to JavaScript execution");
|
||||
const onPanelUpdate = waitForUpdateSelectedNodeAction(inspector.store);
|
||||
info("Select the div to undergo mutation");
|
||||
await selectNode(".test", inspector);
|
||||
await onPanelUpdate;
|
||||
|
||||
info("Check initial issues");
|
||||
await assertIssueList(selectedElementPane, []);
|
||||
await assertIssueList(allElementsPane, []);
|
||||
|
||||
info("Adding inline style with compatibility issue");
|
||||
await testAttributeMutation(
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_HYPHENS],
|
||||
[ISSUE_HYPHENS],
|
||||
async function() {
|
||||
content.document.querySelector(".test").style.hyphens = "none";
|
||||
}
|
||||
);
|
||||
|
||||
info("Adding a class with declarations having compatibility issue");
|
||||
await testAttributeMutation(
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_HYPHENS, ISSUE_CURSOR],
|
||||
[ISSUE_HYPHENS, ISSUE_CURSOR],
|
||||
async function() {
|
||||
content.document.querySelector(".test").classList.add("issue");
|
||||
}
|
||||
);
|
||||
|
||||
info("Removing a class with declarations having compatibility issue");
|
||||
await testAttributeMutation(
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_HYPHENS],
|
||||
[ISSUE_HYPHENS],
|
||||
async function() {
|
||||
content.document.querySelector(".test").classList.remove("issue");
|
||||
}
|
||||
);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
async function testAttributeMutation(
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
expectedSelectedElementIssues,
|
||||
expectedAllElementsIssues,
|
||||
contentTaskFunction
|
||||
) {
|
||||
const onPanelUpdate = Promise.all([
|
||||
inspector.once("markupmutation"),
|
||||
waitForDispatch(inspector.store, COMPATIBILITY_UPDATE_NODE_COMPLETE),
|
||||
]);
|
||||
info("Run the task in webpage context");
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, contentTaskFunction);
|
||||
info("Wait for changes to reflect");
|
||||
await onPanelUpdate;
|
||||
|
||||
info("Check issues listed in selected element pane");
|
||||
await assertIssueList(selectedElementPane, expectedSelectedElementIssues);
|
||||
info("Check issues listed in all issues pane");
|
||||
await assertIssueList(allElementsPane, expectedAllElementsIssues);
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MDNCompatibility = require("devtools/shared/compatibility/MDNCompatibility");
|
||||
|
||||
const {
|
||||
COMPATIBILITY_APPEND_NODE_COMPLETE,
|
||||
COMPATIBILITY_CLEAR_DESTROYED_NODES,
|
||||
} = require("devtools/client/inspector/compatibility/actions/index");
|
||||
|
||||
// Test the behavior rules are dynamically added
|
||||
|
||||
const ISSUE_CURSOR = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY,
|
||||
property: "cursor",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/cursor",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const ISSUE_HYPHENS = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY_ALIASES,
|
||||
aliases: ["hyphens"],
|
||||
property: "hyphens",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/hyphens",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const TEST_URI = `
|
||||
<style>
|
||||
.child {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
info("Testing dynamic DOM mutation using JavaScript");
|
||||
const tab = await addTab(
|
||||
"data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)
|
||||
);
|
||||
|
||||
const {
|
||||
allElementsPane,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
} = await openCompatibilityView();
|
||||
|
||||
info("Check initial issues");
|
||||
await assertIssueList(selectedElementPane, []);
|
||||
await assertIssueList(allElementsPane, []);
|
||||
|
||||
info("Append nodes dynamically using JavaScript");
|
||||
await testNodeMutation(
|
||||
".child",
|
||||
COMPATIBILITY_APPEND_NODE_COMPLETE,
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_CURSOR],
|
||||
[ISSUE_HYPHENS, ISSUE_CURSOR],
|
||||
async function() {
|
||||
const doc = content.document;
|
||||
const parent = doc.querySelector("body");
|
||||
|
||||
const newElementWithIssue = doc.createElement("div");
|
||||
newElementWithIssue.style.hyphens = "none";
|
||||
|
||||
const parentOfIssueElement = doc.createElement("div");
|
||||
parentOfIssueElement.classList.add("parent");
|
||||
const child = doc.createElement("div");
|
||||
child.classList.add("child");
|
||||
parentOfIssueElement.appendChild(child);
|
||||
|
||||
parent.appendChild(newElementWithIssue);
|
||||
parent.appendChild(parentOfIssueElement);
|
||||
}
|
||||
);
|
||||
|
||||
info("Remove node whose child has compatibility issue");
|
||||
await testNodeMutation(
|
||||
"div",
|
||||
COMPATIBILITY_CLEAR_DESTROYED_NODES,
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_HYPHENS],
|
||||
[ISSUE_HYPHENS],
|
||||
async function() {
|
||||
const doc = content.document;
|
||||
const parent = doc.querySelector(".parent");
|
||||
parent.remove();
|
||||
}
|
||||
);
|
||||
|
||||
info("Remove node which has compatibility issue");
|
||||
await testNodeMutation(
|
||||
"body",
|
||||
COMPATIBILITY_CLEAR_DESTROYED_NODES,
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[],
|
||||
[],
|
||||
async function() {
|
||||
const doc = content.document;
|
||||
const issueElement = doc.querySelector("div");
|
||||
issueElement.remove();
|
||||
}
|
||||
);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
async function testNodeMutation(
|
||||
selector,
|
||||
action,
|
||||
tab,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
expectedSelectedElementIssues,
|
||||
expectedAllElementsIssues,
|
||||
contentTaskFunction
|
||||
) {
|
||||
let onPanelUpdate = Promise.all([
|
||||
inspector.once("markupmutation"),
|
||||
waitForDispatch(inspector.store, action),
|
||||
]);
|
||||
info("Add a new node with issue and another node whose child has the issue");
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, contentTaskFunction);
|
||||
info("Wait for changes");
|
||||
await onPanelUpdate;
|
||||
|
||||
onPanelUpdate = waitForUpdateSelectedNodeAction(inspector.store);
|
||||
await selectNode(selector, inspector);
|
||||
await onPanelUpdate;
|
||||
|
||||
info("Check element issues");
|
||||
await assertIssueList(selectedElementPane, expectedSelectedElementIssues);
|
||||
|
||||
info("Check all issues");
|
||||
await assertIssueList(allElementsPane, expectedAllElementsIssues);
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MDNCompatibility = require("devtools/shared/compatibility/MDNCompatibility");
|
||||
|
||||
const {
|
||||
COMPATIBILITY_APPEND_NODE_COMPLETE,
|
||||
COMPATIBILITY_REMOVE_NODE_COMPLETE,
|
||||
} = require("devtools/client/inspector/compatibility/actions/index");
|
||||
|
||||
// Test the behavior rules are dynamically added
|
||||
|
||||
const ISSUE_CURSOR = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY,
|
||||
property: "cursor",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/cursor",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const ISSUE_HYPHENS = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY_ALIASES,
|
||||
aliases: ["hyphens"],
|
||||
property: "hyphens",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/hyphens",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const TEST_URI = `
|
||||
<style>
|
||||
div {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div></div>
|
||||
<div class="parent">
|
||||
<div style="hyphens: none"></div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
info("Testing dynamic DOM mutation using JavaScript");
|
||||
const tab = await addTab(
|
||||
"data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)
|
||||
);
|
||||
|
||||
const { allElementsPane, inspector } = await openCompatibilityView();
|
||||
|
||||
info("Check initial issues");
|
||||
await assertIssueList(allElementsPane, [ISSUE_CURSOR, ISSUE_HYPHENS]);
|
||||
|
||||
info("Delete node whose child node has CSS compatibility issue");
|
||||
await testNodeRemoval(".parent", inspector, allElementsPane, [ISSUE_CURSOR]);
|
||||
|
||||
info("Delete node that has CSS compatibility issue");
|
||||
await testNodeRemoval("div", inspector, allElementsPane, []);
|
||||
|
||||
info("Add node that has CSS compatibility issue");
|
||||
await testNodeAddition("div", inspector, allElementsPane, [ISSUE_CURSOR]);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* Simulate a click on the markup-container (a line in the markup-view)
|
||||
* that corresponds to the selector passed.
|
||||
* This overrides the definition in inspector/test/head.js which times
|
||||
* out when the container to be clicked is already the selected node.
|
||||
* @param {String|NodeFront} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {Promise} Resolves when the node has been selected.
|
||||
*/
|
||||
var clickContainer = async function(selector, inspector) {
|
||||
info("Clicking on the markup-container for node " + selector);
|
||||
|
||||
const nodeFront = await getNodeFront(selector, inspector);
|
||||
const container = getContainerForNodeFront(nodeFront, inspector);
|
||||
|
||||
const updated = container.selected
|
||||
? promise.resolve()
|
||||
: inspector.once("inspector-updated");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
container.tagLine,
|
||||
{ type: "mousedown" },
|
||||
inspector.markup.doc.defaultView
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
container.tagLine,
|
||||
{ type: "mouseup" },
|
||||
inspector.markup.doc.defaultView
|
||||
);
|
||||
return updated;
|
||||
};
|
||||
|
||||
async function deleteNode(inspector, selector) {
|
||||
info("Select node " + selector + " and make sure it is focused");
|
||||
await selectNode(selector, inspector);
|
||||
await clickContainer(selector, inspector);
|
||||
|
||||
info("Delete the node");
|
||||
const mutated = inspector.once("markupmutation");
|
||||
const updated = inspector.once("inspector-updated");
|
||||
EventUtils.sendKey("delete", inspector.panelWin);
|
||||
await mutated;
|
||||
await updated;
|
||||
}
|
||||
|
||||
async function testNodeAddition(
|
||||
selector,
|
||||
inspector,
|
||||
allElementsPane,
|
||||
expectedAllElementsIssues
|
||||
) {
|
||||
let onPanelUpdate = Promise.all([
|
||||
inspector.once("markupmutation"),
|
||||
waitForDispatch(inspector.store, COMPATIBILITY_APPEND_NODE_COMPLETE),
|
||||
]);
|
||||
info("Add a new node");
|
||||
await inspector.addNode();
|
||||
await onPanelUpdate;
|
||||
|
||||
onPanelUpdate = waitForUpdateSelectedNodeAction(inspector.store);
|
||||
await selectNode(selector, inspector);
|
||||
await onPanelUpdate;
|
||||
|
||||
info("Check issues list for the webpage");
|
||||
await assertIssueList(allElementsPane, expectedAllElementsIssues);
|
||||
}
|
||||
|
||||
async function testNodeRemoval(
|
||||
selector,
|
||||
inspector,
|
||||
allElementsPane,
|
||||
expectedAllElementsIssues
|
||||
) {
|
||||
const onPanelUpdate = Promise.all([
|
||||
inspector.once("markupmutation"),
|
||||
waitForDispatch(inspector.store, COMPATIBILITY_REMOVE_NODE_COMPLETE),
|
||||
]);
|
||||
info(`Delete the node with selector ${selector}`);
|
||||
await deleteNode(inspector, selector);
|
||||
await onPanelUpdate;
|
||||
|
||||
info("Check issues list for the webpage");
|
||||
await assertIssueList(allElementsPane, expectedAllElementsIssues);
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MDNCompatibility = require("devtools/shared/compatibility/MDNCompatibility");
|
||||
|
||||
const {
|
||||
COMPATIBILITY_UPDATE_NODE_COMPLETE,
|
||||
} = require("devtools/client/inspector/compatibility/actions/index");
|
||||
|
||||
// Test the behavior rules are dynamically added
|
||||
|
||||
const ISSUE_CURSOR = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY,
|
||||
property: "cursor",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/cursor",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const ISSUE_HYPHENS = {
|
||||
type: MDNCompatibility.ISSUE_TYPE.CSS_PROPERTY_ALIASES,
|
||||
aliases: ["hyphens"],
|
||||
property: "hyphens",
|
||||
url: "https://developer.mozilla.org/docs/Web/CSS/hyphens",
|
||||
deprecated: false,
|
||||
experimental: false,
|
||||
};
|
||||
|
||||
const TEST_URI = `
|
||||
<style>
|
||||
.issue {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="test issue"></div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
info("Testing dynamic style change via the devtools inspector's rule view");
|
||||
const tab = await addTab(
|
||||
"data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)
|
||||
);
|
||||
|
||||
const {
|
||||
allElementsPane,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
} = await openCompatibilityView();
|
||||
|
||||
info("Select the div to undergo mutation");
|
||||
const waitForCompatibilityListUpdate = waitForUpdateSelectedNodeAction(
|
||||
inspector.store
|
||||
);
|
||||
await selectNode(".test.issue", inspector);
|
||||
await waitForCompatibilityListUpdate;
|
||||
|
||||
info("Check initial issues");
|
||||
await checkPanelIssues(selectedElementPane, allElementsPane, [ISSUE_CURSOR]);
|
||||
|
||||
await addNewRule(
|
||||
"hyphens",
|
||||
"none",
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
[ISSUE_CURSOR, ISSUE_HYPHENS]
|
||||
);
|
||||
|
||||
info("Toggle the inline issue rendering it disable");
|
||||
await togglePropStatusOnRuleView(inspector, 0, 0);
|
||||
info("Check the issues listed in panel");
|
||||
await checkPanelIssues(selectedElementPane, allElementsPane, [ISSUE_CURSOR]);
|
||||
|
||||
info("Toggle the class rule rendering it disabled");
|
||||
await togglePropStatusOnRuleView(inspector, 1, 0);
|
||||
info("Check the panel issues listed in panel");
|
||||
await checkPanelIssues(selectedElementPane, allElementsPane, []);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
async function addNewRule(
|
||||
newDeclaration,
|
||||
value,
|
||||
inspector,
|
||||
selectedElementPane,
|
||||
allElementsPane,
|
||||
issue
|
||||
) {
|
||||
const { view } = await openRuleView();
|
||||
const waitForCompatibilityListUpdate = waitForDispatch(
|
||||
inspector.store,
|
||||
COMPATIBILITY_UPDATE_NODE_COMPLETE
|
||||
);
|
||||
|
||||
info("Add a new inline property");
|
||||
await addProperty(view, 0, newDeclaration, value);
|
||||
info("Wait for changes");
|
||||
await waitForCompatibilityListUpdate;
|
||||
|
||||
info("Check issues list for element and the webpage");
|
||||
await checkPanelIssues(selectedElementPane, allElementsPane, issue);
|
||||
}
|
||||
|
||||
async function checkPanelIssues(selectedElementPane, allElementsPane, issues) {
|
||||
info("Check selected element issues");
|
||||
await assertIssueList(selectedElementPane, issues);
|
||||
info("Check all panel issues");
|
||||
await assertIssueList(allElementsPane, issues);
|
||||
}
|
|
@ -2,12 +2,11 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
/* import-globals-from ../../../rules/test/head.js */
|
||||
|
||||
/* import-globals-from ../../../test/head.js */
|
||||
|
||||
// Import the inspector's head.js first (which itself imports shared-head.js).
|
||||
// Import the rule view's head.js first (which itself imports inspector's head.js and shared-head.js).
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/rules/test/head.js",
|
||||
this
|
||||
);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче