Compare commits

...

1 Commits

Author SHA1 Message Date
bymyself
5c38946b56 test(e2e): de-flake node-move and assets filter tests
Stabilize timing/race causes behind burst CI failures for two of the
tests fixme'd in the flaky-e2e stopgap.

vueNodes node move (@mobile touch drag): the post-pan position was
asserted with `toBeCloseTo` at the default precision (2 digits ==
within 0.005px), which sub-pixel canvas rounding after a touch pan
cannot satisfy. Poll the header position and assert to the nearest
pixel (precision 0), so the check retries until the pan settles and
tolerates pixel quantization.

Assets sidebar filter helpers: `openFilterMenu`/`openSettingsMenu`
waited on the reka-ui popover with tight 3000ms explicit timeouts that
burst-fail under heavier (cloud) app inits; switch to retrying
`toBeVisible()` on the default timeout. `toggleMediaTypeFilter` also
read `aria-checked` before the popover finished its slide/fade
animation; assert the checkbox is visible first so the read doesn't
race the animation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 16:32:27 -07:00
2 changed files with 22 additions and 12 deletions

View File

@@ -418,26 +418,28 @@ export class AssetsSidebarTab extends SidebarTab {
async openSettingsMenu() {
await this.dismissToasts()
await this.settingsButton.click()
// Wait for popover content to render
await this.listViewOption
.or(this.gridViewOption)
.first()
.waitFor({ state: 'visible', timeout: 3000 })
// Wait for the popover content to render. Use the default timeout so slower
// (e.g. cloud) app inits don't burst-fail a tight explicit timeout.
await expect(
this.listViewOption.or(this.gridViewOption).first()
).toBeVisible()
}
async openFilterMenu() {
await this.dismissToasts()
await this.filterButton.click()
await this.filterCheckbox('Image').waitFor({
state: 'visible',
timeout: 3000
})
// Wait for the filter popover to open. Use the default timeout so slower
// (e.g. cloud) app inits don't burst-fail a tight explicit timeout.
await expect(this.filterCheckbox('Image')).toBeVisible()
}
async toggleMediaTypeFilter(
filter: MediaFilterKind | MediaFilterLabel
): Promise<void> {
const checkbox = this.filterCheckbox(filter)
// Ensure the popover has finished opening before reading its state; a stale
// read here races the reka-ui slide/fade animation.
await expect(checkbox).toBeVisible()
const before = await checkbox.getAttribute('aria-checked')
await checkbox.click()
const expected = before === 'true' ? 'false' : 'true'

View File

@@ -422,9 +422,17 @@ test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => {
loadCheckpointHeaderPos
)
const newHeaderPos = await getLoadCheckpointHeaderPos(comfyPage)
expect(newHeaderPos.x).toBeCloseTo(loadCheckpointHeaderPos.x + 64)
expect(newHeaderPos.y).toBeCloseTo(loadCheckpointHeaderPos.y + 64)
// Poll the header position so the assertion retries until the touch pan
// has settled, instead of reading a single mid-animation bounding box.
// A screen bounding box read is pixel-quantized, so assert to the nearest
// pixel (precision 0 == within 0.5px) rather than the default precision 2
// (within 0.005px), which sub-pixel canvas rounding cannot satisfy.
await expect
.poll(() => getHeaderPos(comfyPage, 'Load Checkpoint').then((p) => p.x))
.toBeCloseTo(loadCheckpointHeaderPos.x + 64, 0)
await expect
.poll(() => getHeaderPos(comfyPage, 'Load Checkpoint').then((p) => p.y))
.toBeCloseTo(loadCheckpointHeaderPos.y + 64, 0)
}
)
})