Skip to content

Commit 76534ac

Browse files
miraoJaromir Obrclaude
authored
fix(playwright): don't block on debug element preview when element is removed (#5740)
In debug mode _locate() previews found elements via Locator.evaluate(), which auto-waits for the element to be attached. If the element was removed between all() and evaluate(), the step blocked for the full helper timeout and failed. Make the preview best-effort with a short timeout. Fixes #5739 Co-authored-by: Jaromir Obr <jobr@spork.tech> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent def64e2 commit 76534ac

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎lib/helper/Playwright.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4946,7 +4946,7 @@ async function highlightActiveElement(element) {
49464946
}
49474947

49484948
async function elToString(el, numberOfElements) {
4949-
const html = await el.evaluate(node => node.outerHTML)
4949+
const html = await el.evaluate(node => node.outerHTML, undefined, { timeout: 100 }).catch(() => '<unavailable>')
49504950
return (
49514951
html
49524952
.replace(/\n/g, '')

‎test/helper/Playwright_test.js‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,39 @@ describe('Playwright', function () {
697697
.then(res => res.length.should.be.equal(0)))
698698
})
699699

700+
describe('#_locate in debug mode', () => {
701+
it('should not wait for timeout when element is removed before preview', async () => {
702+
await I.amOnPage('/form/field')
703+
await I.executeScript(() => {
704+
const el = document.createElement('div')
705+
el.id = 'removed-element'
706+
document.body.append(el)
707+
})
708+
709+
const locatorProto = Object.getPrototypeOf(page.locator('body'))
710+
const originalAll = locatorProto.all
711+
locatorProto.all = async function () {
712+
const els = await originalAll.call(this)
713+
await page.evaluate(() => document.getElementById('removed-element')?.remove())
714+
return els
715+
}
716+
const debugMode = store.debugMode
717+
store.debugMode = true
718+
page.setDefaultTimeout(10000)
719+
720+
try {
721+
const start = Date.now()
722+
const els = await I._locate('#removed-element')
723+
els.length.should.be.equal(1)
724+
expect(Date.now() - start).to.be.below(1000)
725+
} finally {
726+
locatorProto.all = originalAll
727+
store.debugMode = debugMode
728+
page.setDefaultTimeout(I.options.timeout)
729+
}
730+
})
731+
})
732+
700733
describe('check fields: #seeInField, #seeCheckboxIsChecked, ...', () => {
701734
it('should throw error if field is not empty', () =>
702735
I.amOnPage('/form/empty')

0 commit comments

Comments
 (0)