chore: don't leak from waitFor (#22465)
Fixes https://github.com/microsoft/playwright/issues/22458
This commit is contained in:
		
							parent
							
								
									4e9faba34d
								
							
						
					
					
						commit
						d45efe881f
					
				|  | @ -6199,6 +6199,7 @@ | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "packages/playwright-ct-core": { |     "packages/playwright-ct-core": { | ||||||
|  |       "name": "@playwright/experimental-ct-core", | ||||||
|       "version": "1.33.0-next", |       "version": "1.33.0-next", | ||||||
|       "license": "Apache-2.0", |       "license": "Apache-2.0", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|  |  | ||||||
|  | @ -815,6 +815,10 @@ export class Frame extends SdkObject { | ||||||
|           result.dispose(); |           result.dispose(); | ||||||
|           return continuePolling; |           return continuePolling; | ||||||
|         } |         } | ||||||
|  |         if (options.omitReturnValue) { | ||||||
|  |           result.dispose(); | ||||||
|  |           return null; | ||||||
|  |         } | ||||||
|         const element = state === 'attached' || state === 'visible' ? await result.evaluateHandle(r => r.element) : null; |         const element = state === 'attached' || state === 'visible' ? await result.evaluateHandle(r => r.element) : null; | ||||||
|         result.dispose(); |         result.dispose(); | ||||||
|         if (!element) |         if (!element) | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ export type StrictOptions = { | ||||||
| 
 | 
 | ||||||
| export type QueryOnSelectorOptions = StrictOptions & TimeoutOptions; | export type QueryOnSelectorOptions = StrictOptions & TimeoutOptions; | ||||||
| 
 | 
 | ||||||
| export type WaitForElementOptions = TimeoutOptions & StrictOptions & { state?: 'attached' | 'detached' | 'visible' | 'hidden' }; | export type WaitForElementOptions = TimeoutOptions & StrictOptions & { state?: 'attached' | 'detached' | 'visible' | 'hidden' } & { omitReturnValue?: boolean }; | ||||||
| 
 | 
 | ||||||
| export type WaitForFunctionOptions = TimeoutOptions & { pollingInterval?: number }; | export type WaitForFunctionOptions = TimeoutOptions & { pollingInterval?: number }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -149,3 +149,33 @@ test('expect should not leak', async ({ page, mode, browserName, toImpl }) => { | ||||||
|     expect(counts.main + counts.utility).toBeLessThan(25); |     expect(counts.main + counts.utility).toBeLessThan(25); | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test('waitFor should not leak', async ({ page, mode, browserName, toImpl }) => { | ||||||
|  |   test.skip(mode !== 'default'); | ||||||
|  | 
 | ||||||
|  |   await page.setContent(` | ||||||
|  |     <button>static button 1</button> | ||||||
|  |     <button>static button 2</button> | ||||||
|  |     <div id="buttons"></div> | ||||||
|  |   `);
 | ||||||
|  | 
 | ||||||
|  |   for (let i = 0; i < 25; ++i) { | ||||||
|  |     await page.evaluate(i => { | ||||||
|  |       const element = document.createElement('button'); | ||||||
|  |       element.textContent = 'dynamic ' + i; | ||||||
|  |       document.getElementById('buttons').appendChild(element); | ||||||
|  |     }, i); | ||||||
|  |     await page.locator('#buttons > button').waitFor(); | ||||||
|  |     await page.evaluate(() => { | ||||||
|  |       document.getElementById('buttons').textContent = ''; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   expect(leakedJSHandles()).toBeFalsy(); | ||||||
|  | 
 | ||||||
|  |   if (browserName === 'chromium') { | ||||||
|  |     const counts = await objectCounts(toImpl(page), 'HTMLButtonElement'); | ||||||
|  |     expect(counts.main + counts.utility).toBeGreaterThanOrEqual(2); | ||||||
|  |     expect(counts.main + counts.utility).toBeLessThan(25); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue