Contributing Guide¶
Thank you for your interest in contributing to the F5 XC Console plugin! This guide covers how to set up your development environment and contribute quality code.
Development Setup¶
Prerequisites¶
- Node.js 18+ (recommended: 20 LTS)
- npm 9+
- Git
Initial Setup¶
# Clone the repository
git clone https://github.com/robinmordasiewicz/f5xc-console.git
cd f5xc-console
# Install dependencies
npm install
# Verify setup
npm run qa
Development Workflow¶
1. Create a Feature Branch¶
2. Make Changes¶
Edit source files in src/ directory.
3. Write Tests¶
Add tests for your changes in tests/unit/ or tests/integration/.
4. Run Tests¶
5. Commit Changes¶
6. Push and Create PR¶
Code Standards¶
TypeScript¶
- Use strict TypeScript (
strict: true) - Export types from modules
- Use interfaces for public APIs
// Good
export interface NavigationResult {
success: boolean;
url: string;
error?: string;
}
export function navigate(target: string): NavigationResult {
// ...
}
Testing¶
- Every new function needs tests
- Aim for 80%+ coverage on new code
- Use descriptive test names
describe('MyModule', () => {
describe('myFunction()', () => {
test('should return success for valid input', () => {
// Arrange
const input = 'valid';
// Act
const result = myFunction(input);
// Assert
expect(result.success).toBe(true);
});
test('should handle empty input gracefully', () => {
const result = myFunction('');
expect(result.success).toBe(false);
expect(result.error).toBeDefined();
});
});
});
Adding New Modules¶
1. Create Source File¶
// src/core/my-module.ts
export interface MyModuleOptions {
timeout?: number;
}
export class MyModule {
constructor(private options: MyModuleOptions = {}) {}
public process(input: string): string {
// Implementation
return input.toUpperCase();
}
}
// Singleton helpers
let instance: MyModule | null = null;
export function getMyModule(options?: MyModuleOptions): MyModule {
if (!instance) {
instance = new MyModule(options);
}
return instance;
}
export function resetMyModule(): void {
instance = null;
}
2. Create Test File¶
// tests/unit/core/my-module.test.ts
import { MyModule, getMyModule, resetMyModule } from '../../../src/core/my-module';
describe('MyModule', () => {
let module: MyModule;
beforeEach(() => {
module = new MyModule();
});
describe('process()', () => {
test('should uppercase input', () => {
expect(module.process('hello')).toBe('HELLO');
});
test('should handle empty string', () => {
expect(module.process('')).toBe('');
});
});
describe('singleton', () => {
afterEach(() => {
resetMyModule();
});
test('getMyModule returns same instance', () => {
const a = getMyModule();
const b = getMyModule();
expect(a).toBe(b);
});
});
});
3. Export from Index¶
Test Helpers¶
Snapshot Factory¶
Use the snapshot factory for creating test data:
import {
createTestSnapshot,
createLoginPageSnapshot,
createAuthenticatedHomeSnapshot,
SnapshotBuilder
} from '../../helpers/snapshot-factory';
// Quick test snapshot
const snapshot = createTestSnapshot([
{ uid: 'btn1', role: 'button', name: 'Click Me', level: 1 }
]);
// Custom builder
const custom = new SnapshotBuilder()
.withUrl('https://test.example.com')
.withTitle('Test Page')
.addElement({ uid: 'el1', role: 'textbox', name: 'Email', level: 1 })
.addElement({ uid: 'el2', role: 'button', name: 'Submit', level: 1 })
.build();
Selector Validator¶
Use the selector validator for CSS testing:
import {
validateCssSelector,
validateHrefPathSelector,
calculateSpecificity
} from '../../helpers/selector-validator';
test('selector is valid', () => {
const result = validateCssSelector('.btn-primary');
expect(result.isValid).toBe(true);
});
Documentation¶
Adding Documentation¶
- Create markdown file in
docs/ - Update
mkdocs.ymlnavigation - Test locally with
mkdocs serve
Documentation Standards¶
- Use clear, concise language
- Include code examples
- Add mermaid diagrams where helpful
- Link to related pages
Pull Request Guidelines¶
PR Title Format¶
Use conventional commits:
feat:New featurefix:Bug fixdocs:Documentationtest:Testsrefactor:Code refactoringchore:Maintenance
PR Checklist¶
- [ ] Tests pass (
npm run qa) - [ ] Code coverage maintained
- [ ] Documentation updated
- [ ] Commit messages follow convention
- [ ] Branch is up to date with main
Review Process¶
- Automated checks must pass
- At least one approval required
- Address review comments
- Squash and merge
Common Tasks¶
Adding a New Handler¶
- Create handler in
src/handlers/ - Add tests in
tests/unit/handlers/ - Export from
src/handlers/index.ts - Document in
docs/reference/api.md
Adding a New Registry¶
- Create registry in
src/registry/ - Load data from
skills/xc-console/ - Add tests in
tests/unit/registry/ - Document in
docs/metadata/
Adding a New Workflow¶
- Create workflow in
skills/xc-console/workflows/ - Add test in
tests/unit/workflows/ - Document in
docs/features/workflows.md
Troubleshooting¶
Tests Fail Locally¶
TypeScript Errors¶
Coverage Drops¶
Getting Help¶
- Issues: GitHub Issues
- Discussions: GitHub Discussions
License¶
By contributing, you agree that your contributions will be licensed under the MIT License.