An express application that fetches data from a back end JSON based api and renders it to the screen. This front end layer is primarily turning requests from the browser into back end API calls and then rendering them using Nunjucks template language.
The client layer applies the ideals of progressive enhancement so that a wide range of devices can access it, no matter what their limitation.
In order to use the application the front end layer must be run, with a small number of settings, and be provided with a back end server to provide the API, data storage and search engine capabilities.
The project comes with docker compose files, this means if you have docker you can start the app with a single command.
There are 2 docker files.
This will run the front end server locally, but will point to a remote backend. This file expects the following environment variables:
Name | Description |
---|---|
API_ROOT | The url for a back end server instance for the service |
POSTCODE_KEY | Part of the frontend looks up addresses for postcodes using getaddress.io. Obtain a key for the service and set it here |
API_CLIENT_ID | Half the credentials needed to talk to the back end |
API_CLIET_SECRET | The second half of the credentials needed to talk to the backend |
GOOGLE_TAG_MANAGER_KEY | The key needed to integrate with google tag manager to track usage |
REDIS_HOST | You need to run redis and provide the host name for it here unless you specify the entire url |
REDIS_URL | A full length url to conenct to redis |
REDISTOGO_URL | Probably for use with heroku |
ASSETS_HOST | Optional host for assets CDN, defaults to app’s host |
ZEN_TOKEN | Zendesk auth token |
ZEN_DOMAIN | Domain used on Zendesk |
ZEN_EMAIL | Zendesk email address |
ZEN_BROWSER | Zendesk browser ID |
ZEN_IMPACT | Zendesk impact ID |
ZEN_SERVICE | Zendesk service ID |
SENTRY_DSN | Sentry DSN (optional) |
WEBPACK_ENV | Optionally select the webpack configuration variation to use, the default will correctly pick a production or development config based on NODE_ENV. Valid values include prod , develop and docker |
Either set these variables manually or why not look at autoenv. To start the server just:
docker-compose up
The server starts in developer mode, which means that when you make local changes it will auto-compile sass or javavscript, and will restart nodejs when server side changes are made. A container with redis will also start, this is linked to the data hub container.
You can access the server on port 3000, http://localhost:3000. You can also run a remote debug session over port 5858 if using webstorm/Intellij or Visual Studio Code
Docker Compose supports declaring default environment variables in an environment file. If you wish to send through environment variables to the docker containers please add them into the .env
file in the projects root.
The project is using ES6 async/await therefore Node 8 is required.
-
Clone repository and change directory:
git clone https://github.com/UKTradeInvestment/data-hub-frontend && cd data-hub-frontend
-
Install node dependencies:
yarn install
-
Create a copy of the sample .env file and add values for the keys (a current member of the project team can give you these):
cp sample.env .env
-
Run an instance of Redis and change
REDIS_HOST
andREDIS_PORT
in your .env file if necessary
Builds static assets and runs a server using node
yarn run build && yarn start
Server watches for changes and rebuilds sass or compiles js using webpack as needed. Changes to server side code will result in the server autorestarting. The server will run with the node debug flag so you can debug with Webstorm or Visual Studio Code.
yarn run develop
The package.json file includes a number of useful scripts for other tasks.
Run BDD tests using Mocha:
yarn run test
Lint both SASS and JS to make sure it conforms to rules:
yarn run lint
See the contributing guide.
This app includes support for including components using a custom nunjucks tag. This method allows components to be available in all layouts, views, includes and macros and allows each component to be a separating entity which makes maintaining and testing them easier.
To include a component with its default state or one that expects no data:
{% component 'person' %}
To include a component and pass data to it:
{% component 'person', {
name: 'Barry',
age: '55'
} %}
Component can take multiple arguments. It will combine them in single object:
res.render('some-page', {
personData: {
name: 'Barry',
age: 55
}
})
{% component 'person', personData, gender='male' %}
Is the same as:
{% component 'person', {
name: 'Barry',
age: '55',
gender: 'male'
} %}
Templates use Nunjuck's template inheritance. There are several top level blocks which are used for injecting content during rendering. Each subsequent template that extends the base layout can include these additional blocks.
Template block names are structured by combining main element names to form path. e.g. head
wraps everything inside
the head
element, head_content
wraps the section that is used to contain contents of head
element. Thus allowing
to completely override everything inside head
element if needed or just the section reserved for basic use cases.
head
- contains the whole head elementhead_title_content
- contains title element contenthead_content
- wraps main content for head elementhead_stylesheets
- wraps stylesheet declarations
body
- contains the whole body elementbody_skiplinks
- wraps container with "skip to content" link (first element inside body)body_notifications
- wraps cookie message container (above site_header, after skiplinks)body_site_header
- wraps site headerheader_site_title
- wraps the site titleheader_menu
- wraps the header menu
body_main
- wraps the main content blockbody_main_header
- contains the header of the main blockbody_main_header_content
- contains the heading of the main blockbody_main_content
- contains main content (inside main#content)
body_footer
- wraps site footer container (inside body > footer)body_footer_content
- contains content inside site footer
Base layout checks for certain variables.
siteTitle
{string} - name of the site. Defaults to 'Department for International Trade'.serviceTitle
{string} - name of the service.phaseBanner
{boolean} - whether to show the separate phase banner or default to phase tag in the global header. Possible values:true
andfalse
.projectPhase
{string} - phase of the project. Possible values:alpha
andbeta
.
layouts/
+-> dit-base.njk
|
+-> +-+ datahub-base.njk <-----+
| |
| +++-> _base-two-column.njk +-+
| |||
| ||| contact/
| |||
| ||+---+ _layout.njk <--------+
| || |
| || details.njk +--------+
| ||
| || company/
| ||
| |+-----+ _layout-edit.njk <--+
| | |
| +------+ _layout.view.njk <-+|
| ||
| details-ltd.njk +-+|
| |
| edit-ltd.njk +-----+
|
+-----+ login.njk
Data hub uses Nightwatch.js, nightwatch-cucumber and cucumber.js to run acceptance tests.
For information on cucumber-js tags please see the nightwatch-cucumber
docs executing-individual-feature-files-or-scenarios
You run acceptance tests via:
yarn test:acceptance
You can run a group (folder) of tests via:
yarn test:acceptance -- --group <folder-name>
e.g:
yarn test:acceptance -- --group audit
You can run a specific feature via:
yarn test:acceptance -- --tag <feature-tag>
e.g:
yarn test:acceptance -- --tag audit-company--name
We use singular or plural folder names. E.g contacts
, companies
, audit
.
We use singular names
page-object
names with PascalCase case. E.gLogin
,Contact
,ContactList
.step_definitions
names with Kebabcase case. E.glogin
,contact
,company
.feature
names with Kebabcase case. E.gcreate
,login
,list
.
We name features after the folder name and file name. So /auth/login.feature
would have the feature tag @auth-login
We name scenarios after the feature name with a double hyphen separating the scenarios tag. So a scenario in the @auth-login
feature would be @auth-login--logout
You can tell nightwatch.js
not to run a feature by adding the tag @ignore
.
Data hub uses CircleCI for continuous integration.
The acceptance tests use the docker image ukti/docker-selenium-base
.
Details can be found in the GitHub repo.
CircleCI has been configured to show you a summary report of what has failed on the following workflows:
unit_tests
lint_code
acceptance_tests
When acceptance tests fail you can also have a look at the Nightwatch.js
html report found in the jobs artifacts folder.
This can be accessed by logging in to CircleCI
Commits to develop
are automatically deployed to a heroku instance. Pull
requests deploy to a review app
from this heroku instance.
Deployments to staging and production are done manually through Jenkins and are
deployed from the master
branch.