AutomationFlowsAI & RAG › Automatic Jest Test Generation for Github Prs with Dual AI Review

Automatic Jest Test Generation for Github Prs with Dual AI Review

ByVarritech @varritech on n8n.io

This workflow listens for GitHub pull-request events, analyzes changed React/TypeScript files, auto-generates Jest tests via AI, has them reviewed by a second AI pass, and posts suggestions back as PR comments: GitHub Webhook → PR opened or updated Fetch & Diff → Retrieve raw…

Webhook trigger★★★★☆ complexityAI-powered24 nodesGitHubHTTP RequestGithub ToolOutput Parser StructuredAgentOpenAI Chat
AI & RAG Trigger: Webhook Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #4013 — we link there as the canonical source.

This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "7vi7pp915Xoh9Ovu",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automatic Unit Test Creator from Github",
  "tags": [],
  "nodes": [
    {
      "id": "abb61423-4f32-41ce-a519-754b0b960503",
      "name": "GH - Get PR",
      "type": "n8n-nodes-base.github",
      "position": [
        -1820,
        -420
      ],
      "parameters": {},
      "retryOnFail": true,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "4bef0a06-16e7-4016-badb-5dcfb4c60a69",
      "name": "GET .diff file",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -520,
        -100
      ],
      "parameters": {},
      "typeVersion": 4.2
    },
    {
      "id": "11edfe11-11a1-4182-bb00-377688d974ed",
      "name": "Splits text into array",
      "type": "n8n-nodes-base.code",
      "position": [
        -300,
        -100
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "24a69dd5-d956-480a-8b90-4bfe0b65846e",
      "name": "FIlter for components",
      "type": "n8n-nodes-base.code",
      "position": [
        -80,
        -100
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "865a7c7c-7459-4869-96b7-9b86b401426f",
      "name": "Extrat API URL, owner and repo",
      "type": "n8n-nodes-base.code",
      "position": [
        -940,
        40
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "3ba6c65f-0089-41b5-8af5-7bcc31345530",
      "name": "Get File name",
      "type": "n8n-nodes-base.code",
      "position": [
        -80,
        140
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "fc2667a8-ae72-40da-9a9d-be930fba5ebb",
      "name": "Get Files",
      "type": "n8n-nodes-base.githubTool",
      "position": [
        -1260,
        680
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3a32bccc-e751-4757-9d6e-04c4eab58988",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1020,
        680
      ],
      "parameters": {},
      "typeVersion": 1.2
    },
    {
      "id": "a112221f-9f2d-4199-83f8-e7713b20154b",
      "name": "Merge info needed",
      "type": "n8n-nodes-base.merge",
      "position": [
        -300,
        140
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "2a3ad69b-06af-41a7-a3dc-7ace5671553e",
      "name": "Test Maker",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1360,
        460
      ],
      "parameters": {},
      "typeVersion": 1.8
    },
    {
      "id": "87cbff84-a239-446e-a5c8-ed07432ab7a1",
      "name": "Get Repo",
      "type": "n8n-nodes-base.githubTool",
      "position": [
        -1140,
        680
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3913cdac-ff53-4a46-a445-2fd4b9ab3f9f",
      "name": "Code Reviewer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -900,
        460
      ],
      "parameters": {},
      "typeVersion": 1.8
    },
    {
      "id": "d36b6f35-1e25-4366-a23d-139e89eb45f0",
      "name": "o3-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1460,
        680
      ],
      "parameters": {},
      "typeVersion": 1.2
    },
    {
      "id": "c4611e9c-c51b-404d-968a-b144e4251f69",
      "name": "gpt4.1-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -840,
        680
      ],
      "parameters": {},
      "typeVersion": 1.2
    },
    {
      "id": "dfaedcea-5bf5-48f6-9776-f64bb96244ff",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -520,
        460
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "769d0846-4ba7-42bd-9117-8fc1cb9fbb2c",
      "name": "Prepare for POST",
      "type": "n8n-nodes-base.code",
      "position": [
        -300,
        460
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "3c8c6f4a-4031-47d4-9086-81d435f06238",
      "name": "POST Comments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -80,
        460
      ],
      "parameters": {},
      "typeVersion": 4.2
    },
    {
      "id": "bb3e84fb-f1a9-41f6-8e34-f6fb8b2b7ea7",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1240,
        40
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "d02bb743-f9ce-4753-9fb3-a0c99a7e5a19",
      "name": "2nd Node for Testing",
      "type": "n8n-nodes-base.code",
      "position": [
        -1560,
        -400
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "0a50732e-619d-4def-a63d-d5762934df9b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1860,
        -520
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "64f8767b-eb19-4aa1-ae71-6959c09c0d50",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -120
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "a3df6a54-8fd1-47fe-9e07-d9fb58baa1fa",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -620,
        -180
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "82b5aa37-2b56-436d-bde7-c8788357b6a6",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1880,
        380
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "460aeeaf-e104-4b9c-b434-335e4db73250",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -700,
        680
      ],
      "parameters": {},
      "typeVersion": 1.2
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d0882c15-ed71-40f6-acd7-5848ef4d6d72",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Prepare for POST",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Extrat API URL, owner and repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "o3-mini": {
      "ai_languageModel": [
        [
          {
            "node": "Test Maker",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get Repo": {
      "ai_tool": [
        [
          {
            "node": "Test Maker",
            "type": "ai_tool",
            "index": 0
          },
          {
            "node": "Code Reviewer",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get Files": {
      "ai_tool": [
        [
          {
            "node": "Test Maker",
            "type": "ai_tool",
            "index": 0
          },
          {
            "node": "Code Reviewer",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Test Maker": {
      "main": [
        [
          {
            "node": "Code Reviewer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GH - Get PR": {
      "main": [
        []
      ]
    },
    "gpt4.1-mini": {
      "ai_languageModel": [
        [
          {
            "node": "Code Reviewer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code Reviewer": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get File name": {
      "main": [
        [
          {
            "node": "Test Maker",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST Comments": {
      "main": [
        []
      ]
    },
    "GET .diff file": {
      "main": [
        [
          {
            "node": "Splits text into array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare for POST": {
      "main": [
        [
          {
            "node": "POST Comments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge info needed": {
      "main": [
        [
          {
            "node": "Get File name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2nd Node for Testing": {
      "main": [
        []
      ]
    },
    "FIlter for components": {
      "main": [
        [
          {
            "node": "Merge info needed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Splits text into array": {
      "main": [
        [
          {
            "node": "FIlter for components",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Test Maker",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Code Reviewer",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extrat API URL, owner and repo": {
      "main": [
        [
          {
            "node": "GET .diff file",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge info needed",
            "type": "main",
            "index": 1
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow listens for GitHub pull-request events, analyzes changed React/TypeScript files, auto-generates Jest tests via AI, has them reviewed by a second AI pass, and posts suggestions back as PR comments: GitHub Webhook → PR opened or updated Fetch & Diff → Retrieve raw…

Source: https://n8n.io/workflows/4013/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

by Varritech Technologies

Chat Trigger, Agent, OpenAI Chat +8
AI & RAG

⏺ 🚀 How it works

Agent, Anthropic Chat, Output Parser Structured +6
AI & RAG

🧠 Gwen – The AI Voice Marketing Agent Gwen is your intelligent voice-powered marketing assistant built in n8n. She combines the power of OpenAI, ElevenLabs, and automation workflows to handle content

Tool Workflow, Memory Buffer Window, Agent +10
AI & RAG

Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo

HTTP Request, Google Drive, Google Sheets +6
AI & RAG

Production-ready Reddit lead generation system with progressive data loading for optimal UX. This workflow integrates with a web frontend, sending results in real-time as they're processed instead of

Output Parser Structured, Agent, Reddit +3