Skip to content
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/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ npm run integration # Run Playwright integration tests
npm run integration:debug # Debug mode with browser
npx playwright test -g "test name" # Run single test (from integration folder)

# Unit testing (js package)
npm run test # Run Vitest unit tests
npm run test:cov # Run with code coverage report

# Visual regression
npm run screenshots:light # Light theme only
npm run screenshots:all # All themes
Expand Down
37 changes: 34 additions & 3 deletions .github/instructions/js.instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Atlas JS - Copilot Instructions

applyTo: "js/**"
applyTo: "js/\*\*"

This is the `@microsoft/atlas-js` package, providing TypeScript/JavaScript behaviors for the Atlas Design System.

Expand All @@ -20,13 +20,16 @@ js/
│ ├── elements/ # Custom elements / web components
│ ├── utilities/ # Shared utility functions
│ └── index.ts # Main entry point
├── test/ # Unit tests (mirrors src/ structure)
└── dist/ # Compiled JavaScript output
```

## Key Commands

- `npm run build` - Compile TypeScript to JavaScript
- `npm run lint` - Run ESLint on TypeScript files
- `npm run test` - Run unit tests with Vitest
- `npm run test:cov` - Run unit tests with code coverage report
- `npm run prepublishOnly` - Lint and build before publishing

## When to Add JavaScript
Expand Down Expand Up @@ -60,12 +63,40 @@ Atlas prioritizes CSS-only solutions. Add JavaScript only when:
## Integration Testing

Behavioral tests are in the `integration` package:

- Tests use Playwright
- Run from repository root: `npm run integration`

## Unit Testing

Unit tests use [Vitest](https://vitest.dev/) with a jsdom environment for DOM APIs.

### Running Tests

- `npm run test` - Run all unit tests (from `js/` folder or repo root)
- `npm run test:cov` - Run tests with code coverage report
- `npx vitest --watch` - Watch mode during development (from `js/` folder)
- `npx vitest run test/utilities/util.test.ts` - Run a specific test file

### Writing Tests

1. **Place test files in `test/`** - Mirror the `src/` folder structure (e.g., `test/utilities/util.test.ts` for `src/utilities/util.ts`)
2. **Import from vitest** - Use `import { describe, it, expect } from 'vitest'`
3. **Use jsdom for DOM tests** - The test environment provides `document`, `window`, etc.
4. **Test pure functions directly** - For utilities, test inputs and outputs
5. **Test DOM behaviors** - For behaviors/elements, create DOM fixtures and assert side effects

### Coverage

- Coverage uses the `v8` provider via `@vitest/coverage-v8`
- Reports are generated in `js/coverage/` (text, JSON summary, and HTML)
- Coverage runs automatically in CI and is reported in the GitHub Actions job summary

## When Making Changes

1. Run `npm run lint` before committing
2. Build with `npm run build` to verify compilation
3. Test interactively with the site package
4. Add integration tests for new behaviors in the `integration` package
3. Run `npm run test` to ensure all unit tests pass
4. Test interactively with the site package
5. Add unit tests for new utilities and pure functions
6. Add integration tests for new behaviors in the `integration` package
6 changes: 5 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This is a basic workflow to help you get started with Actions

name: Ensure build and lint
name: Ensure build, lint, and test

# Controls when the action will run.
on:
Expand Down Expand Up @@ -45,6 +45,10 @@ jobs:
- name: Run lint
run: npm run lint;

# Run unit tests with coverage
- name: Run tests
run: npm run test:cov;

# Run Dart Sass build
- name: Build CSS
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ dist
toc.json
test-results/
playwright-report/
coverage/
.wireit
.netrc
2 changes: 1 addition & 1 deletion extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"esbuild-watch": "npm run esbuild-base -- --sourcemap --watch"
},
"dependencies": {
"@microsoft/atlas-css": "^6.0.0"
"@microsoft/atlas-css": "^6.6.1"
},
"devDependencies": {
"@types/glob": "^8.1.0",
Expand Down
1 change: 1 addition & 0 deletions js/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
ignorePatterns: ['vitest.config.ts'],
env: {
browser: true,
node: false,
Expand Down
8 changes: 6 additions & 2 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"build": "tsc --project \"./tsconfig.json\" --outDir \"./dist\" --declaration true --declarationMap true",
"lint": "eslint . --ext .ts",
"prebuild": "rimraf dist",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "vitest run",
"test:cov": "vitest run --coverage",
"prepublishOnly": "npm run lint && npm run build"
},
"homepage": "https://github.com/microsoft/atlas-design",
Expand Down Expand Up @@ -37,13 +38,16 @@
"author": "Microsoft Corporation",
"license": "MIT",
"devDependencies": {
"@vitest/coverage-v8": "^4.1.6",
"eslint": "^8.43.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jasmine": "^4.1.3",
"eslint-plugin-jsdoc": "^46.3.0",
"eslint-plugin-security": "^1.7.1",
"jsdom": "^29.1.1",
"rimraf": "^5.0.1",
"tslib": "^2.6.0",
"typescript": "^5.1.5"
"typescript": "^5.1.5",
"vitest": "^4.1.6"
}
}
29 changes: 29 additions & 0 deletions js/test/utilities/util.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, it, expect } from 'vitest';
import { generateElementId, kebabToCamelCase } from '../../src/utilities/util';

describe('generateElementId', () => {
it('should return a string starting with "bx-"', () => {
const id = generateElementId();
expect(id).toMatch(/^bx-\d+$/);
});

it('should return unique ids on subsequent calls', () => {
const id1 = generateElementId();
const id2 = generateElementId();
expect(id1).not.toBe(id2);
});
});

describe('kebabToCamelCase', () => {
it('should convert kebab-case to camelCase', () => {
expect(kebabToCamelCase('my-variable-name')).toBe('myVariableName');
});

it('should return the same string if no hyphens', () => {
expect(kebabToCamelCase('simple')).toBe('simple');
});

it('should handle single hyphen', () => {
expect(kebabToCamelCase('foo-bar')).toBe('fooBar');
});
});
22 changes: 22 additions & 0 deletions js/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
environment: 'jsdom',
include: ['test/**/*.test.ts'],
reporters: process.env.GITHUB_ACTIONS === 'true' ? ['default', 'github-actions'] : ['default'],
coverage: {
provider: 'v8',
reporter: ['text', 'json-summary', 'html'],
reportsDirectory: './coverage',
include: ['src/**/*.ts'],
exclude: ['src/index.ts']
// thresholds: {
// statements: 80,
// branches: 80,
// functions: 80,
// lines: 80
// }
}
}
});
Loading
Loading