feat(tests): move SDK integration tests to integration-tests to share globalSetup

This commit is contained in:
mingholy.lmh
2025-12-01 14:56:11 +08:00
parent ae7d6af717
commit 3056f8a63d
17 changed files with 95 additions and 86 deletions

View File

@@ -238,7 +238,7 @@ export default tseslint.config(
prettierConfig,
// extra settings for scripts that we run directly with node
{
files: ['./integration-tests/**/*.js'],
files: ['./integration-tests/**/*.{js,ts,tsx}'],
languageOptions: {
globals: {
...globals.node,

View File

@@ -1,6 +1,6 @@
/**
* @license
* Copyright 2025 Google LLC
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,6 +30,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = join(__dirname, '..');
const integrationTestsDir = join(rootDir, '.integration-tests');
let runDir = ''; // Make runDir accessible in teardown
let sdkE2eRunDir = ''; // SDK E2E test run directory
const memoryFilePath = join(
os.homedir(),
@@ -48,14 +49,36 @@ export async function setup() {
// File doesn't exist, which is fine.
}
// Setup for CLI integration tests
runDir = join(integrationTestsDir, `${Date.now()}`);
await mkdir(runDir, { recursive: true });
// Setup for SDK E2E tests (separate directory with prefix)
sdkE2eRunDir = join(integrationTestsDir, `sdk-e2e-${Date.now()}`);
await mkdir(sdkE2eRunDir, { recursive: true });
// Clean up old test runs, but keep the latest few for debugging
try {
const testRuns = await readdir(integrationTestsDir);
if (testRuns.length > 5) {
const oldRuns = testRuns.sort().slice(0, testRuns.length - 5);
// Clean up old CLI integration test runs (without sdk-e2e- prefix)
const cliTestRuns = testRuns.filter((run) => !run.startsWith('sdk-e2e-'));
if (cliTestRuns.length > 5) {
const oldRuns = cliTestRuns.sort().slice(0, cliTestRuns.length - 5);
await Promise.all(
oldRuns.map((oldRun) =>
rm(join(integrationTestsDir, oldRun), {
recursive: true,
force: true,
}),
),
);
}
// Clean up old SDK E2E test runs (with sdk-e2e- prefix)
const sdkTestRuns = testRuns.filter((run) => run.startsWith('sdk-e2e-'));
if (sdkTestRuns.length > 5) {
const oldRuns = sdkTestRuns.sort().slice(0, sdkTestRuns.length - 5);
await Promise.all(
oldRuns.map((oldRun) =>
rm(join(integrationTestsDir, oldRun), {
@@ -69,24 +92,37 @@ export async function setup() {
console.error('Error cleaning up old test runs:', e);
}
// Environment variables for CLI integration tests
process.env['INTEGRATION_TEST_FILE_DIR'] = runDir;
process.env['GEMINI_CLI_INTEGRATION_TEST'] = 'true';
process.env['TELEMETRY_LOG_FILE'] = join(runDir, 'telemetry.log');
// Environment variables for SDK E2E tests
process.env['E2E_TEST_FILE_DIR'] = sdkE2eRunDir;
process.env['TEST_CLI_PATH'] = join(rootDir, 'dist/cli.js');
if (process.env['KEEP_OUTPUT']) {
console.log(`Keeping output for test run in: ${runDir}`);
console.log(`Keeping output for SDK E2E test run in: ${sdkE2eRunDir}`);
}
process.env['VERBOSE'] = process.env['VERBOSE'] ?? 'false';
console.log(`\nIntegration test output directory: ${runDir}`);
console.log(`SDK E2E test output directory: ${sdkE2eRunDir}`);
console.log(`CLI path: ${process.env['TEST_CLI_PATH']}`);
}
export async function teardown() {
// Cleanup the test run directory unless KEEP_OUTPUT is set
// Cleanup the CLI test run directory unless KEEP_OUTPUT is set
if (process.env['KEEP_OUTPUT'] !== 'true' && runDir) {
await rm(runDir, { recursive: true, force: true });
}
// Cleanup the SDK E2E test run directory unless KEEP_OUTPUT is set
if (process.env['KEEP_OUTPUT'] !== 'true' && sdkE2eRunDir) {
await rm(sdkE2eRunDir, { recursive: true, force: true });
}
if (originalMemoryContent !== null) {
await mkdir(dirname(memoryFilePath), { recursive: true });
await writeFile(memoryFilePath, originalMemoryContent, 'utf-8');

View File

@@ -13,7 +13,7 @@ import {
isSDKAssistantMessage,
type TextBlock,
type ContentBlock,
} from '../../src/index.js';
} from '@qwen-code/sdk-typescript';
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
const SHARED_TEST_OPTIONS = createSharedTestOptions();

View File

@@ -12,12 +12,12 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
isSDKSystemMessage,
type SDKMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
extractText,

View File

@@ -10,8 +10,8 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
isSDKResultMessage,
isSDKSystemMessage,
@@ -19,7 +19,7 @@ import {
type SDKMessage,
type ToolUseBlock,
type SDKSystemMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
createMCPServer,

View File

@@ -4,8 +4,8 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKUserMessage,
isSDKAssistantMessage,
isSDKSystemMessage,
@@ -21,7 +21,7 @@ import {
type SDKMessage,
type ControlMessage,
type ToolUseBlock,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
const SHARED_TEST_OPTIONS = createSharedTestOptions();

View File

@@ -13,8 +13,8 @@ import {
beforeEach,
afterEach,
} from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
isSDKResultMessage,
isSDKUserMessage,
@@ -22,7 +22,7 @@ import {
type SDKUserMessage,
type ToolUseBlock,
type ContentBlock,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
createSharedTestOptions,

View File

@@ -4,8 +4,8 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
isSDKSystemMessage,
isSDKResultMessage,
@@ -13,7 +13,7 @@ import {
type SDKMessage,
type SDKSystemMessage,
type SDKAssistantMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
extractText,

View File

@@ -10,14 +10,14 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
type SDKMessage,
type SubagentConfig,
type ContentBlock,
type ToolUseBlock,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
extractText,

View File

@@ -4,12 +4,12 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
isSDKSystemMessage,
type SDKUserMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import { SDKTestHelper, createSharedTestOptions } from './test-helper.js';
const SHARED_TEST_OPTIONS = createSharedTestOptions();
@@ -265,7 +265,7 @@ describe('System Control (E2E)', () => {
// First model change
await q.setModel('qwen3-turbo');
resumeResolve1?.();
resumeResolve1!();
// Wait for second response
await Promise.race([
@@ -277,7 +277,7 @@ describe('System Control (E2E)', () => {
// Second model change
await q.setModel('qwen3-vl-plus');
resumeResolve2?.();
resumeResolve2!();
// Wait for third response
await Promise.race([

View File

@@ -21,12 +21,12 @@ import type {
ContentBlock,
TextBlock,
ToolUseBlock,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
isSDKAssistantMessage,
isSDKSystemMessage,
isSDKResultMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
// ============================================================================
// Core Test Helper Class

View File

@@ -12,11 +12,11 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { query } from '../../src/index.js';
import {
query,
isSDKAssistantMessage,
type SDKMessage,
} from '../../src/types/protocol.js';
} from '@qwen-code/sdk-typescript';
import {
SDKTestHelper,
extractText,

View File

@@ -2,7 +2,13 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"allowJs": true
"allowJs": true,
"baseUrl": ".",
"paths": {
"@qwen-code/sdk-typescript": [
"../packages/sdk-typescript/dist/index.d.ts"
]
}
},
"include": ["**/*.ts"],
"references": [{ "path": "../packages/core" }]

View File

@@ -1,12 +1,15 @@
/**
* @license
* Copyright 2025 Google LLC
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { defineConfig } from 'vitest/config';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const timeoutMinutes = Number(process.env.TB_TIMEOUT_MINUTES || '5');
const __dirname = dirname(fileURLToPath(import.meta.url));
const timeoutMinutes = Number(process.env['TB_TIMEOUT_MINUTES'] || '5');
const testTimeoutMs = timeoutMinutes * 60 * 1000;
export default defineConfig({
@@ -25,4 +28,13 @@ export default defineConfig({
},
},
},
resolve: {
alias: {
// Use built SDK bundle for e2e tests
'@qwen-code/sdk-typescript': resolve(
__dirname,
'../packages/sdk-typescript/dist/index.mjs',
),
},
},
});

View File

@@ -22,6 +22,7 @@
"scripts": {
"build": "node scripts/build.js",
"test": "vitest run",
"test:ci": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"lint": "eslint src test",

View File

@@ -18,6 +18,14 @@ export type {
SDKResultMessage,
SDKPartialAssistantMessage,
SDKMessage,
ControlMessage,
CLIControlRequest,
CLIControlResponse,
ControlCancelRequest,
SubagentConfig,
SubagentLevel,
ModelConfig,
RunConfig,
} from './types/protocol.js';
export {
@@ -26,6 +34,9 @@ export {
isSDKSystemMessage,
isSDKResultMessage,
isSDKPartialAssistantMessage,
isControlRequest,
isControlResponse,
isControlCancel,
} from './types/protocol.js';
export type {

View File

@@ -1,57 +0,0 @@
/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { mkdir, readdir, rm } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = join(__dirname, '../..');
const e2eTestsDir = join(rootDir, '.integration-tests');
let runDir = '';
export async function setup() {
runDir = join(e2eTestsDir, `sdk-e2e-${Date.now()}`);
await mkdir(runDir, { recursive: true });
// Clean up old test runs, but keep the latest few for debugging
try {
const testRuns = await readdir(e2eTestsDir);
const sdkTestRuns = testRuns.filter((run) => run.startsWith('sdk-e2e-'));
if (sdkTestRuns.length > 5) {
const oldRuns = sdkTestRuns.sort().slice(0, sdkTestRuns.length - 5);
await Promise.all(
oldRuns.map((oldRun) =>
rm(join(e2eTestsDir, oldRun), {
recursive: true,
force: true,
}),
),
);
}
} catch (e) {
console.error('Error cleaning up old test runs:', e);
}
process.env['E2E_TEST_FILE_DIR'] = runDir;
process.env['QWEN_CLI_E2E_TEST'] = 'true';
process.env['TEST_CLI_PATH'] = join(rootDir, '../../dist/cli.js');
if (process.env['KEEP_OUTPUT']) {
console.log(`Keeping output for test run in: ${runDir}`);
}
process.env['VERBOSE'] = process.env['VERBOSE'] ?? 'false';
console.log(`\nSDK E2E test output directory: ${runDir}`);
console.log(`CLI path: ${process.env['TEST_CLI_PATH']}`);
}
export async function teardown() {
// Cleanup the test run directory unless KEEP_OUTPUT is set
if (process.env['KEEP_OUTPUT'] !== 'true' && runDir) {
await rm(runDir, { recursive: true, force: true });
}
}