Skip to content

Commit

Permalink
333 add ui tests (vega#336)
Browse files Browse the repository at this point in the history
* Add infrastructure to support UI tests with Jest. Also add minimal test for lib-voyager.tsx

* revert some package updates in an attempt to get ui tests working again

* snapshot commit before possibly reverting changes.

* Add infrastructure for running UI tests. Add some initial tests for 
app.tsx and lib-voyager.tsx

* update tests to use ‘it’ instead of ‘test’. fixed up test.
  • Loading branch information
tafsiri authored and kanitw committed May 31, 2017
1 parent 1bb1b80 commit a48f45f
Show file tree
Hide file tree
Showing 8 changed files with 543 additions and 55 deletions.
13 changes: 13 additions & 0 deletions config/jest-ui.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"testPathDirs": [
"<rootDir>/lib/"
],
"testPathIgnorePatterns": [
"<rootDir>/node_modules/"
],
"testRegex": "(test\\.ui\\.(ts|tsx|jsx|js)\\.js$)",
"moduleFileExtensions": [
"js"
],
"collectCoverage": false
}
83 changes: 40 additions & 43 deletions webpack.lib.config.js → config/webpack.lib.config.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,36 @@
var path = require('path');

const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');

const getClientEnvironment = require('./env');
// Get environment variables to inject into our app.
var publicUrl = '';
const env = getClientEnvironment(publicUrl);

module.exports = {
entry: {
bundle: path.resolve(__dirname, 'src/lib-voyager.tsx'),
// Bundling deps into the bundle for now...
// vendor: [
// // React
// 'react-css-modules',
// 'react-dnd',
// 'react-dnd-html5-backend',
// 'react-redux',
// 'react-split-pane',
// 'redux-thunk',
// 'redux-undo',
//
// 'reselect',
//
// // Other Lib
// 'd3',
// 'tslib',
//
// // Vega Dep
// 'compassql',
// 'vega-lite',
// 'vega'
// ]
bundle: path.resolve(__dirname, '../src/lib-voyager.tsx'),
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, 'lib'),
publicPath: '/lib/',
libraryTarget: "umd",
library: "voyager",
path: path.resolve(__dirname, '../lib'),
// Add /* filename */ comments to generated require()s in the output.
pathinfo: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: 'static/js/[name].chunk.js',
publicPath: '/lib/'
},

// Enable sourcemaps for debugging webpack's output.
devtool: 'cheap-eval-source-map',
// devtool: "source-map", // this is better for production
// If it is inline, it will break CSS sourcemaps because of
// `extract-text-webpack-plugin`
devtool: 'source-map',

devServer: {
contentBase: __dirname,
contentBase: path.resolve(__dirname, '../'),
compress: true,
port: 9000
},
Expand All @@ -54,13 +42,7 @@ module.exports = {

module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
configFileName: "tsconfig.lib.json",
},
},
{ test: /\.tsx?$/, use: "ts-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, use: "source-map-loader", enforce: "pre" },

Expand Down Expand Up @@ -91,8 +73,9 @@ module.exports = {
}, {
loader: "sass-loader",
options: {
sourceMap: true,
includePaths: [
path.resolve(__dirname, "node_modules/normalize-scss/sass")
path.resolve(__dirname, "../node_modules/normalize-scss/sass")
]
}
}]
Expand Down Expand Up @@ -121,15 +104,29 @@ module.exports = {
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
// externals: {
// "react": "React",
// "react-dom": "ReactDOM"
// },
externals: {
// "react": "React",
// "react-dom": "ReactDOM"
},
plugins: [
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
new webpack.DefinePlugin(env.stringified),

// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebookincubator/create-react-app/issues/240
new CaseSensitivePathsPlugin(),
new ExtractTextPlugin({
filename: "style.css",
disable: false
}),
new WebpackNotifierPlugin()
]
],
// Turn off performance hints during development because we don't do any
// splitting or minification in interest of speed. These warnings become
// cumbersome.
performance: {
hints: false,
},
};
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"clean": "find -E dist -regex '.*\\.(js|js.map|d.ts)' -delete",
"lint": "tslint -c tslint.json 'src/**/*.ts' 'src/**/*.tsx'",
"lint-fix": "npm run lint -- --fix",
"test": "jest --no-cache --coverage",
"test": "npm run test:logic && npm run test:ui",
"test:logic": "jest --no-cache --coverage",
"test:ui": "NODE_ENV=test node scripts/jest.js",
"posttest": "npm run lint",
"codecov": "jest --no-cache --coverage && codecov"
},
Expand Down Expand Up @@ -57,6 +59,7 @@
},
"devDependencies": {
"@types/classnames": "^0.0.32",
"@types/enzyme": "^2.8.0",
"@types/jest": "^18.1.1",
"@types/react": "^15.0.8",
"@types/react-css-modules": "^3.7.6",
Expand All @@ -70,13 +73,15 @@
"case-sensitive-paths-webpack-plugin": "^2.0.0",
"codecov": "^1.0.1",
"css-loader": "^0.26.1",
"enzyme": "^2.8.2",
"extract-text-webpack-plugin": "beta",
"file-loader": "^0.10.1",
"fs-extra": "^3.0.1",
"html-webpack-plugin": "^2.28.0",
"jest": "~18",
"node-sass": "^4.5.0",
"postcss-loader": "^1.3.3",
"react-addons-test-utils": "15.4.2",
"react-dev-utils": "^0.5.2",
"sass-loader": "^5.0.1",
"source-map-loader": "^0.1.6",
Expand Down
40 changes: 40 additions & 0 deletions scripts/jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env node

const path = require('path');
const webpack = require('webpack');
// const config = require('../config/webpack.config.dev');
const config = require('../config/webpack.lib.config');
const glob = require('glob');


const basedir = path.resolve(__dirname, '../src');
const tests = glob.sync('*.{test,spec}.ui.{ts,tsx,js,jsx}', {
cwd: basedir,
matchBase: true,
});

config.entry = tests
.reduce(function(carry, key) {
carry[key] = path.resolve(basedir, key);
return carry;
}, {});


const compiler = webpack(config);
compiler.run(function() {});

compiler.plugin('done', function(compilation) {

if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = 'test';
}

const jestConf = `--config ${path.resolve(__dirname, '../config', 'jest-ui.config.json')}`;

try {
require('jest-cli/build/cli').run(jestConf);
}
catch (_) {
require('jest/node_modules/jest-cli/build/cli').run(jestConf);
}
});
78 changes: 78 additions & 0 deletions src/components/app.test.ui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @jest-environment jsdom
*/
import {mount} from 'enzyme';
import * as React from 'react';


import {Provider} from 'react-redux';
import {configureStore} from '../store';
import {App} from './app';

describe('Voyager', () => {
describe('instantiation via component', () => {
it('renders voyager', done => {
const config = {};
const data: any = undefined;
const store = configureStore();

setTimeout(() => {
try {
const wrapper = mount(
<Provider store={store}>
<App
config={config}
data={data}
dispatch={store.dispatch}
/>
</Provider>,
);

const header = wrapper.find('header');
expect(header.exists());
expect(header.text()).toContain('Voyager 2');
} catch (err) {
done.fail(err);
}
done();
}, 10);
});

it('renders voyager with custom data', done => {
const config = {};
const data: any = {
"values": [
{"fieldA": "A", "fieldB": 28}, {"fieldA": "B", "fieldB": 55}, {"fieldA": "C", "fieldB": 43},
{"fieldA": "D", "fieldB": 91}, {"fieldA": "E", "fieldB": 81}, {"fieldA": "F", "fieldB": 53},
{"fieldA": "G", "fieldB": 19}, {"fieldA": "H", "fieldB": 87}, {"fieldA": "I", "fieldB": 52}
]
};
const store = configureStore();

setTimeout(() => {
try {
const wrapper = mount(
<Provider store={store}>
<App
config={config}
data={data}
dispatch={store.dispatch}
/>
</Provider>,
);

const fieldList = wrapper.find('.field-list__field-list-item');
const fields = fieldList.children().map(d => d.text());

expect(fields).toContain('fieldA');
expect(fields).toContain('fieldB');

done();
} catch (err) {
done.fail(err);
}
}, 10);
});

});
});
Loading

0 comments on commit a48f45f

Please sign in to comment.