From 842a9f74fcc0b67a4936e05cac43e4af95b3aecf Mon Sep 17 00:00:00 2001 From: bymyself Date: Fri, 17 Jan 2025 15:11:49 -0700 Subject: [PATCH] [BrowserTest] Fix flaky gallery test (#2150) --- browser_tests/assets/image32x32.webp | Bin 0 -> 488 bytes browser_tests/assets/image64x64.webp | Bin 0 -> 1304 bytes .../fixtures/components/SidebarTab.ts | 26 +++++-- browser_tests/fixtures/utils/taskHistory.ts | 7 +- browser_tests/menu.spec.ts | 70 ++++++++---------- 5 files changed, 55 insertions(+), 48 deletions(-) create mode 100644 browser_tests/assets/image32x32.webp create mode 100644 browser_tests/assets/image64x64.webp diff --git a/browser_tests/assets/image32x32.webp b/browser_tests/assets/image32x32.webp new file mode 100644 index 0000000000000000000000000000000000000000..6e3e1811900763da75ed819b92ec7890d9f50f7b GIT binary patch literal 488 zcmV_h|Dj)zL06y(xs77+l{8<2hGyfO)M?7T+>dpyu+bF=N zn#9TY0RHT=TRZ>AP1|cYna%%z8`tOmyS`BUWFU2}W6bvjx#LOlT-%EH%YS|`7?Y(oQBxmbW<0t zKmCNMC;k6Lr@Wf8YEb{EHqf&P*+j?MdQwL~sAVkDp0j5ViAg74Wgtig|AH}PzTW4f zNbZ~ablj>z`(D>&N!953Fkh2&Bi-uHCAn!-P~Fg7Wy`SXL(S<2=G*w6|MYqPHy^o0 zX4AUc^`JiQ=>*kBg)u6!+35H0g*qxU5Nm{icZ^)J@?(ze&#svAD~9lYrOb$fey(+Y zcad`Cb`f;Wa^n~LHT?hhgl4lfJ)U30pBp}%ML2fOZ0EP-yx~S09$TSb=1n9CN@GH^ edHK0p!icco6nbjk^D1yuHVy&y5fbVBjsO6d>iB>F literal 0 HcmV?d00001 diff --git a/browser_tests/assets/image64x64.webp b/browser_tests/assets/image64x64.webp new file mode 100644 index 0000000000000000000000000000000000000000..54aa7a5eff5be3958de2048fb928ef2f8f43ba66 GIT binary patch literal 1304 zcmV+z1?T!wNk&Ex1pok7MM6+kP&gn21pojL6abw8DnI~006y(vs!pgRqam&oolyWC ziELQ4U^jPhJ`UZ{`Oo~{yB^ngvuH2*-k@KS|7HJ)svZHlnt5w^e$0e`cv@!n>0XDB zWj~;PIcXXGFl#FPpl*t73V&7g0r_9{Zy;Y5|D^n8`3L-C`4{+q>YuqE;yyq+AT1C% z@o`N*0p`7DcL3>nKCrLb&E^Bme@+8>92T*^2LYG0v6w8PJ(sw60RHR5U;oq;G;_Y< z!5w!*cwxV)M|<{1?HI zX-6*!voeO}RMHEdME>6L)1qrZ#tpqP^h22k04r zV2y$4eq7%k8YKk~pO{6Q!A0WneJe48bCY+hhRT9~V_X&&`5Wc(a{vF9N28YU8ak)X z$cd5e6cs@xi*bJ6I-1?=E#h>op~9z@7l%-k;CbcBzIaq1u;%t#Bg zyu0^pgKzx+@$dLG>8~Ejv4;D?SJD$jI7lU0yMOne93m1tz^B-y4suAs*67|P@KkCe z^mVR`u=EK_Eqmr=pAOL+kn)UzT7%{HLxD`@4})Ip{s;T#tVs4sI0Kkb5WcTheCU<2 zI^k?W#=8L{{%e2O*`byHz>1m-DW)TjB}*$(Neyd3!{KinCX~*URb(tI3}71o6y+t! z>aO-^Ja#t&2hTEvq~05hV!|1@E+x_H6?S64^Cmw-|0M}`_Md`WQj4FAU$MPLjQj?s zgq&A8Q)H*pCJZaA8^lBa`G45)e;Bmm#v@B?$H<;4;BZ`JAj2;e($~lGz`aFmosslR)CxeKxa7(e$8$y~ z+xJzYEejhoc??@-Be9BgTM$qG|NOUPZ-0sX%1uv)AECi;qGQ$jh0^rO-%U$kgVWWV zrdKGSno5zDjnut@E`q8!ZrQ46g1+KzfAEw;zi(L=#p+$1T|*!4296}Rg_vrRe}YwC zPp&k^2FGalJ#Mp^k~_%?bd~Kg-P~kW&Z<}qcnqGahwFUW%cneL4IrtmPULbImRcG2 zpWyf3D^dUQZ0xbFNFBBwuce+-DvEY_vq=1%WW4TC&CZ$gKKi6rM&} zhI?To)2CEfu)u zO>JcV@TBRggX}e=HkEBT>r4N?B(dvbTx3K~rzjPdM$!zbAP7mRfVmT(7IT?#wk5!8 Od6OeuIqtz)0002zijyz^ literal 0 HcmV?d00001 diff --git a/browser_tests/fixtures/components/SidebarTab.ts b/browser_tests/fixtures/components/SidebarTab.ts index 50e4b51121..2bb17880cf 100644 --- a/browser_tests/fixtures/components/SidebarTab.ts +++ b/browser_tests/fixtures/components/SidebarTab.ts @@ -194,6 +194,10 @@ export class QueueSidebarTab extends SidebarTab { return this.root.locator('.no-results-placeholder') } + get galleryImage() { + return this.page.locator('.galleria-image') + } + private getToggleExpandButton(isExpanded: boolean) { const iconSelector = isExpanded ? '.pi-image' : '.pi-images' return this.root.locator(`.toggle-expanded-button ${iconSelector}`) @@ -256,14 +260,24 @@ export class QueueSidebarTab extends SidebarTab { async openTaskPreview(taskIndex: number) { const previewButton = this.getTaskPreviewButton(taskIndex) - await previewButton.hover() await previewButton.click() - return this.getGalleryImage(taskIndex).waitFor({ state: 'visible' }) + return this.galleryImage.waitFor({ state: 'visible' }) } - getGalleryImage(galleryItemIndex: number) { - // Aria labels of Galleria items are 1-based indices - const galleryLabel = `${galleryItemIndex + 1}` - return this.page.getByLabel(galleryLabel).locator('.galleria-image') + getGalleryImage(imageFilename: string) { + return this.galleryImage.and(this.page.getByAltText(imageFilename)) + } + + getTaskImage(imageFilename: string) { + return this.tasks.getByAltText(imageFilename) + } + + /** Trigger the queue store and tasks to update */ + async triggerTasksUpdate() { + await this.page.evaluate(() => { + window['app']['api'].dispatchCustomEvent('status', { + exec_info: { queue_remaining: 0 } + }) + }) } } diff --git a/browser_tests/fixtures/utils/taskHistory.ts b/browser_tests/fixtures/utils/taskHistory.ts index f7e9d60260..33c0ba626a 100644 --- a/browser_tests/fixtures/utils/taskHistory.ts +++ b/browser_tests/fixtures/utils/taskHistory.ts @@ -132,11 +132,12 @@ export default class TaskHistory { private addTask(task: HistoryTaskItem) { setPromptId(task) setQueueIndex(task) - this.tasks.push(task) + this.tasks.unshift(task) // Tasks are added to the front of the queue } - clearTasks() { + clearTasks(): this { this.tasks = [] + return this } withTask( @@ -155,7 +156,7 @@ export default class TaskHistory { /** Repeats the last task in the task history a specified number of times. */ repeat(n: number): this { for (let i = 0; i < n; i++) - this.addTask(structuredClone(this.tasks.at(-1)) as HistoryTaskItem) + this.addTask(structuredClone(this.tasks.at(0)) as HistoryTaskItem) return this } } diff --git a/browser_tests/menu.spec.ts b/browser_tests/menu.spec.ts index 5dedc0d71b..ba479572ed 100644 --- a/browser_tests/menu.spec.ts +++ b/browser_tests/menu.spec.ts @@ -1,9 +1,6 @@ -import { expect, mergeTests } from '@playwright/test' +import { expect } from '@playwright/test' -import { comfyPageFixture } from './fixtures/ComfyPage' -import { webSocketFixture } from './fixtures/ws' - -const test = mergeTests(comfyPageFixture, webSocketFixture) +import { comfyPageFixture as test } from './fixtures/ComfyPage' test.describe('Menu', () => { test.beforeEach(async ({ comfyPage }) => { @@ -948,66 +945,61 @@ test.describe.skip('Queue sidebar', () => { }) test.describe('Gallery', () => { + const firstImage = 'example.webp' + const secondImage = 'image32x32.webp' + test.beforeEach(async ({ comfyPage }) => { await comfyPage .setupHistory() - .withTask(['example.webp']) - .repeat(1) + .withTask([secondImage]) + .withTask([firstImage]) .setupRoutes() await comfyPage.menu.queueTab.open() await comfyPage.menu.queueTab.waitForTasks() + await comfyPage.menu.queueTab.openTaskPreview(0) }) test('displays gallery image after opening task preview', async ({ comfyPage }) => { - await comfyPage.menu.queueTab.openTaskPreview(0) - expect(comfyPage.menu.queueTab.getGalleryImage(0)).toBeVisible() + await comfyPage.nextFrame() + expect(comfyPage.menu.queueTab.getGalleryImage(firstImage)).toBeVisible() }) - test('should maintain active gallery item when new tasks are added', async ({ - comfyPage, - ws + test('maintains active gallery item when new tasks are added', async ({ + comfyPage }) => { - const initialIndex = 0 - await comfyPage.menu.queueTab.openTaskPreview(initialIndex) - // Add a new task while the gallery is still open - comfyPage.setupHistory().withTask(['example.webp']) - await ws.trigger({ - type: 'status', - data: { - status: { exec_info: { queue_remaining: 0 } } - } - }) - await comfyPage.menu.queueTab.waitForTasks() - - // The index of all tasks increments when a new task is prepended - const expectIndex = initialIndex + 1 - expect(comfyPage.menu.queueTab.getGalleryImage(expectIndex)).toBeVisible() + const newImage = 'image64x64.webp' + comfyPage.setupHistory().withTask([newImage]) + await comfyPage.menu.queueTab.triggerTasksUpdate() + await comfyPage.page.waitForTimeout(500) + const newTask = comfyPage.menu.queueTab.tasks.getByAltText(newImage) + await newTask.waitFor({ state: 'visible' }) + // The active gallery item should still be the initial image + expect(comfyPage.menu.queueTab.getGalleryImage(firstImage)).toBeVisible() }) test.describe('Gallery navigation', () => { const paths: { description: string path: ('Right' | 'Left')[] - expectIndex: number + end: string }[] = [ - { description: 'Right', path: ['Right'], expectIndex: 1 }, - { description: 'Left', path: ['Right', 'Left'], expectIndex: 0 }, - { description: 'Right wrap', path: ['Right', 'Right'], expectIndex: 0 }, - { description: 'Left wrap', path: ['Left'], expectIndex: 1 } + { description: 'Right', path: ['Right'], end: secondImage }, + { description: 'Left', path: ['Right', 'Left'], end: firstImage }, + { description: 'Left wrap', path: ['Left'], end: secondImage }, + { description: 'Right wrap', path: ['Right', 'Right'], end: firstImage } ] - paths.forEach(({ description, path, expectIndex }) => { + paths.forEach(({ description, path, end }) => { test(`can navigate gallery ${description}`, async ({ comfyPage }) => { - await comfyPage.menu.queueTab.openTaskPreview(0) for (const direction of path) - await comfyPage.page.keyboard.press(`Arrow${direction}`) - - expect( - comfyPage.menu.queueTab.getGalleryImage(expectIndex) - ).toBeVisible() + await comfyPage.page.keyboard.press(`Arrow${direction}`, { + delay: 256 + }) + await comfyPage.nextFrame() + expect(comfyPage.menu.queueTab.getGalleryImage(end)).toBeVisible() }) }) })