# vega-stencil

## Table of Contents
  * [Overview](#overview)
  * [Prerequisite](#prerequisite)
    + [Code linter](#code-linter)
    + [[Optional] Consume new design token](#-optional--consume-new-design-token)
  * [Getting started](#getting-started)
  * [Debug/Development](#debug-development)
  * [Testing](#testing)
    + [If you want to run a single test suite, please run](#if-you-want-to-run-a-single-test-suite--please-run)
    + [If you want to run the specific test case within a single test suite, please run](#if-you-want-to-run-the-specific-test-case-within-a-single-test-suite--please-run)
    + [If you would like to run is duplicate with the cases in other test suite, you can use the below command to specify the test case in a specific suite:](#if-you-would-like-to-run-is-duplicate-with-the-cases-in-other-test-suite--you-can-use-the-below-command-to-specify-the-test-case-in-a-specific-suite-)
      - [If you need to update component images,pls delete the related object in master.json,then run below command and commit the changes:](#if-you-need-to-update-component-images-pls-delete-the-related-object-in-masterjson-then-run-below-command-and-commit-the-changes-)
    + [If you want to disable Featureflag to test cases with old logic](#if-you-want-to-disable-Featureflag-to-test-cases-with-old-logic)
  * [Raising a commit](#raising-a-commit)
  * [Troubleshooting](#troubleshooting)
    + [1. E2E Testing Failure due to the css not loaded](#1-e2e-testing-failure-due-to-the-css-not-loaded)

## Overview
This package is mainly for creating custom web components built with [stencil.js](https://stenciljs.com/docs/introduction).

## Prerequisite

### Code linter
vega-stencil is using eslint (config: `.eslintrc.js`) along with prettier (config: `.prettierrc.js`). 
Make sure both tools have been set up properly in your IDE.

### [Optional] Consume new design token
design token was originally stored at [`../vega-design` package](https://github.com/heartlandpayments/Vega/tree/main/vega-design) which is also responsible for generating corresponding CSS/JS file used by other clients including `vega-stencil`. 

Hence, if you want to test some change of design token and want to integrate them into vega-stencil, you need to re-run the consume command to fetch the CSS/JS files from `vega-design` to `vega-stencil`:

```bash
> npm run consume-design-token
```

## Getting started

Install node dependencies
```bash
> npm install
```

## Debug/Development
To generate a new stencil component
```bash
> npm run generate <element_tag>
```

Start local server to host preview your change for stencil components
```bash
> npm run start
# or 
> npm run debug # no cache
```

To view the change in storybook
```bash
> npm run storybook
```

## Testing
Currently, vega-stencil has two testing environments:
1. Unit test env:
   * In this env, we will run unit test for vega components / non-component logic (e.g. [`vega-badge.spec.tsx`](https://github.com/heartlandpayments/Vega/blob/main/vega-stencil/src/components/vega-badge/test/vega-badge.spec.tsx)). 
   * In this env, there won't be any actual HTML element during runtime and all of them will show up as `MockHTMLElement`
2. E2E test env:
   * This env is using the exact browser runtime (Chromium) to run the test, which means all the UI/UX should be the same as the real one. 
   * The tests we are running in this env are:
     1. E2E test for vega component classes (e.g. [`vega-badge.e2e.ts`](https://github.com/heartlandpayments/Vega/blob/main/vega-stencil/src/components/vega-badge/test/vega-badge.e2e.ts))
     2. E2E test for visual regression checking (e.g. [`vaga-date-picker.visual.e2e.ts`](https://github.com/heartlandpayments/Vega/blob/main/vega-stencil/src/components/vega-date-picker/test/vega-date-picker.visual.e2e.ts))
     3. E2E test for accessibility checking with standard `'wcag2a', 'wcag2aa','wcag21a', 'wcag21aa'` (e.g. [`vega-date-picker.ada.e2e.ts`](https://github.com/heartlandpayments/Vega/blob/main/vega-stencil/src/components/vega-date-picker/test/vega-date-picker.ada.e2e.ts))

The command to run **both <1> and <2>** is 
```bash
> npm run test:base:coverage
# or
> npm run test:base:watch-all # this command will re-run when src files are changed
```
The command to run visual regression test only is 
```bash
> npm run test:visual 
```

### If you want to run a single test suite, please run
```bash
> npm run test:single-suite <suite_file_name>
```
Example: `npm run test:single-suite vega-modal.spec`

### If you want to run the specific test case within a single test suite, please run
```bash
> npm run test:single-case <test_case_name_regex>
```
Which will run only tests with a name that matches the regex. Example: `npm run test:single-case "should render proper css of modal when open modal"`

### If you would like to run is duplicate with the cases in other test suite, you can use the below command to specify the test case in a specific suite:
```bash
> npm run test:single-suite -- --testNamePattern <test_case_name_regex>
```
#### If you need to update component images,pls delete the related object in master.json,then run below command and commit the changes:
1.**<3>** 
2.node scripts/visual-test-screenshot-handle.js

#### If you want to see the difference pic between local and stand,pls follow below step:
1.install Live Server extension
2.open screenshot/compare.html by open with Live Server
3.choose All Screenshots on right top
4.click blank area under left side if the stand pic not show ,and manuel compare it

#### If you want to disable Featureflag to test cases with old logic:
For e2e test to disable a featureflag:
```
describe('vega-input', () => {
  let page: E2EPage;
  beforeEach(async () => {
      page = await newE2EPage();
      await page.evaluateOnNewDocument(() => {
          window['VegaDisabledFeatureKeys'] = ['VEGA_FORM.FORM_FIELD_CONTROLLER_VALIDATION'];
      });
  });
```

For spec test to disable a featureflag:
```
describe('vega-input', () => {
  beforeAll(() => {
    FeatureFlag.disable('VEGA_FORM.FORM_FIELD_CONTROLLER_VALIDATION');
});
```

**Note**:
1. The main difference between unit(spec) test vs e2e test in stencil [can be found here](https://stenciljs.com/docs/testing-overview#unit-testing-vs-end-to-end-testing)
  * Once notice here is, unit test running in `stencil` is **not behave the exact same** as running it with `jest` CLI directly (especially for non-component test suite), this is because stencil is mocking most of the html element by using its own test runtime component, hence we would suggest avoiding using `jest` CLI directly to run unit tests as you might see different testing result when run it in Github pipeline.
2. In vega, we prefer to put test case into spec/unit test over e2e test unless they are not able to test in non-browser env (e.g. simulate user blur/focus event, window resize), the main reason is stencil doesn't support to run test coverage over e2e test case, hence we cannot easily tell the branch inside component is covered properly by e2e test.
3. In the scenario that you have to use e2e test to cover code branch, please use [istanbul/ignoring-code-for-coverage](https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md) and **put additional comment regarding how this branch is covered in e2e test** to skip the code for coverage checking. For example:
   * in `vega-stencil/src/components/vega-carousel/vega-carousel.tsx`
     ```ts
     // ...
     
     /**
     * The below method is e2e-test covered in
     * @see{module:vega-carousel-e2e-render}
     */
     /* istanbul ignore next */
     @Watch('perPage')
     onPerPagePropsChange(): void {
       this.resizeWindowHelper();
       this.applySpacingHelper();
     }
     
     // ...
     ```
   * and the jsdoc module `module:vega-carousel-e2e-render` is defined in `vega-stencil/src/components/vega-carousel/test/vega-carousel.e2e.ts`
     ```ts
     describe('vega-carousel', () => {
       /** @module vega-carousel-e2e-render */
       it('renders', async () => {
         const page: E2EPage = await newE2EPage();
         await page.setContent('<vega-carousel></vega-carousel>');
         const element: E2EElement = await page.find('vega-carousel');
         expect(element).toHaveClass('hydrated');
       });
     });
     ```
   

## Raising a commit
Make sure you have passed the necessary pre commit check by running
```bash
> npm run pre-release
```

Once the above command succeeded, run this command to build the artifacts for releasing
```bash
> npm run release 
```

## Troubleshooting
### 1. E2E Testing Failure due to the css not loaded 
This is because the current stencil build in your workspace is staled and you need to re-build the artifacts by running `yarn run release`.
