Purpose — Build, test, verify, and navigate the codebase for Edit Cookie Malaccamax (v0.2.0).
This handbook describes how to set up the environment, produce a loadable Chromium extension, run tests, and follow project conventions.
Project facts
| Item | Value |
|---|---|
| Version | 0.1.6 |
| Rust edition | 2024 |
| Extension output | dist/chromium/ (load this folder in Chrome) |
| Framework | Oxichrome 0.2, Leptos 0.8 (CSR), wasm-bindgen 0.2 |
| Font Awesome | 6.4.0, bundled locally (no CDN) |
| Theme modes | Light and Dark only (no System / follow-OS option) |
# From the repository root (example path)
cd E:\Github\EditCookieMalaccamax
# Recommended: full automated verification (release build + checks)
.\scripts\Verify-Build.ps1 -Release
# Standard release build (wraps Oxichrome and copies assets — do not use plain cargo --release alone)
.\scripts\Build-Extension.ps1 -Release
# Unit tests
cargo test
# Lint (warnings denied)
cargo clippy --target wasm32-unknown-unknown -- -D warnings
# E2E (Playwright, 14 tests in tests/extension.spec.js)
npx playwright test
Load in Chrome
chrome://extensions/dist/chromium/ (not dist/ alone)| Tool | Purpose | Notes |
|---|---|---|
| Rust (2024 edition) | Compile the extension | Use rustup; match project toolchain if pinned |
wasm32-unknown-unknown |
WASM target | rustup target add wasm32-unknown-unknown |
| Oxichrome CLI | Extension build | cargo install oxichrome (invoked as cargo oxichrome …) |
| Node.js | Playwright E2E | For npx playwright test |
| Git | Version control | — |
rustc --version
rustup target list --installed
cargo oxichrome --version
Core crates used in the extension: oxichrome, leptos, wasm-bindgen, wasm-bindgen-futures, serde, serde_json, serde-wasm-bindgen, web-sys, js-sys. There is no chrono dependency.
The extension uses: tabs, cookies, contextMenus, storage, clipboardWrite. It does not use unlimitedStorage.
Use the project script so Oxichrome output is post-processed (Font Awesome, webfonts, DevTools HTML/JS):
# Release (typical for manual testing and packing)
.\scripts\Build-Extension.ps1 -Release
This runs cargo oxichrome build --release, then copies from public/ into dist/chromium/:
css/fontawesome.min.css)dist)Do not rely on cargo build --release alone for a complete, loadable extension; the script is the supported build entry point.
dist/chromium/)dist/chromium/
├── manifest.json
├── background.js
├── popup.html + popup.js
├── options.html + options.js
├── css/
│ ├── popup.css
│ ├── options.css
│ ├── devtools.css
│ └── fontawesome.min.css
├── webfonts/ # Font Awesome files
├── icons/
├── devtools/ # DevTools HTML (e.g. panel)
├── js/ # DevTools page loader
└── wasm/
├── edit_cookie_malaccamax_bg.wasm
└── edit_cookie_malaccamax.js
.\scripts\Verify-Build.ps1 -Release # full verification
.\scripts\Verify-Build.ps1 -SkipTests # build checks, skip tests
.\scripts\Verify-Build.ps1 -Verbose
The verify script checks toolchain, formatting, tests, build success, expected artifacts under dist/chromium/, and WASM sizes (see script for details).
| Symptom | What to do |
|---|---|
cargo / oxichrome not found |
Ensure ~\.cargo\bin is on PATH; install Oxichrome if needed |
| Missing WASM target | rustup target add wasm32-unknown-unknown |
| Extension loads but assets missing | Run .\scripts\Build-Extension.ps1 -Release (not raw cargo build) |
| Locked files on Windows | Close Chrome tabs using the extension; remove dist/chromium if needed and rebuild |
cookie_monitor.rs).cargo test
cargo test test_name -- --nocapture
Relevant areas: src/core/cookie.rs, src/core/storage.rs, src/core/rules.rs, src/shared/helpers.rs, and other modules as tests are added.
npx playwright test
tests/extension.spec.jsAfter loading dist/chromium/:
.\scripts\Build-Extension.ps1 -Release succeedscargo test passescargo fmt appliedcargo clippy --target wasm32-unknown-unknown -- -D warnings passesdist/chromium/ — no extension errorsnpx playwright test passespublic/ → dist/chromium/chrome.cookies.set.unwrap() on DOM targets; use safe if let / pattern matchingKnown Issues: None currently.
src/)src/
├── lib.rs # Entry point, #[oxichrome::extension] macro
├── chrome_api.rs # wasm-bindgen bindings: cookies, tabs, storage, menus
├── background/
│ ├── mod.rs # Service worker init, re-exports
│ ├── cookie_monitor.rs # onChanged listener, RAII SuppressGuard, auto-restore
│ ├── context_menus.rs # Right-click menu
│ └── devtools.rs # DevTools registration
├── popup/
│ ├── mod.rs # Popup App + CookieListWithSearch
│ ├── cookie_list.rs # CookieRow, CookieDetails, actions, description editor
│ ├── cookie_editor.rs # Standalone editor form (reserved, not currently mounted)
│ └── search.rs # SearchBar component
├── options/
│ ├── mod.rs # Options page App
│ └── preferences.rs # PreferencesForm
├── core/
│ ├── mod.rs # Module exports
│ ├── cookie.rs # Cookie CRUD: get_all, get_all_for_url, set, remove
│ ├── storage.rs # PreferencesStorage, DataStorage, CustomDescriptions
│ └── rules.rs # Filter matching, is_read_only, maybe_shorten
├── shared/
│ ├── mod.rs # Module exports
│ ├── types.rs # Cookie, Preferences, Filter, ReadOnlyCookie, ExtensionStats
│ ├── helpers.rs # get_active_tab, get_current_tab_url, apply_theme, ensure_stylesheets
│ └── known_cookies.rs # Built-in cookie description dictionary (~100 entries)
└── devtools/
└── mod.rs # DevTools panel UI
chrome.storage.local)| Script | Role |
|---|---|
scripts/Build-Extension.ps1 |
Oxichrome build + post-build asset copy to dist/chromium/ |
scripts/Verify-Build.ps1 |
Automated build verification |
get_untracked() in async and long-lived closuresWhen a signal’s value is read inside a closure that is later run asynchronously (or where you must not create a stale reactive dependency), use get_untracked() instead of get().
// Avoid: .get() can tie the closure to reactive updates incorrectly for async work
// Prefer:
let value = signal.get_untracked();
let chainsEdition 2024 expects collapsed let-chains — avoid nested if let where the edition style guide prefers a single chained form. Match surrounding code and compiler hints.
Oxichrome emits minimal HTML without linked project CSS. ensure_stylesheets() (in shared/helpers.rs) injects the correct stylesheets at runtime so popup, options, and DevTools match the bundled dist/chromium/css/ layout.
chrome.cookies.setFor host-only cookies, omit the domain field in chrome.cookies.set when appropriate so Chrome does not create an extra domain-scoped cookie alongside the host-only one.
Bindings live in src/chrome_api.rs (wasm-bindgen to chrome.*).
cookiesgetAll, set, remove, onChangedsetcookie_monitor.rs uses a RAII SuppressGuard to avoid feedback loops while applying auto-restorestoragestorage.local for preferences and custom descriptionstabscontextMenusbackground/context_menus.rs)clipboardWrite as declared in the manifest| Problem | What to check |
|---|---|
| Blank popup or missing styles | Console errors; confirm ensure_stylesheets runs; rebuild with Build-Extension.ps1 |
Wrong or empty dist/ layout |
Load dist/chromium/; run the build script, not only cargo build |
| Clippy / WASM | Use --target wasm32-unknown-unknown as in the lint command above |
| Stale UI values in handlers | Replace .get() with .get_untracked() where the closure captures state for async work |
| Cookies doubling after set | Host-only vs domain cookies: omit domain when setting host-only cookies |
| Playwright failures | Extension path must point at built dist/chromium/; see Playwright config |
Preferences in src/shared/types.rs (and Default).src/options/preferences.rs and persistence via src/core/storage.rs as needed.src/popup/cookie_list.rs (or related popup modules).src/core/cookie.rs or chrome_api.rs as appropriate.Edit source styles under public/css/ (e.g. popup.css); rebuild with Build-Extension.ps1 so dist/chromium/css/ updates.
cookie_list.rs.CopyFormat (or equivalent) in src/shared/types.rs and expose in preferences if required.# After release build
Get-Item .\dist\chromium\wasm\edit_cookie_malaccamax_bg.wasm
# Optional: wasm-decompile or similar tools on that path
In the popup or options devtools console:
chrome.storage.local.get(null, console.log);
chrome://extensions/ → your extension → Reload → reopen popup / DevTools.
Last Updated: March 2026