Last updated: 2026-04-23
All notable changes to X-Proxy Chrome Extension will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Enhanced error handling and user feedback
- Performance optimizations
- Blog content creation for SEO
- Multi-language support (Chinese, Japanese, Russian)
- Keyboard navigation for the profile modal: Escape closes the modal; focus is restored to the triggering button on close; the first form field is auto-focused on open; Tab and Shift+Tab wrap inside the modal instead of leaking into the page behind it. Clears WCAG 2.1.2 "No Keyboard Trap" and aligns with the WAI-ARIA dialog pattern.
lib/icon-paths.js: pure helperresolveIconPaths(profileColor, mode)shared by the background worker and unit tests. Makes the three-way branch (profile / direct / system) testable without stubbingchrome.action.- E2E coverage pass to close long-standing blind spots:
e2e/modal-visual.spec.ts— 6 visual baselines (Add/Edit modal in light + dark, Options Profiles dark, Options About dark).e2e/migration.spec.ts— storage v1→v2 integration guard (non-destructive reads, first-write upgrade, Direct-mode distinct persistence).e2e/keyboard-nav.spec.ts— 6 tests driving the new keyboard behavior red→green.
- Regression guards (earlier in 1.6.1):
tests/update-icon.test.js— pins down the path resolver contract (8 assertions incl. the direct-vs-system distinctness rule).e2e/popup-visual-simplicity.spec.ts— asserts.status-dot/.action-checkare removed from the DOM and#addProfileBtntoggles with thestate-emptybody class.e2e/icon-differentiation.spec.ts— asserts Direct and System resolve to strictly differentchrome.action.setIconpaths via a newlastIconPaths/lastIconModefield onGET_STATE.e2e/popup-visual.spec.ts— screenshot baselines for empty / populated / direct-active / system-active / profile-active popup states.
npm run test:e2e:updatescript so regenerating baselines is discoverable.
- Popup active-mode signaling reduced from 4 simultaneous indicators to 2 (per sergeevabc's feedback on #28). Removed the animated
.status-dotin the top status chip and the right-edge.action-check✓ on each card. The active card still communicates selection via its blue gradient background and white-inherited icon — enough signal without the visual noise. - Visual regression tolerance tightened from
maxDiffPixelRatio: 0.05to0.01. The previous ~46k-pixel budget on a 1280×720 frame silently absorbed entire text changes like the About-panel version string, so baselines could drift several versions while CI kept passing. CONTRIBUTING.mdrewritten to match the actual project (plain JS + three-component Vite build, no React, no.tssource) and gains a three-tier Release Checklist so future version bumps can't missdocs/index.htmlJSON-LD, STORE_LISTING, or the hardcoded version assertion ine2e/options.spec.ts.
- Toolbar icon now distinguishes Direct from System mode (#28 tail). Previously both modes resolved to
icon-inactive-*.png(gray) so there was no way to tell at a glance whether the extension was actively bypassing proxies or deferring to the OS. Direct mode now renders a new green arrow icon family (icon-direct-{16,32,48,128}.png); System mode keeps the gray inactive icon it had before. - Popup empty-state no longer shows three redundant "add profile" entry points (#36). The header "+" button is hidden while the profile list is empty — the big "Add your first profile" CTA is the single obvious action. The header "+" returns once profiles exist.
- CSS-transition race in axe color-contrast scans.
emulateMedia({colorScheme:'dark'})flipped:rootcustom properties synchronously, buttransition: all var(--transition-base)interpolated element colors over ~250ms, so axe sampled mid-transition rgba values and reported spurious AA failures. Fixed by disabling CSS transitions before the media flip (e2e/a11y.spec.ts). - Stale version references across
options.htmlAbout panel,README.mdroadmap,docs/index.htmlJSON-LDsoftwareVersion(user-visible in Google search results),docs/STORE_LISTING.md,docs/SEO_GUIDE.md, and the hardcoded assertion ine2e/options.spec.ts. Caused by having no single source of truth for "where does the version string live"; the new Release Checklist Tier 1 table pins this down. - Nine stale visual baselines under
e2e/__screenshots__/visual.spec.ts/regenerated so screenshots match shipped UI.
- Thanks again to @sergeevabc for the detailed UX feedback on #28 and for filing #36. Your "count the signals" instinct was the right call.
- Direct Connection mode: new top-level mode that bypasses all proxies (including the OS-level / IE proxy that
Systemfalls back to). Surfaces as a dedicated button in the popup next toSystem. Closes a gap where users on Windows couldn't escape an IE-wide proxy without leaving the extension. (#28) - Storage schema v2: new top-level
mode: 'direct' | 'system' | 'profile'field inx-proxy-data. Automatic one-way v1 → v2 migration infersmodefrom existingactiveProfileId; stale ids are dropped safely. No user action required. - Regression guards: new Vitest suite for migration edge cases (
tests/mode-migration.test.js) and new Playwright spec for the Direct button (e2e/direct-mode.spec.ts).
- Toolbar icon color was delayed after profile activation. Activating a profile from the popup did not immediately repaint the toolbar icon; it stayed gray until the user interacted with the address bar. The real root cause was that the icon logic only painted the profile color when the current tab's URL started with
http(s)://— onchrome://newtab,about:blank, or any extension page it fell through to the inactive gray icon even with a profile active. Fixed by showing the profile color unconditionally when no per-domain routing rules are enabled (the simple case); per-tab indication is preserved for profiles that DO have routing rules since that's where it carries real information. The popup-window tab-query path was also hardened viachrome.windows.getLastFocused({windowTypes:['normal']})as a belt-and-braces improvement.
- Visual polish pass on the options page: added missing
--border-radius/--transitiondesign tokens (previously falling back to0, flattening inputs and killing hover transitions), added proper dark-mode support for the options page (previously hardcoded light), and aligned focus-ring and danger-hover colors with the iOS blue/red palette used throughout.
- Thanks to @sergeevabc for reporting issue #28.
- Performance: Removed
backdrop-filter: blur()from options modal, options header/sidebar, and popup header/footer. Fixes severe UI lag on low-end hardware without GPU acceleration (reported on Windows 7 without dedicated GPU, where switching between form fields in the Add Profile dialog could take several seconds). Modal overlay opacity bumped fromrgba(0,0,0,0.4)torgba(0,0,0,0.55)to preserve visual separation. (#27)
- Regression guard: New Playwright spec
e2e/no-blur.spec.tsassertsbackdrop-filter: noneon all five previously-blurred surfaces, so nobody can quietly reintroduce blur.
- Thanks to @sergeevabc for reporting issue #27.
- Dynamic toolbar icon colors — icon reflects the active profile's color (blue, green, red, orange, purple, teal, yellow, gray)
- Dark mode improvements — enhanced popup visuals with corrected CSS variables, better contrast and readability
- Security: Upgraded Vite to v6.4.2 (fixes GHSA-4w7w-66w2-5vf9, GHSA-p9ff-h696-f583)
- CI: Updated Node.js test matrix to 20/22, removed deprecated tsconfig
baseUrl
- Thanks to @Schleuse (René Schleusner) for contributing PR #21 (icon colors) and PR #22 (dark mode improvements)
- Custom PAC (Proxy Auto-Configuration) file support
- New
PAC (Auto-Config)proxy type alongside HTTP/HTTPS and SOCKS5 - Supports HTTP/HTTPS URLs (e.g.,
http://example.com/proxy.pac) - Supports local file paths (e.g.,
C:\data\proxy.pac,/etc/proxy.pac) - Supports
file://URLs directly - Automatic conversion of local file paths to
file://URLs
- New
- Options page UI updates
- PAC type option in proxy type dropdown
- Dedicated PAC URL input field (shown when PAC type selected)
- Host/port/auth/routing fields hidden for PAC profiles
- Import/Export: PAC profiles supported in JSON import/export
- Unit Tests: 28 new test cases for PAC URL conversion, normalization, and proxy config building (TDD)
- New test file:
tests/pac-url.test.js(18 tests) - Extended:
tests/pac.test.js(+8 tests),tests/normalize.test.js(+10 tests)
- New test file:
- Username/Password authentication for proxy servers
- Optional username and password fields in profile configuration
- Handled via
chrome.webRequest.onAuthRequired(Manifest V3) - Works with both HTTP/HTTPS and SOCKS5 proxy types
- Credentials stored locally, never transmitted externally
- New permissions:
webRequest,webRequestAuthProvider - Unit Tests: auth normalization tests + auth handler tests (TDD)
- Missing
modeproperty in routingRules normalizationnormalizeProfile()in options.js and popup.js did not includemodein fallback defaultsnormalizeProfileForSave()in options.js had the same issue- This caused PAC script generation to receive
mode: undefined, breaking domain-based routing - Users reported: "Proxy doesn't work by domains although such settings exist"
- Profile normalization tests (
tests/normalize.test.js)- Tests for routingRules fallback defaults including
modeproperty - Round-trip normalization tests (normalize → save → reload → normalize)
- Tests for both options.js and popup.js normalization functions
- Tests for routingRules fallback defaults including
- PAC script generation tests (
tests/pac.test.js)- Whitelist mode: whitelisted domains use proxy, others go direct
- Blacklist mode: blacklisted domains go direct, others use proxy
- Wildcard domain matching tests
- Proxy type formatting (HTTP vs SOCKS5)
- Mode fallback behavior when
modeis undefined
- Vitest configuration (
vitest.config.ts)- Configured vitest for running unit tests
- Updated npm scripts:
test,test:watch,test:coverage
- Updated npm test scripts to use vitest instead of placeholder echo commands
-
Export Profiles
- Export all proxy profiles as JSON file
- Clean export format with version metadata for forward compatibility
- Automatic filename with date:
x-proxy-profiles-YYYY-MM-DD.json
-
Import Profiles
- Import profiles from JSON export file
- Strict validation of file format and profile data
- Non-destructive append mode (existing profiles preserved)
- Partial import support with skip count for invalid profiles
- Graceful error handling with user-friendly messages
- Enhanced
isValidDomain()method- Added IPv4 address support (e.g.,
127.0.0.1,192.168.*,10.0.0.0/24) - Added IPv6 address support (e.g.,
::1,fe80::1) - Added simple hostname support (e.g.,
localhost) - Added single-level wildcard support (e.g.,
*.local) - Fixed: blacklist domains like
localhost,127.0.0.1can now be saved
- Added IPv4 address support (e.g.,
- Thanks to @jasonliaotw for reporting the issue and contributing the regex patterns
-
Routing Mode Selection
- Added radio buttons for whitelist/blacklist mode selection
- Whitelist mode: only listed domains use proxy (existing behavior)
- Blacklist mode: listed domains bypass proxy, all others use proxy
- Dynamic label and placeholder updates based on selected mode
-
User Interface Enhancements
- Clean radio button design with visual feedback
- Mode-specific placeholder text with example domains
- Help text for domain pattern syntax
- Profile color now displayed in Popup (matches Options page)
- Simplified "Add Profile" button text
-
PAC Script Generation
- Enhanced
generatePAC()to support both whitelist and blacklist modes - Blacklist mode reverses proxy logic (matched domains go direct)
- Maintains backward compatibility with existing whitelist-only profiles
- Enhanced
-
Data Model
- Extended
routingRuleswithmodeproperty ("whitelist" | "blacklist") - Default mode:
'whitelist'for backward compatibility - Profile duplication now copies routing mode
- Extended
- New helper method:
updateDomainListLabel() - CSS styling for radio button components
- Updated profile normalization to include
modeproperty
- Existing profiles without
modedefault to whitelist behavior - No migration required for existing configurations
-
Profile-Level Routing Rules
- Added domain whitelist configuration for each proxy profile
- Only specified domains use the proxy, all others go direct
- Supports wildcard patterns (e.g.,
*.google.com,*.youtube.com) - Toggle switch to enable/disable routing rules per profile
- Textarea input for domain list (one domain per line)
-
PAC Script Generation
- Automatic PAC (Proxy Auto-Configuration) script generation
- Uses
shExpMatch()for efficient wildcard domain matching - Seamless switching between PAC mode (with routing) and fixed_servers mode (all traffic)
-
User Interface
- Clean, intuitive routing rules section in profile editor
- Polished toggle switch with proper sizing and shadow effects
- Unified font styling across all input fields
- Domain validation with clear error messages
- Auto-clear domain list when routing toggle is disabled
- English-only UI for simplicity
-
User Experience Improvements
- Auto-reactivate when editing currently active profile (changes apply immediately)
- Copy routing rules when duplicating profiles
- Visual feedback with status messages (success/warning/error)
- Proxy Activation Logic
activateProxy()now detects routing rules and uses appropriate proxy mode- PAC mode when routing rules enabled, fixed_servers mode otherwise
- Maintains backward compatibility with existing profiles
- Improved data normalization for both old and new profile formats
- Extended profile data model with
config.routingRules: { enabled, domains } - Added domain validation helper (
isValidDomain()) - Normalized profile data handling across options and popup
- Updated Chrome proxy API usage to support both PAC and fixed_servers modes
- Existing profiles without routing rules work unchanged
- Default routing rules:
{ enabled: false, domains: [] } - All existing functionality preserved
-
Privacy Policy HTML Version
- Created SEO-optimized HTML version of privacy policy (
docs/PRIVACY_POLICY/index.html) - Added comprehensive meta tags (title, description, Open Graph, Twitter Card)
- Implemented consistent header/footer styling with main site
- Added breadcrumb navigation for improved UX and SEO
- Ensured mobile responsiveness and accessibility
- Created SEO-optimized HTML version of privacy policy (
-
Content Organization
- Preserved Markdown source as
policy.mdfor easy maintenance - Applied highlight boxes for key privacy statements
- Improved content hierarchy with proper heading structure
- Enhanced link accessibility with rel="noopener" for external links
- Preserved Markdown source as
-
SEO Benefits
- Independent meta tag control for search engines
- Unified design language across all GitHub Pages
- Better discoverability through optimized meta descriptions
- Improved user experience with consistent navigation
- Privacy Policy List Alignment
- Corrected list items alignment from center to left for better readability
- Updated
docs/PRIVACY_POLICY/index.htmlinline styles - Updated
docs/assets/css/style.cssfor consistent alignment
-
SEO Enhancements
- Added comprehensive Schema.org structured data (SoftwareApplication)
- Implemented FAQPage schema with 8 common questions
- Enhanced meta tags for better search engine visibility
- Added canonical URL and improved Open Graph tags
- Created sitemap.xml for search engine indexing
- Created robots.txt with crawler instructions
- Added preload directives for critical resources
-
UI/UX Improvements
- Unified button system with consistent styling across all CTAs
- Added SVG icons to primary action buttons (Install, GitHub, Donate)
- Improved button hover effects with smooth transitions
- Enhanced mobile responsive design for button layouts
- Implemented fade-in animation for better page load experience
-
Performance Optimizations
- Extracted inline CSS to external stylesheet (docs/assets/css/style.css)
- Implemented lazy loading support for images
- Added Intersection Observer for efficient scroll animations
- Optimized critical rendering path with minimal inline CSS
- Added support for reduced motion preferences
-
Content Additions
- Added comprehensive FAQ section targeting user search intent
- Improved keyword density and semantic content structure
- Enhanced accessibility with proper ARIA labels and semantic HTML
-
Documentation
- Created SEO_OPTIMIZATION_GUIDE.md with detailed implementation roadmap
- Documented button styling system and design patterns
- Added validation checklist and next steps guide
- GitHub Pages Website
- Restructured index.html with better SEO optimization
- Updated hero section buttons with unified design language
- Improved content hierarchy and heading structure
- Enhanced external link handling with rel="noopener"
-
New Files
docs/assets/css/style.css- Centralized stylesheetdocs/sitemap.xml- XML sitemap for search enginesdocs/robots.txt- Search engine crawler rulesdocs/SEO_OPTIMIZATION_GUIDE.md- Comprehensive SEO documentation
-
Modified Files
docs/index.html- Complete SEO and UI overhaul- Button classes:
.btn,.btn-primary,.btn-secondary,.btn-donate
- Target keywords: chrome proxy extension, proxy switcher, socks5 chrome
- Expected organic traffic: 100-200 visitors/month (3 months), 500-1000 visitors/month (6 months)
- Rich snippet opportunities via FAQ and Software Application schema
- PayPal donate button on GitHub Pages site in Hero section
- Consistent styling with existing button components
- Responsive design support for mobile devices
- Added
.btn-donateCSS class with PayPal brand colors (#0070ba) - Integrated existing PayPal link from extension popup
- Maintained design consistency across all buttons
- Simple and reliable proxy switching
- Support for HTTP/HTTPS and SOCKS5 proxies
- Basic profile management (create, edit, duplicate, delete)
- Clean, intuitive user interface
- Chrome Manifest V3 compliance
- TypeScript implementation with strict type checking
- Comprehensive test suite with 48+ test cases covering:
- Unit tests for proxy configurations
- Integration tests for Chrome API interactions
- End-to-end tests for complete user workflows
- Bug regression prevention tests
- Production build process with Vite
- Proper error handling and validation
- Real-time proxy status indication
- UI consistency issues (Edit buttons now use text instead of icons)
- Add Profile button styling (+ icon color matches text)
- Stale active profile reference cleanup
- RangeError handling for invalid date values
- Popup data synchronization improvements
- Removed deprecated PAC script functionality
- Simplified codebase to focus on core proxy switching
- Updated all documentation to reflect actual functionality
- Comprehensive test coverage for all implemented features
- Clean project structure with proper TypeScript configuration
- Major (X.0.0): Breaking changes, major feature additions, significant UI overhauls
- Minor (0.X.0): New features, significant improvements, non-breaking changes
- Patch (0.0.X): Bug fixes, small improvements, security patches
- Pull latest changes from main branch
- Run
npm installto update dependencies - Run
npm run buildto create new build - Test thoroughly before release
Found a bug or have a feature request? Please open an issue on our GitHub repository.
This project is licensed under the MIT License - see the LICENSE file for details.