From b45ccec0dc23b6dc90f678be6f4ebef592ee2f45 Mon Sep 17 00:00:00 2001 From: Bob Qiu Date: Tue, 3 Nov 2026 15:54:47 +0800 Subject: [PATCH] fix(insomnia-test): fix lint warnings in cloud-sync and git-sync specs Share the backend project meta.json reader across cloud-sync specs, use locator assertions in the git-sync disabled specs, and split the pull-conflict spec into explicit cases. Co-Authored-By: Claude Sonnet 5.5 --- ...concurrent-workspace-creation-race.spec.ts | 21 ++--- .../delete-unsynced-remote-file.spec.ts | 21 ++--- .../delete-workspace-log-signature.spec.ts | 18 +---- ...new-collection-own-backend-project.spec.ts | 18 ++--- .../new-collection-survives-restart.spec.ts | 17 +---- ...-action-during-collection-creation.spec.ts | 25 ++---- .../disabled-via-feature-flag.spec.ts | 18 ++--- .../disabled-via-storage-rule.spec.ts | 12 +-- .../git-sync/pull-conflict-resolution.spec.ts | 76 +++++++++++-------- 9 files changed, 83 insertions(+), 143 deletions(-) diff --git a/packages/insomnia-test/tests/cloud-sync/concurrent-workspace-creation-race.spec.ts b/packages/insomnia-test/tests/cloud-sync/concurrent-workspace-creation-race.spec.ts index e93edf6f3d..baf738efba 100644 --- a/packages/insomnia-test/tests/cloud-sync/concurrent-workspace-creation-race.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/concurrent-workspace-creation-race.spec.ts @@ -2,12 +2,12 @@ import * as fs from "node:fs"; import path from "node:path"; import { faker } from "@faker-js/faker"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; +import { getCloudSyncGraphQLRequestLog, setCloudSyncGraphQLDelay } from "@package/misc/cloud-sync-mock"; import { MOCK_API_SERVER, resetCloudSyncState, SESSION_ID, test } from "@package/misc/fixtures"; import { Collection } from "@package/models/collection"; import { expect } from "@playwright/test"; -import { getCloudSyncGraphQLRequestLog, setCloudSyncGraphQLDelay } from "@package/misc/cloud-sync-mock"; - // Every Cloud Sync workspace used to share one VCS singleton, so creating a sibling // collection Y could repoint the singleton's `_backendProject` mid-flight, // while workspace X's `pull()` was still awaiting a network response. X's @@ -55,19 +55,10 @@ test("Verify creating a new collection does not misattribute a concurrent pull's const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); const readProjectMeta = async (workspaceId: string) => { - const dirs = await fs.promises.readdir(projectsDir); - for (const dir of dirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === workspaceId) { - return { backendProjectId: meta.id as string, dir }; - } - } - return; + const [match] = (await readBackendProjectMetas(projectsDir)) + .filter((m) => m.rootDocumentId === workspaceId) + .map((m) => ({ backendProjectId: m.id, dir: m.dir })); + return match; }; const countBlobFiles = async (dir: string) => { const blobsDir = path.join(projectsDir, dir, "blobs"); diff --git a/packages/insomnia-test/tests/cloud-sync/delete-unsynced-remote-file.spec.ts b/packages/insomnia-test/tests/cloud-sync/delete-unsynced-remote-file.spec.ts index 55cf27e228..5103a73a52 100644 --- a/packages/insomnia-test/tests/cloud-sync/delete-unsynced-remote-file.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/delete-unsynced-remote-file.spec.ts @@ -3,12 +3,12 @@ import path from "node:path"; import { faker } from "@faker-js/faker"; import { HttpMethod } from "@package/enums/http-method"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; +import { getCloudSyncProjectInfo, setCloudSyncArchiveFailure } from "@package/misc/cloud-sync-mock"; import { HTTP_SERVER, resetCloudSyncState, test } from "@package/misc/fixtures"; import { Collection } from "@package/models/collection"; import { expect } from "@playwright/test"; -import { getCloudSyncProjectInfo, setCloudSyncArchiveFailure } from "@package/misc/cloud-sync-mock"; - test.afterAll(async () => { await resetCloudSyncState(); }); @@ -68,19 +68,10 @@ test("Verify the dashboard can delete a never-pulled unsynced remote file and a const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); const readProjectMeta = async (workspaceId: string) => { - const dirs = await fs.promises.readdir(projectsDir); - for (const dir of dirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === workspaceId) { - return { rootDocumentId: meta.rootDocumentId as string, dir }; - } - } - return; + const [match] = (await readBackendProjectMetas(projectsDir)) + .filter((m) => m.rootDocumentId === workspaceId) + .map((m) => ({ rootDocumentId: m.rootDocumentId, dir: m.dir })); + return match; }; const readLatestSnapshotState = async (dir: string) => { const snapshotsDir = path.join(projectsDir, dir, "snapshots"); diff --git a/packages/insomnia-test/tests/cloud-sync/delete-workspace-log-signature.spec.ts b/packages/insomnia-test/tests/cloud-sync/delete-workspace-log-signature.spec.ts index 0127e85816..49b1232b23 100644 --- a/packages/insomnia-test/tests/cloud-sync/delete-workspace-log-signature.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/delete-workspace-log-signature.spec.ts @@ -2,6 +2,7 @@ import * as fs from "node:fs"; import path from "node:path"; import { DeleteMode } from "@package/enums/delete-mode"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; import { resetCloudSyncState, test } from "@package/misc/fixtures"; import { expect } from "@playwright/test"; @@ -19,20 +20,9 @@ test("Verify deleting a synced Cloud Sync workspace archives its own backend pro const workspace = await workspaceFlow.get({ name: "My Environment" }); const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); - const projectDirs = await fs.promises.readdir(projectsDir); - let backendProjectId: string | undefined; - for (const dir of projectDirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === workspace!.id) { - backendProjectId = meta.id; - break; - } - } + const backendProjectId = (await readBackendProjectMetas(projectsDir)).find( + (m) => m.rootDocumentId === workspace!.id, + )?.id; await cloudSyncPage.backToAllProjects(); const logLines = await appFlow.captureMainProcessLog(async () => { diff --git a/packages/insomnia-test/tests/cloud-sync/new-collection-own-backend-project.spec.ts b/packages/insomnia-test/tests/cloud-sync/new-collection-own-backend-project.spec.ts index ea1afe8205..09b5b9b1b5 100644 --- a/packages/insomnia-test/tests/cloud-sync/new-collection-own-backend-project.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/new-collection-own-backend-project.spec.ts @@ -4,6 +4,7 @@ import path from "node:path"; import { faker } from "@faker-js/faker"; import { HttpMethod } from "@package/enums/http-method"; import { SyncStatus } from "@package/enums/sync-status"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; import { HTTP_SERVER, test } from "@package/misc/fixtures"; import { Collection } from "@package/models/collection"; import { expect } from "@playwright/test"; @@ -37,19 +38,10 @@ test("Verify a new collection commits and pushes under its own backend project", const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); const readProjectMeta = async (workspaceId: string) => { - const dirs = await fs.promises.readdir(projectsDir); - for (const dir of dirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === workspaceId) { - return { rootDocumentId: meta.rootDocumentId as string, dir }; - } - } - return; + const [match] = (await readBackendProjectMetas(projectsDir)) + .filter((m) => m.rootDocumentId === workspaceId) + .map((m) => ({ rootDocumentId: m.rootDocumentId, dir: m.dir })); + return match; }; const readLatestSnapshotState = async (dir: string) => { const snapshotsDir = path.join(projectsDir, dir, "snapshots"); diff --git a/packages/insomnia-test/tests/cloud-sync/new-collection-survives-restart.spec.ts b/packages/insomnia-test/tests/cloud-sync/new-collection-survives-restart.spec.ts index 80feafdd9e..deee24dabf 100644 --- a/packages/insomnia-test/tests/cloud-sync/new-collection-survives-restart.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/new-collection-survives-restart.spec.ts @@ -4,6 +4,7 @@ import path from "node:path"; import { faker } from "@faker-js/faker"; import { HttpMethod } from "@package/enums/http-method"; import { SyncStatus } from "@package/enums/sync-status"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; import { HTTP_SERVER, test } from "@package/misc/fixtures"; import { Collection } from "@package/models/collection"; import { expect } from "@playwright/test"; @@ -48,19 +49,9 @@ test("Verify a new collection is not left in an unsynced state after an app rest const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); - const dirs = await fs.promises.readdir(projectsDir); - const matchingDirs: string[] = []; - for (const dir of dirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === collectionYId) { - matchingDirs.push(dir); - } - } + const matchingDirs = (await readBackendProjectMetas(projectsDir)) + .filter((m) => m.rootDocumentId === collectionYId) + .map((m) => m.dir); const combinedLog = [...creationLog, ...restartLog].join("\n"); diff --git a/packages/insomnia-test/tests/cloud-sync/unrelated-action-during-collection-creation.spec.ts b/packages/insomnia-test/tests/cloud-sync/unrelated-action-during-collection-creation.spec.ts index f4ce693ffd..33f7da5108 100644 --- a/packages/insomnia-test/tests/cloud-sync/unrelated-action-during-collection-creation.spec.ts +++ b/packages/insomnia-test/tests/cloud-sync/unrelated-action-during-collection-creation.spec.ts @@ -2,13 +2,13 @@ import * as fs from "node:fs"; import path from "node:path"; import { faker } from "@faker-js/faker"; +import { readBackendProjectMetas } from "@package/misc/backend-projects"; +import { getCloudSyncGraphQLRequestLog, setCloudSyncGraphQLDelay } from "@package/misc/cloud-sync-mock"; import { MOCK_API_SERVER, resetCloudSyncState, SESSION_ID, test } from "@package/misc/fixtures"; import { Collection } from "@package/models/collection"; import type { Environment } from "@package/models/environment"; import { expect } from "@playwright/test"; -import { getCloudSyncGraphQLRequestLog, setCloudSyncGraphQLDelay } from "@package/misc/cloud-sync-mock"; - test.afterAll(async () => { await setCloudSyncGraphQLDelay(0); await fetch(`${MOCK_API_SERVER}/_admin/cloud-sync/new-commit`, { @@ -36,23 +36,10 @@ test("Verify an unrelated action during collection creation is equally safe", as const dataPath = await appFlow.getDataPath(); const projectsDir = path.join(dataPath, "version-control", "projects"); const readProjectMeta = async (workspaceId: string) => { - const dirs = await fs.promises.readdir(projectsDir); - for (const dir of dirs) { - const meta = JSON.parse( - await fs.promises.readFile( - path.join(projectsDir, dir, "meta.json"), - "utf8", - ), - ); - if (meta.rootDocumentId === workspaceId) { - return { - rootDocumentId: meta.rootDocumentId as string, - backendProjectId: meta.id as string, - dir, - }; - } - } - return; + const [match] = (await readBackendProjectMetas(projectsDir)) + .filter((m) => m.rootDocumentId === workspaceId) + .map((m) => ({ rootDocumentId: m.rootDocumentId, backendProjectId: m.id, dir: m.dir })); + return match; }; const countBlobFiles = async (dir: string) => { const blobsDir = path.join(projectsDir, dir, "blobs"); diff --git a/packages/insomnia-test/tests/git-sync/disabled-via-feature-flag.spec.ts b/packages/insomnia-test/tests/git-sync/disabled-via-feature-flag.spec.ts index acea47a52a..cdfcf1b810 100644 --- a/packages/insomnia-test/tests/git-sync/disabled-via-feature-flag.spec.ts +++ b/packages/insomnia-test/tests/git-sync/disabled-via-feature-flag.spec.ts @@ -30,17 +30,11 @@ test( ) .toBeTruthy(); expect(bannerText).toContain("Git Sync limited to organizations"); - await expect - .poll(() => projectSettingsPage.isHidden(projectSettingsPage.gitSetupForm), { - timeout: DEFAULT_TIMEOUT, - }) - .toBe(true); - await expect - .poll( - () => - projectSettingsPage.isDisabled(projectSettingsPage.scanForFilesButton), - { timeout: DEFAULT_TIMEOUT }, - ) - .toBe(true); + await expect(projectSettingsPage.gitSetupForm).toBeHidden({ + timeout: DEFAULT_TIMEOUT, + }); + await expect(projectSettingsPage.scanForFilesButton).toBeDisabled({ + timeout: DEFAULT_TIMEOUT, + }); }, ); diff --git a/packages/insomnia-test/tests/git-sync/disabled-via-storage-rule.spec.ts b/packages/insomnia-test/tests/git-sync/disabled-via-storage-rule.spec.ts index 0c663e57fb..957a08fde5 100644 --- a/packages/insomnia-test/tests/git-sync/disabled-via-storage-rule.spec.ts +++ b/packages/insomnia-test/tests/git-sync/disabled-via-storage-rule.spec.ts @@ -30,14 +30,8 @@ test( .toBeTruthy(); expect(bannerText).toContain("Cloud Sync and Local Vault"); expect(bannerText).not.toContain("Git Sync"); - await expect - .poll( - () => - projectSettingsPage.isDisabled( - projectSettingsPage.projectTypeTile(ProjectType.Git), - ), - { timeout: DEFAULT_TIMEOUT }, - ) - .toBe(true); + await expect( + projectSettingsPage.projectTypeTile(ProjectType.Git), + ).toBeDisabled({ timeout: DEFAULT_TIMEOUT }); }, ); diff --git a/packages/insomnia-test/tests/git-sync/pull-conflict-resolution.spec.ts b/packages/insomnia-test/tests/git-sync/pull-conflict-resolution.spec.ts index 38e0988ed6..0fd6634b7e 100644 --- a/packages/insomnia-test/tests/git-sync/pull-conflict-resolution.spec.ts +++ b/packages/insomnia-test/tests/git-sync/pull-conflict-resolution.spec.ts @@ -1,43 +1,53 @@ import { faker } from '@faker-js/faker'; import { ProjectType } from '@package/enums/project-types'; +import type { UserSession } from '@package/misc/fixtures'; import { buildCollectionFile, DEFAULT_TIMEOUT, GIT_CREDENTIAL, pushServerFile, test } from '@package/misc/git-fixtures'; import { Collection } from '@package/models/collection'; import { Project } from '@package/models/project'; import { expect } from "@playwright/test"; -for (const { version, keepsLocal } of [ - { version: 'Current', keepsLocal: true }, - { version: 'Incoming', keepsLocal: false }, -] as const) { - test(`Verify resolving a pull conflict by choosing the ${version} version keeps that side's collection name`, async ({ - user, - }) => { - const { gitSyncFlow, preferencesFlow, workspaceFlow } = user.flowManager; - const { gitSyncPage, workspacePage, gitBranchesDialogPage } = user.pageManager; +async function pullIntoConflict(user: UserSession, version: 'Current' | 'Incoming') { + const { gitSyncFlow, preferencesFlow, workspaceFlow } = user.flowManager; + const { gitBranchesDialogPage } = user.pageManager; - await preferencesFlow.addGitCredential(GIT_CREDENTIAL); - const project = await workspaceFlow.cloneGitProject( - new Project(faker.string.alphanumeric(10), ProjectType.Git), - GIT_CREDENTIAL.name, - ); - const fileName = faker.string.alpha(10).toLowerCase(); - const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)), fileName); - await gitSyncFlow.commitAndPush(faker.string.alphanumeric(10)); + await preferencesFlow.addGitCredential(GIT_CREDENTIAL); + const project = await workspaceFlow.cloneGitProject( + new Project(faker.string.alphanumeric(10), ProjectType.Git), + GIT_CREDENTIAL.name, + ); + const fileName = faker.string.alpha(10).toLowerCase(); + const collection = await workspaceFlow.createCollection(project, new Collection(faker.string.alphanumeric(10)), fileName); + await gitSyncFlow.commitAndPush(faker.string.alphanumeric(10)); - const localCollection = new Collection(faker.string.alpha(10)); - const remoteCollection = new Collection(faker.string.alpha(10)); - await workspaceFlow.renameCollection(collection, localCollection.name); - await gitSyncFlow.commit(faker.string.alphanumeric(10)); - await pushServerFile({ path: `${fileName}.yaml`, content: buildCollectionFile(remoteCollection.name) }); - await gitSyncFlow.pull(); - await gitBranchesDialogPage.resolveMergeConflicts(version); - - const keptCollection = keepsLocal ? localCollection : remoteCollection; - await expect - .poll(async () => workspacePage.findItemNode(keptCollection), { timeout: DEFAULT_TIMEOUT }) - .toBeDefined(); - if (keepsLocal) { - expect(await workspacePage.findItemNode(remoteCollection)).toBeUndefined(); - } - }); + const localCollection = new Collection(faker.string.alpha(10)); + const remoteCollection = new Collection(faker.string.alpha(10)); + await workspaceFlow.renameCollection(collection, localCollection.name); + await gitSyncFlow.commit(faker.string.alphanumeric(10)); + await pushServerFile({ path: `${fileName}.yaml`, content: buildCollectionFile(remoteCollection.name) }); + await gitSyncFlow.pull(); + await gitBranchesDialogPage.resolveMergeConflicts(version); + return { localCollection, remoteCollection }; } + +test("Verify resolving a pull conflict by choosing the Current version keeps that side's collection name", async ({ + user, +}) => { + const { workspacePage } = user.pageManager; + const { localCollection, remoteCollection } = await pullIntoConflict(user, 'Current'); + + await expect + .poll(async () => workspacePage.findItemNode(localCollection), { timeout: DEFAULT_TIMEOUT }) + .toBeDefined(); + expect(await workspacePage.findItemNode(remoteCollection)).toBeUndefined(); +}); + +test("Verify resolving a pull conflict by choosing the Incoming version keeps that side's collection name", async ({ + user, +}) => { + const { workspacePage } = user.pageManager; + const { remoteCollection } = await pullIntoConflict(user, 'Incoming'); + + await expect + .poll(async () => workspacePage.findItemNode(remoteCollection), { timeout: DEFAULT_TIMEOUT }) + .toBeDefined(); +});