Skip to content

Commit

Permalink
Run some tests under karma
Browse files Browse the repository at this point in the history
Including a regression test for
#1314
  • Loading branch information
richvdh committed Apr 13, 2016
1 parent 69ce3c4 commit 322af65
Show file tree
Hide file tree
Showing 9 changed files with 595 additions and 11 deletions.
17 changes: 9 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
node_modules
vector/bundle.*
lib
.DS_Store
key.pem
cert.pem
vector/components.css
packages/
/cert.pem
/.DS_Store
/karma-reports
/key.pem
/lib
/node_modules
/packages/
/vector/bundle.*
/vector/components.css
3 changes: 3 additions & 0 deletions jenkins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ npm install
# we may be using a dev branch of react-sdk, in which case we need to build it
(cd node_modules/matrix-react-sdk && npm run build)

# run the mocha tests
npm run test

# build our artifacts; dumps them in ./vector
npm run build

Expand Down
134 changes: 134 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// karma.conf.js - the config file for karma, which runs our tests.

var path = require('path');
var fs = require('fs');
var webpack = require('webpack');

/*
* We use webpack to build our tests. It's a pain to have to wait for webpack
* to build everything; however it's the easiest way to load our dependencies
* from node_modules.
*
* If you run karma in multi-run mode (with `npm run test-multi`), it will watch
* the tests for changes, and webpack will rebuild using a cache. This is much quicker
* than a clean rebuild.
*/

// the name of the test file. By default, a special file which runs all tests.
var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js';

process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
process.env.Q_DEBUG = 1;

module.exports = function (config) {
config.set({
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],

// list of files / patterns to load in the browser
files: [
testFile,
{pattern: 'vector/img/*', watched: false, included: false, served: true, nocache: false},
],

// redirect img links to the karma server
proxies: {
"/img/": "/base/vector/img/",
},

// preprocess matching files before serving them to the browser
// available preprocessors:
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/**/*.js': ['webpack', 'sourcemap']
},

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'junit'],

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR ||
// config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file
// changes
autoWatch: true,

// start these browsers
// available browser launchers:
// https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'Chrome',
//'PhantomJS',
],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
// singleRun: false,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,

junitReporter: {
outputDir: 'karma-reports',
},

webpack: {
module: {
loaders: [
{ test: /\.json$/, loader: "json" },
{
test: /\.js$/, loader: "babel",
include: [path.resolve('./src'),
path.resolve('./test'),
],
query: {
// we're using babel 5, for consistency with
// the release build, which doesn't use the
// presets.
// presets: ['react', 'es2015'],
},
},
],
noParse: [
// don't parse the languages within highlight.js. They
// cause stack overflows
// (https://github.com/webpack/webpack/issues/1721), and
// there is no need for webpack to parse them - they can
// just be included as-is.
/highlight\.js\/lib\/languages/,

// also disable parsing for sinon, because it
// tries to do voodoo with 'require' which upsets
// webpack (https://github.com/webpack/webpack/issues/304)
/sinon\/pkg\/sinon\.js$/,
],
},
resolve: {
alias: {
// alias any requires to the react module to the one in our path, otherwise
// we tend to get the react source included twice when using npm link.
react: path.resolve('./node_modules/react'),

sinon: 'sinon/pkg/sinon.js',
},
root: [
path.resolve('./src'),
path.resolve('./test'),
],
},
devtool: 'inline-source-map',
},
});
};
20 changes: 17 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"start:prod": "parallelshell \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
"clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*",
"prepublish": "npm run build:css && npm run build:compile"
"prepublish": "npm run build:css && npm run build:compile",
"test": "karma start --single-run=true --browsers PhantomJS",
"test:multi": "karma start"
},
"dependencies": {
"babel-polyfill": "^6.5.0",
Expand All @@ -41,7 +43,7 @@
"matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
"modernizr": "^3.1.0",
"q": "^1.4.1",
"react": "^0.14.2",
"react": "^0.14.8",
"react-dnd": "^2.0.2",
"react-dnd-html5-backend": "^2.0.0",
"react-dom": "^0.14.2",
Expand All @@ -54,11 +56,23 @@
"babel-loader": "^5.3.2",
"catw": "^1.0.1",
"css-raw-loader": "^0.1.1",
"expect": "^1.16.0",
"http-server": "^0.8.4",
"json-loader": "^0.5.3",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-cli": "^0.1.2",
"karma-junit-reporter": "^0.4.1",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"mocha": "^2.4.5",
"parallelshell": "^1.2.0",
"phantomjs-prebuilt": "^2.1.7",
"react-addons-test-utils": "^0.14.8",
"rimraf": "^2.4.3",
"source-map-loader": "^0.1.5",
"webpack": "^1.12.13"
"webpack": "^1.12.14"
}
}
7 changes: 7 additions & 0 deletions test/all-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// all-tests.js
//
// Our master test file: uses the webpack require API to find our test files
// and run them

var context = require.context('./app-tests', true, /\.jsx?$/);
context.keys().forEach(context);
165 changes: 165 additions & 0 deletions test/app-tests/joining.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/* joining.js: tests for the various paths when joining a room */

require('skin-sdk');

var jssdk = require('matrix-js-sdk');

var sdk = require('matrix-react-sdk');
var peg = require('matrix-react-sdk/lib/MatrixClientPeg');
var dis = require('matrix-react-sdk/lib/dispatcher');
var MatrixChat = sdk.getComponent('structures.MatrixChat');
var RoomDirectory = sdk.getComponent('structures.RoomDirectory');
var RoomPreviewBar = sdk.getComponent('rooms.RoomPreviewBar');
var RoomView = sdk.getComponent('structures.RoomView');

var React = require('react');
var ReactDOM = require('react-dom');
var ReactTestUtils = require('react-addons-test-utils');
var expect = require('expect');
var q = require('q');

var test_utils = require('../test-utils');
var MockHttpBackend = require('../mock-request');

var HS_URL='http://localhost';
var IS_URL='http://localhost';
var USER_ID='@me:localhost';
var ACCESS_TOKEN='access_token';

describe('joining a room', function () {
describe('over federation', function () {
var parentDiv;
var httpBackend;
var matrixChat;

beforeEach(function() {
test_utils.beforeEach(this);
httpBackend = new MockHttpBackend();
jssdk.request(httpBackend.requestFn);
parentDiv = document.createElement('div');
document.body.appendChild(parentDiv);
});

afterEach(function() {
if (parentDiv) {
ReactDOM.unmountComponentAtNode(parentDiv);
document.body.removeChild(parentDiv);
parentDiv = null;
}
httpBackend.verifyNoOutstandingRequests();
});

it('should not get stuck at a spinner', function(done) {
var ROOM_ALIAS = '#alias:localhost';
var ROOM_ID = '!id:localhost';

httpBackend.when('PUT', '/presence/'+encodeURIComponent(USER_ID)+'/status')
.respond(200, {});
if (test_utils.browserSupportsWebRTC()) {
httpBackend.when('GET', '/voip/turnServer').respond(200, {});
}
httpBackend.when('GET', '/pushrules').respond(200, {});
httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
httpBackend.when('GET', '/sync').respond(200, {});
httpBackend.when('GET', '/publicRooms').respond(200, {chunk: []});

// start with a logged-in client
peg.replaceUsingAccessToken(HS_URL, IS_URL, USER_ID, ACCESS_TOKEN);

var mc = <MatrixChat config={{}}/>;
matrixChat = ReactDOM.render(mc, parentDiv);

// switch to the Directory
dis.dispatch({
action: 'view_room_directory',
});

var roomView;
httpBackend.flush().then(() => {
var roomDir = ReactTestUtils.findRenderedComponentWithType(
matrixChat, RoomDirectory);

// enter an alias in the input, and simulate enter
var input = ReactTestUtils.findRenderedDOMComponentWithTag(
roomDir, 'input');
input.value = ROOM_ALIAS;
ReactTestUtils.Simulate.keyUp(input, {key: 'Enter'});

// that should create a roomview which will start a peek; wait
// for the peek.
httpBackend.when('GET', '/rooms/'+encodeURIComponent(ROOM_ALIAS)+"/initialSync")
.respond(401, {errcode: 'M_GUEST_ACCESS_FORBIDDEN'});
return httpBackend.flush();
}).then(() => {
httpBackend.verifyNoOutstandingExpectation();

// we should now have a roomview, with a preview bar
roomView = ReactTestUtils.findRenderedComponentWithType(
matrixChat, RoomView);

var previewBar = ReactTestUtils.findRenderedComponentWithType(
roomView, RoomPreviewBar);

var joinLink = ReactTestUtils.findRenderedDOMComponentWithTag(
previewBar, 'a');

ReactTestUtils.Simulate.click(joinLink);

// that will fire off a request to check our displayname, followed by a
// join request
httpBackend.when('GET', '/profile/'+encodeURIComponent(USER_ID))
.respond(200, {displayname: 'boris'});
httpBackend.when('POST', '/join/'+encodeURIComponent(ROOM_ALIAS))
.respond(200, {room_id: ROOM_ID});
return httpBackend.flush();
}).then(() => {
httpBackend.verifyNoOutstandingExpectation();

// the roomview should now be loading
expect(roomView.state.room).toBe(null);
expect(roomView.state.joining).toBe(true);

// there should be a spinner
ReactTestUtils.findRenderedDOMComponentWithClass(
roomView, "mx_Spinner");

// now send the room down the /sync pipe
httpBackend.when('GET', '/sync').
respond(200, {
rooms: {
join: {
[ROOM_ID]: {
state: {},
timeline: {
events: [],
limited: true,
},
},
},
},
});
return httpBackend.flush();
}).then(() => {
// now the room should have loaded
expect(roomView.state.room).toExist();
expect(roomView.state.joining).toBe(false);
}).done(done, done);
});
});
});
Loading

0 comments on commit 322af65

Please sign in to comment.