# Testing Setup Guide

## Overview

This project uses a sophisticated dual-testing approach with:

- **Japa** for Node.js unit tests (server-side)
- **Web Test Runner** for browser tests (client-side)

## Test Structure

```text
├── test/                    # Browser tests (Web Test Runner)
│   ├── **/*.browser.test.ts # Browser-specific tests
│   ├── **/*.spec.ts         # Browser test specs
│   └── env.ts               # Test environment configuration
├── tests/                   # Node.js tests (Japa)
│   └── unit/                # Unit tests for server-side code
│       └── **/*.spec.ts     # Node.js test specs
└── bin/
    ├── test.ts              # Japa test runner
    ├── test-web.ts          # Web Test Runner launcher
    └── plugins/             # Custom test plugins
```

## Available Test Commands

### Node.js Tests

```bash
npm run test:node           # Run all Node.js tests
npm run test:node:coverage  # Run with coverage
```

### Browser Tests

```bash
npm run test:browser        # Run all browser tests
npm run test:browser:watch  # Run in watch mode
```

### Combined Tests

```bash
npm test                    # Run both Node.js and browser tests
npm run test:coverage       # Run both with coverage
```

## Test Frameworks & Libraries

### Node.js Testing Stack

- **@japa/runner** - Test runner
- **@japa/assert** - Assertions
- **@japa/api-client** - HTTP client for API testing
- **@japa/expect-type** - TypeScript type testing
- **sinon** - Mocking and spying
- **c8** - Code coverage

### Browser Testing Stack

- **@web/test-runner** - Test runner
- **@esm-bundle/chai** - Assertions for browser
- **@web/test-runner-playwright** - Browser automation
- **sinon** - Mocking (browser compatible)

## Writing Tests

### Node.js Tests Example

```typescript
import { test } from '@japa/runner'

test.group('YourModule', (group) => {
  group.each.setup(() => {
    // Setup before each test
  })

  test('should do something', ({ assert }) => {
    // Your test logic
    assert.equal(actual, expected)
  })
})
```

### Browser Tests Example

```typescript
import { assert } from '@esm-bundle/chai'

describe('YourModule', () => {
  it('should work in browser', () => {
    // Your browser test logic
    assert.equal(actual, expected)
  })
})
```

## Test Environment Setup

### OAuth2 Mock Server

- Automatically starts on available port 8000-8100
- Provides endpoints for various OAuth2 flows
- Configured in `web-test-runner.config.js`

### HTTP Servers

- Express servers with CORS support
- NTLM authentication support
- Custom middleware for specific test scenarios

## Test Plugins

### Sinon Plugin

```typescript
test('should mock', ({ sinon, assert }) => {
  const stub = sinon.stub(obj, 'method')
  // ... test logic
})
```

### Events Plugin

```typescript
test('should handle events', ({ events, assert }) => {
  // Custom event testing logic
})
```

## Configuration Files

### TypeScript Configurations

- `test/tsconfig.json` - Browser test compilation
- `tests/tsconfig.json` - Node.js test compilation
- `tsconfig.browser.json` - Browser build configuration
- `tsconfig.node.json` - Node.js build configuration

### Test Runner Configurations

- `web-test-runner.config.js` - Browser test configuration
- `bin/test.ts` - Japa test configuration

## Running Specific Tests

### Run specific test files

```bash
# Node.js specific file
npm run test:node  -- --files=tests/unit/specific-test.spec.ts

# Browser specific file
npm run test:browser -- --files=test/specific-test.browser.test.ts
```

### Run tests with debugging

```bash
# Node.js with debugging
node --inspect --import ts-node-maintained/register/esm bin/test.ts

# Browser with debugging
npm run test:browser -- --open --manual
```

## Coverage Reports

Coverage is generated using **c8** for Node.js tests:

- Reports in `lcov` and `text` formats
- Configured to work with TypeScript source maps
- Excludes test files and build artifacts

## Best Practices

1. **Separate browser and Node.js tests** - Use appropriate file naming
2. **Use proper assertions** - Japa's assert for Node.js, Chai for browser
3. **Mock external dependencies** - Use Sinon for consistent mocking
4. **Test async code properly** - Use proper async/await patterns
5. **Group related tests** - Use test groups for better organization

## Troubleshooting

### Common Issues

1. **Port conflicts** - OAuth2 server uses dynamic ports
2. **TypeScript compilation** - Check tsconfig files
3. **Browser timeouts** - Increase timeout in web-test-runner config
4. **Import issues** - Ensure proper ES module imports

### Debug Tips

1. Use `--watch` mode for development
2. Check browser console for client-side errors
3. Use `console.log` or debugger statements
4. Verify mock server responses
