diff --git a/Packages/macOS/CmuxBrowser/Sources/CmuxBrowser/Import/Values/BrowserImportBrowserDescriptor.swift b/Packages/macOS/CmuxBrowser/Sources/CmuxBrowser/Import/Values/BrowserImportBrowserDescriptor.swift index 94be84e502a1..89f78f9123bb 100644 --- a/Packages/macOS/CmuxBrowser/Sources/CmuxBrowser/Import/Values/BrowserImportBrowserDescriptor.swift +++ b/Packages/macOS/CmuxBrowser/Sources/CmuxBrowser/Import/Values/BrowserImportBrowserDescriptor.swift @@ -211,6 +211,17 @@ public struct BrowserImportBrowserDescriptor: Hashable, Sendable { dataArtifactRelativePaths: [], supportsDataOnlyDetection: true ), + BrowserImportBrowserDescriptor( + id: "aside", + displayName: "Aside", + family: .chromium, + tier: 2, + bundleIdentifiers: ["at.studio.AsideBrowser"], + appNames: ["Aside.app"], + dataRootRelativePaths: ["Library/Application Support/Aside"], + dataArtifactRelativePaths: [], + supportsDataOnlyDetection: true + ), BrowserImportBrowserDescriptor( id: "perplexity-comet", displayName: "Perplexity Comet", diff --git a/Packages/macOS/CmuxBrowser/Tests/CmuxBrowserTests/Import/BrowserInstalledBrowserDetectorTests.swift b/Packages/macOS/CmuxBrowser/Tests/CmuxBrowserTests/Import/BrowserInstalledBrowserDetectorTests.swift index 7f02817b5646..da06c46ad3b4 100644 --- a/Packages/macOS/CmuxBrowser/Tests/CmuxBrowserTests/Import/BrowserInstalledBrowserDetectorTests.swift +++ b/Packages/macOS/CmuxBrowser/Tests/CmuxBrowserTests/Import/BrowserInstalledBrowserDetectorTests.swift @@ -84,6 +84,50 @@ struct BrowserInstalledBrowserDetectorTests { #expect(dia.profiles.map(\.rootURL.lastPathComponent) == ["Default", "Profile 1"]) } + @Test("detects Aside Chromium profiles") + func detectsAsideProfiles() throws { + let home = try makeTempHome() + defer { try? FileManager.default.removeItem(at: home) } + + let asideRoot = home + .appendingPathComponent("Library/Application Support/Aside", isDirectory: true) + let defaultProfile = asideRoot.appendingPathComponent("Default", isDirectory: true) + try FileManager.default.createDirectory(at: defaultProfile, withIntermediateDirectories: true) + try Data().write(to: defaultProfile.appendingPathComponent("History")) + try Data().write(to: defaultProfile.appendingPathComponent("Cookies")) + try Data( + """ + { + "profile": { + "info_cache": { + "Default": { + "name": "Personal" + } + } + } + } + """.utf8 + ).write(to: asideRoot.appendingPathComponent("Local State")) + + let fakeApp = home.appendingPathComponent("Aside.app", isDirectory: true) + let detector = BrowserInstalledBrowserDetector( + homeDirectoryURL: home, + bundleLookup: { bundleID in + bundleID == "at.studio.AsideBrowser" ? fakeApp : nil + }, + applicationSearchDirectories: [], + fileManager: .default + ) + + let aside = try #require(detector.detectInstalledBrowsers().first { $0.id == "aside" }) + #expect(aside.displayName == "Aside") + #expect(aside.family == .chromium) + #expect(aside.appURL == fakeApp) + #expect(aside.dataRootURL == asideRoot) + #expect(aside.profiles.map(\.displayName) == ["Personal"]) + #expect(aside.profiles.first?.isDefault == true) + } + @Test("detects Arc Chromium profiles and Network cookie stores under User Data") func detectsArcProfilesUnderUserData() throws { let home = try makeTempHome()