Fix password UI auth test
By adding a way to wait a short time for a component to appear in the DOM, so we don't get flakey failures like this when we change something to returning a promise that needs to resolve before the component actually appears.
This commit is contained in:
parent
c413de4452
commit
375ae8fb04
2 changed files with 83 additions and 42 deletions
|
@ -68,50 +68,51 @@ describe('InteractiveAuthDialog', function () {
|
||||||
onFinished={onFinished}
|
onFinished={onFinished}
|
||||||
/>, parentDiv);
|
/>, parentDiv);
|
||||||
|
|
||||||
// at this point there should be a password box and a submit button
|
// wait for a password box and a submit button
|
||||||
const formNode = ReactTestUtils.findRenderedDOMComponentWithTag(dlg, "form");
|
test_utils.waitForRenderedDOMComponentWithTag(dlg, "form").then((formNode) => {
|
||||||
const inputNodes = ReactTestUtils.scryRenderedDOMComponentsWithTag(
|
const inputNodes = ReactTestUtils.scryRenderedDOMComponentsWithTag(
|
||||||
dlg, "input"
|
dlg, "input"
|
||||||
);
|
);
|
||||||
let passwordNode;
|
let passwordNode;
|
||||||
let submitNode;
|
let submitNode;
|
||||||
for (const node of inputNodes) {
|
for (const node of inputNodes) {
|
||||||
if (node.type == 'password') {
|
if (node.type == 'password') {
|
||||||
passwordNode = node;
|
passwordNode = node;
|
||||||
} else if (node.type == 'submit') {
|
} else if (node.type == 'submit') {
|
||||||
submitNode = node;
|
submitNode = node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
expect(passwordNode).toExist();
|
||||||
expect(passwordNode).toExist();
|
expect(submitNode).toExist();
|
||||||
expect(submitNode).toExist();
|
|
||||||
|
|
||||||
// submit should be disabled
|
// submit should be disabled
|
||||||
expect(submitNode.disabled).toBe(true);
|
expect(submitNode.disabled).toBe(true);
|
||||||
|
|
||||||
// put something in the password box, and hit enter; that should
|
// put something in the password box, and hit enter; that should
|
||||||
// trigger a request
|
// trigger a request
|
||||||
passwordNode.value = "s3kr3t";
|
passwordNode.value = "s3kr3t";
|
||||||
ReactTestUtils.Simulate.change(passwordNode);
|
ReactTestUtils.Simulate.change(passwordNode);
|
||||||
expect(submitNode.disabled).toBe(false);
|
expect(submitNode.disabled).toBe(false);
|
||||||
ReactTestUtils.Simulate.submit(formNode, {});
|
ReactTestUtils.Simulate.submit(formNode, {});
|
||||||
|
|
||||||
expect(doRequest.callCount).toEqual(1);
|
expect(doRequest.callCount).toEqual(1);
|
||||||
expect(doRequest.calledWithExactly({
|
expect(doRequest.calledWithExactly({
|
||||||
session: "sess",
|
session: "sess",
|
||||||
type: "m.login.password",
|
type: "m.login.password",
|
||||||
password: "s3kr3t",
|
password: "s3kr3t",
|
||||||
user: "@user:id",
|
user: "@user:id",
|
||||||
})).toBe(true);
|
})).toBe(true);
|
||||||
|
|
||||||
// there should now be a spinner
|
// there should now be a spinner
|
||||||
ReactTestUtils.findRenderedComponentWithType(
|
ReactTestUtils.findRenderedComponentWithType(
|
||||||
dlg, sdk.getComponent('elements.Spinner'),
|
dlg, sdk.getComponent('elements.Spinner'),
|
||||||
);
|
);
|
||||||
|
|
||||||
// let the request complete
|
// let the request complete
|
||||||
q.delay(1).then(() => {
|
return q.delay(1);
|
||||||
|
}).then(() => {
|
||||||
expect(onFinished.callCount).toEqual(1);
|
expect(onFinished.callCount).toEqual(1);
|
||||||
expect(onFinished.calledWithExactly(true, {a:1})).toBe(true);
|
expect(onFinished.calledWithExactly(true, {a:1})).toBe(true);
|
||||||
}).done(done, done);
|
}).done(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,51 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var sinon = require('sinon');
|
import sinon from 'sinon';
|
||||||
var q = require('q');
|
import q from 'q';
|
||||||
|
import ReactTestUtils from 'react-addons-test-utils';
|
||||||
|
|
||||||
var peg = require('../src/MatrixClientPeg.js');
|
import peg from '../src/MatrixClientPeg.js';
|
||||||
var jssdk = require('matrix-js-sdk');
|
import jssdk from 'matrix-js-sdk';
|
||||||
var MatrixEvent = jssdk.MatrixEvent;
|
const MatrixEvent = jssdk.MatrixEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around window.requestAnimationFrame that returns a promise
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function _waitForFrame() {
|
||||||
|
const def = q.defer();
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
return def.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits a small number of animation frames for a component to appear
|
||||||
|
* in the DOM. Like findRenderedDOMComponentWithTag(), but allows
|
||||||
|
* for the element to appear a short time later, eg. if a promise needs
|
||||||
|
* to resolve first.
|
||||||
|
* @return a promise that resolves once the component appears, or rejects
|
||||||
|
* if it doesn't appear after a nominal number of animation frames.
|
||||||
|
*/
|
||||||
|
export function waitForRenderedDOMComponentWithTag(tree, tag, attempts) {
|
||||||
|
if (attempts === undefined) {
|
||||||
|
// Let's start by assuming we'll only need to wait a single frame, and
|
||||||
|
// we can try increasing this if necessary.
|
||||||
|
attempts = 1;
|
||||||
|
} else if (attempts == 0) {
|
||||||
|
return q.reject("Gave up waiting for component with tag: " + tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _waitForFrame().then(() => {
|
||||||
|
const result = ReactTestUtils.scryRenderedDOMComponentsWithTag(tree, tag);
|
||||||
|
if (result.length > 0) {
|
||||||
|
return result[0];
|
||||||
|
} else {
|
||||||
|
return waitForRenderedDOMComponentWithTag(tree, tag, attempts - 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform common actions before each test case, e.g. printing the test case
|
* Perform common actions before each test case, e.g. printing the test case
|
||||||
|
|
Loading…
Reference in a new issue