mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
\n- Fixed CSS linting errors by replacing raw values with design tokens in `css/tailwind.source.css`. - Updated `scripts/check-design-tokens.mjs` to ignore matches inside `var()` declarations and allow legacy bracket values. - Fixed a failing unit test in `tests/ui/similar-content-card.test.mjs` to match current component behavior. - Updated `CONTRIBUTING.md` to include `npm run build:css` and clarify linting requirements. - Enhanced `.devcontainer/devcontainer.json` to include `npm run build:css` in `postCreateCommand`.
2284 lines
71 KiB
Plaintext
2284 lines
71 KiB
Plaintext
|
|
> [email protected] test:unit
|
|
> node scripts/run-unit-tests.mjs
|
|
|
|
|
|
→ Running tests/app-batch-fetch-profiles.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[batchFetchProfiles] Failed to fetch profiles from relay wss://fail.example: Error: relay timed out
|
|
at Object.list (file:///app/tests/app-batch-fetch-profiles.test.mjs:80:31)
|
|
at file:///app/js/utils/profileBatchFetcher.js:115:10
|
|
at Array.map (<anonymous>)
|
|
at batchFetchProfilesFromRelays (file:///app/js/utils/profileBatchFetcher.js:112:75)
|
|
at TestContext.<anonymous> (file:///app/tests/app-batch-fetch-profiles.test.mjs:87:11)
|
|
at Test.runInAsyncScope (node:async_hooks:214:14)
|
|
at Test.run (node:internal/test_runner/test:1047:25)
|
|
at Test.start (node:internal/test_runner/test:944:17)
|
|
at startSubtestAfterBootstrap (node:internal/test_runner/harness:296:17)
|
|
TAP version 13
|
|
# Subtest: batchFetchProfiles handles fast and failing relays
|
|
ok 1 - batchFetchProfiles handles fast and failing relays
|
|
---
|
|
duration_ms: 3.951918
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 15.780109
|
|
|
|
→ Running tests/app/channel-profile-moderation.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 2,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
TAP version 13
|
|
# Subtest: renderChannelVideosFromList decorates videos before storing
|
|
ok 1 - renderChannelVideosFromList decorates videos before storing
|
|
---
|
|
duration_ms: 235.250894
|
|
type: 'test'
|
|
...
|
|
# Subtest: renderChannelVideosFromList applies moderation blur without existing metadata
|
|
ok 2 - renderChannelVideosFromList applies moderation blur without existing metadata
|
|
---
|
|
duration_ms: 35.089875
|
|
type: 'test'
|
|
...
|
|
# Subtest: applyChannelVisualBlur blurs banner and avatar when viewer mutes author
|
|
ok 3 - applyChannelVisualBlur blurs banner and avatar when viewer mutes author
|
|
---
|
|
duration_ms: 11.70126
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation override clears channel blur via event wiring
|
|
ok 4 - moderation override clears channel blur via event wiring
|
|
---
|
|
duration_ms: 37.096643
|
|
type: 'test'
|
|
...
|
|
# Subtest: channel header moderation badge reflects blur state and override actions
|
|
ok 5 - channel header moderation badge reflects blur state and override actions
|
|
---
|
|
duration_ms: 33.232907
|
|
type: 'test'
|
|
...
|
|
# Subtest: channel video cards update moderation state in place when summary changes
|
|
ok 6 - channel video cards update moderation state in place when summary changes
|
|
---
|
|
duration_ms: 22.396668
|
|
type: 'test'
|
|
...
|
|
1..6
|
|
# tests 6
|
|
# suites 0
|
|
# pass 6
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 386.655131
|
|
|
|
→ Running tests/app/hash-change-handler.test.mjs
|
|
TAP version 13
|
|
# Subtest: handleHashChange defaults to for-you when logged in
|
|
ok 1 - handleHashChange defaults to for-you when logged in
|
|
---
|
|
duration_ms: 74.801774
|
|
type: 'test'
|
|
...
|
|
# Subtest: handleHashChange defaults to most-recent-videos when logged out
|
|
ok 2 - handleHashChange defaults to most-recent-videos when logged out
|
|
---
|
|
duration_ms: 10.494088
|
|
type: 'test'
|
|
...
|
|
# Subtest: handleHashChange respects explicit view regardless of login state
|
|
ok 3 - handleHashChange respects explicit view regardless of login state
|
|
---
|
|
duration_ms: 10.070045
|
|
type: 'test'
|
|
...
|
|
1..3
|
|
# tests 3
|
|
# suites 0
|
|
# pass 3
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 112.392492
|
|
|
|
→ Running tests/app/hydrate-sidebar-navigation.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: hydrateSidebarNavigation reveals chrome controls for authenticated viewers
|
|
ok 1 - hydrateSidebarNavigation reveals chrome controls for authenticated viewers
|
|
---
|
|
duration_ms: 90.214045
|
|
type: 'test'
|
|
...
|
|
# Subtest: hydrateSidebarNavigation hides chrome controls for logged-out viewers
|
|
ok 2 - hydrateSidebarNavigation hides chrome controls for logged-out viewers
|
|
---
|
|
duration_ms: 14.210417
|
|
type: 'test'
|
|
...
|
|
1..2
|
|
# tests 2
|
|
# suites 0
|
|
# pass 2
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 116.64085
|
|
|
|
→ Running tests/app/is-user-logged-in.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: isUserLoggedIn returns false when no user pubkey is set
|
|
ok 1 - isUserLoggedIn returns false when no user pubkey is set
|
|
---
|
|
duration_ms: 1.332334
|
|
type: 'test'
|
|
...
|
|
# Subtest: isUserLoggedIn treats extension logins as authenticated
|
|
ok 2 - isUserLoggedIn treats extension logins as authenticated
|
|
---
|
|
duration_ms: 0.367174
|
|
type: 'test'
|
|
...
|
|
# Subtest: isUserLoggedIn guards against mismatched nostrClient state
|
|
ok 3 - isUserLoggedIn guards against mismatched nostrClient state
|
|
---
|
|
duration_ms: 0.27112
|
|
type: 'test'
|
|
...
|
|
# Subtest: isUserLoggedIn ignores anonymous session actor mismatches
|
|
ok 4 - isUserLoggedIn ignores anonymous session actor mismatches
|
|
---
|
|
duration_ms: 0.24882
|
|
type: 'test'
|
|
...
|
|
# Subtest: isUserLoggedIn rejects mismatched managed session actors
|
|
ok 5 - isUserLoggedIn rejects mismatched managed session actors
|
|
---
|
|
duration_ms: 0.410749
|
|
type: 'test'
|
|
...
|
|
1..5
|
|
# tests 5
|
|
# suites 0
|
|
# pass 5
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 30.339495
|
|
|
|
→ Running tests/app/moderation-overrides.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: handleModerationOverride decorates stored and current videos then refreshes UI
|
|
ok 1 - handleModerationOverride decorates stored and current videos then refreshes UI
|
|
---
|
|
duration_ms: 206.84042
|
|
type: 'test'
|
|
...
|
|
# Subtest: handleModerationOverride resumes deferred playback
|
|
ok 2 - handleModerationOverride resumes deferred playback
|
|
---
|
|
duration_ms: 1.281286
|
|
type: 'test'
|
|
...
|
|
# Subtest: handleModerationBlock requests a block, clears overrides, and refreshes hidden state
|
|
ok 3 - handleModerationBlock requests a block, clears overrides, and refreshes hidden state
|
|
---
|
|
duration_ms: 3.901754
|
|
type: 'test'
|
|
...
|
|
# Subtest: handleModerationBlock returns false when viewer is logged out
|
|
ok 4 - handleModerationBlock returns false when viewer is logged out
|
|
---
|
|
duration_ms: 1.537005
|
|
type: 'test'
|
|
...
|
|
1..4
|
|
# tests 4
|
|
# suites 0
|
|
# pass 4
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 243.156495
|
|
|
|
→ Running tests/app/moderation-settings-refresh.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: handleModerationSettingsChange refreshes feeds with updated thresholds
|
|
ok 1 - handleModerationSettingsChange refreshes feeds with updated thresholds
|
|
---
|
|
duration_ms: 228.305239
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 260.71303
|
|
|
|
→ Running tests/app/similar-content.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: orders similar videos by shared tags then timestamp
|
|
ok 1 - orders similar videos by shared tags then timestamp
|
|
---
|
|
duration_ms: 5.487142
|
|
type: 'test'
|
|
...
|
|
# Subtest: returns no matches when the active video lacks tags
|
|
ok 2 - returns no matches when the active video lacks tags
|
|
---
|
|
duration_ms: 0.423977
|
|
type: 'test'
|
|
...
|
|
# Subtest: skips candidates without tag metadata
|
|
ok 3 - skips candidates without tag metadata
|
|
---
|
|
duration_ms: 0.441076
|
|
type: 'test'
|
|
...
|
|
# Subtest: filters NSFW and private videos when NSFW content is disabled
|
|
ok 4 - filters NSFW and private videos when NSFW content is disabled
|
|
---
|
|
duration_ms: 0.592795
|
|
type: 'test'
|
|
...
|
|
1..4
|
|
# tests 4
|
|
# suites 0
|
|
# pass 4
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 36.044094
|
|
|
|
→ Running tests/comment-event-builder.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[nostrEventSchemas] Dropping unmatched surrogate characters from event content
|
|
[nostrEventSchemas] Dropping unmatched surrogate characters from event content
|
|
TAP version 13
|
|
# Subtest: buildCommentEvent emits NIP-22 root metadata while keeping legacy fallbacks
|
|
ok 1 - buildCommentEvent emits NIP-22 root metadata while keeping legacy fallbacks
|
|
---
|
|
duration_ms: 3.104537
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildCommentEvent includes parent pointers, kinds, and authors for replies
|
|
ok 2 - buildCommentEvent includes parent pointers, kinds, and authors for replies
|
|
---
|
|
duration_ms: 0.528982
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildCommentEvent normalizes relays and preserves explicit overrides
|
|
ok 3 - buildCommentEvent normalizes relays and preserves explicit overrides
|
|
---
|
|
duration_ms: 0.993098
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildCommentEvent falls back to event pointers when no address is supplied
|
|
ok 4 - buildCommentEvent falls back to event pointers when no address is supplied
|
|
---
|
|
duration_ms: 0.297693
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildCommentEvent accepts partial metadata for parent overrides
|
|
ok 5 - buildCommentEvent accepts partial metadata for parent overrides
|
|
---
|
|
duration_ms: 0.447865
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildCommentEvent sanitizes additional tags before signing
|
|
ok 6 - buildCommentEvent sanitizes additional tags before signing
|
|
---
|
|
duration_ms: 0.894764
|
|
type: 'test'
|
|
...
|
|
1..6
|
|
# tests 6
|
|
# suites 0
|
|
# pass 6
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 20.531041
|
|
|
|
→ Running tests/comment-thread-service.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[commentThread] Cached 1 comments for AABBCC11223344556677889900aabbcc11223344556677889900aabbcc112233.
|
|
[commentThread] Loaded 1 cached comments for aabbcc11223344556677889900aabbcc11223344556677889900aabbcc112233.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
TAP version 13
|
|
# Subtest: CommentThreadService caches mixed-case video ids consistently
|
|
ok 1 - CommentThreadService caches mixed-case video ids consistently
|
|
---
|
|
duration_ms: 3.933777
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService surfaces cache read failures
|
|
ok 2 - CommentThreadService surfaces cache read failures
|
|
---
|
|
duration_ms: 0.831116
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService surfaces cache write failures
|
|
ok 3 - CommentThreadService surfaces cache write failures
|
|
---
|
|
duration_ms: 0.532641
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService persists caches safely during teardown failures
|
|
ok 4 - CommentThreadService persists caches safely during teardown failures
|
|
---
|
|
duration_ms: 1.928927
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService logs cache usage and fallback decisions
|
|
ok 5 - CommentThreadService logs cache usage and fallback decisions
|
|
---
|
|
duration_ms: 1.323553
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService normalizes mixed-case event ids in thread state
|
|
ok 6 - CommentThreadService normalizes mixed-case event ids in thread state
|
|
---
|
|
duration_ms: 2.49746
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService normalizes mixed-case pubkeys during hydration
|
|
ok 7 - CommentThreadService normalizes mixed-case pubkeys during hydration
|
|
---
|
|
duration_ms: 1.140252
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService deduplicates mixed-case event ids and pubkeys
|
|
ok 8 - CommentThreadService deduplicates mixed-case event ids and pubkeys
|
|
---
|
|
duration_ms: 1.091031
|
|
type: 'test'
|
|
...
|
|
[commentThread] Profile hydration attempt 1/3 failed for pubkeys: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc, dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd. Error: temporary hydration failure
|
|
at CommentThreadService.batchFetchProfiles (file:///app/tests/comment-thread-service.test.mjs:545:15)
|
|
at file:///app/js/services/commentThreadService.js:908:40
|
|
at CommentThreadService.flushProfileQueue (file:///app/js/services/commentThreadService.js:955:7)
|
|
at Timeout._onTimeout (file:///app/js/services/commentThreadService.js:884:12)
|
|
at listOnTimeout (node:internal/timers:588:17)
|
|
at process.processTimers (node:internal/timers:523:7)
|
|
[commentThread] Retrying profile hydration in 50ms for pubkeys: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc, dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
|
|
# Subtest: CommentThreadService retries profile hydration before succeeding
|
|
ok 9 - CommentThreadService retries profile hydration before succeeding
|
|
---
|
|
duration_ms: 77.367641
|
|
type: 'test'
|
|
...
|
|
[nostr] Comments cache miss for ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
[nostr] Comments cache hit for ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
# Subtest: CommentThreadService surfaces profile hydration failures after retries
|
|
ok 10 - CommentThreadService surfaces profile hydration failures after retries
|
|
---
|
|
duration_ms: 201.376938
|
|
type: 'test'
|
|
...
|
|
# Subtest: listVideoComments accepts builder events without parent ids and filters replies
|
|
ok 11 - listVideoComments accepts builder events without parent ids and filters replies
|
|
---
|
|
duration_ms: 5.425376
|
|
type: 'test'
|
|
...
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
[commentThread] Improved fetching fallback: feature disabled.
|
|
# Subtest: CommentThreadService hydrates, subscribes, and dedupes incoming comment events
|
|
ok 12 - CommentThreadService hydrates, subscribes, and dedupes incoming comment events
|
|
---
|
|
duration_ms: 35.140487
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService loadThread falls back to event id when address is missing
|
|
ok 13 - CommentThreadService loadThread falls back to event id when address is missing
|
|
---
|
|
duration_ms: 1.062026
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService requests and snapshots comments by root identifier
|
|
ok 14 - CommentThreadService requests and snapshots comments by root identifier
|
|
---
|
|
duration_ms: 1.067756
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService falls back to pointerIdentifiers root id
|
|
ok 15 - CommentThreadService falls back to pointerIdentifiers root id
|
|
---
|
|
duration_ms: 0.763797
|
|
type: 'test'
|
|
...
|
|
[commentThread] Comment cache miss for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: no entry present.
|
|
[commentThread] Cached 0 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
|
|
[commentThread] Loaded 0 cached comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
|
|
[commentThread] Cached 0 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
|
|
[commentThread] Cached 1 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
|
|
[commentThread] Cached 1 comments for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
|
|
# Subtest: CommentThreadService preserves raw video author pubkeys during hydration fetches
|
|
ok 16 - CommentThreadService preserves raw video author pubkeys during hydration fetches
|
|
---
|
|
duration_ms: 5.385664
|
|
type: 'test'
|
|
...
|
|
# Subtest: CommentThreadService teardown cancels hydration timers
|
|
ok 17 - CommentThreadService teardown cancels hydration timers
|
|
---
|
|
duration_ms: 81.497501
|
|
type: 'test'
|
|
...
|
|
1..17
|
|
# tests 17
|
|
# suites 0
|
|
# pass 17
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 432.59068
|
|
|
|
→ Running tests/design-system-metrics.test.mjs
|
|
TAP version 13
|
|
# Subtest: metric probe falls back to numeric parsing when measurement fails
|
|
ok 1 - metric probe falls back to numeric parsing when measurement fails
|
|
---
|
|
duration_ms: 139.398911
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 150.264845
|
|
|
|
→ Running tests/dm-decryptor.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: decryptDM handles kind 4 events with nip04 ciphertext
|
|
ok 1 - decryptDM handles kind 4 events with nip04 ciphertext
|
|
---
|
|
duration_ms: 72.295197
|
|
type: 'test'
|
|
...
|
|
# Subtest: decryptDM prefers recipient pubkeys when actor is the sender
|
|
ok 2 - decryptDM prefers recipient pubkeys when actor is the sender
|
|
---
|
|
duration_ms: 16.831318
|
|
type: 'test'
|
|
...
|
|
# Subtest: decryptDM unwraps kind 1059 gift wraps with nip44
|
|
ok 3 - decryptDM unwraps kind 1059 gift wraps with nip44
|
|
---
|
|
duration_ms: 57.638741
|
|
type: 'test'
|
|
...
|
|
# Subtest: decryptDM returns failure when decryptors are unavailable
|
|
ok 4 - decryptDM returns failure when decryptors are unavailable
|
|
---
|
|
duration_ms: 0.323647
|
|
type: 'test'
|
|
...
|
|
1..4
|
|
# tests 4
|
|
# suites 0
|
|
# pass 4
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 159.925109
|
|
|
|
→ Running tests/edit-modal-submit-state.test.mjs
|
|
TAP version 13
|
|
# Subtest: ignores additional submissions while pending without spurious errors
|
|
ok 1 - ignores additional submissions while pending without spurious errors
|
|
---
|
|
duration_ms: 267.689298
|
|
type: 'test'
|
|
...
|
|
# Subtest: editing the magnet refreshes torrent hints when ws/xs remain locked
|
|
ok 2 - editing the magnet refreshes torrent hints when ws/xs remain locked
|
|
---
|
|
duration_ms: 107.212911
|
|
type: 'test'
|
|
...
|
|
# Subtest: does not show missing video error after modal closes
|
|
ok 3 - does not show missing video error after modal closes
|
|
---
|
|
duration_ms: 85.29678
|
|
type: 'test'
|
|
...
|
|
1..3
|
|
# tests 3
|
|
# suites 0
|
|
# pass 3
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 474.328316
|
|
|
|
→ Running tests/feed-engine/tag-preference-filter.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: tag preference stage filters by interests and excludes disinterests
|
|
ok 1 - tag preference stage filters by interests and excludes disinterests
|
|
---
|
|
duration_ms: 2.480596
|
|
type: 'test'
|
|
...
|
|
# Subtest: tag preference stage accepts interests from nip71 hashtags
|
|
ok 2 - tag preference stage accepts interests from nip71 hashtags
|
|
---
|
|
duration_ms: 0.410859
|
|
type: 'test'
|
|
...
|
|
1..2
|
|
# tests 2
|
|
# suites 0
|
|
# pass 2
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 13.697422
|
|
|
|
→ Running tests/hashtag-preferences.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: load decrypts nip44 payloads and normalizes tags
|
|
ok 1 - load decrypts nip44 payloads and normalizes tags
|
|
---
|
|
duration_ms: 19.422102
|
|
type: 'test'
|
|
...
|
|
# Subtest: load falls back to nip04 decryption
|
|
ok 2 - load falls back to nip04 decryption
|
|
---
|
|
duration_ms: 1.385346
|
|
type: 'test'
|
|
...
|
|
# Subtest: load retries decryptors when hinted scheme fails
|
|
ok 3 - load retries decryptors when hinted scheme fails
|
|
---
|
|
duration_ms: 1.577638
|
|
type: 'test'
|
|
...
|
|
# Subtest: interest and disinterest lists remain exclusive
|
|
ok 4 - interest and disinterest lists remain exclusive
|
|
---
|
|
duration_ms: 0.676935
|
|
type: 'test'
|
|
...
|
|
# Subtest: publish encrypts payload and builds event via builder
|
|
ok 5 - publish encrypts payload and builds event via builder
|
|
---
|
|
duration_ms: 8.669487
|
|
type: 'test'
|
|
...
|
|
# Subtest: publish falls back to window nostr encryptors
|
|
ok 6 - publish falls back to window nostr encryptors
|
|
---
|
|
duration_ms: 2.457867
|
|
type: 'test'
|
|
...
|
|
# Subtest: load prefers canonical kind when timestamps match while accepting legacy payload
|
|
ok 7 - load prefers canonical kind when timestamps match while accepting legacy payload
|
|
---
|
|
duration_ms: 1.553075
|
|
type: 'test'
|
|
...
|
|
1..7
|
|
# tests 7
|
|
# suites 0
|
|
# pass 7
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 45.729471
|
|
|
|
→ Running tests/magnet-utils.test.mjs
|
|
TAP version 13
|
|
# Subtest: safeDecodeMagnet handles encoded values
|
|
ok 1 - safeDecodeMagnet handles encoded values
|
|
---
|
|
duration_ms: 1.609313
|
|
type: 'test'
|
|
...
|
|
# Subtest: safeDecodeMagnet leaves plain strings untouched
|
|
ok 2 - safeDecodeMagnet leaves plain strings untouched
|
|
---
|
|
duration_ms: 0.282348
|
|
type: 'test'
|
|
...
|
|
# Subtest: bare hashes normalize consistently across helpers
|
|
ok 3 - bare hashes normalize consistently across helpers
|
|
---
|
|
duration_ms: 3.796459
|
|
type: 'test'
|
|
...
|
|
# Subtest: legacy %3A payloads decode across helpers
|
|
ok 4 - legacy %3A payloads decode across helpers
|
|
---
|
|
duration_ms: 0.613367
|
|
type: 'test'
|
|
...
|
|
# Subtest: duplicate trackers and hints stay in sync
|
|
ok 5 - duplicate trackers and hints stay in sync
|
|
---
|
|
duration_ms: 1.216889
|
|
type: 'test'
|
|
...
|
|
# Subtest: object helper enforces HTTPS web seeds when on HTTPS
|
|
ok 6 - object helper enforces HTTPS web seeds when on HTTPS
|
|
---
|
|
duration_ms: 0.652082
|
|
type: 'test'
|
|
...
|
|
# Subtest: object helper allows HTTP seeds on HTTP origins
|
|
ok 7 - object helper allows HTTP seeds on HTTP origins
|
|
---
|
|
duration_ms: 0.421209
|
|
type: 'test'
|
|
...
|
|
# Subtest: extractMagnetHints returns first ws/xs pair
|
|
ok 8 - extractMagnetHints returns first ws/xs pair
|
|
---
|
|
duration_ms: 0.414267
|
|
type: 'test'
|
|
...
|
|
# Subtest: string helper skips insecure ws hints on HTTPS origins
|
|
ok 9 - string helper skips insecure ws hints on HTTPS origins
|
|
---
|
|
duration_ms: 0.867344
|
|
type: 'test'
|
|
...
|
|
# Subtest: object helper reports didChange when output differs
|
|
ok 10 - object helper reports didChange when output differs
|
|
---
|
|
duration_ms: 0.768602
|
|
type: 'test'
|
|
...
|
|
# Subtest: helpers trim fragments from non-magnet values
|
|
ok 11 - helpers trim fragments from non-magnet values
|
|
---
|
|
duration_ms: 0.317559
|
|
type: 'test'
|
|
...
|
|
1..11
|
|
# tests 11
|
|
# suites 0
|
|
# pass 11
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 31.9769
|
|
|
|
→ Running tests/media-loader.test.mjs
|
|
TAP version 13
|
|
# Subtest: MediaLoader assigns image sources once intersecting
|
|
ok 1 - MediaLoader assigns image sources once intersecting
|
|
---
|
|
duration_ms: 81.726329
|
|
type: 'test'
|
|
...
|
|
# Subtest: MediaLoader loads video sources and poster fallbacks
|
|
ok 2 - MediaLoader loads video sources and poster fallbacks
|
|
---
|
|
duration_ms: 22.682034
|
|
type: 'test'
|
|
...
|
|
# Subtest: MediaLoader clears unsupported lazy targets without inline styles
|
|
ok 3 - MediaLoader clears unsupported lazy targets without inline styles
|
|
---
|
|
duration_ms: 10.849001
|
|
type: 'test'
|
|
...
|
|
1..3
|
|
# tests 3
|
|
# suites 0
|
|
# pass 3
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 128.204579
|
|
|
|
→ Running tests/modal-accessibility.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: UploadModal closes on Escape and restores trigger focus
|
|
ok 1 - UploadModal closes on Escape and restores trigger focus
|
|
---
|
|
duration_ms: 233.801182
|
|
type: 'test'
|
|
...
|
|
# Subtest: UploadModal backdrop click closes and restores trigger focus
|
|
ok 2 - UploadModal backdrop click closes and restores trigger focus
|
|
---
|
|
duration_ms: 80.917943
|
|
type: 'test'
|
|
...
|
|
# Subtest: UploadModal mode toggle updates button states
|
|
ok 3 - UploadModal mode toggle updates button states
|
|
---
|
|
duration_ms: 63.028207
|
|
type: 'test'
|
|
...
|
|
# Subtest: EditModal Escape closes and restores trigger focus
|
|
ok 4 - EditModal Escape closes and restores trigger focus
|
|
---
|
|
duration_ms: 103.844176
|
|
type: 'test'
|
|
...
|
|
# Subtest: EditModal backdrop click closes and restores trigger focus
|
|
ok 5 - EditModal backdrop click closes and restores trigger focus
|
|
---
|
|
duration_ms: 82.193753
|
|
type: 'test'
|
|
...
|
|
# Subtest: EditModal visibility toggle updates button state
|
|
ok 6 - EditModal visibility toggle updates button state
|
|
---
|
|
duration_ms: 71.274165
|
|
type: 'test'
|
|
...
|
|
# Subtest: RevertModal Escape closes and restores trigger focus
|
|
ok 7 - RevertModal Escape closes and restores trigger focus
|
|
---
|
|
duration_ms: 54.603962
|
|
type: 'test'
|
|
...
|
|
# Subtest: static modal helper toggles accessibility hooks
|
|
ok 8 - static modal helper toggles accessibility hooks
|
|
---
|
|
duration_ms: 13.310668
|
|
type: 'test'
|
|
...
|
|
1..8
|
|
# tests 8
|
|
# suites 0
|
|
# pass 8
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 715.120434
|
|
|
|
→ Running tests/moderation-service.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: trusted report summaries respect personal blocks and admin lists
|
|
ok 1 - trusted report summaries respect personal blocks and admin lists
|
|
---
|
|
duration_ms: 4.925643
|
|
type: 'test'
|
|
...
|
|
# Subtest: user block updates recompute summaries and emit notifications
|
|
ok 2 - user block updates recompute summaries and emit notifications
|
|
---
|
|
duration_ms: 4.205645
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation thresholds emit logger hooks only when crossing
|
|
ok 3 - moderation thresholds emit logger hooks only when crossing
|
|
---
|
|
duration_ms: 1.584069
|
|
type: 'test'
|
|
...
|
|
# Subtest: trusted mute aggregation tracks F1 mute lists
|
|
ok 4 - trusted mute aggregation tracks F1 mute lists
|
|
---
|
|
duration_ms: 1.704481
|
|
type: 'test'
|
|
...
|
|
# Subtest: viewer mute list publishes and updates aggregation
|
|
ok 5 - viewer mute list publishes and updates aggregation
|
|
---
|
|
duration_ms: 4.067495
|
|
type: 'test'
|
|
...
|
|
1..5
|
|
# tests 5
|
|
# suites 0
|
|
# pass 5
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 29.799291
|
|
|
|
→ Running tests/moderation-stage.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'c',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 5,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'd',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 3,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'muted',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'normal',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'custom-threshold',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'custom-threshold',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'runtime-threshold',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 3,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-report-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'runtime-threshold',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 3,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'resolver-threshold',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 2,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'resolver-threshold',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 2,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-report-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'whitelisted-video',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'muted-video',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 3,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'whitelisted-video',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'muted-video',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'viewer-muted',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '9999999999999999999999999999999999999999999999999999999999999999',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 1,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '9999999999999999999999999999999999999999999999999999999999999999',
|
|
blockAutoplay: false,
|
|
blurThumbnail: false,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
TAP version 13
|
|
# Subtest: moderation stage enforces admin lists without whitelist bypass
|
|
ok 1 - moderation stage enforces admin lists without whitelist bypass
|
|
---
|
|
duration_ms: 5.360424
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage annotates trusted mute metadata
|
|
ok 2 - moderation stage annotates trusted mute metadata
|
|
---
|
|
duration_ms: 1.204999
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage applies provided thresholds
|
|
ok 3 - moderation stage applies provided thresholds
|
|
---
|
|
duration_ms: 1.49787
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage respects runtime threshold changes
|
|
ok 4 - moderation stage respects runtime threshold changes
|
|
---
|
|
duration_ms: 1.564344
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage supports function-based threshold resolvers
|
|
ok 5 - moderation stage supports function-based threshold resolvers
|
|
---
|
|
duration_ms: 1.243856
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage propagates whitelist, muters, and threshold updates
|
|
ok 6 - moderation stage propagates whitelist, muters, and threshold updates
|
|
---
|
|
duration_ms: 1.736849
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage blurs viewer-muted authors
|
|
ok 7 - moderation stage blurs viewer-muted authors
|
|
---
|
|
duration_ms: 0.766481
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage clears cached reporters and muters after service signals
|
|
ok 8 - moderation stage clears cached reporters and muters after service signals
|
|
---
|
|
duration_ms: 1.144956
|
|
type: 'test'
|
|
...
|
|
1..8
|
|
# tests 8
|
|
# suites 0
|
|
# pass 8
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 29.108905
|
|
|
|
→ Running tests/moderation/hide-thresholds.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '1111111111111111111111111111111111111111111111111111111111111111',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-mute-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '2222222222222222222222222222222222222222222222222222222222222222',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 5,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-report-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '6666666666666666666666666666666666666666666666666666666666666666',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-mute-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '6666666666666666666666666666666666666666666666666666666666666666',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '9999999999999999999999999999999999999999999999999999999999999999',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: null,
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '9999999999999999999999999999999999999999999999999999999999999999',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-mute-hide',
|
|
hideBypass: null
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '3333333333333333333333333333333333333333333333333333333333333333',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 4,
|
|
reportType: 'nudity',
|
|
hidden: false,
|
|
hideReason: 'trusted-report-hide',
|
|
hideBypass: 'feed-policy'
|
|
}
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: '4444444444444444444444444444444444444444444444444444444444444444',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 6,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-report-hide',
|
|
hideBypass: null
|
|
}
|
|
TAP version 13
|
|
# Subtest: moderation stage hides videos muted by trusted when threshold met
|
|
ok 1 - moderation stage hides videos muted by trusted when threshold met
|
|
---
|
|
duration_ms: 5.088284
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage hides videos when trusted reports exceed threshold
|
|
ok 2 - moderation stage hides videos when trusted reports exceed threshold
|
|
---
|
|
duration_ms: 0.979496
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage respects runtime hide threshold changes
|
|
ok 3 - moderation stage respects runtime hide threshold changes
|
|
---
|
|
duration_ms: 1.30707
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage supports trusted mute hide resolver functions
|
|
ok 4 - moderation stage supports trusted mute hide resolver functions
|
|
---
|
|
duration_ms: 1.523941
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage bypasses hard hides on home feed
|
|
ok 5 - moderation stage bypasses hard hides on home feed
|
|
---
|
|
duration_ms: 1.244957
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderation stage hides admin-whitelisted videos once thresholds fire
|
|
ok 6 - moderation stage hides admin-whitelisted videos once thresholds fire
|
|
---
|
|
duration_ms: 0.879699
|
|
type: 'test'
|
|
...
|
|
1..6
|
|
# tests 6
|
|
# suites 0
|
|
# pass 6
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 24.126063
|
|
|
|
→ Running tests/moderation/submit-report.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: submitReport emits NIP-56 compliant report tags
|
|
ok 1 - submitReport emits NIP-56 compliant report tags
|
|
---
|
|
duration_ms: 8.765812
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 16.699107
|
|
|
|
→ Running tests/moderation/trust-seeds.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
TAP version 13
|
|
# Subtest: default trust seeds derive from config
|
|
ok 1 - default trust seeds derive from config
|
|
---
|
|
duration_ms: 2.220024
|
|
type: 'test'
|
|
...
|
|
# Subtest: trusted seeds contribute to trusted mute counts
|
|
ok 2 - trusted seeds contribute to trusted mute counts
|
|
---
|
|
duration_ms: 4.71981
|
|
type: 'test'
|
|
...
|
|
# Subtest: trusted seeds contribute to trusted report counts
|
|
ok 3 - trusted seeds contribute to trusted report counts
|
|
---
|
|
duration_ms: 2.905957
|
|
type: 'test'
|
|
...
|
|
# Subtest: trusted seed updates recompute guest report summaries
|
|
ok 4 - trusted seed updates recompute guest report summaries
|
|
---
|
|
duration_ms: 1.454472
|
|
type: 'test'
|
|
...
|
|
# Subtest: moderator seeds populate trusted contacts
|
|
ok 5 - moderator seeds populate trusted contacts
|
|
---
|
|
duration_ms: 0.990639
|
|
type: 'test'
|
|
...
|
|
[trustBootstrap] bootstrapTrustedSeeds called
|
|
[trustBootstrap] waitForAccessControl result { ok: true, timedOut: false }
|
|
[trustBootstrap] Applying 2 trusted seeds [
|
|
'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx',
|
|
'npub1moderatorexamplemoderatorexamplemoderatorexample1'
|
|
]
|
|
[trustBootstrap] Applying 2 trusted seeds [
|
|
'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx',
|
|
'npub1moderatorexamplemoderatorexamplemoderatorexample1'
|
|
]
|
|
[trustBootstrap] Applying 3 trusted seeds [
|
|
'npub15jnttpymeytm80hatjqcvhhqhzrhx6gxp8pq0wn93rhnu8s9h9dsha32lx',
|
|
'npub1newmoderatorexamplemoderatorexamplemoderator',
|
|
'npub1secondmoderatorexamplemoderatorexamplemod'
|
|
]
|
|
# Subtest: bootstrap seeds track editor roster and ignore whitelist-only changes
|
|
ok 6 - bootstrap seeds track editor roster and ignore whitelist-only changes
|
|
---
|
|
duration_ms: 83.776059
|
|
type: 'test'
|
|
...
|
|
1..6
|
|
# tests 6
|
|
# suites 0
|
|
# pass 6
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 3604.451748
|
|
|
|
→ Running tests/moderation/trusted-mute-lists.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
[feedEngine/moderation] metadata.moderation updated {
|
|
stage: 'moderation',
|
|
videoId: 'video-muted',
|
|
blockAutoplay: true,
|
|
blurThumbnail: true,
|
|
trustedCount: 0,
|
|
reportType: 'nudity',
|
|
hidden: true,
|
|
hideReason: 'trusted-mute-hide',
|
|
hideBypass: null
|
|
}
|
|
# Subtest: trusted mute lists from seeds hide authors for anonymous viewers
|
|
ok 1 - trusted mute lists from seeds hide authors for anonymous viewers
|
|
---
|
|
duration_ms: 14.907941
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 23.034046
|
|
|
|
→ Running tests/moderation/trusted-report-count.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
[bitvid] [moderationService] moderation threshold crossed
|
|
TAP version 13
|
|
# Subtest: trustedReportCount dedupes multiple reports from the same trusted reporter
|
|
ok 1 - trustedReportCount dedupes multiple reports from the same trusted reporter
|
|
---
|
|
duration_ms: 5.950726
|
|
type: 'test'
|
|
...
|
|
# Subtest: trustedReportCount ignores reports from muted or blocked reporters
|
|
ok 2 - trustedReportCount ignores reports from muted or blocked reporters
|
|
---
|
|
duration_ms: 2.480359
|
|
type: 'test'
|
|
...
|
|
# Subtest: blocking and unblocking reporters recomputes trusted summaries
|
|
ok 3 - blocking and unblocking reporters recomputes trusted summaries
|
|
---
|
|
duration_ms: 2.895828
|
|
type: 'test'
|
|
...
|
|
# Subtest: trustedReportCount only counts eligible F1 reporters and admin whitelist
|
|
ok 4 - trustedReportCount only counts eligible F1 reporters and admin whitelist
|
|
---
|
|
duration_ms: 2.271767
|
|
type: 'test'
|
|
...
|
|
1..4
|
|
# tests 4
|
|
# suites 0
|
|
# pass 4
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 26.863456
|
|
|
|
→ Running tests/moderation/video-card.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: VideoCard renders moderation badges and respects viewer override
|
|
ok 1 - VideoCard renders moderation badges and respects viewer override
|
|
---
|
|
duration_ms: 325.224556
|
|
type: 'test'
|
|
...
|
|
# Subtest: VideoCard hides content when hide metadata is present and override unmasks it
|
|
ok 2 - VideoCard hides content when hide metadata is present and override unmasks it
|
|
---
|
|
duration_ms: 36.652683
|
|
type: 'test'
|
|
...
|
|
# Subtest: VideoCard blurs viewer-muted creators
|
|
ok 3 - VideoCard blurs viewer-muted creators
|
|
---
|
|
duration_ms: 17.308476
|
|
type: 'test'
|
|
...
|
|
# Subtest: VideoCard blurs thumbnails when trusted mute triggers without reports
|
|
ok 4 - VideoCard blurs thumbnails when trusted mute triggers without reports
|
|
---
|
|
duration_ms: 16.834475
|
|
type: 'test'
|
|
...
|
|
# Subtest: VideoCard block action restores trusted mute hide state after override
|
|
ok 5 - VideoCard block action restores trusted mute hide state after override
|
|
---
|
|
duration_ms: 29.140064
|
|
type: 'test'
|
|
...
|
|
# Subtest: applyModerationContextDatasets clears blur when overrides are active
|
|
ok 6 - applyModerationContextDatasets clears blur when overrides are active
|
|
---
|
|
duration_ms: 8.486614
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildModerationBadgeText returns trusted contact block copy when autoplay block and trusted mute combine
|
|
ok 7 - buildModerationBadgeText returns trusted contact block copy when autoplay block and trusted mute combine
|
|
---
|
|
duration_ms: 0.20802
|
|
type: 'test'
|
|
...
|
|
1..7
|
|
# tests 7
|
|
# suites 0
|
|
# pass 7
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 442.41748
|
|
|
|
→ Running tests/more-menu-controller.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: copy-link action writes to clipboard and shows success
|
|
ok 1 - copy-link action writes to clipboard and shows success
|
|
---
|
|
duration_ms: 3.180901
|
|
type: 'test'
|
|
...
|
|
# Subtest: blacklist-author requires moderator access and refreshes subscriptions
|
|
ok 2 - blacklist-author requires moderator access and refreshes subscriptions
|
|
---
|
|
duration_ms: 0.626384
|
|
type: 'test'
|
|
...
|
|
# Subtest: blacklist-author shows error when no moderator session is available
|
|
ok 3 - blacklist-author shows error when no moderator session is available
|
|
---
|
|
duration_ms: 0.329829
|
|
type: 'test'
|
|
...
|
|
# Subtest: block-author updates user blocks, reloads videos, and refreshes feeds
|
|
ok 4 - block-author updates user blocks, reloads videos, and refreshes feeds
|
|
---
|
|
duration_ms: 0.760243
|
|
type: 'test'
|
|
...
|
|
# Subtest: mute-author updates viewer mute list and refreshes feeds
|
|
ok 5 - mute-author updates viewer mute list and refreshes feeds
|
|
---
|
|
duration_ms: 0.612503
|
|
type: 'test'
|
|
...
|
|
# Subtest: unmute-author removes creators from viewer mute list
|
|
ok 6 - unmute-author removes creators from viewer mute list
|
|
---
|
|
duration_ms: 0.565561
|
|
type: 'test'
|
|
...
|
|
1..6
|
|
# tests 6
|
|
# suites 0
|
|
# pass 6
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 19.149113
|
|
|
|
→ Running tests/nip71-base-event-tags.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: 30078 events carry nip71 metadata tags and hydrate fallback metadata
|
|
ok 1 - 30078 events carry nip71 metadata tags and hydrate fallback metadata
|
|
---
|
|
duration_ms: 7.626422
|
|
type: 'test'
|
|
...
|
|
# Subtest: imeta tags lower-case mime values
|
|
ok 2 - imeta tags lower-case mime values
|
|
---
|
|
duration_ms: 0.557257
|
|
type: 'test'
|
|
...
|
|
1..2
|
|
# tests 2
|
|
# suites 0
|
|
# pass 2
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 19.425838
|
|
|
|
→ Running tests/nip71-builder.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: buildNip71VideoEvent assembles rich metadata
|
|
ok 1 - buildNip71VideoEvent assembles rich metadata
|
|
---
|
|
duration_ms: 4.167966
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildNip71VideoEvent falls back to summary and selects kind
|
|
ok 2 - buildNip71VideoEvent falls back to summary and selects kind
|
|
---
|
|
duration_ms: 0.45331
|
|
type: 'test'
|
|
...
|
|
# Subtest: buildNip71VideoEvent attaches pointer tags
|
|
ok 3 - buildNip71VideoEvent attaches pointer tags
|
|
---
|
|
duration_ms: 0.49872
|
|
type: 'test'
|
|
...
|
|
# Subtest: extractNip71MetadataFromTags parses metadata and pointers
|
|
ok 4 - extractNip71MetadataFromTags parses metadata and pointers
|
|
---
|
|
duration_ms: 3.010408
|
|
type: 'test'
|
|
...
|
|
1..4
|
|
# tests 4
|
|
# suites 0
|
|
# pass 4
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 22.058195
|
|
|
|
→ Running tests/nip71-form-manager.test.mjs
|
|
TAP version 13
|
|
# Subtest: collectSection sanitizes and deduplicates hashtags
|
|
ok 1 - collectSection sanitizes and deduplicates hashtags
|
|
---
|
|
duration_ms: 104.317193
|
|
type: 'test'
|
|
...
|
|
# Subtest: hydrateSection renders sanitized hashtags with prefix
|
|
ok 2 - hydrateSection renders sanitized hashtags with prefix
|
|
---
|
|
duration_ms: 21.67468
|
|
type: 'test'
|
|
...
|
|
1..2
|
|
# tests 2
|
|
# suites 0
|
|
# pass 2
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 138.388304
|
|
|
|
→ Running tests/nostr-login-permissions.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw
|
|
Whitelist: []
|
|
Blacklist: []
|
|
Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
User logged out.
|
|
Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw
|
|
Whitelist: []
|
|
Blacklist: []
|
|
Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
User logged out.
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: object permissions unsupported
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:299:31)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32)
|
|
at NostrClient.login (file:///app/js/nostr/client.js:3799:43)
|
|
at TestContext.<anonymous> (file:///app/tests/nostr-login-permissions.test.mjs:309:38)
|
|
Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw
|
|
Whitelist: []
|
|
Blacklist: []
|
|
Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
User logged out.
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: payloads not supported
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:342:31)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32)
|
|
at NostrClient.login (file:///app/js/nostr/client.js:3799:43)
|
|
at TestContext.<anonymous> (file:///app/tests/nostr-login-permissions.test.mjs:349:38)
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: payloads not supported
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:342:31)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26)
|
|
at async NostrClient.login (file:///app/js/nostr/client.js:3799:32)
|
|
at async TestContext.<anonymous> (file:///app/tests/nostr-login-permissions.test.mjs:349:20)
|
|
Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw
|
|
Whitelist: []
|
|
Blacklist: []
|
|
Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
User logged out.
|
|
TAP version 13
|
|
# Subtest: NIP-07 login requests decrypt permissions upfront
|
|
ok 1 - NIP-07 login requests decrypt permissions upfront
|
|
---
|
|
duration_ms: 7.507317
|
|
type: 'test'
|
|
...
|
|
# Subtest: NIP-07 decrypt reuses cached extension permissions
|
|
ok 2 - NIP-07 decrypt reuses cached extension permissions
|
|
---
|
|
duration_ms: 2.913123
|
|
type: 'test'
|
|
...
|
|
# Subtest: NIP-07 login falls back when structured permissions fail
|
|
ok 3 - NIP-07 login falls back when structured permissions fail
|
|
---
|
|
duration_ms: 2.826926
|
|
type: 'test'
|
|
...
|
|
# Subtest: NIP-07 login supports extensions that only allow enable() without payload
|
|
ok 4 - NIP-07 login supports extensions that only allow enable() without payload
|
|
---
|
|
duration_ms: 2.393743
|
|
type: 'test'
|
|
...
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: Timed out waiting for the NIP-07 extension. Confirm the extension prompt in your browser toolbar and try again.
|
|
at Timeout.<anonymous> (file:///app/js/nostr/nip07Permissions.js:164:14)
|
|
at listOnTimeout (node:internal/timers:588:17)
|
|
at process.processTimers (node:internal/timers:523:7)
|
|
Got pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
Converted to npub: npub1lllllllllllllllllllllllllllllllllllllllllllllllllllsq7lrjw
|
|
Whitelist: []
|
|
Blacklist: []
|
|
Logged in with extension. Pubkey: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
User logged out.
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: permission denied
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:32)
|
|
at NostrClient.login (file:///app/js/nostr/client.js:3799:43)
|
|
at file:///app/tests/nostr-login-permissions.test.mjs:435:44
|
|
[bitvid] [nostr] extension.enable request with explicit permissions failed: Error: permission denied
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:36)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26)
|
|
at async NostrClient.login (file:///app/js/nostr/client.js:3799:32)
|
|
at async waitForActual (node:assert:644:5)
|
|
[bitvid] Login error: Error: The NIP-07 extension reported "permission denied". Please approve the prompt and try again.
|
|
at NostrClient.login (file:///app/js/nostr/client.js:3805:29)
|
|
at async waitForActual (node:assert:644:5)
|
|
at async Function.rejects (node:assert:767:25)
|
|
at async TestContext.<anonymous> (file:///app/tests/nostr-login-permissions.test.mjs:435:5)
|
|
at async Test.run (node:internal/test_runner/test:1054:7)
|
|
at async Test.processPendingSubtests (node:internal/test_runner/test:744:7) {
|
|
cause: Error: permission denied
|
|
at enableImpl (file:///app/tests/nostr-login-permissions.test.mjs:430:29)
|
|
at Object.enable (file:///app/tests/nostr-login-permissions.test.mjs:60:32)
|
|
at runNip07WithRetry.label (file:///app/js/nostr/nip07Permissions.js:282:64)
|
|
at getOrStartOperation (file:///app/js/nostr/nip07Permissions.js:202:41)
|
|
at withNip07Timeout (file:///app/js/nostr/nip07Permissions.js:170:23)
|
|
at runNip07WithRetry (file:///app/js/nostr/nip07Permissions.js:214:18)
|
|
at requestEnablePermissions (file:///app/js/nostr/nip07Permissions.js:281:13)
|
|
at async NostrClient.ensureExtensionPermissions (file:///app/js/nostr/client.js:2488:26)
|
|
at async NostrClient.login (file:///app/js/nostr/client.js:3799:32)
|
|
at async waitForActual (node:assert:644:5)
|
|
}
|
|
User logged out.
|
|
# Subtest: NIP-07 login quickly retries when a permission payload stalls
|
|
ok 5 - NIP-07 login quickly retries when a permission payload stalls
|
|
---
|
|
duration_ms: 82.426611
|
|
type: 'test'
|
|
...
|
|
# Subtest: NIP-07 login surfaces enable permission errors
|
|
ok 6 - NIP-07 login surfaces enable permission errors
|
|
---
|
|
duration_ms: 2.978705
|
|
type: 'test'
|
|
...
|
|
# Subtest: runNip07WithRetry respects timeout without retry multiplier
|
|
ok 7 - runNip07WithRetry respects timeout without retry multiplier
|
|
---
|
|
duration_ms: 61.293887
|
|
type: 'test'
|
|
...
|
|
1..7
|
|
# tests 7
|
|
# suites 0
|
|
# pass 7
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 172.692684
|
|
|
|
→ Running tests/nostr-private-key-signer.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: registerPrivateKeySigner exposes nip04 helpers
|
|
ok 1 - registerPrivateKeySigner exposes nip04 helpers
|
|
---
|
|
duration_ms: 215.641844
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 239.319305
|
|
|
|
→ Running tests/nostr-send-direct-message.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: sendDirectMessage succeeds with private key signer and no extension
|
|
ok 1 - sendDirectMessage succeeds with private key signer and no extension
|
|
---
|
|
duration_ms: 214.554605
|
|
type: 'test'
|
|
...
|
|
1..1
|
|
# tests 1
|
|
# suites 0
|
|
# pass 1
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 236.740125
|
|
|
|
→ Running tests/nostr-service-access-control.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[moderationService] reconcileTrustedMuteSubscriptions { previous: 0, next: 0 }
|
|
[moderationService] subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
(moderationService) ensurePool failed while subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef Error: nostr-client-unavailable
|
|
at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13)
|
|
at file:///app/js/services/moderationService.js:1128:20
|
|
at ModerationService.subscribeToTrustedMuteList (file:///app/js/services/moderationService.js:1195:7)
|
|
at ModerationService.reconcileTrustedMuteSubscriptions (file:///app/js/services/moderationService.js:1076:12)
|
|
at ModerationService.rebuildTrustedContacts (file:///app/js/services/moderationService.js:655:10)
|
|
at ModerationService.clearTrustedMuteTracking (file:///app/js/services/moderationService.js:1039:10)
|
|
at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1887:10)
|
|
at ModerationService.refreshViewerFromClient (file:///app/js/services/moderationService.js:1861:17)
|
|
at NostrService.getModerationService (file:///app/js/services/nostrService.js:870:32)
|
|
at NostrService.isViewerVideoAuthor (file:///app/js/services/nostrService.js:1706:12)
|
|
[moderationService] ensurePool failed while fetching contacts Error: nostr-client-unavailable
|
|
at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13)
|
|
at ModerationService.fetchTrustedContacts (file:///app/js/services/moderationService.js:1937:18)
|
|
at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1903:36)
|
|
at ModerationService.refreshViewerFromClient (file:///app/js/services/moderationService.js:1861:17)
|
|
at NostrService.getModerationService (file:///app/js/services/nostrService.js:870:32)
|
|
at NostrService.isViewerVideoAuthor (file:///app/js/services/nostrService.js:1706:12)
|
|
at NostrService.shouldIncludeVideo (file:///app/js/services/nostrService.js:1002:33)
|
|
at TestContext.<anonymous> (file:///app/tests/nostr-service-access-control.test.mjs:143:13)
|
|
at Test.runInAsyncScope (node:async_hooks:214:14)
|
|
at Test.run (node:internal/test_runner/test:1047:25)
|
|
[moderationService] ensurePool failed while subscribing to contacts Error: nostr-client-unavailable
|
|
at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13)
|
|
at ModerationService.subscribeToContactList (file:///app/js/services/moderationService.js:2011:18)
|
|
at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1918:10)
|
|
TAP version 13
|
|
# Subtest: shouldIncludeVideo returns true for whitelist author when npubEncode throws
|
|
ok 1 - shouldIncludeVideo returns true for whitelist author when npubEncode throws
|
|
---
|
|
duration_ms: 1.912078
|
|
type: 'test'
|
|
...
|
|
# Subtest: shouldIncludeVideo rejects blacklisted authors provided as npub
|
|
ok 2 - shouldIncludeVideo rejects blacklisted authors provided as npub
|
|
---
|
|
duration_ms: 0.36329
|
|
type: 'test'
|
|
...
|
|
# Subtest: shouldIncludeVideo rejects blacklisted authors provided as hex when npubEncode throws
|
|
ok 3 - shouldIncludeVideo rejects blacklisted authors provided as hex when npubEncode throws
|
|
---
|
|
duration_ms: 0.466305
|
|
type: 'test'
|
|
...
|
|
# Subtest: shouldIncludeVideo always returns true for the viewer's own video
|
|
ok 4 - shouldIncludeVideo always returns true for the viewer's own video
|
|
---
|
|
duration_ms: 4.946118
|
|
type: 'test'
|
|
...
|
|
# Subtest: shouldIncludeVideo allows access when access control would deny the author
|
|
ok 5 - shouldIncludeVideo allows access when access control would deny the author
|
|
---
|
|
duration_ms: 55.162154
|
|
type: 'test'
|
|
...
|
|
[moderationService] subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
(moderationService) ensurePool failed while subscribing to trusted mute list for 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef Error: nostr-client-unavailable
|
|
at ModerationService.ensurePool (file:///app/js/services/moderationService.js:1842:13)
|
|
at file:///app/js/services/moderationService.js:1128:20
|
|
at ModerationService.subscribeToTrustedMuteList (file:///app/js/services/moderationService.js:1195:7)
|
|
at ModerationService.ensureViewerMuteListLoaded (file:///app/js/services/moderationService.js:1516:35)
|
|
at ModerationService.setViewerPubkey (file:///app/js/services/moderationService.js:1923:16)
|
|
1..5
|
|
# tests 5
|
|
# suites 0
|
|
# pass 5
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 74613.335323
|
|
|
|
→ Running tests/nostr/adapters.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: createNsecAdapter wires signing and cipher capabilities
|
|
ok 1 - createNsecAdapter wires signing and cipher capabilities
|
|
---
|
|
duration_ms: 150.290933
|
|
type: 'test'
|
|
...
|
|
# Subtest: createNip07Adapter maps extension methods and permissions
|
|
ok 2 - createNip07Adapter maps extension methods and permissions
|
|
---
|
|
duration_ms: 3.006499
|
|
type: 'test'
|
|
...
|
|
# Subtest: createNip46Adapter wraps the remote signer client
|
|
ok 3 - createNip46Adapter wraps the remote signer client
|
|
---
|
|
duration_ms: 0.958011
|
|
type: 'test'
|
|
...
|
|
1..3
|
|
# tests 3
|
|
# suites 0
|
|
# pass 3
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 175.387843
|
|
|
|
→ Running tests/nostr/cachePolicies.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
TAP version 13
|
|
# Subtest: CACHE_POLICIES structure
|
|
ok 1 - CACHE_POLICIES structure
|
|
---
|
|
duration_ms: 2.125347
|
|
type: 'test'
|
|
...
|
|
# Subtest: VIDEO_POST policy
|
|
ok 2 - VIDEO_POST policy
|
|
---
|
|
duration_ms: 0.367339
|
|
type: 'test'
|
|
...
|
|
# Subtest: WATCH_HISTORY policy
|
|
ok 3 - WATCH_HISTORY policy
|
|
---
|
|
duration_ms: 0.174163
|
|
type: 'test'
|
|
...
|
|
# Subtest: SUBSCRIPTION_LIST policy
|
|
ok 4 - SUBSCRIPTION_LIST policy
|
|
---
|
|
duration_ms: 0.281416
|
|
type: 'test'
|
|
...
|
|
# Subtest: VIDEO_COMMENT policy
|
|
ok 5 - VIDEO_COMMENT policy
|
|
---
|
|
duration_ms: 0.431424
|
|
type: 'test'
|
|
...
|
|
1..5
|
|
# tests 5
|
|
# suites 0
|
|
# pass 5
|
|
# fail 0
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 23.105958
|
|
|
|
→ Running tests/nostr/comment-events.test.mjs
|
|
[bitvid] Initialized nostr nip04 helpers.
|
|
[bitvid] Initialized nostr nip44 helpers.
|
|
[nostr] Comments cache miss for video-1
|
|
[nostr] Comments cache hit for video-1
|
|
[nostr] Comments cache hit for video-1
|
|
[nostr] Comments cache miss for video-rooted
|
|
[nostr] Comments cache miss for legacy-video
|
|
TAP version 13
|
|
# Subtest: publishComment prefers active signer when available
|
|
not ok 1 - publishComment prefers active signer when available
|
|
---
|
|
duration_ms: 7.754503
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:57:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
publish should succeed when relay accepts the event
|
|
|
|
false !== true
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: true
|
|
actual: false
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:96:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3)
|
|
...
|
|
# Subtest: publishComment rejects when active signer is unavailable
|
|
not ok 2 - publishComment rejects when active signer is unavailable
|
|
---
|
|
duration_ms: 2.486495
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:131:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
missing signer should yield auth-required
|
|
+ actual - expected
|
|
|
|
+ Error: Publishing comments is not allowed for session actors.
|
|
+ at publishComment (file:///app/js/nostr/commentEvents.js:1120:19)
|
|
+ at TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:139:24)
|
|
+ at Test.runInAsyncScope (node:async_hooks:214:14)
|
|
+ at Test.run (node:internal/test_runner/test:1047:25)
|
|
+ at Test.processPendingSubtests (node:internal/test_runner/test:744:18)
|
|
+ at Test.postRun (node:internal/test_runner/test:1173:19)
|
|
+ at Test.run (node:internal/test_runner/test:1101:12)
|
|
+ at async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3) {
|
|
+ code: 'session-actor-publish-blocked'
|
|
+ }
|
|
- 'auth-required'
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: 'auth-required'
|
|
actual:
|
|
error: 'Publishing comments is not allowed for session actors.'
|
|
code: 'session-actor-publish-blocked'
|
|
stack: |-
|
|
publishComment (file:///app/js/nostr/commentEvents.js:1120:19)
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:139:24)
|
|
Test.runInAsyncScope (node:async_hooks:214:14)
|
|
Test.run (node:internal/test_runner/test:1047:25)
|
|
Test.processPendingSubtests (node:internal/test_runner/test:744:18)
|
|
Test.postRun (node:internal/test_runner/test:1173:19)
|
|
Test.run (node:internal/test_runner/test:1101:12)
|
|
async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3)
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:154:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: publishComment accepts legacy targets with only an event id
|
|
not ok 3 - publishComment accepts legacy targets with only an event id
|
|
---
|
|
duration_ms: 1.286551
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:158:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
publishing should succeed without a definition address
|
|
|
|
false !== true
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: true
|
|
actual: false
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:185:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: publishComment derives root and parent metadata from parent comment tags
|
|
not ok 4 - publishComment derives root and parent metadata from parent comment tags
|
|
---
|
|
duration_ms: 3.902995
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:203:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
Expected values to be strictly deep-equal:
|
|
+ actual - expected
|
|
|
|
+ []
|
|
- [
|
|
- [
|
|
- 'A',
|
|
- '30078:videopk:root',
|
|
- 'wss://definition'
|
|
- ],
|
|
- [
|
|
- 'K',
|
|
- '30078'
|
|
- ],
|
|
- [
|
|
- 'P',
|
|
- 'videopk',
|
|
- 'wss://author'
|
|
- ],
|
|
- [
|
|
- 'E',
|
|
- 'video-event',
|
|
- 'wss://root'
|
|
- ],
|
|
- [
|
|
- 'E',
|
|
- 'parent-comment',
|
|
- 'wss://parent',
|
|
- 'parentpk'
|
|
- ],
|
|
- [
|
|
- 'K',
|
|
- '1111'
|
|
- ],
|
|
- [
|
|
- 'P',
|
|
- 'parentpk',
|
|
- 'wss://parent'
|
|
- ]
|
|
- ]
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected:
|
|
0:
|
|
0: 'A'
|
|
1: '30078:videopk:root'
|
|
2: 'wss://definition'
|
|
1:
|
|
0: 'K'
|
|
1: '30078'
|
|
2:
|
|
0: 'P'
|
|
1: 'videopk'
|
|
2: 'wss://author'
|
|
3:
|
|
0: 'E'
|
|
1: 'video-event'
|
|
2: 'wss://root'
|
|
4:
|
|
0: 'E'
|
|
1: 'parent-comment'
|
|
2: 'wss://parent'
|
|
3: 'parentpk'
|
|
5:
|
|
0: 'K'
|
|
1: '1111'
|
|
6:
|
|
0: 'P'
|
|
1: 'parentpk'
|
|
2: 'wss://parent'
|
|
actual:
|
|
operator: 'deepStrictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:240:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: listVideoComments matches comments even when tag casing and whitespace differ
|
|
ok 5 - listVideoComments matches comments even when tag casing and whitespace differ
|
|
---
|
|
duration_ms: 2.511808
|
|
type: 'test'
|
|
...
|
|
# Subtest: listVideoComments matches uppercase definition addresses without lowering
|
|
not ok 6 - listVideoComments matches uppercase definition addresses without lowering
|
|
---
|
|
duration_ms: 1.510679
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:290:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
matched event should be returned
|
|
+ actual - expected
|
|
|
|
+ 'case-comment'
|
|
- 'uppercase-comment'
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: 'uppercase-comment'
|
|
actual: 'case-comment'
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:312:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: publishComment emits only uppercase video event pointer when address and parent are absent
|
|
not ok 7 - publishComment emits only uppercase video event pointer when address and parent are absent
|
|
---
|
|
duration_ms: 0.762215
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:323:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
publishing should succeed with only a video id
|
|
|
|
false !== true
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: true
|
|
actual: false
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:345:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: listVideoComments builds filters with uppercase roots plus legacy fallbacks
|
|
not ok 8 - listVideoComments builds filters with uppercase roots plus legacy fallbacks
|
|
---
|
|
duration_ms: 1.202307
|
|
type: 'test'
|
|
location: '/app/tests/nostr/comment-events.test.mjs:359:1'
|
|
failureType: 'testCodeFailure'
|
|
error: |-
|
|
newest event should be retained
|
|
+ actual - expected
|
|
|
|
+ 'case-comment'
|
|
- 'comment-2'
|
|
|
|
code: 'ERR_ASSERTION'
|
|
name: 'AssertionError'
|
|
expected: 'comment-2'
|
|
actual: 'case-comment'
|
|
operator: 'strictEqual'
|
|
stack: |-
|
|
TestContext.<anonymous> (file:///app/tests/nostr/comment-events.test.mjs:416:10)
|
|
async Test.run (node:internal/test_runner/test:1054:7)
|
|
async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
|
|
...
|
|
# Subtest: listVideoComments emits uppercase root filters when only the identifier is known
|
|
ok 9 - listVideoComments emits uppercase root filters when only the identifier is known
|
|
---
|
|
duration_ms: 4.010105
|
|
type: 'test'
|
|
...
|
|
# Subtest: listVideoComments supports legacy targets without a definition address
|
|
ok 10 - listVideoComments supports legacy targets without a definition address
|
|
---
|
|
duration_ms: 2.422431
|
|
type: 'test'
|
|
...
|
|
# Subtest: subscribeVideoComments forwards matching events and cleans up unsubscribe
|
|
ok 11 - subscribeVideoComments forwards matching events and cleans up unsubscribe
|
|
---
|
|
duration_ms: 29.092262
|
|
type: 'test'
|
|
...
|
|
# Subtest: subscribeVideoComments supports video targets without a definition address
|
|
ok 12 - subscribeVideoComments supports video targets without a definition address
|
|
---
|
|
duration_ms: 2.015456
|
|
type: 'test'
|
|
...
|
|
1..12
|
|
# tests 12
|
|
# suites 0
|
|
# pass 5
|
|
# fail 7
|
|
# cancelled 0
|
|
# skipped 0
|
|
# todo 0
|
|
# duration_ms 77.571445
|
|
file:///app/scripts/run-unit-tests.mjs:68
|
|
reject(new Error(`${relativePath} failed with exit code ${code}`));
|
|
^
|
|
|
|
Error: tests/nostr/comment-events.test.mjs failed with exit code 1
|
|
at ChildProcess.<anonymous> (file:///app/scripts/run-unit-tests.mjs:68:16)
|
|
at ChildProcess.emit (node:events:519:28)
|
|
at maybeClose (node:internal/child_process:1101:16)
|
|
at ChildProcess._handle.onexit (node:internal/child_process:304:5)
|
|
|
|
Node.js v22.21.1
|