Bug 1291322 - Manually throttle CssRuleView tests; r=tromey

This patch provides a mechanism for overriding the throttle function in
inspector tests with a manually controllable throttle. I did modify a
few tests to not check for a second "ruleview-changed" as it required
using a setTimeout to defer the code to the next frame to get it to work
as it currently exists. I figured it was safer to just not flush the
throttle, and reduce how many "ruleview-changed" events that the test
expected.

MozReview-Commit-ID: 8AIMouZjLBf

--HG--
extra : rebase_source : 27eb17fc5c26af065a8fa84f3508b91c297c5ed7
This commit is contained in:
Greg Tatum 2016-08-02 11:27:27 -05:00
Родитель 2c922beb50
Коммит 12b7603161
18 изменённых файлов: 91 добавлений и 18 удалений

Просмотреть файл

@ -40,10 +40,9 @@ add_task(function* () {
editor.input.value = "background-color";
info("Pressing RETURN and waiting for the value field focus");
// Pressing ENTER triggeres 2 changed events, one for the new property, and
// one for the preview.
let onNameAdded = waitForNEvents(view, "ruleview-changed", 2);
let onNameAdded = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onNameAdded;
editor = inplaceEditor(view.styleDocument.activeElement);

Просмотреть файл

@ -120,6 +120,9 @@ function* testCompletion([key, completion, open, selected],
info("Synthesizing key " + key);
EventUtils.synthesizeKey(key, {}, view.styleWindow);
// Flush the throttle for the preview text.
view.throttle.flush();
yield onSuggest;
yield onPopupEvent;

Просмотреть файл

@ -98,6 +98,10 @@ function* testCompletion([key, modifiers, completion, open, selected, change],
let onPopupEvent = editor.popup.isOpen !== open ? once(editor.popup, popupEvent) : null;
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
// Flush the throttle for the preview text.
view.throttle.flush();
yield onDone;
yield onPopupEvent;

Просмотреть файл

@ -106,6 +106,10 @@ function* testCompletion([key, modifiers, completion, open, selected, change],
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
// Flush the throttle for the preview text.
view.throttle.flush();
yield onDone;
yield onPopupEvent;

Просмотреть файл

@ -41,12 +41,14 @@ add_task(function* () {
let onSuggest = editor.once("after-suggest");
let node = editor.popup.elements.get(bgcItem);
EventUtils.synthesizeMouseAtCenter(node, {}, editor.popup._window);
yield onSuggest;
is(editor.input.value, "background-color", "Correct value is autocompleted");
info("Press RETURN to move the focus to a property value editor.");
let onModifications = waitForNEvents(view, "ruleview-changed", 2);
let onModifications = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onModifications;
// Getting the new value editor after focus

Просмотреть файл

@ -99,6 +99,7 @@ add_task(function* () {
let node = editor.popup._list.childNodes[editor.popup.selectedIndex];
EventUtils.synthesizeMouseAtCenter(node, {}, editor.popup._window);
view.throttle.flush();
yield onSuggest;
yield onRuleviewChanged;

Просмотреть файл

@ -72,6 +72,7 @@ function* runTestData(view, {value, commitKey, modifiers, expected}) {
info("Entering test data " + value);
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.sendString(value, view.styleWindow);
view.throttle.flush();
yield onRuleViewChanged;
info("Entering the commit key " + commitKey + " " + modifiers);

Просмотреть файл

@ -43,6 +43,8 @@ function* editAndCheck(view) {
info("Waiting for the throttled previewValue to apply the " +
"changes to document");
view.throttle.flush();
yield onPropertyChange;
info("Waiting for ruleview-refreshed after previewValue was applied.");

Просмотреть файл

@ -235,6 +235,7 @@ function* runIncrementTest(propertyEditor, view, tests) {
// requests when the test ends).
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
view.throttle.flush();
yield onRuleViewChanged;
}
@ -263,9 +264,12 @@ function* testIncrement(editor, options, view) {
EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift},
view.styleWindow);
yield onKeyUp;
// Only expect a change if the value actually changed!
if (options.start !== options.end) {
if (options.start !== options.end) {
view.throttle.flush();
yield onRuleViewChanged;
}

Просмотреть файл

@ -69,6 +69,7 @@ function* testEditProperty(inspector, ruleView) {
for (let ch of "red;") {
let onPreviewDone = ruleView.once("ruleview-changed");
EventUtils.sendChar(ch, ruleView.styleWindow);
ruleView.throttle.flush();
yield onPreviewDone;
is(prop.editor.warning.hidden, true,
"warning triangle is hidden or shown as appropriate");

Просмотреть файл

@ -22,11 +22,10 @@ add_task(function* () {
info("Typing ENTER to focus the next field: property value");
let onFocus = once(brace.parentNode, "focus", true);
// The rule view changes twice, once for the first field to loose focus
// and a second time for the second field to gain focus
let onRuleViewChanged = view.once("ruleview-changed").then(
() => view.once("ruleview-changed"));
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.sendKey("return");
yield onFocus;
yield onRuleViewChanged;
ok(true, "The value field was focused");

Просмотреть файл

@ -53,6 +53,7 @@ function* testLivePreviewData(data, ruleView, selector) {
info("Entering value in the editor: " + data.value);
let onPreviewDone = ruleView.once("ruleview-changed");
EventUtils.sendString(data.value, ruleView.styleWindow);
ruleView.throttle.flush();
yield onPreviewDone;
let onValueDone = ruleView.once("ruleview-changed");

Просмотреть файл

@ -19,9 +19,7 @@ add_task(function* () {
function* testCreateNewMultiUnfinished(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 0);
let onMutation = inspector.once("markupmutation");
// There are 2 rule-view updates: one for the preview and one for
// the final commit.
let onRuleViewChanged = waitForNEvents(view, "ruleview-changed", 2);
let onRuleViewChanged = view.once("ruleview-changed");
yield createNewRuleViewProperty(ruleEditor,
"color:blue;background : orange ; text-align:center; border-color: ");
yield onMutation;

Просмотреть файл

@ -15,10 +15,7 @@ add_task(function* () {
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
// Expect 2 ruleview-changed events.
// - one when focusing the property-name editor
// - one after pressing RETURN, which will focus the property-value editor
let onDone = waitForNEvents(view, "ruleview-changed", 2);
let onDone = view.once("ruleview-changed");
yield createNewRuleViewProperty(ruleEditor, "width:");
yield onDone;

Просмотреть файл

@ -61,6 +61,7 @@ add_task(function* () {
info("Entering a value and bluring the field to expect a rule change");
onRuleViewChanged = view.once("ruleview-changed");
editor.input.value = "100%";
view.throttle.flush();
yield onRuleViewChanged;
onRuleViewChanged = view.once("ruleview-changed");

Просмотреть файл

@ -52,10 +52,10 @@ function* modifyRuleViewWidth(value, ruleView, inspector) {
info("Pressing return and waiting for the field to blur and for the " +
"markup-view to show the mutation");
let onBlur = once(editor.input, "blur", true);
let onMutation = inspector.once("markupmutation");
let onStyleChanged = waitForStyleModification(inspector);
EventUtils.sendKey("return");
yield onBlur;
yield onMutation;
yield onStyleChanged;
info("Escaping out of the new property field that has been created after " +
"the value was edited");

Просмотреть файл

@ -530,6 +530,7 @@ var addProperty = Task.async(function* (view, ruleIndex, name, value,
// triggers a ruleview-changed event (see bug 1209295).
let onPreview = view.once("ruleview-changed");
editor.input.value = value;
view.throttle.flush();
yield onPreview;
let onValueAdded = view.once("ruleview-changed");
@ -568,6 +569,7 @@ var setProperty = Task.async(function* (view, textProp, value,
} else {
EventUtils.sendString(value, view.styleWindow);
}
view.throttle.flush();
yield onPreview;
let onValueDone = view.once("ruleview-changed");
@ -790,3 +792,23 @@ function openStyleContextMenuAndGetAllItems(view, target) {
return allItems;
}
/**
* Wait for a markupmutation event on the inspector that is for a style modification.
* @param {InspectorPanel} inspector
* @return {Promise}
*/
function waitForStyleModification(inspector) {
return new Promise(function (resolve) {
function checkForStyleModification(name, mutations) {
for (let mutation of mutations) {
if (mutation.type === "attributes" && mutation.attributeName === "style") {
inspector.off("markupmutation", checkForStyleModification);
resolve();
return;
}
}
}
inspector.on("markupmutation", checkForStyleModification);
});
}

Просмотреть файл

@ -67,6 +67,10 @@ var openInspectorSidebarTab = Task.async(function* (id) {
*/
function openRuleView() {
return openInspectorSidebarTab("ruleview").then(data => {
// Replace the view to use a custom throttle function that can be triggered manually
// through an additional ".flush()" property.
data.inspector.ruleview.view.throttle = manualThrottle();
return {
toolbox: data.toolbox,
inspector: data.inspector,
@ -150,3 +154,33 @@ var selectNode = Task.async(function* (selector, inspector, reason = "test") {
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
});
/**
* Create a throttling function that can be manually "flushed". This is to replace the
* use of the `throttle` function from `devtools/client/inspector/shared/utils.js`, which
* has a setTimeout that can cause intermittents.
* @return {Function} This function has the same function signature as throttle, but
* the property `.flush()` has been added for flushing out any
* throttled calls.
*/
function manualThrottle() {
let calls = [];
function throttle(func, wait, scope) {
return function () {
let existingCall = calls.find(call => call.func === func);
if (existingCall) {
existingCall.args = arguments;
} else {
calls.push({ func, wait, scope, args: arguments });
}
};
}
throttle.flush = function () {
calls.forEach(({func, scope, args}) => func.apply(scope, args));
calls = [];
};
return throttle;
}