Fox Testing
Fox Testing checks your Fiscal Ox components for common mistakes before they go live. It looks at each component's .html and .js files, tells you what is wrong and on which line, and writes an easy-to-read testing report you can share with your team.
It can also use Groq AI to take a deeper look at a component and catch problems that simple checks can't, such as user input that isn't escaped or a modal that isn't cleared before it opens again.
Before you start
Fox Testing switches on when you open a folder named Fiscal Ox (or a folder that contains it). That folder needs a components folder, and each component needs an .html file and a .js file with the same name as its folder.
If you open any other folder, the commands still show up, but they tell you why they can't run.
AI features need a Groq API key. Everything else works without one.
Commands
Open the Command Palette with Cmd + Shift + P (Windows/Linux: Ctrl + Shift + P) and type Fox Testing to see all commands.
Testing
| Command |
What it does |
| Fox Testing: Test Components |
The main command. Asks what you want to test (All Components, Particular Component or Particular File), lets you pick it, runs the tests and saves the testing report. |
| Fox Testing: Run All Tests |
Tests every component in the open Fiscal Ox folder and shows the results in the Testing view and the Problems panel. No report file is written. |
| Fox Testing: Test Current Component |
Tests the component whose file is open in the editor. You'll also find it as a ▶ button at the top of the editor. |
| Fox Testing: AI Review Current Component |
Tests the open component and also asks Groq AI to review its code. AI results are marked so you can tell them apart. |
| Fox Testing: Clear Test Results |
Clears all results from the Testing view and the Problems panel. |
Reports
| Command |
What it does |
| Fox Testing: Show Test Report |
Opens a dashboard with the latest results: pass/fail per component, the most common issues and every finding. |
| Fox Testing: Export Test Report |
Saves the latest results as an HTML, JSON or Markdown file. |
Groq AI
| Command |
What it does |
| Fox Testing: Set Groq API Key |
Saves your Groq API key securely on your machine. Run it again any time to replace the key with a new one. |
| Fox Testing: Remove Stored Groq API Key |
Deletes the saved key. AI features stop working until you set a key again. |
| Fox Testing: Show AI Usage |
Shows how many AI tokens and requests you've used today, and how much of your daily limit is left. |
| Fox Testing: Clear AI Cache |
Forgets saved AI answers so the next AI review asks Groq again. Useful if you want fresh results for code that hasn't changed. |
- In the Explorer: right-click the
components folder, a component folder or a component file and choose Test Components.
- In the editor: right-click inside a component file to find Test Components, Test Current Component and AI Review Current Component.
Testing your components
Run Fox Testing: Test Components.
Choose what to test:
- All Components: pick the
components folder or the Fiscal Ox folder.
- Particular Component: pick one component folder.
- Particular File: pick one
.html or .js file of a component.
You can pick a Fiscal Ox folder anywhere on your computer, not only the one you have open.
A Testing... message shows the progress. You can cancel it at any time.
When it's done, you'll see Testing completed. Testing report generated successfully. Click Open Report to read it.
The testing report
The report is saved as Fox Testing Report.md in the Fiscal Ox folder. It's replaced every time you run a new test.
What's inside:
- Result: passed or failed, and how many components need fixing
- Summary: a short explanation of the result and what to fix first
- Issue Status: how many issues there are of each type
- Top Issues: the most serious and most common problems
- Component Results: one line per component with its result
- Issues by Component: each issue with the file and line number
- Issue Guide: why each issue matters and how to fix it
Every issue gets one of three labels:
| Label |
Meaning |
| 🔴 Critical |
Must be fixed before release. |
| 🟠 Needs Improvement |
Should be fixed. It affects reliability, consistency or how easy the code is to maintain. |
| 🔵 Good Practice |
A recommendation. Low risk, but worth doing. |
A component fails if it has at least one critical issue.
When you test a single component or file, Groq AI also reviews the code and adds anything extra it finds, marked (AI review). When you test all components, this deeper review is skipped so you don't use up your daily AI limit. If you haven't set a Groq key, you still get the full report, just without the AI-written summary.
Other helpful features
- Problems panel: every issue is listed with its file and line. Click one to jump straight to it.
- Quick fixes: for simple issues, click the 💡 light bulb to fix them in one click. For example: add
type="button" to a button, hide a create panel on load, remove a console.log, or delete commented-out code.
- Explain with AI: from the 💡 menu you can ask AI to explain any issue and suggest a fix.
- Turn a check off: if a check doesn't fit your project, you can turn it off from the 💡 menu.
- Testing view: every component is listed with one test per check area, so you can see at a glance what passes and what doesn't.
- Test on save: when you save a component file, it's re-tested automatically. This never uses AI.
Hiding issues in your code
By default, Fox Testing marks problems right in your code: underlines, red error boxes and grey INFO / WARNING notes at the end of lines, entries in the Problems panel and 💡 suggestions. If you'd rather keep your editor clean, turn this off:
- Open Settings (Cmd + , on macOS, Ctrl + , on Windows/Linux).
- Search for Fox Testing: Show In Editor.
- Untick the box.
Everything Fox Testing shows inside your code disappears right away, and nothing new is added while the setting is off. Testing, the pass/fail results in the Testing view and the testing report keep working as normal. Tick the box again to bring everything back.
What gets checked
Fox Testing runs 98 checks, grouped into 15 component checks (C01–C15) and 5 code review areas (R1–R5).
- Critical (
error) issues fail the test.
- Needs Improvement (
warning) and Good Practice (info) issues are reported but don't fail it, unless you change the failOn setting.
C01 · Component structure & page registration
| Check |
Level |
What it looks for |
fox/component-files |
error |
Folder name and both file names are identical |
fox/folder-name-case |
warning |
Folder name is lowerCamelCase |
fox/no-version-suffix |
warning |
No numbered copies of a component |
fox/purpose-prefix |
info |
Name uses an established purpose prefix |
fox/no-inline-script |
error |
Behaviour lives in the .js file, not a <script> block |
fox/no-inline-handlers |
warning |
No inline event-handler attributes |
fox/page-registration |
warning |
Component is registered in a page definition |
C02 · Panel layout & identifiers
| Check |
Level |
What it looks for |
fox/panel-root-class |
error |
Root element carries aasaanPanel |
fox/panel-root-wrapper |
warning |
Standard root wrapper and ibox structure |
fox/panel-id |
warning |
Panel uses a standard identifier |
fox/panel-hidden-on-load |
error |
Create and edit panels ship hidden |
fox/list-visible-on-load |
info |
List panel is visible on load |
fox/fixed-pixel-width |
info |
No fixed pixel widths for layout |
fox/duplicate-element-id |
error |
Element ids are unique within the component |
C03 · Panel headings & action buttons
| Check |
Level |
What it looks for |
fox/panel-heading |
warning |
ibox-title holds one Title Case <h5> |
fox/button-classes |
warning |
Button carries btn and a standard colour variant |
fox/button-size |
warning |
Panel header buttons use btn-sm |
fox/button-type |
error |
Every <button> sets type="button" |
fox/button-label-icon |
warning |
Buttons carry an icon and a text label |
fox/button-purpose-class |
warning |
Buttons carry a <context><Action>Btn purpose class |
fox/button-colour-meaning |
warning |
Button colour matches the meaning of the action |
fox/button-order |
warning |
Buttons ordered destructive → secondary → committing |
C04 · Form fields & labels
| Check |
Level |
What it looks for |
fox/input-form-control |
warning |
Controls carry the form-control class |
fox/input-name |
warning |
Controls have a lowerCamelCase name matching the data object field |
fox/input-purpose-class |
warning |
Controls carry a <panel><Entity>Input purpose class |
fox/label-for |
warning |
Labels are paired with their control by for/id |
fox/label-title-case |
info |
Labels and column headings are Title Case |
C05 · select2 & date handling
| Check |
Level |
What it looks for |
fox/select2-class |
warning |
Dropdowns use select2 |
fox/optional-select-first-option |
info |
Optional dropdowns start with --none-- or All |
fox/date-field-datepicker |
warning |
Date fields use the datepicker class |
fox/select2-reinit |
warning |
select2 re-initialised after options are appended |
fox/manual-date-format |
info |
Dates converted through JSUTIL, not hand-written string operations |
C06 · List tables
| Check |
Level |
What it looks for |
fox/table-responsive |
warning |
Tables are wrapped in table-responsive |
fox/table-markup |
warning |
List table ships headings and an identified empty body |
fox/table-rows-single-append |
error |
Rows are built in one string and appended once |
fox/reinitialize-datatable |
warning |
JSUTIL.reinitializeDataTable() follows a table rebuild |
fox/delegated-row-events |
error |
Row events are delegated, not re-bound after each render |
C07 · Status indicators
| Check |
Level |
What it looks for |
fox/status-label-colour |
warning |
Status labels use the standard colour mapping |
fox/status-as-label |
warning |
Status shown as a theme label, not coloured text |
C08 · Modals
| Check |
Level |
What it looks for |
fox/modal-name |
warning |
Modal id is lowerCamelCase and ends in Modal |
fox/modal-structure |
error |
Modal has header, body and footer |
fox/modal-title |
warning |
Modal header carries one Title Case h4.modal-title |
fox/modal-size |
info |
Modal width is modal-md unless it holds a table or preview |
fox/modal-attributes |
info |
Modal root carries the standard attributes |
fox/modal-error-panel |
warning |
Modal with inputs has a hidden inline error panel |
fox/modal-footer-buttons |
warning |
Footer has a dismiss action and an identified committing action |
fox/modal-fields-full-width |
info |
Fields in a medium modal use col-sm-12 |
fox/modal-open-from-script |
error |
Modals are opened from script, never with data-toggle |
fox/modal-reset-on-open |
info |
Modal is reset every time it is opened |
C09 · User dialogs & server failure handling
| Check |
Level |
What it looks for |
fox/no-browser-dialogs |
error |
No alert(), confirm() or prompt() |
fox/error-message-quality |
warning |
Error modals carry an actionable sentence, not raw server output |
fox/server-call-failure-branch |
warning |
Every server call handles its failure branch |
fox/success-modal-usage |
info |
Success modal only after a commit whose result is not already visible |
C10 · Irreversible actions & delete confirmation
| Check |
Level |
What it looks for |
fox/delete-confirm-dispatcher |
error |
Delete confirmation is bound once through a single dispatcher |
fox/irreversible-needs-confirm |
warning |
Irreversible actions are confirmed first |
C11 · Icons
| Check |
Level |
What it looks for |
fox/icon-syntax-mixed |
error |
One Font Awesome syntax per component file |
fox/icon-set |
warning |
Icons come from Font Awesome only |
fox/standard-action-icon |
info |
The same icon is used for the same action everywhere |
C12 · CSS, colour & inline styles
| Check |
Level |
What it looks for |
fox/single-style-block |
error |
Custom CSS lives in one <style> block at the top of the HTML |
fox/no-global-theme-restyle |
error |
No global theme class or element is restyled |
fox/no-raw-colours |
warning |
Colours come from :root tokens, not raw values |
fox/no-gradients |
warning |
No decorative gradients |
fox/standard-tokens |
info |
:root uses the standard token names |
fox/inline-style-typography |
warning |
No inline colour, typography, borders or shadows |
fox/inline-visibility |
info |
Inline display:none only on panels, modals and error panels |
fox/css-in-js |
warning |
No styling from the .js file |
C13 · JavaScript conventions
| Check |
Level |
What it looks for |
fox/handlers-in-document-ready |
warning |
Handlers and plug-ins are wired inside $(document).ready |
fox/raw-ajax |
error |
Server calls go through JSUTIL, never raw $.ajax or fetch |
fox/endpoint-via-geturl |
warning |
Endpoint paths are built with JSUTIL.getUrl |
fox/encode-query-values |
warning |
Query-string values pass through encodeURIComponent |
fox/named-callbacks |
warning |
Server calls use named callbackAfter…/callbackSuccess… handlers |
fox/escape-user-input |
warning |
User input is escaped before it is inserted as HTML |
fox/no-console |
error |
No diagnostic console.log statements |
fox/generic-global-names |
warning |
Top-level names are specific to the record they hold |
fox/page-global-collision |
error |
No top-level name collides with another component on the same page |
fox/location-reload |
info |
Refresh the affected panel instead of reloading the page |
C14 · Third-party libraries
| Check |
Level |
What it looks for |
fox/no-duplicate-core-library |
error |
jQuery, Bootstrap, Font Awesome, select2 and DataTables are not re-included |
fox/cdn-https-pinned |
error |
CDN references use https and an exact version |
fox/library-approval |
info |
External libraries prefer the local theme path and need approval |
C15 · Verified on page at desktop & tablet width
This one can't be automated, so it always shows as skipped. Open the component on its page and check it at desktop and tablet width yourself.
R1 · Correctness & safety
| Check |
Level |
What it looks for |
review/js-syntax-error |
error |
JavaScript parses without syntax errors |
review/response-null-safety |
warning |
API responses are validated before their fields are read |
review/array-index-unchecked |
info |
Array results are checked for emptiness before indexing |
review/required-fields-validated |
warning |
Mandatory fields are validated before submission |
R2 · Performance
| Check |
Level |
What it looks for |
review/api-in-loop |
warning |
No API calls inside loops |
review/repeated-api-call |
info |
The same data is not fetched repeatedly |
review/unpaginated-list |
info |
Lists that can grow large are paginated |
R3 · Structure & maintainability
| Check |
Level |
What it looks for |
review/duplicate-code |
warning |
No copy-pasted blocks within a file |
review/shared-function-duplicate |
warning |
No function copied between components |
review/one-handler-per-element |
error |
One click handler per element |
review/rebind-in-handler |
warning |
Handlers are not re-bound every time another event fires |
review/panel-modal-separate |
warning |
Panels and modals are separate components |
review/naming |
info |
Names reveal intent and follow casing conventions |
review/long-function |
info |
Functions stay small and focused |
review/deep-nesting |
info |
Callbacks are not nested too deeply |
R4 · UI / UX consistency
| Check |
Level |
What it looks for |
review/empty-state |
info |
Lists render an empty state |
R5 · General reviewer checks
| Check |
Level |
What it looks for |
review/commented-out-code |
warning |
No commented-out code |
review/hardcoded-secret |
error |
No secrets or credentials in code |
review/todo-comments |
info |
Open TODO/FIXME notes are resolved or ticketed |
AI checks
When AI review runs, it also looks for:
- Missing null checks on server responses
- Required fields that aren't validated before saving
- The same data being requested more than once
- A panel shown without hiding the other panels
- A modal that isn't reset, or a success message shown while a modal is still open
- Approve, reject or sign actions that skip the e-signature step
- User input added to the page without escaping
- Pending ids that aren't cleared after a confirmed action
- Logic bugs, or handlers that do unrelated things
- Missing loading, empty or error states
AI findings are suggestions. They can be Needs Improvement at most, so AI alone will never fail a component.
Groq AI
Setting up your key
- Create a free API key at console.groq.com.
- Run Fox Testing: Set Groq API Key and paste it in.
Your key is stored in your computer's secure storage (Keychain on macOS, Credential Manager on Windows). It's only ever sent to Groq, and it never shows up in logs.
If you prefer, you can set a GROQ_API_KEY environment variable instead.
Staying within the free plan
Fox Testing is built to work on Groq's free plan:
- It keeps track of how much you use per minute and per day, and slows down before you hit Groq's limits.
- It sends only the relevant parts of large files, not the whole file.
- It remembers answers for code that hasn't changed, so re-testing the same component costs nothing.
- If the main AI model runs out of quota for the day, it switches to a backup model automatically.
Run Fox Testing: Show AI Usage to see where you stand.
The default models are openai/gpt-oss-120b, with openai/gpt-oss-20b as the backup. Groq sometimes retires models. If that happens, Fox Testing will let you know, and you can pick another one from Groq's model list in the settings.
Settings
Search for Fox Testing in VS Code settings.
| Setting |
Default |
What it does |
fiscalOxTesting.failOn |
error |
When a component counts as failed. error fails only on critical issues. warning also fails on Needs Improvement issues. |
fiscalOxTesting.runOnSave |
true |
Re-test a component when you save one of its files. |
fiscalOxTesting.showInEditor |
true |
Show issues inside your code: underlines, inline error and warning messages, Problems panel entries and 💡 quick fixes. Turn off for a clean editor. |
fiscalOxTesting.showInfoFindings |
true |
Show Good Practice suggestions in the editor and Problems panel. |
fiscalOxTesting.exclude |
[] |
Component folders to skip. |
fiscalOxTesting.rules |
{} |
Change the level of any check, or turn it off. For example: { "fox/label-for": "error", "review/naming": "off" } |
fiscalOxTesting.maxFindingsPerRule |
25 |
How many times one check can report in a single file before the rest are grouped together. |
fiscalOxTesting.ai.enabled |
true |
Turn AI features on or off. |
fiscalOxTesting.ai.model |
openai/gpt-oss-120b |
Main Groq model. |
fiscalOxTesting.ai.fallbackModel |
openai/gpt-oss-20b |
Backup model when the main one runs out of quota. Leave empty for no backup. |
fiscalOxTesting.ai.maxComponentsPerRun |
10 |
Most components sent to AI in one run. |
fiscalOxTesting.ai.maxInputTokens |
3000 |
How much code is sent in one AI request. |
fiscalOxTesting.ai.maxOutputTokens |
700 |
Longest answer the AI can give per request. |
fiscalOxTesting.ai.requestsPerMinute |
25 |
Most AI requests per minute. |
fiscalOxTesting.ai.tokensPerMinute |
10000 |
Most AI tokens per minute. |
fiscalOxTesting.ai.dailyTokenBudget |
90000 |
Most AI tokens per day. |
fiscalOxTesting.ai.dailyRequestBudget |
900 |
Most AI requests per day. |
fiscalOxTesting.ai.cacheTtlDays |
14 |
How many days AI answers are remembered for unchanged code. 0 turns this off. |
Sharing settings with your team
To make sure everyone on the team uses the same settings, add a .fiscalox-testing.json file to the root of the Fiscal Ox folder:
{
"failOn": "error",
"exclude": ["mathJS"],
"maxFindingsPerRule": 25,
"rules": {
"fox/label-for": "error",
"review/naming": "off"
}
}
Your own VS Code settings are applied on top of this file.
Requirements
- VS Code 1.85 or later
- A Groq API key (only for AI features)