diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c600a3c2..6f39dfd7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,7 +108,17 @@ jobs: run: pnpm install - name: โšก Run vitest - run: pnpm exec vitest --coverage + run: pnpm run test:coverage + + - name: ๐Ÿ“Š Coverage summary + run: | + node -e "const summary=require('./coverage/coverage-summary.json').total; const pct=(value)=>typeof value==='number'?value.toFixed(1):value; const lines=pct(summary.lines.pct); const functions=pct(summary.functions.pct); const branches=pct(summary.branches.pct); const statements=pct(summary.statements.pct); const row='| Metric | Coverage |\n| --- | --- |\n| Lines | '+lines+'% |\n| Functions | '+functions+'% |\n| Branches | '+branches+'% |\n| Statements | '+statements+'% |\n'; console.log('## Coverage\n'); console.log(row);" >> "$GITHUB_STEP_SUMMARY" + + - name: ๐Ÿ“ฆ Upload coverage artifact + uses: actions/upload-artifact@v7 + with: + name: vitest-coverage + path: coverage # cypress: # name: โšซ๏ธ Cypress diff --git a/.gitignore b/.gitignore index 1cab40f0..bd43c540 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ node_modules /cypress/screenshots /cypress/videos /postgres-data +/coverage diff --git a/README.md b/README.md index b880074a..009e6326 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ This repository uses commitizen. Commit code changes for pr's with `pnpm run com Use `pnpm` for the root project and commit `pnpm-lock.yaml`. Do not regenerate a root `package-lock.json`. +## ๐Ÿงช Testing + +- Run the monitor-focused unit and integration layers with `pnpm run test:monitor` +- Run full Vitest coverage with `pnpm run test:coverage` +- Coverage reports are written to `coverage/` as HTML, LCOV, and JSON summary files, and CI uploads the same directory as an artifact + ## ๐Ÿ† Credits Atlas System was originally created and made open source by the Riverside Healthcare Analytics team. See the [credits](https://www.atlas.bi/about/) for more details. diff --git a/app/components/ui/alert.tsx b/app/components/ui/alert.tsx index f10fc26b..980987f6 100644 --- a/app/components/ui/alert.tsx +++ b/app/components/ui/alert.tsx @@ -3,7 +3,7 @@ import { type VariantProps, cva } from "class-variance-authority"; import * as React from "react"; const alertVariants = cva( - "relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + "relative w-full rounded-lg border p-4 has-[svg]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", { variants: { variant: { diff --git a/app/components/ui/badge.tsx b/app/components/ui/badge.tsx index 24cd1701..b15a86d2 100644 --- a/app/components/ui/badge.tsx +++ b/app/components/ui/badge.tsx @@ -3,7 +3,7 @@ import { type VariantProps, cva } from "class-variance-authority"; import * as React from "react"; const badgeVariants = cva( - "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { variant: { diff --git a/app/components/ui/button.tsx b/app/components/ui/button.tsx index 71325cde..22a5a785 100644 --- a/app/components/ui/button.tsx +++ b/app/components/ui/button.tsx @@ -4,7 +4,7 @@ import { type VariantProps, cva } from "class-variance-authority"; import * as React from "react"; const buttonVariants = cva( - "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { diff --git a/app/components/ui/checkbox.tsx b/app/components/ui/checkbox.tsx index ce47b6f1..8c5f8658 100644 --- a/app/components/ui/checkbox.tsx +++ b/app/components/ui/checkbox.tsx @@ -12,7 +12,7 @@ const Checkbox = React.forwardRef< { return ( - + {children} @@ -41,7 +41,7 @@ const CommandDialogDynamic = ({ children, ...props }: CommandDialogProps) => { {children} @@ -58,7 +58,7 @@ const CommandInput = React.forwardRef< {children} - + Close diff --git a/app/components/ui/dropdown-menu.tsx b/app/components/ui/dropdown-menu.tsx index c9cfac3a..01b039f5 100644 --- a/app/components/ui/dropdown-menu.tsx +++ b/app/components/ui/dropdown-menu.tsx @@ -26,7 +26,7 @@ const DropdownMenuSubTrigger = React.forwardRef< ( { if (e.key === "Enter") { handleUnselect(item); @@ -119,7 +119,7 @@ export function MultiSelect({ onBlur={() => setOpen(false)} onFocus={() => setOpen(true)} placeholder={placeholder} - className="ml-0 bg-transparent outline-none placeholder:text-muted-foreground flex-1" + className="ml-0 bg-transparent outline-hidden placeholder:text-muted-foreground flex-1" /> @@ -132,7 +132,7 @@ export function MultiSelect({ }} > {open && selectables.length > 0 ? ( -
+
{/*No results found.*/} {selectables.map((framework) => { diff --git a/app/components/ui/navigation-menu.tsx b/app/components/ui/navigation-menu.tsx index 5aae2f13..d62790db 100644 --- a/app/components/ui/navigation-menu.tsx +++ b/app/components/ui/navigation-menu.tsx @@ -40,7 +40,7 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName; const NavigationMenuItem = NavigationMenuPrimitive.Item; const navigationMenuTriggerStyle = cva( - "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50", + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-hidden disabled:pointer-events-none disabled:opacity-50 data-active:bg-accent/50 data-[state=open]:bg-accent/50", ); const NavigationMenuTrigger = React.forwardRef< @@ -54,7 +54,7 @@ const NavigationMenuTrigger = React.forwardRef< > {children}{" "}