Skip to content

Commit 0a4d282

Browse files
hl662Copilot
andcommitted
fix: make SheetViewState viewport test resilient to async IPC events
Replace waitForReload() with pendingReload() pattern that registers a one-shot listener on onViewAttachmentsReloaded BEFORE the action, then awaits the event AFTER the save/undo. This moves the areAllTilesLoaded assertion to after the reload event resolves, where it is deterministic (SheetViewState invalidates the viewport scene on the line before it raises the event). Previously, the test asserted areAllTilesLoaded === false immediately after saveBriefcaseChanges, but under Electron IPC the push notification can arrive after the IPC response, causing a race condition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5831f81 commit 0a4d282

1 file changed

Lines changed: 26 additions & 16 deletions

File tree

full-stack-tests/core/src/frontend/hub/SheetViewState.test.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,14 @@ describe("SheetViewState", () => {
347347
await vp.waitForSceneCompletion();
348348
expect(vp.areAllTilesLoaded).to.be.true;
349349

350-
// Modify the placement of the attachment
351-
async function waitForReload() {
352-
await waitForViewAttachmentsToReload(view, async () => undefined);
353-
await vp.waitForSceneCompletion();
350+
// Register a one-shot listener for the reload event BEFORE the action
351+
// that triggers it. SheetViewState invalidates the viewport scene
352+
// on the line before it raises onViewAttachmentsReloaded, so
353+
// areAllTilesLoaded is guaranteed false right after this resolves.
354+
function pendingReload(): Promise<void> {
355+
return new Promise<void>((resolve) => {
356+
view.onViewAttachmentsReloaded.addOnce(() => resolve());
357+
});
354358
}
355359

356360
// Modify the placement of the attachment
@@ -362,10 +366,11 @@ describe("SheetViewState", () => {
362366
await coreFullStackTestCommandIpc.updateElement(iModel.key, props);
363367

364368
expect(vp.areAllTilesLoaded).to.be.true;
365-
const reloadAfterUpdate = waitForReload();
369+
const reloadAfterUpdate = pendingReload();
366370
await saveBriefcaseChanges(iModel);
367-
expect(vp.areAllTilesLoaded).to.be.false;
368371
await reloadAfterUpdate;
372+
expect(vp.areAllTilesLoaded).to.be.false;
373+
await vp.waitForSceneCompletion();
369374
expect(vp.areAllTilesLoaded).to.be.true;
370375

371376
// Verify the view reloaded the attachment with the updated placement.
@@ -377,10 +382,11 @@ describe("SheetViewState", () => {
377382
const newAttachmentId = await coreFullStackTestCommandIpc.insertElement(iModel.key, props);
378383

379384
expect(vp.areAllTilesLoaded).to.be.true;
380-
const reloadAfterInsert = waitForReload();
385+
const reloadAfterInsert = pendingReload();
381386
await saveBriefcaseChanges(iModel);
382-
expect(vp.areAllTilesLoaded).to.be.false;
383387
await reloadAfterInsert;
388+
expect(vp.areAllTilesLoaded).to.be.false;
389+
await vp.waitForSceneCompletion();
384390
expect(vp.areAllTilesLoaded).to.be.true;
385391

386392
expect(view.viewAttachmentProps.length).to.equal(2);
@@ -390,10 +396,11 @@ describe("SheetViewState", () => {
390396
// Delete an attachment
391397
await deleteElements(iModel, [newAttachmentId]);
392398
expect(vp.areAllTilesLoaded).to.be.true;
393-
const reloadAfterDelete = waitForReload();
399+
const reloadAfterDelete = pendingReload();
394400
await saveBriefcaseChanges(iModel);
395-
expect(vp.areAllTilesLoaded).to.be.false;
396401
await reloadAfterDelete;
402+
expect(vp.areAllTilesLoaded).to.be.false;
403+
await vp.waitForSceneCompletion();
397404
expect(vp.areAllTilesLoaded).to.be.true;
398405

399406
expect(view.viewAttachmentProps.length).to.equal(1);
@@ -402,26 +409,29 @@ describe("SheetViewState", () => {
402409

403410
// Undo everything so we don't affect subsequent tests (and to verify the Viewport reacts).
404411
// -- undo delete
405-
const reloadAfterUndoDelete = waitForReload();
412+
const reloadAfterUndoDelete = pendingReload();
406413
await iModel.txns.reverseSingleTxn();
407-
expect(vp.areAllTilesLoaded).to.be.false;
408414
await reloadAfterUndoDelete;
415+
expect(vp.areAllTilesLoaded).to.be.false;
416+
await vp.waitForSceneCompletion();
409417
expect(vp.areAllTilesLoaded).to.be.true;
410418
expect(view.viewAttachmentProps.length).to.equal(2);
411419

412420
// -- undo insert
413-
const reloadAfterUndoInsert = waitForReload();
421+
const reloadAfterUndoInsert = pendingReload();
414422
await iModel.txns.reverseSingleTxn();
415-
expect(vp.areAllTilesLoaded).to.be.false;
416423
await reloadAfterUndoInsert;
424+
expect(vp.areAllTilesLoaded).to.be.false;
425+
await vp.waitForSceneCompletion();
417426
expect(vp.areAllTilesLoaded).to.be.true;
418427
expect(view.viewAttachmentProps.length).to.equal(1);
419428

420429
// -- undo update
421-
const reloadAfterUndoUpdate = waitForReload();
430+
const reloadAfterUndoUpdate = pendingReload();
422431
await iModel.txns.reverseSingleTxn();
423-
expect(vp.areAllTilesLoaded).to.be.false;
424432
await reloadAfterUndoUpdate;
433+
expect(vp.areAllTilesLoaded).to.be.false;
434+
await vp.waitForSceneCompletion();
425435
expect(vp.areAllTilesLoaded).to.be.true;
426436
expect(view.viewAttachmentProps.length).to.equal(1);
427437
expect(view.viewAttachmentProps[0].placement?.origin).to.deep.equal([100, 100]);

0 commit comments

Comments
 (0)