diff --git a/src/tools/utils.ts b/src/tools/utils.ts index 497b038..338c189 100644 --- a/src/tools/utils.ts +++ b/src/tools/utils.ts @@ -78,7 +78,13 @@ export function sanitizeForFilePath(s: string) { } export async function generateLocator(locator: playwright.Locator): Promise { - return (locator as any)._generateLocatorString(); + try { + return await (locator as any)._generateLocatorString(); + } catch (e) { + if (e instanceof Error && /locator._generateLocatorString: Timeout .* exceeded/.test(e.message)) + throw new Error('Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.'); + throw e; + } } export async function callOnPageNoTrace(page: playwright.Page, callback: (page: playwright.Page) => Promise): Promise { diff --git a/tests/core.spec.ts b/tests/core.spec.ts index 003ea98..a35e7ed 100644 --- a/tests/core.spec.ts +++ b/tests/core.spec.ts @@ -237,3 +237,41 @@ await page.setViewportSize({ width: 390, height: 780 }); \`\`\``); await expect.poll(() => client.callTool({ name: 'browser_snapshot' })).toContainTextContent('Window size: 390x780'); }); + +test('old locator error message', async ({ client, server }) => { + server.setContent('/', ` + + + + `, 'text/html'); + + expect(await client.callTool({ + name: 'browser_navigate', + arguments: { + url: server.PREFIX, + }, + })).toContainTextContent(` + - button "Button 1" [ref=e2] + - button "Button 2" [ref=e3] + `.trim()); + + await client.callTool({ + name: 'browser_click', + arguments: { + element: 'Button 1', + ref: 'e2', + }, + }); + + expect(await client.callTool({ + name: 'browser_click', + arguments: { + element: 'Button 2', + ref: 'e3', + }, + })).toContainTextContent('Ref not found'); +});