Skip to content

[CI Failure Doctor] CI Failure Doctor: close_older_issues.test.cjs uses Jest instead of Vitest #10895

@github-actions

Description

@github-actions

Summary

The CI workflow failed on commit c1c6704 (PR #10882) because the newly added test file close_older_issues.test.cjs uses Jest test framework syntax (@jest/globals and jest.fn()) instead of the Vitest framework used throughout the codebase.

Failure Details

Root Cause Analysis

Primary Error

Error: Cannot find module '@jest/globals'
Require stack:
- /home/runner/work/gh-aw/gh-aw/actions/setup/js/close_older_issues.test.cjs
 ❯ close_older_issues.test.cjs:3:46

Technical Details

The test file close_older_issues.test.cjs (334 lines) uses Jest syntax patterns that are incompatible with Vitest:

Incorrect imports (Line 3):

const { describe, it, expect, beforeEach } = require("@jest/globals");

Incorrect mocking (Lines 8-10):

global.core = {
  info: jest.fn(),    // ❌ Should be vi.fn()
  warning: jest.fn(),
  error: jest.fn(),
};

Incorrect module loading:

  • Uses CommonJS require() instead of ES modules import

Correct Patterns Used in Other Test Files

All existing test files use Vitest:

// ✅ Correct - From add_comment.test.cjs, add_labels.test.cjs, etc.
import { describe, it, expect, beforeEach, vi } from "vitest";

const mockCore = {
  debug: vi.fn(),
  info: vi.fn(),
  warning: vi.fn(),
  error: vi.fn(),
};

Additional Test Failures

The run also showed 42 other test failures, mostly in collect_ndjson_output.test.cjs and safe_outputs_mcp_server_defaults.test.cjs, but these appear to be pre-existing issues unrelated to this specific failure.

Recommended Actions

Fix #1: Convert Test File to Vitest (Required)

Replace Jest syntax with Vitest in close_older_issues.test.cjs:

Changes needed:

  1. Update imports (line 3):

    // Before:
    const { describe, it, expect, beforeEach } = require("@jest/globals");
    
    // After:
    import { describe, it, expect, beforeEach, vi } from "vitest";
  2. Update module imports (line 4):

    // Before:
    const { closeOlderIssues, ... } = require("./close_older_issues.cjs");
    
    // After:
    import { closeOlderIssues, ... } from "./close_older_issues.cjs";
  3. Update mocking (lines 8-10):

    // Before:
    global.core = {
      info: jest.fn(),
      warning: jest.fn(),
      error: jest.fn(),
    };
    
    // After:
    global.core = {
      info: vi.fn(),
      warning: vi.fn(),
      error: vi.fn(),
    };
  4. Update all mock functions (lines 18-28 and throughout):

    // Before:
    mockGithub = {
      rest: {
        search: {
          issuesAndPullRequests: jest.fn(),
        },
        issues: {
          createComment: jest.fn(),
          update: jest.fn(),
        },
      },
    };
    
    // After:
    mockGithub = {
      rest: {
        search: {
          issuesAndPullRequests: vi.fn(),
        },
        issues: {
          createComment: vi.fn(),
          update: vi.fn(),
        },
      },
    };
  5. Update beforeEach (line 17):

    beforeEach(() => {
      vi.clearAllMocks();  // Instead of jest.clearAllMocks()
      // ... rest of setup
    });

Fix #2: Run Local Tests Before Committing

Always run the full test suite locally:

cd actions/setup/js
npm test

This would have caught the error immediately.

Prevention Strategies

1. Add Pre-commit Validation

Update AGENTS.md to emphasize test validation:

### JavaScript Test Requirements

**ALWAYS use Vitest patterns for JavaScript tests:**

1. **Imports**: Use `import { describe, it, expect, vi } from "vitest"`
2. **Mocking**: Use `vi.fn()` instead of `jest.fn()`
3. **Module loading**: Use ES module `import` instead of `require()`
4. **Clear mocks**: Use `vi.clearAllMocks()` instead of `jest.clearAllMocks()`

**Before committing JavaScript files:**
``````bash
cd actions/setup/js
npm ci              # Install dependencies
npm test           # Run all tests (includes typecheck)
npm run lint       # Run linter

Example - Correct test file structure:

import { describe, it, expect, beforeEach, vi } from "vitest";
import { myFunction } from "./my-module.cjs";

const mockCore = {
  info: vi.fn(),
  warning: vi.fn(),
  error: vi.fn(),
};

describe("my-module", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should do something", () => {
    // Test implementation
  });
});

### 2. Lint Rule for Jest Usage

Consider adding an ESLint rule to prevent Jest imports:

``````json
{
  "rules": {
    "no-restricted-imports": ["error", {
      "patterns": ["*jest*"]
    }]
  }
}

3. Template Test File

Create a template test file in the repository:

# actions/setup/js/TEMPLATE.test.cjs

AI Team Self-Improvement

Instructions to add to AGENTS.md:

### JavaScript Testing with Vitest (NOT Jest)

**CRITICAL**: This project uses **Vitest**, NOT Jest. Never import from `@jest/globals`.

**Correct test file pattern:**
``````javascript
// ✅ CORRECT - Always use this pattern
import { describe, it, expect, beforeEach, vi } from "vitest";
import { functionToTest } from "./module.cjs";

global.core = {
  info: vi.fn(),      // ✅ Use vi.fn()
  warning: vi.fn(),
  error: vi.fn(),
};

describe("module-name", () => {
  beforeEach(() => {
    vi.clearAllMocks();  // ✅ Use vi.clearAllMocks()
  });

  it("test description", async () => {
    // Test implementation
  });
});

Incorrect patterns to avoid:

// ❌ WRONG - Never use Jest
const { describe, it, expect } = require("@jest/globals");  // ❌ Wrong framework
const module = require("./module.cjs");                      // ❌ Use import instead
jest.fn()                                                    // ❌ Use vi.fn()
jest.clearAllMocks()                                         // ❌ Use vi.clearAllMocks()

Pre-commit checklist for JavaScript tests:

  • Import from vitest, NOT @jest/globals
  • Use vi.fn() for mocks, NOT jest.fn()
  • Use ES module import, NOT require()
  • Run npm test locally before committing
  • All tests pass with npm test

## Historical Context

This is a **new type of failure pattern**. While similar test-related issues have occurred before:
- Issue #3772: "Add test coverage for untested JavaScript files" emphasized using Vitest patterns
- Issue #10427: TypeScript type error in handle_agent_failure.cjs (different error type)

This is the **first time** a test file using Jest syntax has been merged to main, indicating that:
1. The pre-commit validation may not catch framework mismatches
2. Code reviewers may not have caught the Jest/Vitest difference
3. Local testing may have been skipped

## Files Affected

- `actions/setup/js/close_older_issues.test.cjs` - New test file with Jest syntax (334 lines)
- `actions/setup/js/close_older_issues.cjs` - New implementation file (259 lines)
- `actions/setup/js/create_issue.cjs` - Modified to integrate close-older-issues (21 changes)

## PR Context

PR #10882 added the "close-older-issues" feature to allow workflows to automatically close older issues when creating a new one. The implementation looks correct, but the test file was written using the wrong test framework.

## Verification Test

After applying the fix:

``````bash
cd actions/setup/js
npm ci
npm test 2>&1 | grep "close_older_issues.test.cjs"

# Expected: Tests should pass
# close_older_issues.test.cjs (15 tests) ✓

Investigation completed: 2026-01-20T20:00:00Z
Pattern stored: /tmp/gh-aw/cache-memory/investigations/2026-01-20-21185259940.json
Error Pattern: MODULE_NOT_FOUND_JEST_GLOBALS
Severity: High (blocks CI)
Complexity: Low (straightforward find-replace fix)
Automated Fix: Possible (systematic replacement of Jest with Vitest syntax)

AI generated by CI Failure Doctor

To add this workflow in your repository, run gh aw add githubnext/agentics/workflows/ci-doctor.md@ea350161ad5dcc9624cf510f134c6a9e39a6f94d. See usage guide.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions