Keep browser sign-ins across tabs and restarts (#2089)
* feat(desktop): share persistent browser data across tabs Keep browser sign-ins and site storage across tabs and app restarts, with a Settings action to clear the shared profile. * fix(settings): prevent duplicate browser data clears * fix(desktop): complete browser data cleanup Clear legacy per-tab profiles after upgrades and localize the browser data settings in every supported language. * fix(desktop): close browser profile cleanup races
This commit is contained in:
@@ -73,10 +73,7 @@ class FakeDaemonClient {
|
||||
|
||||
class FakeBrowserBridge {
|
||||
public readonly executedRequests: BrowserAutomationExecuteRequest[] = [];
|
||||
public readonly registeredWorkspaceBrowsers: Array<{ browserId: string; workspaceId: string }> =
|
||||
[];
|
||||
public readonly unregisteredWorkspaceBrowsers: string[] = [];
|
||||
public readonly clearedPartitions: string[] = [];
|
||||
public readonly activeWorkspaceBrowsers: Array<{
|
||||
browserId: string | null;
|
||||
workspaceId: string;
|
||||
@@ -94,21 +91,10 @@ class FakeBrowserBridge {
|
||||
return this.response ?? currentListTabsPayload(request.requestId);
|
||||
};
|
||||
|
||||
public registerWorkspaceBrowser = async (input: {
|
||||
browserId: string;
|
||||
workspaceId: string;
|
||||
}): Promise<void> => {
|
||||
this.registeredWorkspaceBrowsers.push(input);
|
||||
};
|
||||
|
||||
public unregisterWorkspaceBrowser = async (browserId: string): Promise<void> => {
|
||||
this.unregisteredWorkspaceBrowsers.push(browserId);
|
||||
};
|
||||
|
||||
public clearPartition = async (browserId: string): Promise<void> => {
|
||||
this.clearedPartitions.push(browserId);
|
||||
};
|
||||
|
||||
public setWorkspaceActiveBrowser = async (input: {
|
||||
browserId: string | null;
|
||||
workspaceId: string;
|
||||
@@ -118,9 +104,17 @@ class FakeBrowserBridge {
|
||||
}
|
||||
|
||||
class FakeResidentBrowser {
|
||||
public readonly ensuredWebviews: Array<{ browserId: string; url: string }> = [];
|
||||
public readonly ensuredWebviews: Array<{
|
||||
browserId: string;
|
||||
workspaceId: string;
|
||||
url: string;
|
||||
}> = [];
|
||||
|
||||
public ensure = (input: { browserId: string; url: string }): HTMLElement | null => {
|
||||
public ensure = (input: {
|
||||
browserId: string;
|
||||
workspaceId: string;
|
||||
url: string;
|
||||
}): HTMLElement | null => {
|
||||
this.ensuredWebviews.push(input);
|
||||
return null;
|
||||
};
|
||||
@@ -321,12 +315,13 @@ describe("mountBrowserAutomationHandler", () => {
|
||||
}),
|
||||
);
|
||||
expect(openedTabs[0]?.tabId).not.toBe(previousFocusedTabId);
|
||||
expect(browser.browser.registeredWorkspaceBrowsers).toEqual([
|
||||
{ browserId: result.browserId, workspaceId: "wks_workspace_a" },
|
||||
]);
|
||||
expect(browser.browser.activeWorkspaceBrowsers).toEqual([]);
|
||||
expect(browser.resident.ensuredWebviews).toEqual([
|
||||
{ browserId: result.browserId, url: "https://example.com" },
|
||||
{
|
||||
browserId: result.browserId,
|
||||
workspaceId: "wks_workspace_a",
|
||||
url: "https://example.com",
|
||||
},
|
||||
]);
|
||||
expect(browser.browser.executedRequests).toEqual([
|
||||
{
|
||||
@@ -366,7 +361,10 @@ describe("mountBrowserAutomationHandler", () => {
|
||||
},
|
||||
]);
|
||||
expect(browser.resident.ensuredWebviews).toEqual([
|
||||
expect.objectContaining({ url: "https://example.com" }),
|
||||
expect.objectContaining({
|
||||
workspaceId: "wks_workspace_a",
|
||||
url: "https://example.com",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -440,7 +438,7 @@ describe("mountBrowserAutomationHandler", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("browser_close_tab removes the workspace tab, browser record, resident webview, registry entry, and partition", async () => {
|
||||
test("browser_close_tab removes the workspace tab, browser record, resident webview, and registry entry", async () => {
|
||||
const browser = new BrowserAutomationHandlerHarness();
|
||||
const workspaceKey = buildWorkspaceTabPersistenceKey({
|
||||
serverId: "server-1",
|
||||
@@ -466,7 +464,6 @@ describe("mountBrowserAutomationHandler", () => {
|
||||
expect(workspaceBrowserTabs(workspaceKey, result.browserId)).toEqual([]);
|
||||
expect(useBrowserStore.getState().browsersById[result.browserId]).toBeUndefined();
|
||||
expect(browser.browser.unregisteredWorkspaceBrowsers).toEqual([result.browserId]);
|
||||
expect(browser.browser.clearedPartitions).toEqual([result.browserId]);
|
||||
expect(currentBrowserTabs()).toEqual([]);
|
||||
});
|
||||
|
||||
|
||||
@@ -258,7 +258,6 @@ async function closeBrowserTabForRequest(params: {
|
||||
useBrowserStore.getState().removeBrowser(browserId);
|
||||
removeResidentBrowserWebview(browserId);
|
||||
await browserHost?.unregisterWorkspaceBrowser?.(browserId);
|
||||
await browserHost?.clearPartition?.(browserId);
|
||||
|
||||
return {
|
||||
requestId: request.requestId,
|
||||
@@ -337,10 +336,8 @@ async function openBrowserTabForRequest(params: {
|
||||
browserId,
|
||||
});
|
||||
|
||||
await browserHost?.registerWorkspaceBrowser?.({ browserId, workspaceId });
|
||||
|
||||
if (browserHost?.executeAutomationCommand) {
|
||||
ensureResidentBrowserWebview({ browserId, url: normalizedUrl });
|
||||
ensureResidentBrowserWebview({ browserId, workspaceId, url: normalizedUrl });
|
||||
const registered = await waitForBrowserRegistration({
|
||||
request,
|
||||
browserId,
|
||||
|
||||
Reference in New Issue
Block a user