diff --git a/playwright b/playwright index 1ab3002..502df20 160000 --- a/playwright +++ b/playwright @@ -1 +1 @@ -Subproject commit 1ab300291c842a7d9356790bca0b08532bf336d6 +Subproject commit 502df20d7577b20edc760c45a68c18e1b44724b2 diff --git a/playwriter/CHANGELOG.md b/playwriter/CHANGELOG.md index 6503328..e0e8b5b 100644 --- a/playwriter/CHANGELOG.md +++ b/playwriter/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.0.80 + +### Improvements + +- **Descriptive click timeout errors**: When `locator.click()` times out due to actionability failures, the error now includes the reason (e.g. "Element is not visible", "Element is not stable", " + + \`); + `, + }, + }) + const result = await client.callTool({ + name: 'execute', + arguments: { + code: js` + await state.errorTestPage.click('#hidden-btn'); + `, + }, + }) + expect((result as any).isError).toBe(true) + const text = (result as any).content[0].text + // Strip stack traces and call logs to only match the descriptive error line + const errorLine = text.split('\n').find((l: string) => l.includes('Timeout') || l.includes('not visible') || l.includes('not stable')) + expect(errorLine).toMatchInlineSnapshot(`"Error executing code: page.click: Timeout 2000ms exceeded. Element is not visible"`) + // Cleanup + await client.callTool({ name: 'execute', arguments: { code: js`await state.errorTestPage.close(); delete state.errorTestPage;` } }) + }, 30000) + + it('should show descriptive error when clicking an element covered by another', async () => { + await client.callTool({ + name: 'execute', + arguments: { + code: js` + state.errorTestPage = await context.newPage(); + await state.errorTestPage.setContent(\` +
+ +
Overlay
+
+ \`); + `, + }, + }) + const result = await client.callTool({ + name: 'execute', + arguments: { + code: js` + await state.errorTestPage.click('#covered-btn'); + `, + }, + }) + expect((result as any).isError).toBe(true) + const text = (result as any).content[0].text + const errorLine = text.split('\n').find((l: string) => l.includes('Timeout') || l.includes('intercepts')) + expect(errorLine).toMatchInlineSnapshot(`"Error executing code: page.click: Timeout 2000ms exceeded.
Overlay
intercepts pointer events"`) + await client.callTool({ name: 'execute', arguments: { code: js`await state.errorTestPage.close(); delete state.errorTestPage;` } }) + }, 30000) + + it('should show descriptive error when clicking a display:none element', async () => { + await client.callTool({ + name: 'execute', + arguments: { + code: js` + state.errorTestPage = await context.newPage(); + await state.errorTestPage.setContent(''); + `, + }, + }) + const result = await client.callTool({ + name: 'execute', + arguments: { + code: js` + await state.errorTestPage.click('#invisible'); + `, + }, + }) + expect((result as any).isError).toBe(true) + const text = (result as any).content[0].text + const errorLine = text.split('\n').find((l: string) => l.includes('Timeout') || l.includes('not visible')) + expect(errorLine).toMatchInlineSnapshot(`"Error executing code: page.click: Timeout 2000ms exceeded. Element is not visible"`) + await client.callTool({ name: 'execute', arguments: { code: js`await state.errorTestPage.close(); delete state.errorTestPage;` } }) + }, 30000) + })