Skip to content

Commit 70e5641

Browse files
konardclaude
andcommitted
Add manual E2E test workflow for Qwen Code CLI
- Add .github/workflows/e2e-qwen.yml for manual E2E testing - Supports workflow_dispatch for manual trigger - Tests Qwen Code CLI installation and configuration - Tests agent-commander integration in dry-run mode - Provides clear instructions for authenticated testing - Add js/experiments/test-qwen-integration.mjs - Comprehensive test script for Qwen tool configuration - Tests model mapping, argument building, output parsing - Tests session ID extraction, usage extraction, error detection - Can be run locally without authentication 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4492953 commit 70e5641

File tree

2 files changed

+543
-0
lines changed

2 files changed

+543
-0
lines changed

.github/workflows/e2e-qwen.yml

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
name: E2E Tests - Qwen Code CLI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
test_prompt:
7+
description: 'Test prompt to send to Qwen Code'
8+
required: false
9+
default: 'Hello, respond with a single word: working'
10+
type: string
11+
working_directory:
12+
description: 'Working directory for the test'
13+
required: false
14+
default: '/tmp/qwen-e2e-test'
15+
type: string
16+
model:
17+
description: 'Model to use for testing'
18+
required: false
19+
default: 'qwen3-coder'
20+
type: choice
21+
options:
22+
- qwen3-coder
23+
- coder
24+
- gpt-4o
25+
26+
concurrency:
27+
group: e2e-qwen-${{ github.ref }}
28+
cancel-in-progress: true
29+
30+
jobs:
31+
e2e-qwen-test:
32+
name: Qwen Code E2E Test
33+
runs-on: ubuntu-latest
34+
steps:
35+
- uses: actions/checkout@v4
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: '20.x'
41+
42+
- name: Install dependencies
43+
working-directory: js
44+
run: npm install
45+
46+
- name: Install Qwen Code CLI
47+
run: |
48+
npm install -g @qwen-code/qwen-code@latest
49+
echo "Qwen Code CLI version:"
50+
qwen --version || echo "Version command not available"
51+
52+
- name: Create test working directory
53+
run: |
54+
mkdir -p ${{ github.event.inputs.working_directory || '/tmp/qwen-e2e-test' }}
55+
echo "# Test Project" > "${{ github.event.inputs.working_directory || '/tmp/qwen-e2e-test' }}/README.md"
56+
echo "This is a test project for Qwen Code E2E testing." >> "${{ github.event.inputs.working_directory || '/tmp/qwen-e2e-test' }}/README.md"
57+
58+
- name: Test Qwen Code CLI directly
59+
id: direct_test
60+
continue-on-error: true
61+
run: |
62+
echo "Testing Qwen Code CLI directly..."
63+
cd "${{ github.event.inputs.working_directory || '/tmp/qwen-e2e-test' }}"
64+
65+
# Test with headless mode (-p flag)
66+
# Note: This requires authentication. In CI, we test that the CLI is installed
67+
# and responds correctly to basic commands.
68+
69+
# Test help command
70+
echo "=== Testing help command ==="
71+
qwen --help || echo "Help command failed"
72+
73+
# Test version
74+
echo "=== Testing version ==="
75+
qwen --version || echo "Version command not available"
76+
77+
echo "direct_test_completed=true" >> $GITHUB_OUTPUT
78+
79+
- name: Test Qwen tool configuration
80+
run: |
81+
echo "Testing Qwen tool configuration..."
82+
cd js
83+
84+
# Create a test script to verify the tool configuration
85+
cat > test-qwen-config.mjs << 'EOF'
86+
import { getTool, listTools, isToolSupported } from './src/tools/index.mjs';
87+
88+
console.log('=== Qwen Tool Configuration Test ===\n');
89+
90+
// Test 1: List tools includes qwen
91+
const tools = listTools();
92+
console.log('Available tools:', tools);
93+
if (!tools.includes('qwen')) {
94+
console.error('FAIL: qwen not in tool list');
95+
process.exit(1);
96+
}
97+
console.log('PASS: qwen is in tool list\n');
98+
99+
// Test 2: isToolSupported returns true for qwen
100+
if (!isToolSupported({ toolName: 'qwen' })) {
101+
console.error('FAIL: qwen not supported');
102+
process.exit(1);
103+
}
104+
console.log('PASS: qwen is supported\n');
105+
106+
// Test 3: getTool returns qwen configuration
107+
const qwenTool = getTool({ toolName: 'qwen' });
108+
console.log('Qwen tool config:', {
109+
name: qwenTool.name,
110+
displayName: qwenTool.displayName,
111+
executable: qwenTool.executable,
112+
defaultModel: qwenTool.defaultModel,
113+
supportsJsonOutput: qwenTool.supportsJsonOutput,
114+
supportsYolo: qwenTool.supportsYolo,
115+
});
116+
117+
// Test 4: Model mapping works
118+
console.log('\nModel mapping tests:');
119+
const testModels = ['qwen3-coder', 'coder', 'gpt-4o', 'custom-model'];
120+
for (const model of testModels) {
121+
const mapped = qwenTool.mapModelToId({ model });
122+
console.log(` ${model} -> ${mapped}`);
123+
}
124+
125+
// Test 5: buildArgs produces correct arguments
126+
console.log('\nbuildArgs test:');
127+
const args = qwenTool.buildArgs({
128+
prompt: 'Test prompt',
129+
model: 'qwen3-coder',
130+
yolo: true,
131+
streamJson: true,
132+
});
133+
console.log(' Args:', args);
134+
135+
if (!args.includes('-p') || !args.includes('Test prompt')) {
136+
console.error('FAIL: prompt argument missing');
137+
process.exit(1);
138+
}
139+
if (!args.includes('--yolo')) {
140+
console.error('FAIL: --yolo flag missing');
141+
process.exit(1);
142+
}
143+
if (!args.includes('--output-format') || !args.includes('stream-json')) {
144+
console.error('FAIL: stream-json output format missing');
145+
process.exit(1);
146+
}
147+
console.log('PASS: buildArgs produces correct arguments\n');
148+
149+
// Test 6: buildCommand produces correct command
150+
console.log('buildCommand test:');
151+
const cmd = qwenTool.buildCommand({
152+
workingDirectory: '/tmp/test',
153+
prompt: 'Review code',
154+
model: 'coder',
155+
});
156+
console.log(' Command:', cmd);
157+
158+
if (!cmd.includes('qwen')) {
159+
console.error('FAIL: command does not include qwen');
160+
process.exit(1);
161+
}
162+
console.log('PASS: buildCommand produces correct command\n');
163+
164+
// Test 7: parseOutput handles NDJSON
165+
console.log('parseOutput test:');
166+
const testOutput = '{"type":"message","content":"Hello"}\n{"type":"done"}';
167+
const messages = qwenTool.parseOutput({ output: testOutput });
168+
console.log(' Parsed messages:', messages);
169+
170+
if (messages.length !== 2) {
171+
console.error('FAIL: expected 2 messages, got', messages.length);
172+
process.exit(1);
173+
}
174+
console.log('PASS: parseOutput handles NDJSON correctly\n');
175+
176+
// Test 8: extractSessionId works
177+
console.log('extractSessionId test:');
178+
const sessionOutput = '{"session_id":"test-123"}\n{"type":"done"}';
179+
const sessionId = qwenTool.extractSessionId({ output: sessionOutput });
180+
console.log(' Session ID:', sessionId);
181+
182+
if (sessionId !== 'test-123') {
183+
console.error('FAIL: expected test-123, got', sessionId);
184+
process.exit(1);
185+
}
186+
console.log('PASS: extractSessionId works correctly\n');
187+
188+
// Test 9: detectErrors finds errors
189+
console.log('detectErrors test:');
190+
const errorOutput = '{"type":"error","message":"Test error"}';
191+
const errorResult = qwenTool.detectErrors({ output: errorOutput });
192+
console.log(' Error result:', errorResult);
193+
194+
if (!errorResult.hasError) {
195+
console.error('FAIL: expected error to be detected');
196+
process.exit(1);
197+
}
198+
console.log('PASS: detectErrors works correctly\n');
199+
200+
console.log('=== All Qwen Tool Configuration Tests Passed ===');
201+
EOF
202+
203+
node test-qwen-config.mjs
204+
rm test-qwen-config.mjs
205+
206+
- name: Test agent-commander with Qwen (dry-run)
207+
run: |
208+
echo "Testing agent-commander with Qwen tool (dry-run mode)..."
209+
cd js
210+
211+
# Test the CLI in dry-run mode
212+
node bin/start-agent.mjs \
213+
--tool qwen \
214+
--working-directory "${{ github.event.inputs.working_directory || '/tmp/qwen-e2e-test' }}" \
215+
--prompt "${{ github.event.inputs.test_prompt || 'Hello, respond with a single word: working' }}" \
216+
--model "${{ github.event.inputs.model || 'qwen3-coder' }}" \
217+
--dry-run
218+
219+
- name: E2E Test Summary
220+
run: |
221+
echo "=== E2E Test Summary ==="
222+
echo ""
223+
echo "✅ Qwen Code CLI installed successfully"
224+
echo "✅ Qwen tool configuration tests passed"
225+
echo "✅ agent-commander dry-run with Qwen completed"
226+
echo ""
227+
echo "Note: Full E2E tests with actual API calls require authentication."
228+
echo "To run authenticated tests locally:"
229+
echo " 1. Install Qwen Code: npm install -g @qwen-code/qwen-code@latest"
230+
echo " 2. Authenticate: qwen then /auth"
231+
echo " 3. Run: start-agent --tool qwen --working-directory ./project --prompt 'Your prompt'"

0 commit comments

Comments
 (0)