Spaces:
Paused
Paused
Browser: navigating a closed browser's tab opens it anew
Browse files- piweb/hf-design.patch +13 -5
piweb/hf-design.patch
CHANGED
|
@@ -32877,10 +32877,10 @@ index 0000000..9cac779
|
|
| 32877 |
+}
|
| 32878 |
diff --git a/lib/browser/host.integration.test.mjs b/lib/browser/host.integration.test.mjs
|
| 32879 |
new file mode 100644
|
| 32880 |
-
index 0000000..
|
| 32881 |
--- /dev/null
|
| 32882 |
+++ b/lib/browser/host.integration.test.mjs
|
| 32883 |
-
@@ -0,0 +1,
|
| 32884 |
+import assert from "node:assert/strict";
|
| 32885 |
+import { spawn } from "node:child_process";
|
| 32886 |
+import { existsSync } from "node:fs";
|
|
@@ -33548,6 +33548,13 @@ index 0000000..b8e3a6d
|
|
| 33548 |
+ assert.equal(result.isError, undefined, text(result));
|
| 33549 |
+ assert.equal(host.getState().running, true);
|
| 33550 |
+ assert.deepEqual(host.getState().tabs.map((tab) => tab.title), ["Second"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33551 |
+});
|
| 33552 |
+
|
| 33553 |
+test("the browser closes itself when idle, but not while someone watches", { skip }, async () => {
|
|
@@ -33608,10 +33615,10 @@ index 0000000..b8e3a6d
|
|
| 33608 |
+});
|
| 33609 |
diff --git a/lib/browser/host.ts b/lib/browser/host.ts
|
| 33610 |
new file mode 100644
|
| 33611 |
-
index 0000000..
|
| 33612 |
--- /dev/null
|
| 33613 |
+++ b/lib/browser/host.ts
|
| 33614 |
-
@@ -0,0 +1,
|
| 33615 |
+import { AsyncLocalStorage } from "node:async_hooks";
|
| 33616 |
+import { createHash } from "node:crypto";
|
| 33617 |
+import { existsSync } from "node:fs";
|
|
@@ -34815,7 +34822,8 @@ index 0000000..e5e4bdd
|
|
| 34815 |
+ this.touch();
|
| 34816 |
+ switch (action.action) {
|
| 34817 |
+ case "navigate": {
|
| 34818 |
-
+
|
|
|
|
| 34819 |
+ const tab = chosen.crashed ? await this.replaceCrashed(chosen) : chosen;
|
| 34820 |
+ return this.userNavigation(tab, () => tab.page.goto(action.url, { waitUntil: "commit", timeout: USER_NAVIGATION_TIMEOUT_MS }));
|
| 34821 |
+ }
|
|
|
|
| 32877 |
+}
|
| 32878 |
diff --git a/lib/browser/host.integration.test.mjs b/lib/browser/host.integration.test.mjs
|
| 32879 |
new file mode 100644
|
| 32880 |
+
index 0000000..400b569
|
| 32881 |
--- /dev/null
|
| 32882 |
+++ b/lib/browser/host.integration.test.mjs
|
| 32883 |
+
@@ -0,0 +1,732 @@
|
| 32884 |
+import assert from "node:assert/strict";
|
| 32885 |
+import { spawn } from "node:child_process";
|
| 32886 |
+import { existsSync } from "node:fs";
|
|
|
|
| 33548 |
+ assert.equal(result.isError, undefined, text(result));
|
| 33549 |
+ assert.equal(host.getState().running, true);
|
| 33550 |
+ assert.deepEqual(host.getState().tabs.map((tab) => tab.title), ["Second"]);
|
| 33551 |
+
+ // A pane out of sight while the browser closed still names its old tab: the navigation opens the browser anew.
|
| 33552 |
+
+ const stale = host.getState().tabs[0].id;
|
| 33553 |
+
+ await host.userAction({ action: "shutdown" });
|
| 33554 |
+
+ const reopened = await host.userAction({ action: "navigate", url: `${base}/second`, tabId: stale });
|
| 33555 |
+
+ assert.equal(reopened.warning, undefined);
|
| 33556 |
+
+ assert.equal(host.getState().running, true);
|
| 33557 |
+
+ assert.equal(host.getState().tabs.length, 1);
|
| 33558 |
+});
|
| 33559 |
+
|
| 33560 |
+test("the browser closes itself when idle, but not while someone watches", { skip }, async () => {
|
|
|
|
| 33615 |
+});
|
| 33616 |
diff --git a/lib/browser/host.ts b/lib/browser/host.ts
|
| 33617 |
new file mode 100644
|
| 33618 |
+
index 0000000..f3df253
|
| 33619 |
--- /dev/null
|
| 33620 |
+++ b/lib/browser/host.ts
|
| 33621 |
+
@@ -0,0 +1,1849 @@
|
| 33622 |
+import { AsyncLocalStorage } from "node:async_hooks";
|
| 33623 |
+import { createHash } from "node:crypto";
|
| 33624 |
+import { existsSync } from "node:fs";
|
|
|
|
| 34822 |
+ this.touch();
|
| 34823 |
+ switch (action.action) {
|
| 34824 |
+ case "navigate": {
|
| 34825 |
+
+ // A pane that was out of sight may still name a tab of a browser closed since: open it anew.
|
| 34826 |
+
+ const chosen = action.tabId && this.context ? this.runningTab(action.tabId) : await this.agentTab(true);
|
| 34827 |
+ const tab = chosen.crashed ? await this.replaceCrashed(chosen) : chosen;
|
| 34828 |
+ return this.userNavigation(tab, () => tab.page.goto(action.url, { waitUntil: "commit", timeout: USER_NAVIGATION_TIMEOUT_MS }));
|
| 34829 |
+ }
|