Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component library unit tests #34

Merged
merged 15 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ jobs:
- name: Install dependencies
run: pnpm install

- name: Lint source code
shell: bash
run: pnpm lint

- name: Run test suite
shell: bash
run: pnpm test
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.16.0
v20.11.0
35 changes: 10 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,50 +21,35 @@ This project uses [pnpm workspaces](https://pnpm.io/workspaces). To work with th
pnpm install
```

Run the test suite with coverage metrics generated:
To run the complete test suite, with coverage metrics generated:

```bash
pnpm test
```

To develop on the frontend app, run:
To run tests in watch mode (except the `infra` tests, which use Jest):

```bash
pnpm build
pnpm vitest
```

then
To start developing with hot reloading, use:

```bash
cd apps/spotlight
pnpm dev --concurrency 12
```

To run an app server:
These local servers will be started:

```bash
pnpm start
```

To extract form fields, their attributes and labels from an HTML code and output them in a JSON file, go to the "htmlParser" directory:

```bash
cd apps/spotlight/src/htmlParser
```
- Astro website - http://localhost:4321/
- Storybook - http://localhost:61610/

If you're already in the "spotlight" directory
To lint the source code:

```bash
cd src/htmlParser
pnpm lint
```

Replace the HTML content that's inside the "form-input.html" with your HTML, then run:

```bash
node processHtml.js yourCustomJSONFileName.json
```

Be sure to replace "yourCustomJSONFileName.json" with whatever name you want your output JSON file to be called. If you don't indicate a new file name, your file will be given the default file name which is "form-field-output.json".

## Command-line interface

A command-line interface is provided for manually running operations. The corresponding app resides in [./apps/cli](./apps/cli). A wrapper script, in the root directory, is provided.
Expand Down
64 changes: 43 additions & 21 deletions apps/spotlight/src/htmlParser/processHtml.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
/**
To extract form fields, their attributes and labels from an HTML code and output them in a JSON file, go to the "htmlParser" directory:

```bash
cd apps/spotlight/src/htmlParser
```

If you're already in the "spotlight" directory

```bash
cd src/htmlParser
```

Replace the HTML content that's inside the "form-input.html" with your HTML, then run:

```bash
node processHtml.js yourCustomJSONFileName.json
```

Be sure to replace "yourCustomJSONFileName.json" with whatever name you want your output JSON file to be called. If you don't indicate a new file name, your file will be given the default file name which is "form-field-output.json".
*/
import { load } from 'cheerio';
import fs from 'fs';
import path from 'path';
Expand All @@ -8,32 +29,33 @@ const outputFileName = process.argv[2] || defaultOutputFileName;
const outputJsonPath = path.join(process.cwd(), outputFileName);

function extractFormFields(htmlContent) {
const $ = load(htmlContent);
let formFields = [];

$('input, textarea, select').each((index, element) => {
const field = $(element);
const label = $("label[for='" + field.attr('id') + "']").text() || 'No Label';
formFields.push({
tag: field.prop('tagName').toLowerCase(),
type: field.attr('type'),
name: field.attr('name'),
id: field.attr('id'),
value: field.attr('value'),
label: label.trim()
});
const $ = load(htmlContent);
let formFields = [];

$('input, textarea, select').each((index, element) => {
const field = $(element);
const label =
$("label[for='" + field.attr('id') + "']").text() || 'No Label';

formFields.push({
tag: field.prop('tagName').toLowerCase(),
type: field.attr('type'),
name: field.attr('name'),
id: field.attr('id'),
value: field.attr('value'),
label: label.trim(),
});
});

return formFields;
return formFields;
}

function processHtmlFile() {
const htmlContent = fs.readFileSync(htmlFilePath, 'utf8');
const formFields = extractFormFields(htmlContent);
const htmlContent = fs.readFileSync(htmlFilePath, 'utf8');
const formFields = extractFormFields(htmlContent);

fs.writeFileSync(outputJsonPath, JSON.stringify(formFields, null, 2));
console.log(`Processed HTML file. Form data written to ${outputJsonPath}`);
fs.writeFileSync(outputJsonPath, JSON.stringify(formFields, null, 2));
console.log(`Processed HTML file. Form data written to ${outputJsonPath}`);
}

processHtmlFile();
processHtmlFile();
4 changes: 2 additions & 2 deletions apps/spotlight/src/pages/forms/index.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
import { FormSection } from '@atj/design/src/form';
import { FormManager } from '@atj/design';
import ContentLayout from '../../layouts/ContentLayout.astro';
---

<ContentLayout title="10x Access to Justice Spotlight">
<FormSection client:only />
<FormManager client:only />
</ContentLayout>
5 changes: 3 additions & 2 deletions apps/spotlight/src/pages/ud105-evicition-form.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
import { FormView } from '@atj/design/src/form/FormView';
import { Form } from '@atj/design';

import formData from '../htmlParser/ud105-form-field-output.json';
import ContentLayout from '../layouts/ContentLayout.astro';
---

<ContentLayout title="10x Access to Justice Spotlight">
<FormView prompt={formData} />
<Form client:only form={formData} />
</ContentLayout>
6 changes: 3 additions & 3 deletions infra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"main": "src/index.js",
"types": "src/index.ts",
"scripts": {
"get": "cdktf get",
"compile": "tsc --pretty",
"dev": "tsc -w",
"deploy": "cdktf deploy",
"get": "cdktf get",
"synth": "cdktf synth",
"compile": "tsc --pretty",
"watch": "tsc -w",
"test": "jest",
"test:watch": "jest --watch"
},
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
"build": "turbo run build",
"clean": "turbo run clean",
"dev": "turbo run dev",
"format": "prettier --write \"packages/**/*.{js,jsx,ts,tsx}\"",
"lint": "turbo run lint",
"pages": "rm -rf node_modules && npm i -g pnpm turbo && pnpm i && pnpm build && ln -sf ./apps/spotlight/dist _site",
"test": "run-p test:*",
"test:infra": "turbo run --filter=infra test",
"test:vitest": "vitest run --coverage.enabled --coverage.reporter=text --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportOnFailure --reporter vitest-github-actions-reporter",
"format": "prettier --write \"packages/**/*.{js,jsx,ts,tsx}\""
"test:vitest": "vitest run --coverage.enabled --coverage.reporter=text --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportOnFailure --reporter vitest-github-actions-reporter"
},
"hooks": {
"pre-commit": "pnpm format"
Expand All @@ -23,11 +24,13 @@
"@vitest/coverage-c8": "^0.33.0",
"@vitest/coverage-v8": "^0.34.6",
"@vitest/ui": "^1.2.1",
"eslint": "^8.56.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.3",
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"turbo": "^1.10.16",
"type-fest": "^4.10.1",
"typescript": "^5.2.2",
"vitest": "^0.34.6",
"vitest-github-actions-reporter": "^0.11.1",
Expand Down
35 changes: 35 additions & 0 deletions packages/design/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
],
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"react"
],
"rules": {
}
}
2 changes: 2 additions & 0 deletions packages/design/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const config: StorybookConfig = {
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-interactions'),
getAbsolutePath('@storybook/addon-a11y'),
getAbsolutePath('@storybook/addon-coverage'),
],
framework: {
name: getAbsolutePath('@storybook/react-vite') as '@storybook/react-vite',
Expand Down
34 changes: 26 additions & 8 deletions packages/design/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,59 @@
"clean": "run-p: clean:*",
"clean:lib": "rm -rf dist",
"clean:styles": "rm -rf static",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"storybook": "storybook dev -p 6006",
"watch": "run-p watch:*",
"watch:lib": "vite",
"watch:storybook": "storybook dev",
"watch:styles": "gulp watch"
"dev": "run-p dev:*",
"dev:lib": "vite",
"dev:storybook": "storybook dev",
"dev:styles": "gulp watch",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"test:storybook": "test-storybook",
"test:url": "test-storybook --url http://127.0.0.1:9009 --config-dir storybook",
"test:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"pnpm build:storybook --quiet && npx http-server storybook/public --port 9009 --silent\" \"wait-on tcp:127.0.0.1:9009 && pnpm test:url --maxWorkers=2\""
},
"files": [
"dist/**/*"
],
"devDependencies": {
"@playwright/test": "^1.41.1",
"@storybook/addon-a11y": "^7.6.10",
"@storybook/addon-coverage": "^1.0.0",
"@storybook/addon-essentials": "^7.6.10",
"@storybook/addon-interactions": "^7.6.10",
"@storybook/addon-links": "^7.6.10",
"@storybook/addon-onboarding": "^1.0.10",
"@storybook/blocks": "^7.6.10",
"@storybook/preview-api": "^7.6.10",
"@storybook/react": "^7.6.10",
"@storybook/react-vite": "^7.6.10",
"@storybook/test": "^7.6.10",
"@storybook/test-runner": "^0.16.0",
"@storybook/types": "^7.6.10",
"@testing-library/react": "^14.1.2",
"@types/prop-types": "^15.7.11",
"@types/react": "^18.2.48",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"@uswds/compile": "github:danielnaab/uswds-compile#package-json-paths",
"@vitejs/plugin-react": "^4.2.1",
"concurrently": "^8.2.2",
"eslint": "^8.56.0",
"eslint-plugin-react": "^7.33.2",
"glob": "^10.3.10",
"gulp": "^4.0.2",
"http-server": "^14.1.1",
"install": "^0.13.0",
"npm": "^10.3.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vite": "^5.0.12",
"vite-plugin-dts": "^3.7.1"
"vite-plugin-dts": "^3.7.1",
"wait-on": "^7.2.0"
},
"dependencies": {
"@atj/documents": "workspace:*",
"@atj/forms": "workspace:*",
"@atj/form-service": "workspace:*",
"@atj/forms": "workspace:*",
"@atj/interviews": "workspace:*",
"@uswds/uswds": "^3.7.1",
"react-hook-form": "^7.49.3",
Expand Down
37 changes: 37 additions & 0 deletions packages/design/src/Form/Form.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';

import { createForm } from '@atj/forms';

import Form from '.';

export default {
title: 'Form',
component: Form,
decorators: [(Story, args) => <Story {...args} />],
args: {
form: createForm(
{
title: 'Test form',
description: 'Test description',
},
[
{
id: 'question-1',
text: 'Question 1',
initial: '',
required: true,
},
{
id: 'question-2',
text: 'Question 2',
initial: 'initial value',
required: false,
},
]
),
},
tags: ['autodocs'],
} satisfies Meta<typeof Form>;

export const FormTest = {} satisfies StoryObj<typeof Form>;
7 changes: 7 additions & 0 deletions packages/design/src/Form/Form.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @vitest-environment jsdom
*/
import { describeStories } from '../test-helper';
import meta, * as stories from './Form.stories';

describeStories(meta.title, stories);
Loading
Loading