diff --git a/LianSyn-platform/app.js b/LianSyn-platform/app.js index 9046554..6b2e4c9 100644 --- a/LianSyn-platform/app.js +++ b/LianSyn-platform/app.js @@ -100,7 +100,7 @@ const persistedExtensionResultVersions = new Map(); let taskCreateInProgress = false; const AUTO_HANDOFF_RETRY_MS = 30_000; -const REQUIRED_EXTENSION_VERSION = '0.5.167'; +const REQUIRED_EXTENSION_VERSION = '0.5.168'; const MANUAL_HANDOFF_LABEL = '确认并提交到 ERP 插件'; const RETRY_HANDOFF_LABEL = '继续提交到 ERP 插件'; const RECONCILE_LABEL = '只读回查 ERP 现有结果'; diff --git a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md index beaf97d..8d917c0 100644 --- a/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md +++ b/agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md @@ -2,7 +2,7 @@ ## 当前基线 -- Chrome 插件:`0.5.167` +- Chrome 插件:`0.5.168` - Agent Prompt:`ltjt-agent-prompt-v1.8-independent-headcount-categories` - 生命周期契约:`ltjt-lifecycle-v2.9-roster-leader-contact-2026-08` - 五个 Skill:`0.5.125`;运营 DOCX:`0.5.125` @@ -10,6 +10,7 @@ - `0.5.166` 在散拼母团列表入口加入立即检查、100ms 条件轮询和 15 秒总超时;每次探测都重新取得当前主 iframe document,按钮一旦可用便立即继续。该等待只发生在点击前,不固定拖慢快速页面,也不触发业务写入重试。 - `0.5.167` 保留插件侧的空闲证明和受控重载安全协议,并继续包含 `0.5.166` 的散拼入口自适应等待。中央服务私有 OSS/ECS 云助手编排及迁移 019 已按用户决定从主线撤回,因此这些插件更新消息在当前主线没有服务端触发方,属于休眠能力;插件仍按现有人工发布/加载流程使用。 +- `0.5.168` 将 ERP 身份门禁从整页子串搜索收紧为唯一 `#Lable_UserName` 登录节点的规范化精确全等;缺失、重复、空白、子串或其他页面文字命中均不再让云电脑进入可执行状态,观察到的账号文本不离开扩展。 运行中的浏览器版本必须实时握手确认。当前制品文件名和 SHA-256 只看 [`../../../dist/release-manifest.json`](../../../dist/release-manifest.json),不从历史日志推断。 diff --git a/archive/releases/2026-09-07/README.md b/archive/releases/2026-09-07/README.md new file mode 100644 index 0000000..3886db4 --- /dev/null +++ b/archive/releases/2026-09-07/README.md @@ -0,0 +1,6 @@ +# 2026-09-07 发布归档 + +本目录只保存被新版本替代的历史发布物,不定义当前运行规则。当前制品文件名和 SHA-256 只以根目录 [`../../../dist/release-manifest.json`](../../../dist/release-manifest.json) 为准。 + +- `release-manifest-0.5.167.json`:收紧 ERP 登录账号身份识别前的历史清单快照。 +- `ltjt-order-assistant-0.5.167.zip`:被 `0.5.168` 的唯一登录节点精确账号匹配替代;保留用于恢复和追溯。 diff --git a/dist/ltjt-order-assistant-0.5.167.zip b/archive/releases/2026-09-07/ltjt-order-assistant-0.5.167.zip similarity index 100% rename from dist/ltjt-order-assistant-0.5.167.zip rename to archive/releases/2026-09-07/ltjt-order-assistant-0.5.167.zip diff --git a/archive/releases/2026-09-07/release-manifest-0.5.167.json b/archive/releases/2026-09-07/release-manifest-0.5.167.json new file mode 100644 index 0000000..a67efa6 --- /dev/null +++ b/archive/releases/2026-09-07/release-manifest-0.5.167.json @@ -0,0 +1,69 @@ +{ + "manifest_version": 1, + "generated_on": "2026-09-03", + "baselines": { + "chrome_extension": "0.5.167", + "skills": "0.5.125", + "business_instruction_docx": "0.5.125", + "agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories" + }, + "artifacts": [ + { + "kind": "chrome_extension", + "version": "0.5.167", + "path": "dist/ltjt-order-assistant-0.5.167.zip", + "source": "chrome-extension/ltjt-order-assistant", + "sha256": "6822ec660097a8889da8ea4fa22d4091467aa022067bff3bee2ac5406864b679" + }, + { + "kind": "skill", + "name": "lwlt-arrangement", + "version": "0.5.125", + "path": "dist/lwlt-arrangement-0.5.125.skill", + "source": "agent设计规范/skills/lwlt-arrangement", + "sha256": "c729bebec84695b8642a6d31cb4dc0d963135b6c6620c2173be095826cd3976d" + }, + { + "kind": "skill", + "name": "lwlt-confirmation", + "version": "0.5.125", + "path": "dist/lwlt-confirmation-0.5.125.skill", + "source": "agent设计规范/skills/lwlt-confirmation", + "sha256": "659f6aca7918a03a29fc78f0b4b938dfa9084ccdbb44ebd71f6399556cfa4609" + }, + { + "kind": "skill", + "name": "lwlt-lifecycle", + "version": "0.5.125", + "path": "dist/lwlt-lifecycle-0.5.125.skill", + "source": "agent设计规范/skills/lwlt-lifecycle", + "sha256": "d964c0a9e482f82757fea25d4713f0c81feb2704486583dfa84f2336ecd930c0" + }, + { + "kind": "skill", + "name": "lwlt-newbooking", + "version": "0.5.125", + "path": "dist/lwlt-newbooking-0.5.125.skill", + "source": "agent设计规范/skills/lwlt-newbooking", + "sha256": "bb610c50dd659fc172aabfa469b3028de98704c249cfd4890463deea0c88cd0c" + }, + { + "kind": "skill", + "name": "lwlt-updating", + "version": "0.5.125", + "path": "dist/lwlt-updating-0.5.125.skill", + "source": "agent设计规范/skills/lwlt-updating", + "sha256": "c6f5bc9008e2f63d170f3f140140003d99411ce5232632c48b38891da1ceee33" + }, + { + "kind": "business_instruction_docx", + "version": "0.5.125", + "path": "dist/老挝联泰AI指令表-0.5.125.docx", + "source": "agent设计规范/templates/business-input-templates.md", + "builder": "tools/build_business_instruction_docx.py", + "sha256": "a0c2fd5f808e3d3f2ac211a652a59f2e435d3824df49c51f763ca4beb7d9b97d", + "source_sha256": "27600fe9bcb0de3898a99550428a9890dd350c701ba704fb3940ca966088dcd9", + "builder_sha256": "c162884210da22e3b78368749b66f1f177df5e9fc6155f4fd9954bd516d187f1" + } + ] +} diff --git a/chrome-extension/ltjt-order-assistant/README.md b/chrome-extension/ltjt-order-assistant/README.md index 234b64c..9cdceb6 100644 --- a/chrome-extension/ltjt-order-assistant/README.md +++ b/chrome-extension/ltjt-order-assistant/README.md @@ -11,9 +11,14 @@ Chrome Manifest V3 扩展,在用户已登录的 LTJT ERP 页面内执行经过 ## 当前版本 -当前源码版本为 `0.5.167`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 +当前源码版本为 `0.5.168`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。 -0.5.167 当前重点: +0.5.168 当前重点: + +- ERP 登录身份只从当前主页面唯一的 `#Lable_UserName` 节点读取,并与平台绑定身份做 Unicode、空白和大小写规范化后的精确全等比较。缺失、重复、空白或仅为子串时都不再执行;不再用整页业务文字猜测账号。 +- 扩展仍只向平台返回账号是否存在、是否唯一和是否匹配,不回传 ERP 页面显示的账号文本。 + +继续保留 0.5.167 的空闲证明和受控重载协议: - 插件 PING 会返回当前运行任务、持久化写入边界和待回查结果汇总后的 `extension_update.safe`。只有内存与持久化状态都完全空闲,服务端才允许同一 ECS 实例进入文件部署。 - 中央服务完成共享目录替换后,平台通过受控消息请求后台 `chrome.runtime.reload()`,并刷新平台页以重新注入 content script;执行中、已跨写边界或待回查状态会拒绝重载。 diff --git a/chrome-extension/ltjt-order-assistant/background.js b/chrome-extension/ltjt-order-assistant/background.js index ce60ae7..b54bf29 100644 --- a/chrome-extension/ltjt-order-assistant/background.js +++ b/chrome-extension/ltjt-order-assistant/background.js @@ -1,6 +1,6 @@ 'use strict'; -importScripts('source-region.js', 'operation-plans.js', 'execution-guard.js', 'lifecycle-result.js', 'operation-timing.js'); +importScripts('source-region.js', 'operation-plans.js', 'execution-guard.js', 'lifecycle-result.js', 'operation-timing.js', 'erp-account-identity.js'); const runningTasks = new Set(); const executionWorkerKeepalives = new Map(); @@ -9,6 +9,7 @@ const operationPlans = self.LTJTOperationPlans; const executionGuard = self.LTJTExecutionGuard; const lifecycleResult = self.LTJTLifecycleResult; const operationTiming = self.LTJTOperationTiming; +const erpAccountIdentity = self.LTJTErpAccountIdentity; const EXTENSION_VERSION = chrome.runtime.getManifest().version; const operationTimingDetailBuffers = new Map(); const erpTabCache = new Map(); @@ -1406,7 +1407,7 @@ async function findOrOpenErpTab(taskId = '') { } async function readErpSessionStatus(expectedErpAccount = '') { - const normalizedExpectedAccount = String(expectedErpAccount || '').trim(); + const normalizedExpectedAccount = erpAccountIdentity.normalizeErpAccountIdentity(expectedErpAccount); const permission = await erpHostPermissionStatus(); const keepalive = await readErpKeepaliveState(); const tabs = await chrome.tabs.query({ url: `${ERP_ORIGIN}/*` }); @@ -1446,25 +1447,44 @@ async function readErpSessionStatus(expectedErpAccount = '') { try { const [inspection] = await executeErpScript(tab.id, { target: { tabId: tab.id }, - func: (expectedAccount) => { + func: () => { const bodyText = document.body?.innerText || ''; + const accountNodes = Array.from(document.querySelectorAll('#Lable_UserName')); + const accountNode = accountNodes.length === 1 ? accountNodes[0] : null; return { url: location.href, title: document.title, - account_configured: Boolean(expectedAccount), - account_matched: Boolean(expectedAccount) && bodyText.includes(expectedAccount), + observed_account_identity: accountNode?.textContent || '', + account_identity_node_count: accountNodes.length, login_or_permission_error: Boolean(document.querySelector('input[type="password"]')) || /login|无权限|权限不足|permission denied/i.test(`${location.href}\n${document.title}\n${bodyText.slice(0, 400)}`) }; }, - args: [normalizedExpectedAccount] + args: [] }); - const inspectionResult = inspection?.result || { + const rawInspectionResult = inspection?.result || { url: tab.url || '', title: '', - account_matched: false, + observed_account_identity: '', + account_identity_node_count: 0, login_or_permission_error: true }; + const { + observed_account_identity: observedAccountIdentity, + ...safeInspectionResult + } = rawInspectionResult; + const inspectionResult = { + ...safeInspectionResult, + account_configured: Boolean(normalizedExpectedAccount), + account_identity_present: Boolean( + erpAccountIdentity.normalizeErpAccountIdentity(observedAccountIdentity) + ), + account_matched: Number(safeInspectionResult.account_identity_node_count) === 1 + && erpAccountIdentity.exactErpAccountIdentityMatch( + normalizedExpectedAccount, + observedAccountIdentity + ) + }; const recoveryRequest = (shouldRecoverFromSessionStatus(inspectionResult) || keepalive.last_status === 'session_expired') ? requestErpLinkRecovery( diff --git a/chrome-extension/ltjt-order-assistant/erp-account-identity.js b/chrome-extension/ltjt-order-assistant/erp-account-identity.js new file mode 100644 index 0000000..b3f6978 --- /dev/null +++ b/chrome-extension/ltjt-order-assistant/erp-account-identity.js @@ -0,0 +1,26 @@ +(function installLTJTErpAccountIdentity(root, factory) { + const api = factory(); + if (typeof module !== 'undefined' && module.exports) module.exports = api; + if (root) root.LTJTErpAccountIdentity = api; +}(typeof self !== 'undefined' ? self : globalThis, () => { + 'use strict'; + + function normalizeErpAccountIdentity(value) { + return String(value || '') + .normalize('NFKC') + .replace(/\s+/gu, ' ') + .trim() + .toLocaleLowerCase(); + } + + function exactErpAccountIdentityMatch(expectedAccount, observedAccount) { + const expected = normalizeErpAccountIdentity(expectedAccount); + const observed = normalizeErpAccountIdentity(observedAccount); + return Boolean(expected && observed && expected === observed); + } + + return { + normalizeErpAccountIdentity, + exactErpAccountIdentityMatch + }; +})); diff --git a/chrome-extension/ltjt-order-assistant/inpage.js b/chrome-extension/ltjt-order-assistant/inpage.js index da2ab9d..ca711ab 100644 --- a/chrome-extension/ltjt-order-assistant/inpage.js +++ b/chrome-extension/ltjt-order-assistant/inpage.js @@ -6118,7 +6118,7 @@ } window.LTJTOrderAssistant = { - version: '0.5.167', + version: '0.5.168', resolveNativeListSearchValues, lookupKeywordMatchesText, inspectLifecycleSearchCriteria: lifecycleSearchCriteria, diff --git a/chrome-extension/ltjt-order-assistant/manifest.json b/chrome-extension/ltjt-order-assistant/manifest.json index 78131b9..1679680 100644 --- a/chrome-extension/ltjt-order-assistant/manifest.json +++ b/chrome-extension/ltjt-order-assistant/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "联泰下单助手", - "version": "0.5.167", + "version": "0.5.168", "description": "在已登录 LTJT ERP 页面内规划并受控执行联泰 ERP 业务操作。", "permissions": [ "activeTab", diff --git a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js index c7c6127..a4be622 100644 --- a/chrome-extension/ltjt-order-assistant/team-batch-inpage.js +++ b/chrome-extension/ltjt-order-assistant/team-batch-inpage.js @@ -944,7 +944,7 @@ window.LTJTOrderAssistant = { ...(window.LTJTOrderAssistant || {}), - version: '0.5.167', + version: '0.5.168', openTeamBatchForm, pingTeamBatchFrame, preflightTeamBatchNative, diff --git a/dist/ltjt-order-assistant-0.5.168.zip b/dist/ltjt-order-assistant-0.5.168.zip new file mode 100644 index 0000000..93a5db1 Binary files /dev/null and b/dist/ltjt-order-assistant-0.5.168.zip differ diff --git a/dist/release-manifest.json b/dist/release-manifest.json index a67efa6..a5ff104 100644 --- a/dist/release-manifest.json +++ b/dist/release-manifest.json @@ -1,8 +1,8 @@ { "manifest_version": 1, - "generated_on": "2026-09-03", + "generated_on": "2026-09-07", "baselines": { - "chrome_extension": "0.5.167", + "chrome_extension": "0.5.168", "skills": "0.5.125", "business_instruction_docx": "0.5.125", "agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories" @@ -10,10 +10,10 @@ "artifacts": [ { "kind": "chrome_extension", - "version": "0.5.167", - "path": "dist/ltjt-order-assistant-0.5.167.zip", + "version": "0.5.168", + "path": "dist/ltjt-order-assistant-0.5.168.zip", "source": "chrome-extension/ltjt-order-assistant", - "sha256": "6822ec660097a8889da8ea4fa22d4091467aa022067bff3bee2ac5406864b679" + "sha256": "2432a882f2fbdcf28bfb6bb8a7fead55986297f86d4cf4ab8e12ea373c72518c" }, { "kind": "skill", diff --git a/mappings/lifecycle.mapping.json b/mappings/lifecycle.mapping.json index 68e11b4..7eb3450 100644 --- a/mappings/lifecycle.mapping.json +++ b/mappings/lifecycle.mapping.json @@ -1,7 +1,7 @@ { "contract_version": "ltjt-lifecycle-v2.9-roster-leader-contact-2026-08", "current_agent_parse_prompt_version": "ltjt-agent-prompt-v1.8-independent-headcount-categories", - "current_extension_version": "0.5.167", + "current_extension_version": "0.5.168", "historical_test_marker": "TEST-202609", "scope": "/System/Business/", "erp_session_keepalive": { @@ -31,6 +31,17 @@ "failure_policy": "record structured recovery status and require manual login/inspection; an interrupted MV3 service worker recovery is normalized out of running and the next successful read-only probe returns the recovery state to idle; never retry a business operation" } }, + "erp_account_identity": { + "source": "the unique #Lable_UserName node in the existing ERP Mainlt.asp document", + "comparison": "NFKC-normalized, whitespace-normalized, case-insensitive exact equality with the platform account's configured ERP identity", + "forbidden_fallbacks": [ + "whole-page substring matching", + "matching an expected account against unrelated ERP business text", + "accepting a missing or duplicate login identity node" + ], + "privacy": "only matched/present/node-count booleans are returned to the platform; the observed ERP account text remains inside the extension session probe", + "failure_policy": "missing, duplicate, blank, or non-equal ERP identity is not execution-ready" + }, "operation_timing": { "schema_version": "ltjt-operation-timing-v1", "scope": "all plugin business executions through the shared result state machine", diff --git a/mappings/plan_add.mapping.json b/mappings/plan_add.mapping.json index 2281cb3..8a83048 100644 --- a/mappings/plan_add.mapping.json +++ b/mappings/plan_add.mapping.json @@ -1,7 +1,7 @@ { "$schema": "https://local.lwltapi/schemas/ltjt_form_mapping.schema.json", "mapping_version": "2026-09-03.shared_plan_create.plan_add.v0.10", - "status": "adaptive_list_entry_readiness_release_gated_0.5.167", + "status": "adaptive_list_entry_readiness_release_gated_0.5.168", "source": { "schema": "schemas/standard_system_operation.schema.json", "action": "shared_plan_create" diff --git a/tools/erp-account-identity.test.mjs b/tools/erp-account-identity.test.mjs new file mode 100644 index 0000000..23e05ff --- /dev/null +++ b/tools/erp-account-identity.test.mjs @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import test from 'node:test'; + +const require = createRequire(import.meta.url); +const identity = require('../chrome-extension/ltjt-order-assistant/erp-account-identity.js'); + +test('ERP account identity comparison accepts only normalized exact equality', () => { + assert.equal(identity.exactErpAccountIdentityMatch('测试AI员工账号', ' 测试ai员工账号 '), true); + assert.equal(identity.exactErpAccountIdentityMatch('ERP-01', 'erp-01'), true); + assert.equal(identity.exactErpAccountIdentityMatch('测试 AI', '测试 ai'), true); +}); + +test('ERP account identity comparison rejects substrings and blank identities', () => { + assert.equal(identity.exactErpAccountIdentityMatch('测试', '测试ai员工账号'), false); + assert.equal(identity.exactErpAccountIdentityMatch('admin', 'erp-admin-01'), false); + assert.equal(identity.exactErpAccountIdentityMatch('', ''), false); + assert.equal(identity.exactErpAccountIdentityMatch('employee', ''), false); +}); + +test('ERP session probe reads the unique login label and never matches against whole-page text', () => { + const background = readFileSync( + new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), + 'utf8' + ); + assert.match(background, /document\.querySelectorAll\('#Lable_UserName'\)/u); + assert.match(background, /accountNodes\.length === 1/u); + assert.match(background, /exactErpAccountIdentityMatch/u); + assert.doesNotMatch(background, /bodyText\.includes\(expectedAccount\)/u); +}); diff --git a/tools/lifecycle-contract.test.mjs b/tools/lifecycle-contract.test.mjs index fb8ba30..27b3bcf 100644 --- a/tools/lifecycle-contract.test.mjs +++ b/tools/lifecycle-contract.test.mjs @@ -1318,7 +1318,7 @@ test('passenger explicit server success is terminal without a post-save row requ assert.doesNotMatch(passengerBranch, /passengerRequery|verifyLifecycleOperation/); assert.doesNotMatch(background, /attemptAutomaticPassengerReconciliation/); assert.match(background, /名单已取得 ERP 明确成功响应,按业务规则确认录入成功/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.167'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.168'/); }); test('uncertain lifecycle writes can only converge through a read-only plugin requery', async () => { @@ -1525,7 +1525,7 @@ test('lifecycle execution keeps the MV3 worker alive until the durable task sett assert.match(background, /arrangement_resource_candidate_data_missing/); }); -test('extension 0.5.167 keeps reload dormant unless its durable execution state is fully idle', async () => { +test('extension 0.5.168 keeps reload dormant unless its durable execution state is fully idle', async () => { const [background, bridge] = await Promise.all([ readFile(new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), 'utf8'), readFile(new URL('../chrome-extension/ltjt-order-assistant/business-bridge.js', import.meta.url), 'utf8') @@ -1964,7 +1964,7 @@ test('delete guard distinguishes independent, shared child, and shared parent ro for (const operation of operations) assert.equal(plans.validateOperation(operation).ok, true, plans.validateOperation(operation).blockers.join('; ')); const mapping = JSON.parse(await readFile(new URL('../mappings/lifecycle.mapping.json', import.meta.url), 'utf8')); - assert.equal(mapping.current_extension_version, '0.5.167'); + assert.equal(mapping.current_extension_version, '0.5.168'); assert.equal( mapping.updates.order_update_independent.field_mapped_pending_live_validation['pax.child_no_bed'], 'ertrenshu' @@ -2333,8 +2333,9 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov assert.match(background, /if \(report\.manual_review_required === true\) return 'execution_uncertain'/); assert.match(background, /async function readErpSessionStatus/); assert.match(background, /message\?\.type === 'LTJT_ERP_SESSION_STATUS'/); - assert.match(background, /account_matched: Boolean\(expectedAccount\) && bodyText\.includes\(expectedAccount\)/); - assert.doesNotMatch(background, /bodyText\.includes\('测试ai员工账号'\)/); + assert.match(background, /document\.querySelectorAll\('#Lable_UserName'\)/); + assert.match(background, /erpAccountIdentity\.exactErpAccountIdentityMatch/); + assert.doesNotMatch(background, /bodyText\.includes\(expectedAccount\)/); assert.match(background, /lifecycle_preflight_ambiguous/); assert.match(background, /lifecycle_frame_discovery_retry_exhausted/); assert.match(background, /lifecycleFrameDiscoveryOnly/); @@ -2347,10 +2348,10 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov assert.match(inpage, /`ys_danweiid\$\{index\}`, resolvedCustomerId/); assert.doesNotMatch(inpage, /product_customer_source_region|sourceRegionCheck|source_reference/); assert.doesNotMatch(teamBatchInpage, /product_customer_source_region|sourceRegionCheck/); - assert.equal(extensionManifest.version, '0.5.167'); - assert.match(inpage, /version: '0\.5\.167'/); - assert.match(teamBatchInpage, /version: '0\.5\.167'/); - assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.167'/); + assert.equal(extensionManifest.version, '0.5.168'); + assert.match(inpage, /version: '0\.5\.168'/); + assert.match(teamBatchInpage, /version: '0\.5\.168'/); + assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.168'/); assert.match(inpage, /function strictIsoDate\(value\)/); assert.match(inpage, /const startDate = strictIsoDate\(controlCanonicalValue\(form, 'riqi0'\)\)/); assert.match(inpage, /const endDate = strictIsoDate\(controlCanonicalValue\(form, 'riqis0'\)\)/);