Merge pull request #2539 from PR0M3TH3AN/agents/daily/test-audit-agent-7897847175000456729

Run daily test audit and fix zero-assertion test
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-02-15 17:40:38 -05:00
commit d345edf9aa
11 files changed
+435 -3

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
# Context: Daily Test Audit
**Goal**: Run a daily audit of the test suite to verify test quality, identify flakiness, and ensure critical paths are covered.
**Scope**:
- Run unit tests with coverage.
- Detect flaky tests by re-running.
- Static analysis for anti-patterns.
- Generate a report.
**Definition of Done**:
- `test-audit-report-YYYY-MM-DD.md` created.
- Logs saved in `test_logs/`.
- Artifacts in `test-audit/`.
@@ -0,0 +1,3 @@
# Decisions
- Using `test-audit/` directory for temporary artifacts.
@@ -0,0 +1,24 @@
# Agent Completion Report: test-audit-agent
**Date**: 2026-02-15
**Agent**: test-audit-agent
**Status**: Success
## Summary
Executed the daily test audit workflow.
- Discovered test runner: `node:test` via `scripts/run-unit-tests.mjs`.
- Ran tests with coverage (c8).
- Detected 0 failing or flaky tests (based on 3 runs).
- Performed static analysis and identified suspicious tests.
- Generated `test-audit-report-2026-02-15.md`.
- Applied a quick fix to `tests/minimal-channel-profile.test.mjs` (zero assertions).
## Outputs
- `test-audit-report-2026-02-15.md`
- `test_logs/TEST_LOG_2026-02-15_20-00-00.md`
- `tests/minimal-channel-profile.test.mjs` (modified)
- `test-audit/` (artifacts)
## Next Steps
- Implement coverage improvements for `js/userBlocks.js`.
- Refactor `setTimeout` usage in tests.
+35
View File
@@ -0,0 +1,35 @@
import fs from 'fs';
import path from 'path';
const criticalFiles = [
'js/services/authService.js',
'js/relayManager.js',
'js/nostr/dmDecryptWorker.js',
'js/nostr/dmDecryptWorkerClient.js',
'js/nostr/watchHistory.js',
'js/userBlocks.js',
'js/ui/ambientBackground.js',
'torrent/app.js'
];
try {
const summary = JSON.parse(fs.readFileSync('test-audit/coverage/coverage-summary.json', 'utf8'));
const report = {};
for (const file of criticalFiles) {
// Find the file in the coverage summary keys (might be absolute paths)
const key = Object.keys(summary).find(k => k.endsWith(file));
if (key) {
report[file] = summary[key].lines.pct;
} else {
report[file] = 0; // Not covered
}
}
console.log("Critical Coverage Report:");
console.log(JSON.stringify(report, null, 2));
fs.writeFileSync('test-audit/coverage-gaps.json', JSON.stringify(report, null, 2));
} catch (e) {
console.error("Error processing coverage summary:", e);
}
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
OUTPUT="test-audit/suspicious-tests.txt"
echo "Suspicious Tests Report" > "$OUTPUT"
echo "=======================" >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "## Tests with zero assertions (heuristic)" >> "$OUTPUT"
# Find test files
find tests -name "*.test.mjs" -o -name "*.test.js" | while read f; do
if ! grep -qE "assert\.|expect\(|t\.is" "$f"; then
echo " - $f" >> "$OUTPUT"
fi
done
echo "" >> "$OUTPUT"
echo "## Tests using .only or .skip" >> "$OUTPUT"
grep -rE "\.(only|skip)\(" tests >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "## Tests using setTimeout/sleep" >> "$OUTPUT"
grep -rE "setTimeout\(|sleep\(|await delay\(" tests >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "## Tests using console logs" >> "$OUTPUT"
grep -rE "console\.(log|warn|error)" tests >> "$OUTPUT"
echo "" >> "$OUTPUT"
echo "## Tests using real network (fetch/axios/WebSocket)" >> "$OUTPUT"
grep -rE "fetch\(|axios\.|new WebSocket" tests >> "$OUTPUT"
+51
View File
@@ -0,0 +1,51 @@
# Test Audit Report: 2026-02-15
## Summary
- **Date**: 2026-02-15
- **Test Runner**: Node.js built-in runner (`node:test`)
- **Total Tests**: ~370
- **Pass Rate**: 100% (based on available runs)
- **Coverage**: Mixed. Core services like `authService` are well covered (77%), but `userBlocks.js` (26%) and `relayManager.js` (50%) need attention.
## Findings
### 1. Suspicious Tests
The following tests were identified as suspicious due to having zero assertions or relying on anti-patterns:
- `tests/minimal-channel-profile.test.mjs`: Zero assertions (smoke test).
- `tests/ui/components/debug_hashtag_strip_helper.test.mjs`: Zero assertions.
- `tests/minimal-webtorrent.test.mjs`: Zero assertions.
- Heavy reliance on `setTimeout` and `sleep` in many tests (e.g., `tests/webtorrent-regression.test.mjs`, `tests/video-card-source-visibility.test.mjs`), which can lead to flakiness.
### 2. Coverage Gaps (Critical Files)
| File | Coverage | Status |
|------|----------|--------|
| `js/userBlocks.js` | 25.86% | **CRITICAL** |
| `js/ui/ambientBackground.js` | 33.02% | High |
| `js/relayManager.js` | 49.93% | Medium |
| `js/nostr/watchHistory.js` | 58.14% | Medium |
| `js/services/authService.js` | 77.34% | Good |
| `js/nostr/dmDecryptWorkerClient.js` | 96.85% | Excellent |
`js/userBlocks.js` implements critical moderation logic (blocking/muting) and its low coverage is a significant risk. It includes a custom Bech32 decoder which appears to be largely untested (or testing relies on `NostrTools` which bypasses it).
### 3. Flakiness
No flaky tests were definitively identified in the sample runs, though the `setTimeout` usage suggests potential for future flakiness.
## Remediation Plan
### Immediate Actions
1. **Fix Zero Assertions**: Update `tests/minimal-channel-profile.test.mjs` to include explicit assertions.
2. **Coverage Improvements**: Plan to add tests for `js/userBlocks.js`, specifically targeting the internal Bech32 implementation and error handling paths.
### Tickets / Issues
- **ISSUE-001**: Increase test coverage for `js/userBlocks.js`.
- **Context**: Current coverage is 25%.
- **Action**: Add tests for internal Bech32 decoder (by simulating missing `NostrTools`) and edge cases in encryption/decryption ordering.
- **ISSUE-002**: Refactor `setTimeout` usage in tests.
- **Context**: 50+ instances of `setTimeout` found.
- **Action**: Replace with deterministic `waitFor` helpers or mock timers.
## Logs
- `test_logs/TEST_LOG_2026-02-15_20-00-00.md`
- `test-audit/suspicious-tests.txt`
- `test-audit/coverage-gaps.json`
+10
View File
@@ -0,0 +1,10 @@
{
"js/services/authService.js": 77.34,
"js/relayManager.js": 49.93,
"js/nostr/dmDecryptWorker.js": 71.8,
"js/nostr/dmDecryptWorkerClient.js": 96.85,
"js/nostr/watchHistory.js": 58.14,
"js/userBlocks.js": 25.86,
"js/ui/ambientBackground.js": 33.02,
"torrent/app.js": 0
}
+231
View File
@@ -0,0 +1,231 @@
Suspicious Tests Report
=======================
## Tests with zero assertions (heuristic)
- tests/minimal-channel-profile.test.mjs
- tests/ui/components/debug_hashtag_strip_helper.test.mjs
- tests/minimal-webtorrent.test.mjs
## Tests using .only or .skip
tests/nostr/sessionActor.test.mjs: t.skip("WebCrypto not available in this environment");
## Tests using setTimeout/sleep
tests/webtorrent-regression.test.mjs: setTimeout(() => {
tests/webtorrent-regression.test.mjs: setTimeout(() => {
tests/video-card-source-visibility.test.mjs: window.requestAnimationFrame = (cb) => setTimeout(() => cb(Date.now()), 16);
tests/video-card-source-visibility.test.mjs: window.requestAnimationFrame = (cb) => setTimeout(() => cb(Date.now()), 16);
tests/nostr-send-direct-message.test.mjs: setTimeout(() => process.exit(0), 100);
tests/nostr-send-direct-message.test.mjs: setTimeout(() => handler(), 0);
tests/view-counter.test.mjs:const flushPromises = () => new Promise((resolve) => setTimeout(resolve, 0));
tests/view-counter.test.mjs: setTimeout(() => handler(), 0);
tests/subscriptions-manager.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/nostr/toolkit.test.mjs: setTimeout(() => {
tests/nostr/sign-request-queue.test.mjs:const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
tests/nostr/sign-request-queue.test.mjs: await delay(50);
tests/nostr/sign-request-queue.test.mjs: await delay(100);
tests/nostr/integration-remote-flow.test.mjs: setTimeout(() => handler(), 0);
tests/nostr/dm-direct-message-flow.test.mjs: await new Promise((r) => setTimeout(r, intervalMs));
tests/nostr/dm-direct-message-flow.test.mjs: await new Promise((resolve) => setTimeout(resolve, 100)); // Still wait to ensure no duplication appears
tests/nostr/dmSignalEvents.test.mjs: if (event === 'ok') setTimeout(cb, 0);
tests/nostr/client.test.mjs: await new Promise(r => setTimeout(r, 300));
tests/nostr/client.test.mjs: if (evt === "eose") setTimeout(handler, 0);
tests/nostr/client.test.mjs: if (evt === "eose") setTimeout(handler, 0);
tests/nostr/nip07Permissions.test.js: setTimeout(() => {
tests/nostr/watchHistory.test.js: setTimeout(handler, 0);
tests/nostr/comment-events.test.mjs: await new Promise(resolve => setTimeout(resolve, 0));
tests/torrent/toast-service.test.mjs: await new Promise((resolve) => setTimeout(resolve, 250));
tests/hashtag-preferences.test.mjs: setTimeout(() => handler(), 0);
tests/hashtag-preferences.test.mjs: setTimeout(() => process.exit(0), 100);
tests/nostr-private-key-signer.test.mjs: setTimeout(() => process.exit(0), 100);
tests/e2e/webseed-playback.spec.ts: test.setTimeout(90000); // Increase timeout for fallback logic
tests/nwc-client.test.mjs: setTimeout(() => {
tests/nwc-client.test.mjs: setTimeout(() => {
tests/watchHistory/watch-history-telemetry.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/feed-engine.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/profile-cache.test.mjs: await new Promise((resolve) => setTimeout(resolve, 20));
tests/profile-cache.test.mjs: await new Promise((resolve) => setTimeout(resolve, 20));
tests/dm-normalization.test.mjs: await new Promise((resolve) => setTimeout(resolve, 50));
tests/dm-normalization.test.mjs: setTimeout(() => process.exit(0), 100);
tests/webtorrent-handlers.test.mjs: setTimeout(() => {
tests/webtorrent-handlers.test.mjs: await new Promise(r => setTimeout(r, 20));
tests/webtorrent-handlers.test.mjs: await new Promise(r => setTimeout(r, 20));
tests/sign-request-queue.test.mjs: await new Promise((resolve) => setTimeout(resolve, 50));
tests/sign-request-queue.test.mjs: await new Promise((resolve) => setTimeout(resolve, 50));
tests/sign-request-queue.test.mjs: await new Promise((resolve) => setTimeout(resolve, 200));
tests/moderation/video-card.test.mjs: window.requestAnimationFrame = (cb) => setTimeout(() => cb(Date.now()), 16);
tests/moderation/video-card.test.mjs: window.requestAnimationFrame = (cb) => setTimeout(() => cb(Date.now()), 16);
tests/moderation/video-card.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/moderation/video-card.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/moderation/video-card.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/moderation/video-card.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/moderation/submit-report.test.mjs: setTimeout(() => handler(), 0);
tests/race/nostr-client-init-race.test.mjs: await new Promise(resolve => setTimeout(resolve, 50));
tests/modal-accessibility.test.mjs: setTimeout(() => callback(Date.now()), 0);
tests/zap-split.test.mjs: setTimeout(() => {
tests/profile-modal-controller.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/profile-modal-controller.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/profile-modal-controller.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/auth-service.test.mjs: await new Promise((resolve) => setTimeout(resolve, 10));
tests/auth-service.test.mjs: await new Promise((resolve) => setTimeout(resolve, 10));
tests/test-helpers/wait-for.mjs: await new Promise((resolve) => setTimeout(resolve, interval));
tests/watch-history.test.mjs: setTimeout(() => {
tests/watch-history.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/watch-history.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/watch-history.test.mjs: await new Promise((resolve) => setTimeout(resolve, 0));
tests/user-blocks.test.mjs:await new Promise((resolve) => setTimeout(resolve, 100));
tests/user-blocks.test.mjs:await new Promise((resolve) => setTimeout(resolve, 100));
tests/nostr-service-access-control.test.mjs: setTimeout(() => process.exit(0), 100);
tests/nostr-login-permissions.test.mjs: setTimeout(() => reject(new Error("permission denied")), 300);
tests/admin-list-store.test.mjs: setTimeout(fn, delay);
tests/admin-list-store.test.mjs:await new Promise((resolve) => setTimeout(resolve, slowRelayDelayMs + 20));
tests/visual/overlay-layers.spec.ts: test.setTimeout(120_000);
tests/state/cache.test.mjs: await new Promise((resolve) => setTimeout(resolve, 10));
tests/nip07-concurrency.test.mjs: await new Promise(resolve => setTimeout(resolve, delay));
tests/nip07-concurrency.test.mjs: await new Promise(resolve => setTimeout(resolve, delay));
tests/nostr-nip46-queue.test.mjs: await new Promise(r => setTimeout(r, 10));
tests/nostr-nip46-queue.test.mjs: await new Promise(r => setTimeout(r, 50));
tests/nostr-nip46-queue.test.mjs: await new Promise(r => setTimeout(r, 100));
tests/ui/uploadModal-integration.test.mjs: await new Promise(r => setTimeout(r, 10));
tests/ui/url-health-controller.test.mjs: await new Promise(resolve => setTimeout(resolve, 100));
tests/ui/url-health-controller.test.mjs: setTimeout(handler, 10);
tests/ui/url-health-controller.test.mjs: setTimeout(handler, 10);
tests/ui/url-health-controller.test.mjs: setTimeout(handler, 0);
tests/ui/url-health-controller.test.mjs: await new Promise(resolve => setTimeout(resolve, 50));
tests/compliance/nip07_compliance.test.mjs: await new Promise(resolve => setTimeout(resolve, 50));
tests/unit/notificationController.test.mjs: setTimeout: mock.fn((cb, ms) => setTimeout(cb, ms)),
tests/unit/client-count-resilience.test.mjs: await new Promise(r => setTimeout(r, 100));
tests/unit/ui/videoModalController.test.mjs: await new Promise(resolve => setTimeout(resolve, 0));
tests/unit/ui/videoModalController.test.mjs: await new Promise(resolve => setTimeout(resolve, 0));
tests/nostr-signer-race.test.mjs: await new Promise(resolve => setTimeout(resolve, 50));
tests/embed_playback_check.spec.mjs: await new Promise(resolve => setTimeout(resolve, 2000));
tests/comment-thread-service.test.mjs:const tick = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms));
tests/services/link-preview-service.test.mjs: await new Promise((r) => setTimeout(r, 10));
tests/services/trustBootstrap.test.mjs: setTimeout(() => {
tests/services/trustBootstrap.test.mjs: await new Promise(resolve => setTimeout(resolve, 300));
tests/services/profileMetadataService.test.mjs: await new Promise(r => setTimeout(r, 0));
tests/services/relay-health-service.test.mjs: setTimeout(() => relay.emit("connect"), 10);
tests/services/playbackService_forcedSource.test.mjs: await new Promise(resolve => setTimeout(resolve, 200));
tests/services/playbackService_forcedSource.test.mjs: await new Promise(resolve => setTimeout(resolve, 200));
tests/services/playbackService_forcedSource.test.mjs: await new Promise(resolve => setTimeout(resolve, 200));
## Tests using console logs
tests/subscriptions-feed.test.mjs:console.log("subscriptions-feed tests passed");
tests/webtorrent-regression.test.mjs: console.log("Failed result:", result);
tests/video-modal-accessibility.test.mjs: console.warn("[tests] failed to reset runtime flags", error);
tests/video-modal-accessibility.test.mjs: console.warn(
tests/video-modal-accessibility.test.mjs: console.warn("[tests] app.destroy failed", error);
tests/video-modal-accessibility.test.mjs: console.warn("[tests] failed to reset runtime flags", error);
tests/nostr-publish-rejection.test.mjs: console.log("nostr publish rejection tests passed");
tests/zap-shared-state.test.mjs:console.log("zap-shared-state tests passed");
tests/view-counter.test.mjs: const originalWarn = console.warn;
tests/view-counter.test.mjs: console.warn = (...args) => {
tests/view-counter.test.mjs: console.warn = originalWarn;
tests/view-counter.test.mjs:console.log("View counter tests completed successfully.");
tests/nostr/countDiagnostics.test.mjs: // Mock console.warn
tests/nostr/countDiagnostics.test.mjs: originalConsoleWarn = console.warn;
tests/nostr/countDiagnostics.test.mjs: console.warn = (...args) => {
tests/nostr/countDiagnostics.test.mjs: console.warn = originalConsoleWarn;
tests/nostr/dmDecryptWorkerClient.test.mjs: originalConsoleWarn = console.warn;
tests/nostr/dmDecryptWorkerClient.test.mjs: // Set dev mode to true to ensure logger calls console.warn
tests/nostr/dmDecryptWorkerClient.test.mjs: console.warn = originalConsoleWarn;
tests/nostr/dmDecryptWorkerClient.test.mjs: console.warn = warnMock;
tests/nostr/nip04WorkerClient.test.mjs: if (console.warn.mock) console.warn.mock.restore();
tests/watch-history-feed.test.mjs:console.log("watch-history-feed.test.mjs completed successfully.");
tests/e2e/repro_issue.spec.ts: console.log('PAGE ERROR:', err.message);
tests/e2e/repro_issue.spec.ts: console.log('Timeout waiting for status change. Current status:', await page.locator('#embedStatus').textContent());
tests/e2e/repro_issue.spec.ts: console.error('Reproduced TypeError:', typeError);
tests/e2e/repro_issue.spec.ts: console.log('No TypeError found.');
tests/e2e/repro_issue.spec.ts: console.log('Console output:', consoleMessages.join('\n'));
tests/e2e/video-modal-share-bug.spec.ts: console.log(\`setGlobalModalState: \${name} = \${isOpen}\`);
tests/e2e/webseed-playback.spec.ts: console.error('Test failed to load video list. Body content:', body.substring(0, 500));
tests/app-batch-fetch-profiles.test.mjs: // console.log("pool.list called with relays:", relays);
tests/app-batch-fetch-profiles.test.mjs: // console.log("poolListCalls.length:", poolListCalls.length);
tests/app-batch-fetch-profiles.test.mjs: // console.log("nostrClient.relays:", nostrClient.relays);
tests/feed-engine.test.mjs:console.log("All feed engine tests passed");
tests/utils/domUtils.test.mjs: inlineScript.textContent = "console.log('hello')";
tests/utils/domUtils.test.mjs: assert.equal(container.querySelector("script").textContent, "console.log('hello')");
tests/event-schemas.test.mjs: originalWarn = console.warn;
tests/event-schemas.test.mjs: console.warn = (...args) => {
tests/event-schemas.test.mjs: console.warn = originalWarn;
tests/nostr-rebroadcast-guard.test.mjs:console.log("nostr rebroadcast guard tests passed");
tests/nostr-boost-actions.test.mjs:console.log("nostr boost action tests passed");
tests/check_resize_observer.mjs: console.log("globalThis.ResizeObserver:", typeof globalThis.ResizeObserver);
tests/nostr-ephemeral-dm-tester.html: console.log(`[${type.toUpperCase()}] ${msg}`);
tests/nostr-ephemeral-dm-tester.html: console.error(err);
tests/zap-split.test.mjs:console.log("zap-split tests passed");
tests/watch-history.test.mjs: console.log("Running normalizeActorKey short-circuit test...");
tests/watch-history.test.mjs: const originalWarn = console.warn;
tests/watch-history.test.mjs: console.warn = (...args) => {
tests/watch-history.test.mjs: console.warn = originalWarn;
tests/watch-history.test.mjs: console.log("Running normalizeActorKey manual fallback test...");
tests/watch-history.test.mjs: const originalWarn = console.warn;
tests/watch-history.test.mjs: console.warn = (...args) => {
tests/watch-history.test.mjs: console.warn = originalWarn;
tests/watch-history.test.mjs: console.warn("WARN: novEvent content is not JSON (likely encrypted), skipping payload assertions");
tests/watch-history.test.mjs: console.log("Running watch history snapshot inflight queue retention test...");
tests/watch-history.test.mjs: console.log("Running watch history snapshot merge test...");
tests/watch-history.test.mjs: console.log("Running watch history card playback metadata test...");
tests/watch-history.test.mjs: console.log("Running watch history stale cache refresh test...");
tests/watch-history.test.mjs: console.log("Running watch history local fallback test...");
tests/watch-history.test.mjs: console.log("Running watch history renderer feed registration fallback test...");
tests/watch-history.test.mjs: console.log("Running watch history logged-in sync override test...");
tests/watch-history.test.mjs: console.log("Running watch history app login fallback test...");
tests/watch-history.test.mjs: console.log("Running watch history feed hydration test...");
tests/watch-history.test.mjs:console.log("watch-history.test.mjs completed successfully");
tests/discussion-count-service.test.mjs:console.log("discussion-count-service tests passed");
tests/nostr-view-events.test.mjs:console.log("nostr view events tests passed");
tests/admin-list-store.test.mjs:const originalConsoleWarn = console.warn;
tests/admin-list-store.test.mjs:console.warn = (...args) => {
tests/admin-list-store.test.mjs: console.warn = originalConsoleWarn;
tests/admin-list-store.test.mjs:console.log("admin-list-store tests passed");
tests/nostr-count-fallback.test.mjs: const originalWarn = console.warn;
tests/nostr-count-fallback.test.mjs: console.warn = (...args) => {
tests/nostr-count-fallback.test.mjs: console.warn = originalWarn;
tests/nostr-count-fallback.test.mjs:console.log("nostr COUNT fallback tests completed successfully.");
tests/visual/moderation.spec.ts: page.on('console', msg => console.log('PAGE LOG:', msg.text()));
tests/visual/moderation.spec.ts: page.on('pageerror', err => console.log('PAGE ERROR:', err.message));
tests/benchmark-explore-data.spec.mjs: console.log(`[Benchmark] buildWatchHistoryTagCounts: ${result.countsTime.toFixed(2)}ms`);
tests/benchmark-explore-data.spec.mjs: console.log(`[Benchmark] buildTagIdf: ${result.idfTime.toFixed(2)}ms`);
tests/benchmark-explore-data.spec.mjs: console.log(`[Benchmark] Counts Size: ${result.countsSize}`);
tests/benchmark-explore-data.spec.mjs: console.log(`[Benchmark] IDF Size: ${result.idfSize}`);
tests/nostr-view-event-bindings.test.mjs:console.log("nostr-view-event-bindings tests passed");
tests/ui/components/debug_hashtag_strip_helper.test.mjs: console.log(`DEBUG: window.addEventListener('${event}') called`);
tests/ui/components/debug_hashtag_strip_helper.test.mjs: console.log("Global ResizeObserver type:", typeof globalThis.ResizeObserver);
tests/ui/components/debug_hashtag_strip_helper.test.mjs: console.log("Helper window ResizeObserver:", typeof helper.window.ResizeObserver);
tests/ui/uploadModal-reset.test.mjs: global.alert = (msg) => { console.log("ALERT CALLED:", msg); };
tests/ui/profileModalController-addProfile.test.mjs: showSuccess: (msg) => { console.log("Success:", msg); },
tests/ui/profileModalController-addProfile.test.mjs: showError: (msg) => { console.error("Error:", msg); },
tests/performance/resolvePostedAt.test.mjs: console.log(`pool.list calls: ${listCalls}`);
tests/performance/resolvePostedAt.test.mjs: console.log(`pool.get calls: ${getCalls}`);
tests/embed_playback_check.spec.mjs: console.log('Starting reproduction script...');
tests/embed_playback_check.spec.mjs: console.log(`Starting local relay on port ${relayPort}...`);
tests/embed_playback_check.spec.mjs: console.log(`Starting web server on port ${serverPort}...`);
tests/embed_playback_check.spec.mjs: console.log('Launching headless browser...');
tests/embed_playback_check.spec.mjs: console.log(`[BROWSER CONSOLE] ${msg.type()}: ${msg.text()}`);
tests/embed_playback_check.spec.mjs: console.log('!!! CAUGHT EXPECTED ERROR IN CONSOLE !!!');
tests/embed_playback_check.spec.mjs: console.log(`[BROWSER PAGEERROR] ${err.message}`);
tests/embed_playback_check.spec.mjs: console.log('!!! CAUGHT EXPECTED ERROR IN PAGEERROR !!!');
tests/embed_playback_check.spec.mjs: console.log(`Navigating to ${baseUrl} to setup...`);
tests/embed_playback_check.spec.mjs: console.log(`Published video event: ${eventId}`);
tests/embed_playback_check.spec.mjs: console.log(`Navigating to embed: ${embedUrl}`);
tests/embed_playback_check.spec.mjs: console.log(`Response status: ${response.status()} ${response.statusText()}`);
tests/embed_playback_check.spec.mjs: console.log(`Response url: ${response.url()}`);
tests/embed_playback_check.spec.mjs: console.log(`Current Location: ${locationHref}`);
tests/embed_playback_check.spec.mjs: console.log('Waiting for error...');
tests/embed_playback_check.spec.mjs: console.log(`Current Embed Status: "${statusText}"`);
tests/embed_playback_check.spec.mjs: console.error('FAILURE: TypeError still present.');
tests/embed_playback_check.spec.mjs: console.log('SUCCESS: TypeError fixed (not found).');
tests/embed_playback_check.spec.mjs: console.error('Test script error:', err);
tests/nostr-delete-flow.test.mjs:console.log("nostr delete flow tests passed");
tests/comment-thread-service.test.mjs: console.error("Test encountered errors:", errorPayloads);
tests/services/link-preview-service.test.mjs: console.warn("[LinkPreviewService Test] Database deletion blocked");
tests/services/exploreDataService.test.mjs: // Mock console.warn BEFORE import so logger.js captures the mock
tests/services/exploreDataService.test.mjs: // if console.warn is already mocked (e.g. by other tests? unlikely in isolated process), restore it first
tests/services/exploreDataService.test.mjs: if (console.warn.mock) console.warn.mock.restore();
## Tests using real network (fetch/axios/WebSocket)
tests/e2e/repro_issue.spec.ts: const ws = new WebSocket(RELAY_URL);
tests/e2e/agent-testability.spec.ts: const resp = await fetch(`${httpUrl}/events`);
tests/e2e/agent-testability.spec.ts: const resp = await fetch(`${httpUrl}/health`);
tests/e2e/helpers/bitvidTestFixture.ts: const resp = await fetch(`${httpUrl}/seed`, {
tests/e2e/helpers/bitvidTestFixture.ts: const resp = await fetch(`${httpUrl}/events`, { method: "DELETE" });
+29
View File
@@ -0,0 +1,29 @@
# Test Log: 2026-02-15
## Setup
- Created directories: `context`, `todo`, `decisions`, `test_logs`, `test-audit`.
- Detected test runner: `node:test` via `scripts/run-unit-tests.mjs`.
## Execution
1. **Coverage Run**:
- Command: `npx c8 --reporter=text --reporter=json-summary --report-dir=test-audit/coverage node scripts/run-unit-tests.mjs`
- Output: `test-audit/coverage-run.log`
- Artifacts: `test-audit/coverage/coverage-summary.json`
2. **Flakiness Check**:
- Command: `node scripts/run-unit-tests.mjs` (x2)
- Logs: `test-audit/flakiness-run-1.log`, `test-audit/flakiness-run-2.log`
- Result: No failures observed.
3. **Static Analysis**:
- Script: `scripts/agent/audit-static-analysis.sh`
- Output: `test-audit/suspicious-tests.txt`
4. **Coverage Mapping**:
- Script: `scripts/agent/audit-coverage-map.js`
- Output: `test-audit/coverage-gaps.json`
## Results
- **Pass Rate**: 100%
- **Critical Gaps**: `js/userBlocks.js` (25%).
- **Suspicious**: 3 tests with zero assertions.
+3 -3
View File
@@ -1,8 +1,8 @@
import "./test-helpers/setup-localstorage.mjs";
import test from "node:test";
import assert from "node:assert/strict";
import { renderChannelVideosFromList } from "../js/channelProfile.js";
test("can import channelProfile", () => {
if (typeof renderChannelVideosFromList !== "function") {
throw new Error("Import failed");
}
assert.equal(typeof renderChannelVideosFromList, "function", "Import failed");
});
+5
View File
@@ -0,0 +1,5 @@
- [ ] Discover test runner
- [ ] Run tests with coverage
- [ ] Run flakiness check (5x)
- [ ] Run static analysis
- [ ] Generate report