Bug 1514815 - Add an onReady prop to the SmartTrace component; r=bgrins.

Since the component renders asynchronously, consumers might
want to hook up to the actual first rendering.
We provide an `onRender` prop that will be called once, when
the component is ready.

Differential Revision: https://phabricator.services.mozilla.com/D14999

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Chevobbe 2018-12-19 21:01:25 +00:00
parent 1d23058d64
commit e753e09155
3 changed files with 45 additions and 1 deletions

View File

@ -24,6 +24,9 @@ class SmartTrace extends Component {
sourceMapService: PropTypes.object,
initialRenderDelay: PropTypes.number,
onSourceMapResultDebounceDelay: PropTypes.number,
// Function that will be called when the SmartTrace is ready, i.e. once it was
// rendered.
onReady: PropTypes.func,
};
}
@ -83,6 +86,12 @@ class SmartTrace extends Component {
}
}
componentDidMount() {
if (this.props.onReady && this.state.ready) {
this.props.onReady();
}
}
shouldComponentUpdate(_, nextState) {
if (this.state.ready === false && nextState.ready === true) {
return true;
@ -95,6 +104,12 @@ class SmartTrace extends Component {
return false;
}
componentDidUpdate(_, previousState) {
if (this.props.onReady && !previousState.ready && this.state.ready) {
this.props.onReady();
}
}
componentWillUnmount() {
if (this.initialRenderDelayTimeoutId) {
clearTimeout(this.initialRenderDelayTimeoutId);

View File

@ -39,11 +39,15 @@ window.onload = function() {
},
];
let onReadyCount = 0;
const props = {
stacktrace,
initialRenderDelay: 2000,
onViewSourceInDebugger: () => {},
onViewSourceInScratchpad: () => {},
onReady: () => {
onReadyCount++;
},
// A mock source map service.
sourceMapService: {
subscribe: function (url, line, column, callback) {
@ -79,6 +83,8 @@ window.onload = function() {
location: "original.js:22",
tooltip: "View source in Debugger → https://bugzilla.mozilla.org/original.js:22",
});
is(onReadyCount, 1, "onReady was called once");
});
add_task(async function testSlowSourcemapService() {
@ -99,12 +105,16 @@ window.onload = function() {
const sourcemapTimeout = 2000;
const initialRenderDelay = 300;
let onReadyCount = 0;
const props = {
stacktrace,
initialRenderDelay,
onViewSourceInDebugger: () => {},
onViewSourceInScratchpad: () => {},
onReady: () => {
onReadyCount++;
},
// A mock source map service.
sourceMapService: {
subscribe: function (url, line, column, callback) {
@ -123,6 +133,7 @@ window.onload = function() {
let traceEl = ReactDOM.findDOMNode(trace);
ok(!traceEl, "Nothing was rendered at first");
is(onReadyCount, 0, "onReady isn't called if SmartTrace isn't rendered");
info("Wait for the initial delay to be over");
await new Promise(res => setTimeout(res, initialRenderDelay));
@ -149,6 +160,8 @@ window.onload = function() {
tooltip: "View source in Debugger → http://myfile.com/bundle.js:2",
});
is(onReadyCount, 1, "onReady was called once");
info("Check the the sourcemapped version is rendered after the sourcemapTimeout");
await waitFor(() => !!traceEl.querySelector(".group"));
@ -158,6 +171,8 @@ window.onload = function() {
const groups = Array.from(traceEl.querySelectorAll(".group"));
is(groups.length, 1, "SmartTrace has a group");
is(groups[0].textContent, "last2React", "A collapsed React group is displayed");
is(onReadyCount, 1, "onReady was only called once");
});
add_task(async function testFlakySourcemapService() {
@ -184,6 +199,7 @@ window.onload = function() {
const initialRenderDelay = 300;
const onSourceMapResultDebounceDelay = 50;
let onReadyCount = 0;
const props = {
stacktrace,
@ -191,6 +207,9 @@ window.onload = function() {
onSourceMapResultDebounceDelay,
onViewSourceInDebugger: () => {},
onViewSourceInScratchpad: () => {},
onReady: () => {
onReadyCount++;
},
// A mock source map service.
sourceMapService: {
subscribe: function (url, line, column, callback) {
@ -212,6 +231,7 @@ window.onload = function() {
let traceEl = ReactDOM.findDOMNode(trace);
ok(!traceEl, "Nothing was rendered at first");
is(onReadyCount, 0, "onReady isn't called if SmartTrace isn't rendered");
info("Wait for the initial delay + debounce to be over");
await waitFor(() => {
@ -224,7 +244,7 @@ window.onload = function() {
let frameEls = Array.from(traceEl.querySelectorAll(".frame"));
ok(frameEls, "Rendered SmartTrace has frames");
is(frameEls.length, 3, "SmartTrace has 2 frames");
is(frameEls.length, 3, "SmartTrace has 3 frames");
info("Check that the original frames are displayed even if there's no sourcemap " +
"response for some frames");
@ -248,6 +268,8 @@ window.onload = function() {
location: "file-3.js:33",
tooltip: "View source in Debugger → http://myfile.com/file-3.js:33",
});
is(onReadyCount, 1, "onReady was only called once");
});
};

View File

@ -40,10 +40,15 @@ window.onload = function() {
},
];
let onReadyCount = 0;
const props = {
stacktrace,
onViewSourceInDebugger: () => {},
onViewSourceInScratchpad: () => {},
onReady: () => {
onReadyCount++;
}
};
const trace = ReactDOM.render(SmartTrace(props), window.document.body);
@ -70,6 +75,8 @@ window.onload = function() {
location: "http://myfile.com/loadee.js:10",
tooltip: "View source in Debugger → http://myfile.com/loadee.js:10",
});
is(onReadyCount, 1, "onReady was called once");
});
};
</script>