test: refresh live deepwiki smoke
This commit is contained in:
parent
83cc3b9a4c
commit
b69dd07dba
14
CHANGELOG.md
14
CHANGELOG.md
@ -3,19 +3,19 @@
|
||||
## [Unreleased]
|
||||
|
||||
### CLI
|
||||
- `mcporter config add` now accepts plural `--args` as an alias for repeated stdio arguments, matching common CLI muscle memory. (PR #93, thanks @Jah-yee)
|
||||
- Preserve OAuth flow vs post-auth transport failures so invalid OAuth/provider errors surface directly, while real legacy 404/405 transport mismatches still fall back to SSE correctly. (PR #97, thanks @mavam)
|
||||
- Ignore static `Authorization` headers once OAuth is active so imported editor configs cannot override fresh OAuth tokens. (PR #123, thanks @ahonn)
|
||||
- Keep `mcporter call --output json` parseable by emitting valid JSON even when the command falls back to raw output. (PR #128, thanks @armanddp)
|
||||
- Render `resource` content blocks in call output helpers instead of dropping them, including markdown resources and JSON text payloads. (PR #124, thanks @mvanhorn)
|
||||
- Preserve full JSON/error payloads when `data` is just one field instead of collapsing the response to `data` alone. (PR #106, thanks @AielloChan)
|
||||
- Generated CLIs now parse object-valued flags as JSON and render object placeholders/examples with JSON-shaped help text, so tools like Jira `fields` no longer receive raw strings. (PR #114, thanks @v2nic)
|
||||
- Deduplicate concurrent keep-alive daemon restarts per server so repeated fatal errors only force-close the cached daemon transport once before retrying. (PR #125, thanks @zm2231)
|
||||
- Keep `mcporter call --output json` parseable by emitting valid JSON even when the command falls back to raw output. (PR #128, thanks @armanddp)
|
||||
- Ignore static `Authorization` headers once OAuth is active so imported editor configs cannot override fresh OAuth tokens. (PR #123, thanks @ahonn)
|
||||
- Preserve full JSON/error payloads when `data` is just one field instead of collapsing the response to `data` alone. (PR #106, thanks @AielloChan)
|
||||
- Render `resource` content blocks in call output helpers instead of dropping them, including markdown resources and JSON text payloads. (PR #124, thanks @mvanhorn)
|
||||
- Preserve OAuth flow vs post-auth transport failures so invalid OAuth/provider errors surface directly, while real legacy 404/405 transport mismatches still fall back to SSE correctly. (PR #97, thanks @mavam)
|
||||
- `mcporter config add` now accepts plural `--args` as an alias for repeated stdio arguments, matching common CLI muscle memory. (PR #93, thanks @Jah-yee)
|
||||
- Preserve default imports when `mcporter config add` writes a config file, instead of forcing `"imports": []`.
|
||||
- OAuth: avoid crashing on headless Linux when `xdg-open` is unavailable; clear stale dynamic-port client registrations; close callback server if stale-client persistence reads fail. (PR #72, thanks @mgonto)
|
||||
- Added optional `oauthScope`/`oauth_scope` config override as an escape hatch for providers that require explicit scopes.
|
||||
- `createCallResult().json()` now collects all parseable JSON entries from MCP content arrays (single item stays backward-compatible), and raw inspect depth now stays readable without unbounded traversal. (PR #91, thanks @Blankdlh)
|
||||
- OAuth wait/redirect now share one deferred to eliminate authorization race windows and preserve stable close-path errors, including wait-before-redirect and repeated-redirect flows. (PR #70, thanks @monotykamary)
|
||||
- `createCallResult().json()` now collects all parseable JSON entries from MCP content arrays (single item stays backward-compatible), and raw inspect depth now stays readable without unbounded traversal. (PR #91, thanks @Blankdlh)
|
||||
- Added `--raw-strings` (numeric coercion off) and `--no-coerce` (all coercion off) for `mcporter call` argument parsing so IDs/codes can stay literal strings. (PR #59, thanks @nobrainer-tech)
|
||||
- Added `CallResult.images()` plus opt-in `mcporter call --save-images <dir>` so image content blocks can be persisted without changing existing stdout output contracts. (PR #61, thanks @daniella-11ways)
|
||||
- OAuth transport retries now classify HTTP 405 as HTTP (not auth) and OAuth promotion applies to configured HTTP servers too, so post-auth fallback flows no longer drop credentials on 405-only endpoints. (PR #48, thanks @caseyg)
|
||||
|
||||
@ -20,12 +20,15 @@ MCP_LIVE_TESTS=1 pnpm test:live
|
||||
This runs the Vitest suite under `tests/live`, in-band, with longer timeouts.
|
||||
|
||||
## Current coverage
|
||||
- **DeepWiki** (both wire protocols):
|
||||
- Streamable HTTP: `https://mcp.deepwiki.com/mcp`
|
||||
- SSE: `https://mcp.deepwiki.com/sse`
|
||||
- Test: calls `read_wiki_structure repoName:facebook/react` and asserts a non-empty result.
|
||||
- **DeepWiki**:
|
||||
- Streamable HTTP success path: `https://mcp.deepwiki.com/mcp`
|
||||
- Deprecated SSE endpoint classification: `https://mcp.deepwiki.com/sse`
|
||||
- Tests:
|
||||
- call `read_wiki_structure repoName:facebook/react` and assert a non-empty result over Streamable HTTP
|
||||
- assert the legacy SSE endpoint currently returns a structured HTTP `410` issue envelope
|
||||
|
||||
## Notes
|
||||
- Tests are skipped entirely unless `MCP_LIVE_TESTS=1` is set.
|
||||
- Ensure network egress is allowed. No secrets are required for the current DeepWiki checks.
|
||||
- As of 2026-03-29, DeepWiki's hosted `/sse` endpoint responds with HTTP `410`, so the live suite treats that as a compatibility/error-classification smoke rather than a success-path transport check.
|
||||
- Keep assertions minimal to reduce flake; these are availability smokes, not full contract tests.
|
||||
|
||||
@ -3,10 +3,8 @@ import { promisify } from 'node:util';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const LIVE_FLAG = process.env.MCP_LIVE_TESTS === '1';
|
||||
const ENDPOINTS = [
|
||||
{ name: 'streamable-http', url: 'https://mcp.deepwiki.com/mcp' },
|
||||
{ name: 'sse', url: 'https://mcp.deepwiki.com/sse' },
|
||||
];
|
||||
const STREAMABLE_HTTP_URL = 'https://mcp.deepwiki.com/mcp';
|
||||
const SSE_URL = 'https://mcp.deepwiki.com/sse';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
@ -18,36 +16,47 @@ function skipReason(): string | undefined {
|
||||
}
|
||||
|
||||
describe.skipIf(Boolean(skipReason()))('deepwiki live', () => {
|
||||
ENDPOINTS.forEach(({ name, url }) => {
|
||||
it(`lists wiki structure via ${name}`, async () => {
|
||||
const { stdout, stderr } = await execFileAsync('node', [
|
||||
'dist/cli.js',
|
||||
'call',
|
||||
url,
|
||||
'read_wiki_structure',
|
||||
'repoName:facebook/react',
|
||||
'--output',
|
||||
'json',
|
||||
]);
|
||||
const normalized = stdout.trim() || stderr.trim();
|
||||
// Response comes back as a JS-object literal string; just assert it contains the section list.
|
||||
expect(normalized).toContain('Available pages for facebook/react');
|
||||
expect(normalized).toContain('Overview');
|
||||
}, 30_000);
|
||||
it('lists wiki structure via streamable-http', async () => {
|
||||
const { stdout, stderr } = await execFileAsync('node', [
|
||||
'dist/cli.js',
|
||||
'call',
|
||||
STREAMABLE_HTTP_URL,
|
||||
'read_wiki_structure',
|
||||
'repoName:facebook/react',
|
||||
'--output',
|
||||
'json',
|
||||
]);
|
||||
const normalized = stdout.trim() || stderr.trim();
|
||||
expect(normalized).toContain('Available pages for facebook/react');
|
||||
expect(normalized).toContain('Overview');
|
||||
}, 30_000);
|
||||
|
||||
it(`prints plain text when default output is used via ${name}`, async () => {
|
||||
const { stdout, stderr } = await execFileAsync('node', [
|
||||
'dist/cli.js',
|
||||
'call',
|
||||
url,
|
||||
'read_wiki_structure',
|
||||
'repoName:facebook/react',
|
||||
]);
|
||||
const normalized = (stdout || stderr).trim();
|
||||
expect(normalized).toContain('Available pages for facebook/react');
|
||||
// Ensure we rendered the text content, not the JSON envelope.
|
||||
expect(normalized).not.toContain('"type"');
|
||||
expect(normalized.startsWith('{')).toBe(false);
|
||||
}, 30_000);
|
||||
});
|
||||
it('prints the readable result when default output is used via streamable-http', async () => {
|
||||
const { stdout, stderr } = await execFileAsync('node', [
|
||||
'dist/cli.js',
|
||||
'call',
|
||||
STREAMABLE_HTTP_URL,
|
||||
'read_wiki_structure',
|
||||
'repoName:facebook/react',
|
||||
]);
|
||||
const normalized = (stdout || stderr).trim();
|
||||
expect(normalized).toContain('Available pages for facebook/react');
|
||||
expect(normalized).toContain('Overview');
|
||||
expect(normalized).not.toContain('"type"');
|
||||
}, 30_000);
|
||||
|
||||
it('reports the deprecated sse endpoint as a structured 410 issue', async () => {
|
||||
const { stdout, stderr } = await execFileAsync('node', [
|
||||
'dist/cli.js',
|
||||
'call',
|
||||
SSE_URL,
|
||||
'read_wiki_structure',
|
||||
'repoName:facebook/react',
|
||||
'--output',
|
||||
'json',
|
||||
]);
|
||||
const normalized = stdout.trim() || stderr.trim();
|
||||
expect(normalized).toContain('"statusCode": 410');
|
||||
expect(normalized).toContain('"kind": "http"');
|
||||
}, 30_000);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user