Repository navigation
fix(core): customElements wait read its timeout from the wrong argument, hanging the CLI forever (PER-10405) #2383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,7 +4,11 @@ import Percy from '@percy/core'; | |||||||
| import Pako from 'pako'; | ||||||||
| import DetectProxy from '@percy/client/detect-proxy'; | ||||||||
| import { validateSnapshotOptions } from '../src/snapshot.js'; | ||||||||
| import { Page, WAIT_FOR_CUSTOM_ELEMENTS_BODY } from '../src/page.js'; | ||||||||
| import { | ||||||||
| Page, | ||||||||
| WAIT_FOR_CUSTOM_ELEMENTS_BODY, | ||||||||
| DEFAULT_WAIT_FOR_CUSTOM_ELEMENTS_TIMEOUT | ||||||||
| } from '../src/page.js'; | ||||||||
|
|
||||||||
| describe('Percy', () => { | ||||||||
| let percy, server; | ||||||||
|
|
@@ -216,6 +220,31 @@ describe('Percy', () => { | |||||||
| ])); | ||||||||
| }); | ||||||||
|
|
||||||||
| it('does not hang on a page holding a never-defined custom element', async () => { | ||||||||
| // PER-10405: an unregistered tag matches `:not(:defined)` forever and its | ||||||||
| // `customElements.whenDefined()` never resolves, so the wait must fall back | ||||||||
| // on its own ceiling. | ||||||||
| server.reply('/', () => [200, 'text/html', ( | ||||||||
| '<p>hi</p><next-route-announcer></next-route-announcer>' | ||||||||
| )]); | ||||||||
| await percy.browser.launch(); | ||||||||
| let page = await percy.browser.page(); | ||||||||
| await page.goto('http://localhost:8000'); | ||||||||
|
|
||||||||
| let undefinedCount = await page.eval( | ||||||||
| () => document.querySelectorAll(':not(:defined)').length); | ||||||||
| expect(undefinedCount).toBe(1); | ||||||||
|
|
||||||||
| let start = Date.now(); | ||||||||
| await expectAsync(page.eval( | ||||||||
| WAIT_FOR_CUSTOM_ELEMENTS_BODY, | ||||||||
| DEFAULT_WAIT_FOR_CUSTOM_ELEMENTS_TIMEOUT | ||||||||
| )).toBeResolved(); | ||||||||
| let elapsed = Date.now() - start; | ||||||||
|
|
||||||||
| expect(elapsed).toBeLessThan(5000); | ||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Low] Elapsed assertion is upper-bound only
Suggestion: pin the deadline branch with a loose lower bound alongside it.
Suggested change
Reviewer: stack-code-reviewer |
||||||||
| }); | ||||||||
|
|
||||||||
| it('runs readiness check before serializing when readiness option is set', async () => { | ||||||||
| server.reply('/', () => [200, 'text/html', '<p>Hello Percy!</p>']); | ||||||||
|
|
||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Low] Ceiling
setTimeoutis never cleared on early resolveWhen
finish()is reached via the normal tick path (the common case —:not(:defined)empties on the first tick), this ceiling timer stays pending in the page realm untiltimeoutMselapses. Harmless, sincefinish()is idempotent viasettled, but it is an avoidable lingering timer.Suggestion: capture the id and clear it in
finish():Reviewer: stack-code-reviewer