@nhonh/qabot 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nhonh/qabot",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "AI-powered universal QA automation tool. Import any project, AI analyzes and runs tests across all layers.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -94,9 +94,13 @@ export class AIEngine {
94
94
  if (!isFirst) {
95
95
  batchContext.existingTestCode = "";
96
96
  batchContext.sourceCode = "";
97
+ batchContext.isContinuation = true;
97
98
  }
98
99
  const prompt = buildGenerationPrompt(batches[i], batchContext);
99
- const code = await this.complete(prompt);
100
+ let code = await this.complete(prompt);
101
+ if (!isFirst) {
102
+ code = stripDuplicateImports(code);
103
+ }
100
104
  fullCode += (isFirst ? "" : "\n\n") + code;
101
105
  }
102
106
  } finally {
@@ -298,6 +302,36 @@ export class AIEngine {
298
302
  }
299
303
  }
300
304
 
305
+ function stripDuplicateImports(code) {
306
+ const lines = code.split("\n");
307
+ let inMockBlock = false;
308
+ let braceDepth = 0;
309
+ const filtered = [];
310
+
311
+ for (const line of lines) {
312
+ const trimmed = line.trim();
313
+
314
+ if (trimmed.startsWith("import ")) continue;
315
+ if (trimmed.startsWith("jest.mock(")) {
316
+ inMockBlock = true;
317
+ braceDepth = 0;
318
+ }
319
+
320
+ if (inMockBlock) {
321
+ braceDepth += (line.match(/\{/g) || []).length;
322
+ braceDepth -= (line.match(/\}/g) || []).length;
323
+ if (braceDepth <= 0 && trimmed.endsWith(");")) {
324
+ inMockBlock = false;
325
+ }
326
+ continue;
327
+ }
328
+
329
+ filtered.push(line);
330
+ }
331
+
332
+ return filtered.join("\n").trim();
333
+ }
334
+
301
335
  function resolveApiKey(config) {
302
336
  if (config.apiKey) return config.apiKey;
303
337
  if (config.apiKeyEnv) return process.env[config.apiKeyEnv] || "";
@@ -44,6 +44,11 @@ export function buildGenerationPrompt(testCases, context) {
44
44
  : "";
45
45
 
46
46
  const importPath = context.importPath || "../index";
47
+ const isContinuation = context.isContinuation || false;
48
+
49
+ const continuationRule = isContinuation
50
+ ? `\nIMPORTANT: This is a CONTINUATION batch. Do NOT include any import statements, require() calls, or jest.mock() calls. Write ONLY describe() and it() blocks. The imports and mocks are already defined in a previous batch.\n`
51
+ : "";
47
52
 
48
53
  return `You are a senior test engineer writing production-quality test code.
49
54
 
@@ -52,16 +57,15 @@ export function buildGenerationPrompt(testCases, context) {
52
57
  - Test Runner: ${context.runner || "jest"}
53
58
  - Language: JavaScript/JSX
54
59
  - Import path for module under test: "${importPath}"
55
- ${sourceSection}${existingTestSection}
60
+ ${sourceSection}${existingTestSection}${continuationRule}
56
61
  ## Test Cases to Implement
57
62
  ${JSON.stringify(testCases, null, 2)}
58
63
 
59
64
  ## Rules
60
- 1. Write a COMPLETE, RUNNABLE test file with all imports
65
+ 1. ${isContinuation ? "Write ONLY describe/it blocks — NO imports, NO jest.mock" : "Write a COMPLETE, RUNNABLE test file with all imports"}
61
66
  2. Use @testing-library/react for rendering components
62
67
  3. Use @testing-library/user-event for user interactions
63
- 4. Use jest.mock() for module mocking
64
- 5. Use screen queries: getByRole, getByText, getByTestId
68
+ ${isContinuation ? "" : "4. Use jest.mock() for module mocking\n"}5. Use screen queries: getByRole, getByText, getByTestId
65
69
  6. Use waitFor and findBy* for async assertions
66
70
  7. Each test must be independent — no shared mutable state
67
71
  8. Use descriptive it() names matching the test case names above
@@ -1,4 +1,4 @@
1
- export const VERSION = "0.5.0";
1
+ export const VERSION = "0.5.1";
2
2
  export const TOOL_NAME = "qabot";
3
3
 
4
4
  export const PROJECT_TYPES = [