Skip to content

Commit 28f2708

Browse files
committed
feat: support page reload
1 parent 21af8da commit 28f2708

File tree

4 files changed

+100
-79
lines changed

4 files changed

+100
-79
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,10 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
247247
- [`hover`](docs/tool-reference.md#hover)
248248
- [`press_key`](docs/tool-reference.md#press_key)
249249
- [`upload_file`](docs/tool-reference.md#upload_file)
250-
- **Navigation automation** (7 tools)
250+
- **Navigation automation** (6 tools)
251251
- [`close_page`](docs/tool-reference.md#close_page)
252252
- [`list_pages`](docs/tool-reference.md#list_pages)
253253
- [`navigate_page`](docs/tool-reference.md#navigate_page)
254-
- [`navigate_page_history`](docs/tool-reference.md#navigate_page_history)
255254
- [`new_page`](docs/tool-reference.md#new_page)
256255
- [`select_page`](docs/tool-reference.md#select_page)
257256
- [`wait_for`](docs/tool-reference.md#wait_for)

docs/tool-reference.md

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
- [`hover`](#hover)
1212
- [`press_key`](#press_key)
1313
- [`upload_file`](#upload_file)
14-
- **[Navigation automation](#navigation-automation)** (7 tools)
14+
- **[Navigation automation](#navigation-automation)** (6 tools)
1515
- [`close_page`](#close_page)
1616
- [`list_pages`](#list_pages)
1717
- [`navigate_page`](#navigate_page)
18-
- [`navigate_page_history`](#navigate_page_history)
1918
- [`new_page`](#new_page)
2019
- [`select_page`](#select_page)
2120
- [`wait_for`](#wait_for)
@@ -151,18 +150,8 @@
151150
**Parameters:**
152151

153152
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
154-
- **url** (string) **(required)**: URL to navigate the page to
155-
156-
---
157-
158-
### `navigate_page_history`
159-
160-
**Description:** Navigates the currently selected page.
161-
162-
**Parameters:**
163-
164-
- **navigate** (enum: "back", "forward") **(required)**: Whether to navigate back or navigate forward in the selected pages history
165-
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
153+
- **type** (enum: "url", "back", "forward", "reload") _(optional)_: Navigate the page by URL, back or forward in history, or reload.
154+
- **url** (string) _(optional)_: Target URL (only type=url)
166155

167156
---
168157

src/tools/pages.ts

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -105,35 +105,13 @@ export const navigatePage = defineTool({
105105
readOnlyHint: false,
106106
},
107107
schema: {
108-
url: zod.string().describe('URL to navigate the page to'),
109-
...timeoutSchema,
110-
},
111-
handler: async (request, response, context) => {
112-
const page = context.getSelectedPage();
113-
114-
await context.waitForEventsAfterAction(async () => {
115-
await page.goto(request.params.url, {
116-
timeout: request.params.timeout,
117-
});
118-
});
119-
120-
response.setIncludePages(true);
121-
},
122-
});
123-
124-
export const navigatePageHistory = defineTool({
125-
name: 'navigate_page_history',
126-
description: `Navigates the currently selected page.`,
127-
annotations: {
128-
category: ToolCategory.NAVIGATION,
129-
readOnlyHint: false,
130-
},
131-
schema: {
132-
navigate: zod
133-
.enum(['back', 'forward'])
108+
type: zod
109+
.enum(['url', 'back', 'forward', 'reload'])
110+
.optional()
134111
.describe(
135-
'Whether to navigate back or navigate forward in the selected pages history',
112+
'Navigate the page by URL, back or forward in history, or reload.',
136113
),
114+
url: zod.string().optional().describe('Target URL (only type=url)'),
137115
...timeoutSchema,
138116
},
139117
handler: async (request, response, context) => {
@@ -142,18 +120,69 @@ export const navigatePageHistory = defineTool({
142120
timeout: request.params.timeout,
143121
};
144122

145-
try {
146-
if (request.params.navigate === 'back') {
147-
await page.goBack(options);
148-
} else {
149-
await page.goForward(options);
150-
}
151-
} catch (error) {
152-
response.appendResponseLine(
153-
`Unable to navigate ${request.params.navigate} in currently selected page. ${error.message}`,
154-
);
123+
if (!request.params.type && !request.params.url) {
124+
throw new Error('Either URL or a type is required.');
155125
}
156126

127+
if (!request.params.type) {
128+
request.params.type = 'url';
129+
}
130+
131+
await context.waitForEventsAfterAction(async () => {
132+
try {
133+
switch (request.params.type) {
134+
case 'url':
135+
if (!request.params.url) {
136+
throw new Error('A URL is required for navigation of type=url.');
137+
}
138+
await page.goto(request.params.url, options);
139+
response.appendResponseLine(
140+
`Successfully navigated to ${request.params.url}.`,
141+
);
142+
break;
143+
case 'back':
144+
await page.goBack(options);
145+
response.appendResponseLine(
146+
`Successfully navigated back to ${page.url()}.`,
147+
);
148+
break;
149+
case 'forward':
150+
await page.goForward(options);
151+
response.appendResponseLine(
152+
`Successfully navigated forward to ${page.url()}.`,
153+
);
154+
break;
155+
case 'reload':
156+
await page.reload(options);
157+
response.appendResponseLine(`Successfully reloaded the page.`);
158+
break;
159+
}
160+
} catch (error) {
161+
switch (request.params.type) {
162+
case 'url':
163+
response.appendResponseLine(
164+
`Unable to navigate in the selected page: ${error.message}.`,
165+
);
166+
break;
167+
case 'back':
168+
response.appendResponseLine(
169+
`Unable to navigate back in the selected page: ${error.message}.`,
170+
);
171+
break;
172+
case 'forward':
173+
response.appendResponseLine(
174+
`Unable to navigate forward in the selected page: ${error.message}.`,
175+
);
176+
break;
177+
case 'reload':
178+
response.appendResponseLine(
179+
`Unable to reload the selected page: ${error.message}.`,
180+
);
181+
break;
182+
}
183+
}
184+
});
185+
157186
response.setIncludePages(true);
158187
},
159188
});

tests/tools/pages.test.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
closePage,
1515
selectPage,
1616
navigatePage,
17-
navigatePageHistory,
1817
resizePage,
1918
handleDialog,
2019
} from '../../src/tools/pages.js';
@@ -29,7 +28,7 @@ describe('pages', () => {
2928
});
3029
});
3130
});
32-
describe('browser_new_page', () => {
31+
describe('new_page', () => {
3332
it('create a page', async () => {
3433
await withBrowser(async (response, context) => {
3534
assert.strictEqual(context.getSelectedPageIdx(), 0);
@@ -43,7 +42,7 @@ describe('pages', () => {
4342
});
4443
});
4544
});
46-
describe('browser_close_page', () => {
45+
describe('close_page', () => {
4746
it('closes a page', async () => {
4847
await withBrowser(async (response, context) => {
4948
const page = await context.newPage();
@@ -67,7 +66,7 @@ describe('pages', () => {
6766
});
6867
});
6968
});
70-
describe('browser_select_page', () => {
69+
describe('select_page', () => {
7170
it('selects a page', async () => {
7271
await withBrowser(async (response, context) => {
7372
await context.newPage();
@@ -78,7 +77,7 @@ describe('pages', () => {
7877
});
7978
});
8079
});
81-
describe('browser_navigate_page', () => {
80+
describe('navigate_page', () => {
8281
it('navigates to correct page', async () => {
8382
await withBrowser(async (response, context) => {
8483
await navigatePage.handler(
@@ -118,17 +117,11 @@ describe('pages', () => {
118117
}
119118
});
120119
});
121-
});
122-
describe('browser_navigate_page_history', () => {
123120
it('go back', async () => {
124121
await withBrowser(async (response, context) => {
125122
const page = context.getSelectedPage();
126123
await page.goto('data:text/html,<div>Hello MCP</div>');
127-
await navigatePageHistory.handler(
128-
{params: {navigate: 'back'}},
129-
response,
130-
context,
131-
);
124+
await navigatePage.handler({params: {type: 'back'}}, response, context);
132125

133126
assert.equal(
134127
await page.evaluate(() => document.location.href),
@@ -142,8 +135,8 @@ describe('pages', () => {
142135
const page = context.getSelectedPage();
143136
await page.goto('data:text/html,<div>Hello MCP</div>');
144137
await page.goBack();
145-
await navigatePageHistory.handler(
146-
{params: {navigate: 'forward'}},
138+
await navigatePage.handler(
139+
{params: {type: 'forward'}},
147140
response,
148141
context,
149142
);
@@ -155,42 +148,53 @@ describe('pages', () => {
155148
assert.ok(response.includePages);
156149
});
157150
});
151+
it('reload', async () => {
152+
await withBrowser(async (response, context) => {
153+
const page = context.getSelectedPage();
154+
await page.goto('data:text/html,<div>Hello MCP</div>');
155+
await navigatePage.handler(
156+
{params: {type: 'reload'}},
157+
response,
158+
context,
159+
);
160+
161+
assert.equal(
162+
await page.evaluate(() => document.location.href),
163+
'data:text/html,<div>Hello MCP</div>',
164+
);
165+
assert.ok(response.includePages);
166+
});
167+
});
158168
it('go forward with error', async () => {
159169
await withBrowser(async (response, context) => {
160-
await navigatePageHistory.handler(
161-
{params: {navigate: 'forward'}},
170+
await navigatePage.handler(
171+
{params: {type: 'forward'}},
162172
response,
163173
context,
164174
);
165175

166176
assert.ok(
167177
response.responseLines
168178
.at(0)
169-
?.startsWith(
170-
'Unable to navigate forward in currently selected page.',
171-
),
179+
?.startsWith('Unable to navigate forward in the selected page:'),
172180
);
173181
assert.ok(response.includePages);
174182
});
175183
});
176184
it('go back with error', async () => {
177185
await withBrowser(async (response, context) => {
178-
await navigatePageHistory.handler(
179-
{params: {navigate: 'back'}},
180-
response,
181-
context,
182-
);
186+
await navigatePage.handler({params: {type: 'back'}}, response, context);
183187

184188
assert.ok(
185189
response.responseLines
186190
.at(0)
187-
?.startsWith('Unable to navigate back in currently selected page.'),
191+
?.startsWith('Unable to navigate back in the selected page:'),
188192
);
189193
assert.ok(response.includePages);
190194
});
191195
});
192196
});
193-
describe('browser_resize', () => {
197+
describe('resize', () => {
194198
it('create a page', async () => {
195199
await withBrowser(async (response, context) => {
196200
assert.strictEqual(context.getSelectedPageIdx(), 0);

0 commit comments

Comments
 (0)