Make tests pass on Chrome again

It seems that a number of the tests had started failing when run in
Chrome. They were fine under PhantomJS, but the MegolmExport tests only work
under Chrome, and I need them to work...

Mostly the problems were timing-related, where assumptions made about how
quickly the `then` handler on a promise would be called were no longer
valid. Possibly Chrome 55 has made some changes to the relative priorities of
setTimeout and sendMessage calls.

One of the TimelinePanel tests was failing because it was expecting the contents
of a div to take up more room than they actually were. It's possible this is
something very environment-specific; hopefully the new value will work on a
wider range of machines.

Also some logging tweaks.
This commit is contained in:
Richard van der Hoff 2017-01-31 22:40:53 +00:00
parent 878e5593ba
commit cd1cf09dc9
6 changed files with 56 additions and 21 deletions

View file

@ -165,6 +165,14 @@ module.exports = function (config) {
}, },
devtool: 'inline-source-map', devtool: 'inline-source-map',
}, },
webpackMiddleware: {
stats: {
// don't fill the console up with a mahoosive list of modules
chunks: false,
},
},
browserNoActivityTimeout: 15000, browserNoActivityTimeout: 15000,
}); });
}; };

View file

@ -570,7 +570,7 @@ module.exports = React.createClass({
var boundingRect = node.getBoundingClientRect(); var boundingRect = node.getBoundingClientRect();
var scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom; var scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
debuglog("Scrolling to token '" + node.dataset.scrollToken + "'+" + debuglog("ScrollPanel: scrolling to token '" + node.dataset.scrollToken + "'+" +
pixelOffset + " (delta: "+scrollDelta+")"); pixelOffset + " (delta: "+scrollDelta+")");
if(scrollDelta != 0) { if(scrollDelta != 0) {
@ -582,7 +582,7 @@ module.exports = React.createClass({
_saveScrollState: function() { _saveScrollState: function() {
if (this.props.stickyBottom && this.isAtBottom()) { if (this.props.stickyBottom && this.isAtBottom()) {
this.scrollState = { stuckAtBottom: true }; this.scrollState = { stuckAtBottom: true };
debuglog("Saved scroll state", this.scrollState); debuglog("ScrollPanel: Saved scroll state", this.scrollState);
return; return;
} }
@ -601,12 +601,12 @@ module.exports = React.createClass({
trackedScrollToken: node.dataset.scrollToken, trackedScrollToken: node.dataset.scrollToken,
pixelOffset: wrapperRect.bottom - boundingRect.bottom, pixelOffset: wrapperRect.bottom - boundingRect.bottom,
}; };
debuglog("Saved scroll state", this.scrollState); debuglog("ScrollPanel: saved scroll state", this.scrollState);
return; return;
} }
} }
debuglog("Unable to save scroll state: found no children in the viewport"); debuglog("ScrollPanel: unable to save scroll state: found no children in the viewport");
}, },
_restoreSavedScrollState: function() { _restoreSavedScrollState: function() {
@ -640,7 +640,7 @@ module.exports = React.createClass({
this._lastSetScroll = scrollNode.scrollTop; this._lastSetScroll = scrollNode.scrollTop;
} }
debuglog("Set scrollTop:", scrollNode.scrollTop, debuglog("ScrollPanel: set scrollTop:", scrollNode.scrollTop,
"requested:", scrollTop, "requested:", scrollTop,
"_lastSetScroll:", this._lastSetScroll); "_lastSetScroll:", this._lastSetScroll);
}, },

View file

@ -42,17 +42,12 @@ describe('RoomView', function () {
it('resolves a room alias to a room id', function (done) { it('resolves a room alias to a room id', function (done) {
peg.get().getRoomIdForAlias.returns(q({room_id: "!randomcharacters:aser.ver"})); peg.get().getRoomIdForAlias.returns(q({room_id: "!randomcharacters:aser.ver"}));
var onRoomIdResolved = sinon.spy(); function onRoomIdResolved(room_id) {
expect(room_id).toEqual("!randomcharacters:aser.ver");
done();
}
ReactDOM.render(<RoomView roomAddress="#alias:ser.ver" onRoomIdResolved={onRoomIdResolved} />, parentDiv); ReactDOM.render(<RoomView roomAddress="#alias:ser.ver" onRoomIdResolved={onRoomIdResolved} />, parentDiv);
process.nextTick(function() {
// These expect()s don't read very well and don't give very good failure
// messages, but expect's toHaveBeenCalled only takes an expect spy object,
// not a sinon spy object.
expect(onRoomIdResolved.called).toExist();
done();
});
}); });
it('joins by alias if given an alias', function (done) { it('joins by alias if given an alias', function (done) {

View file

@ -73,6 +73,7 @@ var Tester = React.createClass({
/* returns a promise which will resolve when the fill happens */ /* returns a promise which will resolve when the fill happens */
awaitFill: function(dir) { awaitFill: function(dir) {
console.log("ScrollPanel Tester: awaiting " + dir + " fill");
var defer = q.defer(); var defer = q.defer();
this._fillDefers[dir] = defer; this._fillDefers[dir] = defer;
return defer.promise; return defer.promise;
@ -80,7 +81,7 @@ var Tester = React.createClass({
_onScroll: function(ev) { _onScroll: function(ev) {
var st = ev.target.scrollTop; var st = ev.target.scrollTop;
console.log("Scroll event; scrollTop: " + st); console.log("ScrollPanel Tester: scroll event; scrollTop: " + st);
this.lastScrollEvent = st; this.lastScrollEvent = st;
var d = this._scrollDefer; var d = this._scrollDefer;
@ -159,10 +160,29 @@ describe('ScrollPanel', function() {
scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass( scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
tester, "gm-scroll-view"); tester, "gm-scroll-view");
// wait for a browser tick to let the initial paginates complete // we need to make sure we don't call done() until q has finished
setTimeout(function() { // running the completion handlers from the fill requests. We can't
done(); // just use .done(), because that will end up ahead of those handlers
}, 0); // in the queue. We can't use window.setTimeout(0), because that also might
// run ahead of those handlers.
const sp = tester.scrollPanel();
let retriesRemaining = 1;
const awaitReady = function() {
return q().then(() => {
if (sp._pendingFillRequests.b === false &&
sp._pendingFillRequests.f === false
) {
return;
}
if (retriesRemaining == 0) {
throw new Error("fillRequests did not complete");
}
retriesRemaining--;
return awaitReady();
});
};
awaitReady().done(done);
}); });
afterEach(function() { afterEach(function() {

View file

@ -99,7 +99,11 @@ describe('TimelinePanel', function() {
// the document so that we can interact with it properly. // the document so that we can interact with it properly.
parentDiv = document.createElement('div'); parentDiv = document.createElement('div');
parentDiv.style.width = '800px'; parentDiv.style.width = '800px';
parentDiv.style.height = '600px';
// This has to be slightly carefully chosen. We expect to have to do
// exactly one pagination to fill it.
parentDiv.style.height = '500px';
parentDiv.style.overflow = 'hidden'; parentDiv.style.overflow = 'hidden';
document.body.appendChild(parentDiv); document.body.appendChild(parentDiv);
}); });
@ -235,7 +239,7 @@ describe('TimelinePanel', function() {
expect(client.paginateEventTimeline.callCount).toEqual(0); expect(client.paginateEventTimeline.callCount).toEqual(0);
done(); done();
}, 0); }, 0);
}, 0); }, 10);
}); });
it("should let you scroll down to the bottom after you've scrolled up", function(done) { it("should let you scroll down to the bottom after you've scrolled up", function(done) {

View file

@ -14,7 +14,15 @@ var MatrixEvent = jssdk.MatrixEvent;
*/ */
export function beforeEach(context) { export function beforeEach(context) {
var desc = context.currentTest.fullTitle(); var desc = context.currentTest.fullTitle();
console.log(); console.log();
// this puts a mark in the chrome devtools timeline, which can help
// figure out what's been going on.
if (console.timeStamp) {
console.timeStamp(desc);
}
console.log(desc); console.log(desc);
console.log(new Array(1 + desc.length).join("=")); console.log(new Array(1 + desc.length).join("="));
}; };