Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/tools/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,12 @@ export const getTabId = definePageTool({
handler: async (request, response, context) => {
const page = context.getPageById(request.params.pageId);
const tabId = (page.pptrPage as unknown as CdpPage)._tabId;
// Puppeteer returns an empty string when the tab id is not known.
if (!tabId) {
response.appendResponseLine('The tab ID is not available for this page');
return;
}
response.setTabId(tabId);
response.appendResponseLine(`Tab ID: ${tabId}`);
},
});
54 changes: 49 additions & 5 deletions tests/tools/pages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1282,18 +1282,62 @@ describe('pages', () => {
await withMcpContext(async (response, context) => {
const page = context.getSelectedMcpPage().pptrPage;
// @ts-expect-error _tabId is internal.
assert.ok(typeof page._tabId === 'string');
// @ts-expect-error _tabId is internal.
page._tabId = 'test-tab-id';
const tabId = page._tabId as string;
assert.ok(tabId);
await getTabId.handler(
{params: {pageId: 1}, page: context.getSelectedMcpPage()},
response,
context,
);
const result = await response.handle('get_tab_id', context);
// @ts-expect-error structuredContent is not typed.
assert.strictEqual(result.structuredContent.tabId, tabId);
assert.deepStrictEqual(response.responseLines, [`Tab ID: ${tabId}`]);
});
});

it('reports the tab id when structured content is disabled', async () => {
await withMcpContext(
async (response, context) => {
const page = context.getSelectedMcpPage().pptrPage;
// @ts-expect-error _tabId is internal.
const tabId = page._tabId as string;
assert.ok(tabId);
await getTabId.handler(
{params: {pageId: 1}, page: context.getSelectedMcpPage()},
response,
context,
);
const result = await response.handle('get_tab_id', context);
const text = result.content
.map(part => (part.type === 'text' ? part.text : ''))
.join('\n');
assert.ok(
text.includes(tabId),
`expected the tab id in the response, got: ${text}`,
);
},
{},
{experimentalInteropTools: true, experimentalStructuredContent: false},
);
});

it('reports when the tab id is not available', async () => {
await withMcpContext(async (response, context) => {
const page = context.getSelectedMcpPage().pptrPage;
// @ts-expect-error _tabId is internal.
assert.strictEqual(result.structuredContent.tabId, 'test-tab-id');
assert.deepStrictEqual(response.responseLines, []);
page._tabId = '';
await getTabId.handler(
{params: {pageId: 1}, page: context.getSelectedMcpPage()},
response,
context,
);
const result = await response.handle('get_tab_id', context);
// @ts-expect-error structuredContent is not typed.
assert.strictEqual(result.structuredContent.tabId, undefined);
assert.deepStrictEqual(response.responseLines, [
'The tab ID is not available for this page',
]);
});
});
});
Expand Down