# SamaroUItest

<p align="center">
  <strong>Comprehensive Testing Framework for Angular</strong>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/samaro-uitest">
    <img src="https://img.shields.io/npm/v/samaro-uitest.svg" alt="npm version">
  </a>
  <a href="https://github.com/samaro/samaro-uitest/blob/main/LICENSE">
    <img src="https://img.shields.io/npm/l/samaro-uitest.svg" alt="license">
  </a>
  <a href="https://angular.io">
    <img src="https://img.shields.io/badge/Angular-15%2B-red.svg" alt="Angular 15+">
  </a>
</p>

<p align="center">
  🚀 <strong>Vitest</strong> + 🎭 <strong>Playwright</strong> + 📊 <strong>Allure</strong>
</p>

---

## Features

- ✅ **One-Command Setup** - Get started in minutes with `ng add samaro-uitest`
- ⚡ **Lightning Fast** - Vitest for rapid unit testing feedback
- 🎭 **Real Browser Testing** - Playwright for E2E and component tests
- 📊 **Beautiful Reports** - Allure integration for all test types
- 🔧 **Pre-Configured** - Works out of the box with Angular
- 🛠️ **Helper Library** - Common testing utilities included
- 🔍 **Debug Interface** - Access Angular app state in tests
- 🚀 **CI/CD Ready** - GitHub Actions, GitLab CI, Azure DevOps support

---

## Installation

### Using Angular CLI (Recommended)

```bash
ng add samaro-uitest
```

### Using npm

```bash
npm install --save-dev samaro-uitest
npx samaro-init
```

### Install Playwright Browsers

```bash
npx playwright install chromium
```

---

## Quick Start

After installation, you can immediately start testing:

```bash
# Run unit tests
npm run test

# Run E2E tests
npm run test:e2e

# Run component tests
npm run test:ct

# Generate and view reports
npm run allure:generate
npm run allure:open
```

---

## Available Scripts

| Script | Description |
|--------|-------------|
| `npm run test` | Run unit tests with Vitest |
| `npm run test:run` | Run unit tests once (CI mode) |
| `npm run test:ui` | Run unit tests with UI |
| `npm run test:coverage` | Run unit tests with coverage |
| `npm run test:e2e` | Run E2E tests with Playwright |
| `npm run test:e2e:ui` | Run E2E tests with Playwright UI |
| `npm run test:e2e:headed` | Run E2E tests in headed mode |
| `npm run test:ct` | Run component tests |
| `npm run allure:generate` | Generate Allure reports |
| `npm run allure:open` | Open Allure reports |
| `npm run allure:clean` | Clean Allure results |

---

## Writing Tests

### Unit Tests

```typescript
// src/app/services/user.service.spec.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});
```

### E2E Tests

```typescript
// e2e/auth.spec.ts
import { test, expect } from '@playwright/test';
import { generateUniqueUser, register } from 'samaro-uitest/helpers';

test('user can register', async ({ page }) => {
  const user = generateUniqueUser();
  
  await register(page, user.username, user.email, user.password);
  
  await expect(page).toHaveURL('/');
});
```

### Component Tests

```typescript
// ct-tests/button.spec.ts
import { test, expect } from '@playwright/test';

test('button renders correctly', async ({ page }) => {
  await page.goto('/button-test');
  
  const button = page.locator('app-button');
  await expect(button).toBeVisible();
});
```

---

## Test Helpers

### Debug Interface

Access your Angular app's state during tests:

```typescript
import { getToken, getAuthState, waitForAuthState } from 'samaro-uitest/helpers';

test('user login', async ({ page }) => {
  await login(page, 'user@example.com', 'password');
  
  // Wait for auth state
  await waitForAuthState(page, 'authenticated');
  
  // Get token
  const token = await getToken(page);
  expect(token).toBeTruthy();
});
```

### Authentication

```typescript
import { generateUniqueUser, register, login, logout } from 'samaro-uitest/helpers';

const user = generateUniqueUser();
await register(page, user.username, user.email, user.password);
await logout(page);
await login(page, user.email, user.password);
```

### API Helpers

Speed up tests by using APIs for setup:

```typescript
import { registerUserViaAPI } from 'samaro-uitest/helpers';

test('create article', async ({ page, request }) => {
  const { token } = await registerUserViaAPI(request, {
    username: 'testuser',
    email: 'test@example.com',
    password: 'password123',
  });
  
  // Use token for authenticated requests
});
```

---

## Configuration

### Vitest Configuration

```typescript
// vitest.config.ts
import { createVitestConfig, mergeConfig } from 'samaro-uitest/config';

export default mergeConfig(
  createVitestConfig({
    testGlob: 'src/**/*.spec.ts',
  }),
  {
    test: {
      coverage: {
        exclude: ['**/legacy/**'],
      },
    },
  }
);
```

### Playwright Configuration

```typescript
// playwright.config.ts
import { createPlaywrightConfig } from 'samaro-uitest/config';

export default createPlaywrightConfig({
  baseURL: 'http://localhost:4200',
  testDir: './e2e',
  webServerCommand: 'npm run start',
  webServerPort: 4200,
});
```

---

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `API_MODE` | Use API for setup operations | `true` |
| `API_BASE` | Base URL for API calls | `http://localhost:4200/api` |
| `DEBUG_INTERFACE_NAME` | Name of debug interface | `__app_debug__` |
| `CI` | CI mode (auto-clean results) | `false` |

---

## CI/CD Integration

### GitHub Actions

```yaml
name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npx playwright install chromium
      - run: npm run test:run
      - run: npm run test:e2e
      - run: npm run allure:generate
```

---

## Troubleshooting

### Playwright browsers not installed

```bash
npx playwright install chromium
```

### Tests fail with timeout

Increase timeout in configuration:

```typescript
export default createPlaywrightConfig({
  webServer: {
    timeout: 180_000,
  },
});
```

### Debug interface not available

Implement debug interface in your Angular app:

```typescript
// app.component.ts
if (typeof window !== 'undefined') {
  window.__app_debug__ = {
    getToken: () => this.authService.getToken(),
    getAuthState: () => this.authService.getAuthState(),
    getCurrentUser: () => this.authService.getCurrentUser(),
  };
}
```

---

## Documentation

- [Vitest Documentation](https://vitest.dev/)
- [Playwright Documentation](https://playwright.dev/)
- [Allure Documentation](https://docs.qameta.io/allure/)
- [Angular Testing Guide](https://angular.io/guide/testing)

---

## License

MIT © [Samaro](https://github.com/samaro)

---

<p align="center">
  Made with ❤️ for the Angular community
</p>
