Skip to content

Commit 234b209

Browse files
olaservoclaude
andcommitted
Fix resource refresh button not triggering re-fetch (#1120)
The readResource function had an early return when the resource URI was already cached, preventing the Refresh button from re-fetching. Add a force parameter to bypass the cache on refresh, and update the cache-hit path to still sync the displayed content when switching between previously viewed resources. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7c8b031 commit 234b209

3 files changed

Lines changed: 73 additions & 6 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { test, expect } from "@playwright/test";
2+
3+
const AUTH_TOKEN = process.env.MCP_PROXY_AUTH_TOKEN ?? "";
4+
const APP_URL = AUTH_TOKEN
5+
? `http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=${AUTH_TOKEN}`
6+
: "http://localhost:6274/";
7+
8+
test.describe("Resource Refresh Button", () => {
9+
test.beforeEach(async ({ page }) => {
10+
await page.goto(APP_URL);
11+
12+
// Set up STDIO transport with server-everything
13+
const transportSelect = page.getByLabel("Transport Type");
14+
await expect(transportSelect).toBeVisible();
15+
await expect(transportSelect).toContainText("STDIO");
16+
17+
const commandInput = page.locator("#command-input");
18+
await commandInput.fill("npx");
19+
20+
const argsInput = page.locator("#arguments-input");
21+
await argsInput.fill("-y @modelcontextprotocol/server-everything@latest");
22+
23+
// Connect
24+
await page.getByRole("button", { name: "Connect" }).click();
25+
26+
// Wait for connection to be established
27+
await expect(page.getByRole("button", { name: "Disconnect" })).toBeVisible({
28+
timeout: 30000,
29+
});
30+
});
31+
32+
test("should re-fetch resource when refresh button is clicked", async ({
33+
page,
34+
}) => {
35+
// Navigate to Resources tab
36+
await page.getByRole("tab", { name: "Resources" }).click();
37+
38+
// List resources
39+
await page.getByRole("button", { name: "List Resources" }).click();
40+
41+
// Wait for a resource to appear and click it
42+
const firstResource = page.getByText("architecture.md").first();
43+
await expect(firstResource).toBeVisible({ timeout: 10000 });
44+
await firstResource.click();
45+
46+
// Wait for resource content to load
47+
await page.waitForTimeout(2000);
48+
49+
// Count current resources/read entries in history
50+
const historyEntries = page.locator("text=resources/read");
51+
const initialCount = await historyEntries.count();
52+
expect(initialCount).toBeGreaterThanOrEqual(1);
53+
54+
// Click the Refresh button
55+
await page.getByRole("button", { name: "Refresh" }).click();
56+
57+
// Verify a new resources/read request appeared in history
58+
await expect(historyEntries).toHaveCount(initialCount + 1, {
59+
timeout: 10000,
60+
});
61+
});
62+
});

client/src/App.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -893,8 +893,13 @@ const App = () => {
893893
setPromptContent(JSON.stringify(response, null, 2));
894894
};
895895

896-
const readResource = async (uri: string) => {
897-
if (fetchingResources.has(uri) || resourceContentMap[uri]) {
896+
const readResource = async (uri: string, force: boolean = false) => {
897+
if (fetchingResources.has(uri)) {
898+
return;
899+
}
900+
901+
if (!force && resourceContentMap[uri]) {
902+
setResourceContent(resourceContentMap[uri]);
898903
return;
899904
}
900905

@@ -1471,9 +1476,9 @@ const App = () => {
14711476
setResourceTemplates([]);
14721477
setNextResourceTemplateCursor(undefined);
14731478
}}
1474-
readResource={(uri) => {
1479+
readResource={(uri, force) => {
14751480
clearError("resources");
1476-
readResource(uri);
1481+
readResource(uri, force);
14771482
}}
14781483
selectedResource={selectedResource}
14791484
setSelectedResource={(resource) => {

client/src/components/ResourcesTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const ResourcesTab = ({
4646
clearResources: () => void;
4747
listResourceTemplates: () => void;
4848
clearResourceTemplates: () => void;
49-
readResource: (uri: string) => void;
49+
readResource: (uri: string, force?: boolean) => void;
5050
selectedResource: Resource | null;
5151
setSelectedResource: (resource: Resource | null) => void;
5252
handleCompletion: (
@@ -229,7 +229,7 @@ const ResourcesTab = ({
229229
<Button
230230
variant="outline"
231231
size="sm"
232-
onClick={() => readResource(selectedResource.uri)}
232+
onClick={() => readResource(selectedResource.uri, true)}
233233
>
234234
<RefreshCw className="w-4 h-4 mr-2" />
235235
Refresh

0 commit comments

Comments
 (0)