Testing Extensions — Validation, Smoke Tests, and Debugging
Comprehensive testing guide for Anisurge .asx extension packs — schema validation, deep link installation testing, playback smoke tests, update verification, and troubleshooting common issues.
Testing Extensions — Validation, Smoke Tests & Debugging
This guide covers everything from automated schema validation to manual smoke tests for verifying that an .asx extension pack installs correctly and produces working video streams.
Schema Validation
The official validate.mjs script checks all pack files for structural correctness:
node scripts/validate.mjsWhat It Checks
| Check | Description | Error Example |
|---|---|---|
| JSON syntax | All .asx files must be valid JSON | Unexpected token at line 3 |
schemaVersion | Must equal 1 | Expected schemaVersion 1, got 2 |
id format | Must match [a-z0-9-]+ | ID "My_Cool_Pack!" contains invalid characters |
versionCode | Must be a positive integer | versionCode must be a positive integer |
| Pipeline completeness | At least one step, must end with map.videos | Pipeline must end with map.videos step |
| Step field validation | Required fields present and correct type | http.get step missing required 'url' field |
| Unknown fields | No unrecognized top-level fields | Unknown field: 'pipeline.resolve.0.randomField' |
| Index consistency | Index entries match pack files | Pack 'anokoto' has version 1.0.1 but index says 1.0.0 |
Running Validation
# Validate all packs and index
node scripts/validate.mjs
# Regenerate index.json from packs (run after adding/modifying packs)
node scripts/generate-index.mjs
# Validate again after regenerating
node scripts/validate.mjsTesting Installation via Deep Link
On Android (Build ≥ 140)
-
Host the
.asxfile at an HTTPS URL (raw GitHub URLs work well:https://raw.githubusercontent.com/<user>/<repo>/main/extensions/<id>/<id>.asx) -
Generate the install deep link:
anisurgex://extensions/install?type=source&engine=ANISURGE&url=<URL>&name=<NAME>&version=<VERSION>- Open on device — tap the link or paste it into a browser address bar
- Confirm installation in the app dialog
- Check Extensions list — the pack should appear under installed sources
Install Confirmation Dialog
The app shows a dialog with:
- Pack name and version
- Engine type (
ANISURGE) - Download URL
- Icon (if
iconUrlprovided) - Confirm and Cancel buttons
On confirm, ExtensionManager.install() runs:
- Detects
.asxextension → callsinstallAsxPack() - Downloads the
.asxfile to a staging path - Parses and validates the file content via
AsxPackParser.parsePack() - Writes the validated pack to
{dataDir}/anisurge/{id}/extension.asx - Updates the installed sources list
Testing Repository Install
For repository-level testing:
anisurgex://extensions/install?type=repo&engine=ANISURGE&url=<INDEX_URL>&name=<REPO_NAME>The app adds the index URL as a repository, fetches the pack list, and shows available packs.
Playback Smoke Tests
After installation, verify the pack produces working streams:
Basic Playback Test
- Open any anime with a known AniList ID that maps to your source
- On the Watch screen, select your extension from the server selector
- If the pack declares
subDub: true, verify both language options - Tap play and observe:
- Video loads within 10 seconds
- Audio plays in sync with video
- Player controls respond (play/pause, seek, volume)
Additional Checks
| Test Case | Expected Result | How to Test |
|---|---|---|
| Valid AniList + episode | At least one video URL returned | Play any episode of a known anime |
| Dub when claimed | Dub track plays without errors | Toggle to Dub in server selector |
| Subtitles | Subtitles appear on screen | Enable subtitles in player if supported |
| Missing mapping | Clear error, no app crash | Try an AniList ID that doesn't exist in the source |
| Corrupt pack | Install rejected with error message | Modify the .asx to have invalid JSON, attempt install |
| Network error during fetch | Graceful fallback or timeout error | Disconnect network, attempt playback |
| Multiple episodes | Each episode resolves correctly | Play episode 1, then episode 12 |
| Intro/outro skip | Skip button appears at correct times | If pack provides intro/outro timestamps |
| Session resume | Playback resumes from last position | Start episode, seek to midpoint, close, reopen |
Update Testing
To verify the auto-update mechanism:
- Install the pack at versionCode 1
- Bump
versionCodeto 2 (andversionstring) in the.asxandindex.json - Regenerate index:
node scripts/generate-index.mjs - Push changes to the repository
- Refresh the app's Extensions list (pull down or tap Refresh)
- Verify: the pack shows an Update badge
- Tap Update: the app re-downloads and replaces the pack
- Verify: version displays as the new version
Troubleshooting
"Failed to install" Error
| Cause | Solution |
|---|---|
| Invalid JSON syntax | Run node scripts/validate.mjs to detect syntax errors |
schemaVersion ≠ 1 | Set "schemaVersion": 1 |
id contains invalid characters | Use only [a-z0-9-] characters |
versionCode missing or zero | Set a positive integer (start at 1) |
Pipeline missing map.videos | Add { "step": "map.videos", "file": "...", ... } as final step |
Network error downloading .asx | Verify the URL is accessible over HTTPS |
"No streams found" Error
| Cause | Solution |
|---|---|
| Provider API changed | Inspect the current provider response with browser dev tools |
| Rate limiting | Add delay between requests or use try branches for fallbacks |
| Region blocking | Test with VPN or proxy |
Incorrect variable path in map.videos | Check {{sources.sources.file}} matches actual JSON structure |
| Headers missing (Referer, User-Agent) | Add required headers to map.videos.headers |
| AniList ID not found in source | Test with a known popular anime ID (e.g., 21 for One Piece) |
Playback Issues
| Symptom | Possible Cause | Check |
|---|---|---|
| Black screen with audio | CDN requires specific Referer/Origin headers | Add headers to map.videos.headers |
| Video stutters | HLS segments too large or CDN throttling | Try a different quality or server |
| Subtitles not showing | Subtitle URL incorrect or CORS blocked | Verify subtitle URL directly in browser |
| Wrong episode loads | Episode number mapping differs (0-indexed vs 1-indexed) | Check provider's episode numbering |
| App crashes on playback | M3U8 format not supported or corrupt segments | Test the M3U8 URL in VLC/mpv desktop |
Debugging Tools
Browser DevTools
Most providers serve HTML or JSON that you can inspect:
curl -H "User-Agent: Mozilla/5.0" "https://provider.example.com/api/21/1" | jq .Testing Without the App
You can simulate the pipeline manually using curl and jq:
# Step 1: http.get
curl -s "https://provider.example.com/api/21/1" -o response.json
# Step 2: json.parse + json.get
cat response.json | jq '.sources[0].file'
# Step 3: verify the stream URL works
ffprobe "$(cat response.json | jq -r '.sources[0].file')" 2>&1 | head -5Logcat (Android Debug)
Monitor deep link handling on Android:
adb logcat -s Anisurge:D *:S | grep -E "deepLink|extension|Deeplink"Pack Validation Checklist
Before submitting a pull request, verify:
-
node scripts/validate.mjspasses without errors - Pack installs via deep link on Android build ≥ 140
- At least one episode plays successfully with video and audio
- Sub and Dub both tested (if
subDub: true) -
versionCodeincremented for any behavior change -
index.jsonregenerated withnode scripts/generate-index.mjs - No hardcoded API keys, tokens, or private URLs
-
nsfw: trueif content requires age restriction - Icon included (optional but recommended)