Frontend app
We will create a very simple React webapp with Redux and using ArtemisaJS for fetching the list of users from the backend.
mkdir frontend
yarn init -y
yarn add react redux artemisa
yarn add -D babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0 babel-plugin-transform-runtime
webpack
Also create a .babelrc file
{
"presets": ["es2015", "stage-0", "react"],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
Now a script to build, edit package.json and under scripts section add
"scripts": {
"build": "webpack --debug"
},
Now lets create a new file for webpack
vi webpack.config.js
With content
module.exports = {
entry: './src/app.jsx',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: { presets: [ 'es2015', 'react' ] }
}
]
}
};
And now lets create the app.jsx file:
mkdir src
touch src/app.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const store = createStore((state={}, action) => state)
ReactDOM.render(
<Provider store={store}>
</Provider>,
document.querySelector("#app"))
And create an index.html file
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<title>E2E testing with Docker</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
Now lets build
yarn build
And open the index.html file with a browser
Let's now add a component to show the users
makdir src/components
touch src/components/UsersList.jsx
import React from 'react'
import { isFetchedSlot, isFetching, fetchingData } from 'artemisa'
import { get } from 'artemisa/lib/core/call'
class UsersList extends React.Component {
render() {
const { users } = this.props
return (
<table className="table table-striped">
<thead><tr><th>Id</th><th>Name</th><th>Created</th></tr></thead>
<tbody>
{isFetchedSlot(users) && (
users.value.map(u => (
<tr>
<td>{u._id}</td>
<td>{u.name}</td>
<td>{u.created_at}</td>
</tr>
))
)}
</tbody>
</table>
)
}
}
export default fetchingData({
users: () => get('api/users')
})(UsersList)
Now we need to configure artemisa that is the library that makes it easier to call the backend to fetch data. Edit *app.jsx so that we include artemisa resolver and middleware
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { Provider } from 'react-redux';
import { service as artemisaMiddleware, reducer as artemisa } from 'artemisa'
import UsersList from './components/UsersList'
const store = createStore(combineReducers({ artemisa }), compose(
applyMiddleware(thunkMiddleware, artemisaMiddleware),
window.devToolsExtension ? window.devToolsExtension() : f => f
))
ReactDOM.render(
<Provider store={store}>
<div>
<h1>E2E testing with Docker</h1>
<div>
<h2>Users</h2>
<UsersList />
</div>
</div>
</Provider>,
document.querySelector("#app"))
And now we will configure webpack-dev-server so that it proxies are resquests to localhost/api to the back end
yarn add -D webpack-dev-server
Then edit webpack.config.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: './src/app.jsx',
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
extensions: ['.js', '.jsx', '.json']
},
output: {
path: `${__dirname}/build`,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: { presets: [ 'es2015', 'react' ] }
}
]
},
plugins: [
new webpack.DefinePlugin({
__IS_BROWSER__: true,
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
],
devServer: {
contentBase: 'public/',
proxy: {
'/api': {
target: 'http://localhost:3001/',
pathRewrite: { '^/api': '' }
}
}
}
};
(we also added the IS BROWSER Env)
And we will reorganize the index.html file
mkdir public
mv index.html public
And add a script to start the server in package.json's scripts section
"start": "webpack-dev-server --history-api-fallback --progress --host 0.0.0.0 --port 3000 --inline --hot --config webpack.config.js --quiet"
This will start in port 3000, so we would need to change the backend to start on another port, let say 3001. In the backend code project edit bin/www changing this line
var port = normalizePort(process.env.PORT || '3001');
(Notice the part has changed to 3001)
Now let start both of them.
yarn start
You should see something like this

That's all !
We now have a backend that serves a list of users, and a front end that consumes that API to fetch users.