From b135da63288c626a456630bfc718e5238bf87f97 Mon Sep 17 00:00:00 2001 From: damingishere-coder Date: Sun, 20 Sep 2026 12:22:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E4=BF=9D=E7=95=99BO?= =?UTF-8?q?SS=E8=81=8A=E5=A4=A9=E8=AF=9D=E6=9C=AF=E6=8D=A2=E8=A1=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=8F=91=E9=80=81=E5=89=8D=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chrome-extension/background.js | 2 +- chrome-extension/boss-content.js | 5 +++-- chrome-extension/manifest.json | 2 +- chrome-extension/tests/boss-hr-assistant.test.cjs | 2 +- chrome-extension/tests/manifest-id.test.cjs | 2 +- .../tests/profile-scoped-scan-contract.test.cjs | 6 +++--- docs/delivery-recovery.md | 3 ++- .../service/BrowserRuntimeRegressionTest.java | 15 +++++++++++++++ 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/chrome-extension/background.js b/chrome-extension/background.js index ae9af01..dd4e2c9 100644 --- a/chrome-extension/background.js +++ b/chrome-extension/background.js @@ -63,7 +63,7 @@ const CONTENT_READY_RETRIES = 12; const CONTENT_READY_INTERVAL_MS = 250; const TAB_LOAD_TIMEOUT_MS = 10000; const DELIVERY_NAVIGATION_TIMEOUT_MS = 15000; -const REQUIRED_BOSS_CONTENT_VERSION = "1.8.18"; +const REQUIRED_BOSS_CONTENT_VERSION = "1.8.19"; const REQUIRED_ZHILIAN_CONTENT_VERSION = "1.8.16"; const LOCAL_API_BASE_URLS = ["http://127.0.0.1:6866"]; const BOSS_LOCAL_API_MAX_ATTEMPTS = 3; diff --git a/chrome-extension/boss-content.js b/chrome-extension/boss-content.js index 0e934ff..79ffd3f 100644 --- a/chrome-extension/boss-content.js +++ b/chrome-extension/boss-content.js @@ -1,5 +1,5 @@ (function () { - const EXTENSION_VERSION = "1.8.18"; + const EXTENSION_VERSION = "1.8.19"; // Manifest injection and a readiness probe can meet in the same document. // Reuse its runner instead of leaving the first runner alive without a listener. if (window.__GET_JOBS_BOSS_CONTENT_VERSION__ === EXTENSION_VERSION) return; @@ -3342,7 +3342,8 @@ return; } input.innerText = text; - input.textContent = text; + // innerText creates real line breaks in contenteditable. Replacing it with + // textContent would collapse those breaks under the editor's normal whitespace. input.dispatchEvent(new InputEvent("input", { bubbles: true, cancelable: true, inputType: "insertText", data: text })); } diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json index 3d276fc..2ac93d9 100644 --- a/chrome-extension/manifest.json +++ b/chrome-extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "投递牛马 Chrome Bridge", - "version": "1.8.18", + "version": "1.8.19", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzzdIlNVOv76Y/cSWrjD5Tg2Vlsha8yWHzsn46PBsg724/2dftOUzIIr2n70VRaRgGwEd8FjO/Y768Ori443zF4pQpWvuxXxm05YO25ILQ/+aJLmUycAEdWbkdhcagr4YXnXJdYlSCGSAToSQBjk+owQOdlBLQn5wofPoshrqayoJjRQ5aAUj1SuSlnNv9iimle8GMA1IaA1l5rw6K/chfcgwMTg6HxRAIoludt5JGbIBryi2Lu1hOJRMaDnL7A57ofBnn3qx3H2HIGWGkkTW9EMkls0XMXwx8+mJVIj5HSYl0EeuCvEoTa1W3i1CbOf3kY2yCPKS3Qz3lOvJiwJ4ZQIDAQAB", "description": "Use signed-in Chrome tabs to scan jobs, confirm deliveries, and review BOSS HR reply drafts for 投递牛马.", "icons": { diff --git a/chrome-extension/tests/boss-hr-assistant.test.cjs b/chrome-extension/tests/boss-hr-assistant.test.cjs index 32a998c..3cd8c46 100644 --- a/chrome-extension/tests/boss-hr-assistant.test.cjs +++ b/chrome-extension/tests/boss-hr-assistant.test.cjs @@ -15,7 +15,7 @@ test("manifest loads the direct HR bridge and one-minute alarm capability", () = const bossScripts = manifest.content_scripts.find((entry) => entry.matches.includes("https://www.zhipin.com/*")).js; assert.deepEqual(bossScripts.slice(-3), ["boss-hr-support.js", "boss-hr-bridge.js", "boss-hr-assistant.js"]); assert.ok(manifest.permissions.includes("alarms")); - assert.equal(manifest.version, "1.8.18"); + assert.equal(manifest.version, "1.8.19"); }); test("assistant exposes policy-gated dedicated watch and preserves explicit manual send", () => { diff --git a/chrome-extension/tests/manifest-id.test.cjs b/chrome-extension/tests/manifest-id.test.cjs index bbd718a..3d8ba0c 100644 --- a/chrome-extension/tests/manifest-id.test.cjs +++ b/chrome-extension/tests/manifest-id.test.cjs @@ -17,7 +17,7 @@ function extensionIdFromKey(key) { test('manifest public key derives the backend allowlisted extension id', () => { const manifestPath = path.join(__dirname, '..', 'manifest.json'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); - assert.equal(manifest.version, '1.8.18'); + assert.equal(manifest.version, '1.8.19'); assert.equal(extensionIdFromKey(manifest.key), EXPECTED_EXTENSION_ID); const publicKey = crypto.createPublicKey({ diff --git a/chrome-extension/tests/profile-scoped-scan-contract.test.cjs b/chrome-extension/tests/profile-scoped-scan-contract.test.cjs index 36b2140..66c0af3 100644 --- a/chrome-extension/tests/profile-scoped-scan-contract.test.cjs +++ b/chrome-extension/tests/profile-scoped-scan-contract.test.cjs @@ -15,10 +15,10 @@ test("extension release and both content scripts use the profile-scoped contract const boss = source("boss-content.js"); const zhilian = source("zhilian-content.js"); - assert.equal(manifest.version, "1.8.18"); + assert.equal(manifest.version, "1.8.19"); assert.match(background, /BACKGROUND_VERSION = "2026-09-14-runtime-adapters"/); - assert.match(background, /REQUIRED_BOSS_CONTENT_VERSION = "1.8.18"/); - assert.match(boss, /EXTENSION_VERSION = "1.8.18"/); + assert.match(background, /REQUIRED_BOSS_CONTENT_VERSION = "1.8.19"/); + assert.match(boss, /EXTENSION_VERSION = "1.8.19"/); assert.match(zhilian, /EXTENSION_VERSION = "1.8.16"/); assert.match(background, /REQUIRED_ZHILIAN_CONTENT_VERSION = "1.8.16"/); const frontendBridge = fs.readFileSync(path.resolve(extensionDir, "../front/lib/chromeBridge.ts"), "utf8"); diff --git a/docs/delivery-recovery.md b/docs/delivery-recovery.md index c8fcda7..e3847f6 100644 --- a/docs/delivery-recovery.md +++ b/docs/delivery-recovery.md @@ -1,7 +1,8 @@ # BOSS / 智联投递恢复 -扩展版本 1.8.18,后台与页面协议 `2026-09-14-runtime-adapters`。 +扩展版本 1.8.19,后台与页面协议 `2026-09-14-runtime-adapters`。 +- BOSS 富文本输入框保留确认话术中的真实换行,不再用 textContent 覆盖 innerText 生成的换行结构;发送前仍逐字核对原话术。 - BOSS 点击操作只触发一次 click,避免先派发 click 再调用 `.click()` 导致收藏切换两次、重复打开沟通入口或重复发送话术。 - 页面进入前进/后退缓存(BFCache)时立即撤销旧页面执行资格;返回页面后重新注入脚本,旧异步任务不得继续点击或填写话术。 - “立即沟通”打开完整聊天页时,由后台接续尚未发送的话术:详情页先确认 OPENING_CHAT 阶段,新聊天页核对选中招聘者和加密岗位 ID,并在点击发送前消耗 GREETING_STARTED 许可。不得重新点击沟通入口;已开始话术发送或扩展重启丢失阶段时仍暂停核对。身份信息来自 BOSS 当前选中会话组件,仅导出 UID 与岗位 ID,不能用姓名或职位文字替代。 diff --git a/src/test/java/com/getjobs/application/service/BrowserRuntimeRegressionTest.java b/src/test/java/com/getjobs/application/service/BrowserRuntimeRegressionTest.java index e8c659e..b7a529d 100644 --- a/src/test/java/com/getjobs/application/service/BrowserRuntimeRegressionTest.java +++ b/src/test/java/com/getjobs/application/service/BrowserRuntimeRegressionTest.java @@ -108,6 +108,21 @@ Object probe(String body) { assertThat(page.locator("body").innerHTML()).isEqualTo(original); } + @Test void bossGreetingKeepsNewlinesInTheRealContenteditable() throws Exception { + fixture("boss", "detail/redacted-header-only-20260915.html", + "
"); + String source = Files.readString(Path.of("chrome-extension/boss-content.js")); + String functions = source.substring(source.indexOf(" function writeChatInput("), + source.indexOf(" function findSendButton(")); + assertThat(probe(functions + """ + function isCurrentContentInstance() { return true; } + const input = document.getElementById('chat-input'); + const expected = '测试岗位沟通。\\n个人作品集:https://example.invalid/'; + writeChatInput(input, expected); + return readChatInput(input); + """)).isEqualTo("测试岗位沟通。\n个人作品集:https://example.invalid/"); + } + @Test void realLayoutRejectsHiddenSuccessAndQuotaOverridesVisibleSuccess() throws Exception { fixture("zhilian", "states/success.html", ""); assertThat(probe("return GetJobsZhilianPageEvidence.detectStatus(document)")).isEqualTo("已投递");