Prerequisites
Before testing, ensure you have:- The
parser_clibinary built (see installation instructions) - A raw transaction hex from your DApp or protocol
- The expected output you want to verify
Quick testing workflow
1. Parse your transaction
Run the parser CLI with your transaction:2. Verify the output
Check that the visualization:- Shows the correct action (swap, transfer, approval, etc.)
- Displays accurate amounts and addresses
- Uses appropriate labels that users will understand
3. Test the condensed view
Hardware wallets have limited screen space. Verify your visualization works in condensed mode:4. Check JSON output
For programmatic validation, use JSON output:jq:
Common issues
Transaction fails to parse
Cause: Incorrect chain type or malformed hex encoding. Solution: Verify the chain flag matches your transaction and that the hex is properly formatted (with or without0x prefix, depending on chain conventions).
Missing protocol details
Cause: The parser does not recognize your contract or protocol. Solution: You may need to add a protocol-specific preset. See Creating Visualizations for patterns.Output too verbose for hardware wallets
Cause: The condensed view includes too many fields. Solution: Review your visualization’sCondensed section in the PreviewLayout and reduce it to only the essential fields.
Amounts display incorrectly
Cause: Decimal handling or token metadata issues. Solution: Verify that token decimals are correctly applied. Use theamount_v2 field type with proper Amount and Abbreviation values.
Adding test fixtures
When your visualization is working, add a test fixture to ensure it does not regress.1. Save your transaction
Create a fixture file in the appropriate chain directory:my_protocol_swap.input.
2. Add expected output
Create a corresponding expected output file with the same name but.expected extension. This captures the correct JSON output for comparison.
3. Write a test
Add a test that compares the parser output against your expected fixture:4. Run tests
Verify your fixture passes:Property-based testing (Solana)
Solana IDL parsing includes proptest-based fuzz tests that verify crash safety and correctness across randomly generated IDLs and instruction data. These tests live in:src/chain_parsers/visualsign-solana/tests/fuzz_idl_parsing.rs— parser-level fuzz and roundtrip testssrc/chain_parsers/visualsign-solana/tests/pipeline_integration.rs— full-pipeline integration testssrc/chain_parsers/visualsign-solana/tests/semantic_pipeline.rs— deterministic tests with real embedded IDLssrc/chain_parsers/visualsign-solana/tests/common/mod.rs— shared test helpers
Running proptest tests
Running cargo fuzz targets (libFuzzer)
Thefuzz/ directory contains libFuzzer targets that feed arbitrary bytes into the full visualsign-solana stack. These require a nightly toolchain and cargo-fuzz:
When a crash is found, libFuzzer writes a reproducer to
artifacts/. Reproduce it with:
Testing against real IDLs
Thescripts/fuzz_all_idls.sh script runs fuzz tests against all embedded production IDLs in one pass:
Roundtrip tests
A roundtrip test constructs an IDL and matching borsh-encoded instruction bytes, feeds them through the parser, and verifies the output matches expectations. “Roundtrip” refers to the encode-then-decode cycle: you know exactly what went in, so you can assert exactly what comes out. There are two kinds in use:-
Concrete roundtrips (e.g.,
roundtrip_single_u64_arg) — Hand-crafted IDL JSON and hand-crafted byte payloads. These assert that specific parsed values match exactly (e.g.,amount == 42). They serve as specification-by-example: each test documents one type scenario (no args, mixed primitives,Option<T>,Vec<T>, defined structs, multi-instruction dispatch). -
Property-based roundtrips (e.g.,
fuzz_valid_data_always_parses_ok) — Randomly generated IDL shapes paired with machine-generated valid borsh bytes fromarb_valid_instruction_bytes. These assert that parsing succeeds and the instruction name matches, without checking specific field values. They verify the parser’s contract holds across all type combinations, not just the hand-picked examples.
Adding a new test
- Write a strategy that generates the IDL shape you want to test (or use an existing one from
solana_parser_fuzz_core::proptest) - Add a
proptest!test that exercises the parser with generated inputs - Add a concrete roundtrip test for the same scenario to serve as specification-by-example
- Run the tests — if proptest finds a failure, it saves a regression seed to
.proptest-regressions - Commit the
.proptest-regressionsfile so the failing case is reproduced in CI
CI workflows
Tests are triggered by adding labels to a PR:test: labels gate test runs; ci: labels gate the build/image pipeline.
When a run fails, the workflow adds an outcome label to the PR: test:fuzz-failure if a fuzz target crashes, test:proptest-failure if a proptest fails, and test:surfpool-failure if a surfpool run fails. These labels are removed automatically on a clean run.
End-to-end format chain with test coverage
This traces every data format transformation from wallet input to visual output, annotated with which testing methodology covers each stage.Annotation legend
Format summary
Validation checklist
Before submitting your visualization:- Parses correctly with
--output human - Condensed view shows critical information only
- Amounts and addresses are accurate
- Labels are clear to non-technical users
- Test fixture added and passing
Related documentation
- Parser CLI Development - Full CLI reference and examples
- Creating Visualizations - Design patterns for visualizations
- Field Types Reference - Available field types and their usage