A WebExtension that automates filling HTML tables and forms using CSV files, with intelligent column mapping and persistent configuration.
Current implementation status:
| Browser | Status | Notes |
|---|---|---|
| Firefox | Implemented | Active target with working manifest and packaging |
| Chrome | Pending | Scaffold prepared in manifests/chrome/PENDING.md |
| Edge | Pending | Scaffold prepared in manifests/edge/PENDING.md |
- CSV Import: Load CSV files directly from the browser
- AI Column Mapping (BYOK): Optional OpenAI-based mapping using your own API key
- Built-in Data Consent: Firefox
data_collection_permissionsdeclaration for transmitted website content - Row-by-Row Fill: Populate target table rows top-to-bottom using all CSV rows
- Persistent Configs: Save and reuse mapping configurations
- Date Transform Options: Auto or explicit output format (
dd.mm.yyyy,dd/mm/yyyy,yyyy-mm-dd) - Target Highlighting: Highlight selected destination table and mapped fields on the page
- Responsive Sidebar UI: Adaptive layout for narrow and wide sidebar widths
- Error/Warning Handling: Clear status messages for success, warning, and error outcomes
# Clone the repository
git clone https://github.com/sbonoc/firefox-addon-csv-to-table-filler.git
cd firefox-addon-csv-to-table-filler
# Install dependencies
npm install
# Run the extension (Firefox target)
npm start
# Or build for distribution
npm run build
# Optional: prepare browser target explicitly
npm run prepare:browser:firefox- Download a signed
.xpifile from releases - Open Firefox and go to
about:addons - Click "Install Add-on from File" and select the
.xpi
- Open a webpage with tables or forms you want to fill
- Click the extension icon in the browser toolbar
- Upload a CSV file from your computer
- Configure mapping: Select destination fields manually or run AI Auto-map
- Configure OpenAI API key in the sidebar
- Select date transform mode (optional)
- Click "Fill Table": The extension fills rows top-to-bottom
- Save mapping for future reuse
FirstName,LastName,Email,Department
John,Doe,john@example.com,Engineering
Jane,Smith,jane@example.com,Sales
Bob,Johnson,bob@example.com,MarketingThe project follows Clean Architecture with 3 implemented layers:
βββββββββββββββββββββββββββββββββββββββββββββ
β PRESENTATION LAYER (User Interface) β
β β’ Sidebar UI (src/presentation/sidebar/)β
β β’ Background script (lifecycle + action)β
β β’ Content script (page integration) β
ββββββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββββββ
β DOMAIN LAYER (Business Logic) β
β β’ csv-parser.js (CSV parsing) β
β β’ mapping.js (column mapping config) β
β β’ table-handler.js (field operations) β
ββββββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββββββ
β INFRASTRUCTURE LAYER (Technical Services)β
β β’ Config (centralized constants) β
β β’ Logger (structured logging) β
β β’ Errors (typed error hierarchy) β
β β’ Storage (browser.storage abstraction)β
β β’ MessageBus (utility event system) β
β β’ Container (dependency injection) β
ββββββββββββββββββββββββββββββββββββββββββββ
- Dependency Injection: Auto-injected services via IoC Container
- Event-Driven Messaging: WebExtensions message channels with sender/action validation
- Error Handling: Typed errors (CSVError, MappingError, etc)
- Logging: Structured context-aware logging
- Repository Pattern: StorageRepository abstracts browser.storage
- Test Pyramid (latest run): 84% unit, 7% integration, 9% E2E
src/
βββ infrastructure/ # Technical services (DI, logging, storage, etc)
β βββ config.js # Configuration & constants
β βββ logger.js # Structured logging system
β βββ errors.js # Error class hierarchy
β βββ storage.js # browser.storage abstraction
β βββ message-bus.js # Event system with middleware & priority
β βββ container.js # Dependency Injection / IoC Container
β βββ index.js # Barrel exports
β
βββ domain/ # Business logic & entities
β βββ csv-parser.js # CSV parsing and validation
β βββ mapping.js # Column mapping configuration
β βββ ai-mapping.js # OpenAI BYOK mapping adapter
β βββ table-handler.js # HTML form field extraction & filling
β
βββ presentation/ # User interface & messaging layer
βββ i18n.js # Lightweight translation dictionaries/helpers
βββ sidebar/ # Sidebar UI component
β βββ sidebar.html # Sidebar UI markup
β βββ sidebar.css # Sidebar styling
β βββ sidebar.js # Sidebar logic with service integration
βββ background.bootstrap.js # Background script entrypoint
βββ content-script.bootstrap.js # Content script entrypoint
tests/
βββ unit/ # Unit tests segregated by module
β βββ csv-parser.test.js
β βββ mapping.test.js
β βββ table-handler.test.js
β βββ infrastructure/
β βββ container.test.js
β βββ infrastructure.test.js
β βββ message-bus.test.js
β βββ storage.test.js
β
βββ integration/ # Integration tests for workflows
β βββ workflow.integration.test.js
β
βββ e2e/ # End-to-end tests with Playwright
β βββ addon.spec.js
β βββ accessibility.spec.js
β
βββ mocks/ # Mock objects for testing
β βββ browser.js # WebExtensions API mocks
β
βββ setup.js # Global test setup
.github/
βββ workflows/
βββ ci.yml # CI for pushes/PRs (master, develop)
βββ release.yml # Release on tag v* only when tag commit is on master
vitest.config.mjs # Unit & integration test configuration
playwright.config.js # E2E test configuration
manifest.json # Firefox extension manifest
manifests/
βββ firefox/
β βββ manifest.json # Active manifest target
βββ chrome/
β βββ PENDING.md # Pending work for Chrome support
βββ edge/
βββ PENDING.md # Pending work for Edge support
package.json # Dependencies and scripts
The project uses a Test Pyramid approach with clear separation:
- Unit Tests (84%): Tests in
tests/unit/covering individual functions with fast feedback - Integration Tests (7%): Tests in
tests/integration/covering module interactions and workflows - E2E Tests (9%): Tests in
tests/e2e/covering complete user journeys with Playwright + Firefox - Accessibility Test: Automated Axe Core scan focused on sidebar UI (
tests/e2e/accessibility.spec.js)
Current Test Inventory: 170 automated tests (142 unit, 12 integration, 16 E2E)
# Fast unit tests (recommended during development)
npm run test:unit
# Integration tests
npm run test:integration
# E2E tests with Playwright and Firefox
npm run test:e2e
# Accessibility test (Axe Core) for sidebar UI
npm run test:a11y
# Core automated suite with consolidated report
npm run test:all
# Watch mode for development
npm run test:watch
# Coverage report
npm run test:coverageCurrent targets:
- Lines: 80%
- Functions: 80%
- Branches: 75%
- Statements: 80%
npm start # Run extension (Firefox target)
npm run build # Build extension (Firefox target)
npm run sign:firefox # Sign with AMO API credentials (unlisted channel)
npm run lint # Lint extension (Firefox target)
npm run prepare:browser # Prepare default target (Firefox)
npm run prepare:browser:chrome # Validate pending Chrome target (expected to fail)
npm run prepare:browser:edge # Validate pending Edge target (expected to fail)
npm run test # Run Vitest suites (unit + integration)
npm run test:e2e # Run Playwright end-to-end tests
npm run test:a11y # Run Axe Core accessibility test for sidebar UI
npm run test:all # Run unit + integration + E2E + consolidated report
npm run test:watch # Watch modeThe codebase follows:
- Clean Architecture: Clear separation of concerns
- SOLID Principles: Single Responsibility, Open/Closed, etc.
- Dependency Injection: Services injected, not created
- Error Handling: Structured error hierarchy
- Logging: Centralized, context-aware logging
- Testing: Test-driven development approach
- Vitest: Unit testing framework
- Happy-DOM: DOM simulation for unit tests
- Playwright: E2E testing with Firefox
- Axe Core: Automated WCAG 2.1 accessibility checks for the sidebar UI
- WebExtensions API: Firefox add-on development
- ES6+ Modules: Modern JavaScript
User uploads CSV file
β
parseCSV() β parse & validate CSV content
β
validateCSVData() β check row counts, columns
β
User maps CSV columns to form fields
β
createMapping() β create mapping config
β
StorageRepository.saveMappingConfig() β save mapping
β
User clicks "Fill Table" button
β
browser.tabs.sendMessage('fillTable') β send mapped rows to content script
β
getTableFields() β detect target fields from first editable row
β
fillRowsByMapping() β fill table rows top-to-bottom
β
content script returns success/warning/error status
β
Form updated, user sees success message
The extension uses domain functions instead of service classes:
| Function | Module | Purpose |
|---|---|---|
parseCSV(content) |
csv-parser.js | Parse raw CSV text into headers & rows |
validateCSVData(data) |
csv-parser.js | Validate CSV against size/row/column limits |
createMapping(headers, config) |
mapping.js | Create validated mapping config |
suggestOpenAIMapping(params) |
ai-mapping.js | Suggest mapping with OpenAI using BYOK API key |
getTableFields(element) |
table-handler.js | Extract form fields from HTML |
fillFields(fields, rowData) |
table-handler.js | Fill form fields with data |
The extension communicates via WebExtensions messaging:
- Sidebar Layer: User uploads CSV, configures mapping, chooses table/date options
- Sidebar β Content:
browser.tabs.sendMessage()forgetTableInfo,highlightTargetTable, andfillTable - Content Layer: Validates request, resolves target table/row mapping, updates DOM
- Response: Content script returns
success|warning|errorwith message and counts - Sidebar Feedback: UI shows status and keeps mapping/table highlight in sync
- Mapping Persistence: Mapping is saved via
browser.storage.local(csvMappingkey)
Messages are validated and sanitized; unauthorized senders/actions are rejected.
- β Core fill workflow runs locally in your browser (CSV parsing, mapping UI, DOM filling)
β οΈ Optional AI Auto-map sends limited metadata to OpenAI only when explicitly triggered- β AI payload excludes CSV row values (headers + target field metadata only)
- β CSV data never persisted (mappings/settings only)
- β Respects browser storage limits
- β No tracking or analytics
- β Open source for transparency
The extension provides typed, actionable error messages:
| Error Type | When Thrown | Resolution |
|---|---|---|
CSVError |
Invalid CSV format, exceeds size/row/column limits | Check CSV file format and size |
MappingError |
Invalid column mapping configuration | Verify column indices and field names match |
TableNotFoundError |
Target table/form not found on page | Check page structure, ensure form exists |
StorageError |
Failed to save/load configuration | Check browser storage permissions |
TimeoutError |
Operation exceeded time limit | Reduce CSV size, check browser performance |
All errors include context logging for debugging and user-friendly messages in the UI.
Configuration is centralized in src/infrastructure/config.js:
CONFIG.STORAGE_KEYS = {
MAPPING: 'csvMapping',
CSV_HISTORY: 'csvHistory',
APP_SETTINGS: 'appSettings',
LAST_USED_TABLE: 'lastUsedTableIndex'
}
CONFIG.LIMITS = {
MAX_CSV_SIZE: 10 * 1024 * 1024, // 10MB
MAX_CSV_ROWS: 50000,
MAX_CSV_COLUMNS: 500
}
CONFIG.TIMEOUTS = {
CONTENT_SCRIPT_RESPONSE: 5000,
FILE_LOAD: 10000,
STORAGE_OPERATION: 3000
}Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Commit with clear messages (
git commit -m 'feat: add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request
- Write tests for all new features
- Follow the existing code style
- Keep commits focused and atomic
- Update documentation as needed
- Run
npm run testbefore submitting PR
- β Firefox 90+
- β³ Chrome/Edge (pending, not implemented yet)
- β Safari (not supported)
MIT License - see LICENSE file for details
The project includes automated GitHub Actions that:
- Runs on every push to
masteranddevelopbranches - Tests on Node.js 20.x
- Unit tests (84%): 142 tests for individual functions
- Integration tests (7%): 12 tests for module interactions
- E2E tests (9%): 16 tests for complete user workflows in real Firefox browser
After each Node 20.x workflow job run, GitHub Actions publishes a detailed test summary in GITHUB_STEP_SUMMARY:
| Type | Total | β Passed | β Failed | βοΈ Skipped | β±οΈ Duration |
|---|---|---|---|---|---|
| ποΈ Unit | 142 | 142 | 0 | 0 | ~0.12s |
| π¦ Integration | 12 | 12 | 0 | 0 | ~0.01s |
| π― E2E | 16 | 16 | 0 | 0 | ~12.87s |
- Pass/fail/skip statistics
- Execution time per test type
- Success rate and total duration
The .xpi is published to GitHub Releases only when all these conditions are true:
- Push event is a tag matching
v*(for examplev1.2.0) - The tagged commit belongs to
master - Release workflow passes lint + tests and signs the add-on in AMO (
unlistedchannel) - Repository secrets
AMO_JWT_ISSUERandAMO_JWT_SECRETare configured
Firefox only installs extensions signed by Mozilla. Configure AMO signing before releasing:
- In AMO Developer Hub, create API credentials (JWT issuer/key and JWT secret).
- In GitHub repository settings, add secrets:
AMO_JWT_ISSUERAMO_JWT_SECRET
- Create/push a tag (
v*) and let the release workflow sign and upload the resulting.xpi.
To release a new version:
# Ensure the target commit is on master first
git checkout master
git pull
# Create the release tag (semantic versioning: v1.1.0)
git tag v1.1.0
# Push the tag
git push origin v1.1.0This automatically:
- Validates that the tag commit is contained in
master - Runs full lint and test suite
- Submits the extension for AMO signing (
unlisted) and waits for the signed package - Creates a GitHub Release page
- Uploads signed
.xpifile for download
Before pushing, run tests locally:
# Unit tests only (fast feedback)
npm run test:unit
# Integration tests
npm run test:integration
# E2E tests (requires Playwright & Firefox)
npm run test:e2e
# Accessibility test for sidebar (Axe Core)
npm run test:a11y
# All tests with detailed report
npm run test:all
# Watch mode (re-run on file changes)
npm run test:watchCurrent version: 1.1.0
- Regular expression column matching
- Import mapping configurations from file
- Batch processing with progress bar
- Persist sidebar UI preferences (date format, selected table)
- Optional language selector in UI
- Multi-browser foundation (targeted manifests + target preparation script)
- Chrome implementation
- Edge implementation
None currently. Please report bugs via GitHub Issues.
- Check the issue tracker for common questions
- Review test files for usage examples
- Check error messages for troubleshooting
Please include:
- What you were trying to do
- What happened instead
- The CSV file (sanitized if sensitive)
- Browser console errors (F12 β Console tab)
- Extension logs (visible in devtools)
- Lines of Code: ~2,000 (core logic)
- Test Coverage: 80%+
- Testing: 170 automated tests (142 unit + 12 integration + 16 E2E)
- Documentation: Comprehensive inline comments
- Performance: < 500ms for typical operations
This project is a good example of:
- Clean Architecture in JavaScript
- Dependency Injection patterns
- Event-driven programming
- WebExtensions API usage
- Professional testing practices
- Error handling best practices
For questions or suggestions:
- Open a GitHub Issue
- Check existing discussions
- Review the inline code comments
Made with β€οΈ for automating tedious tasks
Last updated: February 2026