diff --git a/src/main/browser/browser-cookie-detection-types.ts b/src/main/browser/browser-cookie-detection-types.ts index bac46f6d750..5f4d3f074e0 100644 --- a/src/main/browser/browser-cookie-detection-types.ts +++ b/src/main/browser/browser-cookie-detection-types.ts @@ -69,7 +69,7 @@ export const CHROMIUM_BROWSERS: ChromiumBrowserDef[] = [ keychainService: 'Comet Safe Storage', keychainAccount: 'Comet', macRoot: 'Comet', - winRoot: 'Comet/User Data' + winRoot: 'Perplexity/Comet/User Data' // linuxRoot intentionally omitted — Comet does not ship a Linux build as of 2026-05-15 }, { diff --git a/src/main/browser/browser-cookie-import.comet.test.ts b/src/main/browser/browser-cookie-import.comet.test.ts index f673990e5a3..465446f4b06 100644 --- a/src/main/browser/browser-cookie-import.comet.test.ts +++ b/src/main/browser/browser-cookie-import.comet.test.ts @@ -222,6 +222,66 @@ describe('detectInstalledBrowsers — Comet', () => { }) }) +describe('detectInstalledBrowsers — Comet on Windows', () => { + const originalPlatform = process.platform + const originalLocalAppData = process.env.LOCALAPPDATA + + const localAppData = 'C:\\Users\\test\\AppData\\Local' + const cometRoot = `${slashPath(localAppData)}/Perplexity/Comet/User Data` + + beforeEach(() => { + vi.resetModules() + Object.defineProperty(process, 'platform', { value: 'win32' }) + process.env.LOCALAPPDATA = localAppData + }) + + afterEach(() => { + Object.defineProperty(process, 'platform', { value: originalPlatform }) + if (originalLocalAppData === undefined) { + delete process.env.LOCALAPPDATA + } else { + process.env.LOCALAPPDATA = originalLocalAppData + } + vi.restoreAllMocks() + }) + + function mockCometInstallAt(rootPath: string): void { + vi.doMock('node:fs', async () => { + const actual = await vi.importActual('node:fs') + return { + ...actual, + existsSync: (p: string) => + slashPath(p) === `${rootPath}/Local State` || + slashPath(p) === `${rootPath}/Default/Network/Cookies`, + readFileSync: (p: string) => { + if (typeof p === 'string' && slashPath(p) === `${rootPath}/Local State`) { + return JSON.stringify({ profile: { info_cache: { Default: { name: 'Default' } } } }) + } + throw new Error(`Unexpected fixture read: ${p}`) + } + } + }) + } + + it('detects Comet under the Perplexity vendor directory', async () => { + mockCometInstallAt(cometRoot) + + const { detectInstalledBrowsers } = await import('./browser-cookie-import') + const comet = detectInstalledBrowsers().find((b) => b.family === 'comet') + + expect(comet).toBeDefined() + expect(slashPath(comet?.cookiesPath ?? '')).toBe(`${cometRoot}/Default/Network/Cookies`) + }) + + it('does not detect a Comet data directory sitting directly under LOCALAPPDATA', async () => { + mockCometInstallAt(`${slashPath(localAppData)}/Comet/User Data`) + + const { detectInstalledBrowsers } = await import('./browser-cookie-import') + + expect(detectInstalledBrowsers().find((b) => b.family === 'comet')).toBeUndefined() + }) +}) + describe('BROWSER_FAMILY_LABELS — Comet', () => { it('maps the comet family key to the user-facing label "Comet"', () => { expect(BROWSER_FAMILY_LABELS.comet).toBe('Comet')