Fesk - MyAccount
My Account is an web application developed using FESK (Front End Starter Kit) framework. This application hosts multiple web pages such as My Account Landing page, Orders & Returns pages, Date Reminders, Item Level Returns pages, etc., for M&S, CFTO, COM+ domains.
Getting Started
Further Documentation
Getting Started
The steps below will help you copy the Starter Kit application: Create a new GitHub repo and push your new Starter Kit product to it, as well as get your machine ready to start building our first application.
Setting up
You will need Node.js installed NodeJS Official.
Install Node Modules
For first time installation, within the mns-fe-starter-kit
repository, you need to get a team token from the Pegasus team.
The token is sensitive information and you should store it securely in your vault area.
The token can be set on your machine in the following way:
npm config set //registry.npmjs.org/:_authToken <YOUR TOKEN>
npm config set scope mands
npm config set @mands:registry https://registry.npmjs.org/
Or through the script, available as a part of starter kit:
export NPM_TOKEN=<YOUR TOKEN>
sh ./scripts/create-npmrc.sh
Its also important to make sure you are running the same version of node and npm as stated in package-lock.json
.
The mns-fe-starter-kit
repository is package-locked (Find more on package-lock here - https://docs.npmjs.com/files/package-lock.json). Hence the dependencies would be downloaded from package-lock.json instead of from package.json.
To download the latest version of dependencies, delete the package-lock.json file and then
Running the app
Run locally
When this is running locally it will run Liniting checks, unit tests and will automatically reload the application when making live code changes both client and server side.
Docker-based build
Azure K8s runs the app using a docker container sometimes you want to make one locally to test it works.
docker build --rm -t <imageName> . --build-arg NPM_TOKEN=<token>
docker run -p $PORT:3000 <imageName>
Run production
This is how the application is started after deployment to an environment. This requires the bundled assets.
Run bundle
If you need to create a bundle locally.
Development
Here are the folders a developer is interested in:
src
- pages, common code and services.config
- configs for all of FESK.tests
- visual and functional testing.mns-fe-deployment
- concourse pipeline generator, cloud foundry and k8s config.utilities
- API mock decorator, Header setter, base handler.
Calling APIs locally
By default, We recommend using mockOnLocal
. This is a decorator around API calls in which will return a mock that you supply based upon the environment
value used within the configuration
.
Note: If a requirement for making the API calls locally exists, you can always override the environment
variables for that singular purpose at run time.
How to make a new page
- Create a new folder in
./src/pages
with your pages name. - Structure as follows:
├── <page name>
│ ├── _base.scss
│ ├── client.js
│ ├── client.test.js
│ ├── handler.js
│ ├── handler.server.test.js
│ ├── markup.hbs
│ ├── render.client.test.js
│ ├── route.js
│ ├── route.server.test.js
│ └── w3c.test.js
Note: see pages/main
.
- Path routing is configured in
route.js
(Route testing docs). - Handling requests through
handler.js
(Handler testing docs). - Handlebars templates are specified in
markup.hbs
(template tests). - Rendered pages must be validated against the w3c specification (w3c testing docs).
- Client side JS lives in
client.js
Local patterns
If you have a piece of UI that you often use in your FESK app but isn't reusable enough for the FESK Pattern Library
you can make your own patterns and use them much in a similar fashion to the pattern library.
A example pattern has been given that is based on the warning pattern. In the pattern library it lives in:
/src/common/partials/example-partial
. The main difference is that you have to use relative paths for import or SASS and JS and in the markup import you can use the name directly like so:
handlebars:
{{> example-partial/markup message='example partial'}}
sass:
@import '../../common/partials/example-partial/base';
client.js:
import '../../common/partials/example-partial/client';
Lazy Loading
FESK is equipped with lazyloading of images by default.
We recommend you make use of the image element from mns-fe-pattern-library
.
Otherwise details of how your images should be done in can be found in the lazy sizes repo readme.
Running automated checks
We use the following types of testing in fesk:
To run linting tests:
npm run lint
This will lint all files in the repo of types .js
,.scss
and .sass
.
The language specific configurations are held in the mns-lint-config repo.
Before running the unit tests make sure to first bundle the assets. This is because some of the server tests instantiate the server which requires that the minified html folder is present.
npm run bundle
To run unit tests:
npm run test:unit
The unit test combines three sets of testing:
npm run test:unit:client
npm run test:unit:server
npm run test:func
The commands run tests set in *client.test.js
, *.server.test.js
and functional.test.js
respectively.
test:unit
also runs a code coverage analysis that will fail if there is not a average of 80% test coverage. Information on how it works can be found at istanbul.js
To run functional tests:
npm run test:func
As these tests are JSDOM tests and do not require a running server, this command has also been included in the npm test:unit
command.
We recommend using functional tests to test your local partials in the same way that they are tested in the pattern library. For an example of this please see the Example Partial and functional.test.js
file contained within. These tests should be testing basic user interaction and presence of elements.
Functional tests can also be used to test functionality on full pages by adding a file called functional.test.js
to the page folder.
When to use JSDOM or WebdriverIO
Functional tests are high level tests that run in a real browser. High level tests are notoriously fragile, slow to run and require a high level of mantainence.
For this reason, we recommend that for simple interactions like checking elements are present on the page we should opt for JSDOM; while for more complicated scenarios(e.g. requires mimicking of user interaction), it may be necessary to use WebdriverIO.
If you encounter any real-life example for using WebDriverIO over JSDOM, please contact us or feel free to raise a PR in starter-kit!
To run pa11y-ci tests:
npm run test:a11y
Visual testing TBC
To run the end to end tests:
npm run test:e2e
NB: End to end tests should be written sparingly in a way that follows a common user journey though your page(s)
To run the lighthouse performance tests:
npm run test:perf
For more information please see the following section.
(to be confirmed)
Security testing
To run security testing you MUST have Docker
and docker-compose
installed on you machine.
Please make sure that before running this test you execute the following command in your terminal:
export NPM_TOKEN=<NPM TOKEN FROM YOUR VAULT>
The tests itself can be initiated by running:
npm run test:security
For more information please see the following section.
Using responseLogging
Found in /utilities/middlewares/responseLogging.js
this middleware is responsible for the server response logs
It will log a info message for any code below 400 like this:
info: {
"url": "/",
"id": "82090eef-a835-46e9-87a4-643ba1afe5bf",
"statusMessage": "OK",
"statusCode": 200,
"totalDuration": 122,
"timestamp": "2018-05-18T12:33:12.044Z"
}
And log a error message in red for over 400 codes like so:
ERROR: {
"url": "/notFound",
"id": "190de3a8-4e96-4130-8fca-112fcc438cf3",
"statusMessage": "Not Found",
"statusCode": 404,
"totalDuration": 78,
"timestamp": "2018-05-18T12:33:17.610Z"
}
The module has been kept out of mns-fe-foundation
to allow you the change the logic to help minimise logs and add more info in to help with fixing issues.
CI and Deployment
Concourse
Before you can deploy your pipeline you will need to update TEAM_NAME in /ci/deploy-ci-azure.sh
to your concourse team name.
You can deploy your pipeline by running either of these commands depending on your needs (make sure you have your secrets in the appropriate vault):
- Azure run
npm run ci:deploy:azure
Make sure you unpause your pipeline.
By default the dev environment will be automatically deployed with whatever is in your selected vault branch (default: master
).
To deploy to a different environment this should be done in Concourse detailed below:
- Run
./mns-fe-deployment/scripts/deployment/deploy-ci.sh <target> <hash>
providing two arguments: target - target enviroments (dev, sit2, sit3, perf or prod), please note: multiple enviroments can be supplied if necessary, hash - hash of the last commit which should be included in the release. - This will create a new tag in the project's repo master branch which will be picked up by correct Concourse pipeline.
- At this point you should be able to go to Concourse and see how the build is progressing.
Note: this style of deployment can ONLY be done on master. It is impossible to deploy from a branch using it.
Creating a new environment
See the documentation on how to create a new environment.
Clearing caches and resetting breakers
In the event we need to force update content from APIs you can use the emergency clear link to clear the API memoize caches and reset the circuitBreakers.
Info on how to use Memoize and CircuitBreaker can be found in fesk-documentation foundation components
Setup
-
Make sure you have setup a EMERGENCY_CLEAR_CODE
in your environment variables.
One is provided in the repo by default but we recommend changing it.
-
Check all API function instances you want to clear are in src/pages/emergencyClear/handler.js
.
Note: To work and gain efficiency each API should be required and initialised once in the service/api
and then required from there:
const api = require('../../services/api');
const apis = [
{ id:'getContent', func:api.getContentApi.getContent}
];
Usage
Navigate to /emergencyClear?code=<EMERGENCY_CLEAR_CODE>&&action=<ACTIONS>&&api=<APIs>
where:
Param | Type | Details |
---|
EMERGENCY_CLEAR_CODE | String | your configured pass code |
ACTIONS | comma separated array | breaker ,cache |
APIs | comma separated array | a list of API IDs e.g: /emergencyClear?code=<EMERGENCY_CLEAR_CODE>&&action=breaker&&api=searchProductsApi,searchProductsApi_V2 to reset the breakers on both search APIs |
Potential responses:
Done!
and a log of APIs cleared if all okUnauthorised or Missing one or more parameters.
if incorrect code or missing params- The error message will be displayed if something breaks
All requests are also logged by logger except unauthorised.
Example response:
EMERGENCY CLEAR
Done!
CategoryApi: Cache Cleared Breaker Reset
ContentApi: Cache Cleared Breaker Reset
HeaderL23Api: Cache Cleared Breaker Reset
ProductsListApi: Cache Cleared Breaker Reset
searchProductsApi: Breaker Reset
searchProductsApi_V2: Breaker Reset
Quick Links To Relevant Repositories
Contact
My Account Landing Page
Other Page