const assert = require("node:assert/strict"); const fs = require("node:fs"); const path = require("node:path"); const test = require("node:test"); const root = path.resolve(__dirname, "..", ".."); const harness = fs.readFileSync(path.join( root, "scripts", "Test-LegacyPackageLocalStateSmoke.mjs"), "utf8"); const wrapper = fs.readFileSync(path.join( root, "scripts", "Invoke-LegacyPackageLocalStateSmoke.ps1"), "utf8"); const shared = fs.readFileSync(path.join( root, "scripts", "Invoke-LegacyPackageInputSmoke.ps1"), "utf8"); test("local-state package smoke is a closed thirteen-step physical-input plan", () => { assert.match(harness, /nextInputSequence !== 14/u); assert.match(harness, /evidence\.exchanges\.length !== 13/u); assert.match(wrapper, /exchangeCount = \$ExpectedExchangePlan\.Count/u); assert.match(wrapper, /physicalClickCount/u); assert.match(wrapper, /folderPickerCancelCount/u); assert.match(wrapper, /\[string\]\$LegacyDataDirectory/u); assert.match(wrapper, /'\.\.\\MBN_STOCK_N\\MBN_STOCK_N\\bin\\Debug\\Data'/u); assert.doesNotMatch(wrapper, /C:\\Users\\[^\\]+/iu); assert.match(wrapper, /fileObservationCount/u); assert.match(wrapper, /inputRetryCount = 0/u); assert.match(wrapper, /function Read-LocalHarnessEvidenceFile/u); assert.match(wrapper, /item\.Length -gt 128KB/u); assert.doesNotMatch(wrapper, /Read-SmallJsonEvidenceFile \$EvidencePath 'Local-state harness evidence'/u); }); test("three app-owned folder pickers are clicked once and Escape-cancelled", () => { for (const [target, kind] of [ ["design-folder-picker", "design"], ["resource-folder-picker", "resource"], ["background-folder-picker", "background"] ]) { assert.ok(harness.includes(`[\"${target}\", \"${kind}\"]`)); } assert.match(wrapper, /Wait-UniqueOwnedFolderPicker/u); assert.match(wrapper, /OwnerChainContains/u); assert.match(wrapper, /VisibleTopLevelWindows/u); assert.match(wrapper, /EnumWindows\(callback, IntPtr\.Zero\)/u); assert.match(wrapper, /AutomationElement\]::FromHandle\(\$handle\)/u); assert.match(wrapper, /\$windowClass -cne '#32770'/u); assert.match(wrapper, /\$revalidated\[0\]\.Handle -ne \$picker\.Handle/u); assert.match(wrapper, /ControlType\]::Button/u); assert.match(wrapper, /Current\.ClassName -ceq 'Button'/u); assert.match(wrapper, /\$automationId -ceq '1'/u); assert.match(wrapper, /\$automationId -ceq '2'/u); assert.match(wrapper, /WindowPattern\]::Pattern/u); assert.match(wrapper, /\$windowPattern\.Current\.IsModal/u); assert.match(wrapper, /AcquireOwnedForeground/u); assert.match(wrapper, /OwnerChainContains\(window, expectedOwner\)/u); assert.match(wrapper, /SendEscapeToForegroundWindow/u); assert.match(harness, /waitForTrustedPointerClick/u); assert.match(harness, /isTrusted: event\.isTrusted === true/u); assert.match(wrapper, /closedAfterEscape = \$true/u); assert.match(wrapper, /not destroyed after the one Escape input/u); assert.match(wrapper, /settings file changed during a cancel-only smoke/u); }); test("comparison import preflight and idempotence are exact", () => { for (const hash of [ "1EE76BC464FB1C44C8B6546E99CDC21C726C0E2C24AD344F5C19AE41BFC0D2F2", "13C07BA64587549EDA9C1A694F3DFA19875CB1F888F02C9E071F17C47739E087", "2575C2420800670B0022EBEE819BA3D9640DB14E9552426DF46075D079F1F697" ]) { assert.ok(harness.includes(hash)); assert.ok(wrapper.includes(hash)); } assert.match(harness, /baselineMode === "fresh" \? 8 : 0/u); assert.match(harness, /baselineMode === "fresh" \? 0 : 8/u); assert.match(harness, /waitFor\(`comparison \$\{baselineMode\} baseline`[\s\S]*?\{ allowBusy: true \}\);/u); assert.match(harness, /receipt\?\.addedPairCount === expectedFirstAdded/u); assert.match(harness, /receipt\?\.skippedDuplicateCount === expectedFirstSkipped/u); assert.match(harness, /receipt\?\.addedPairCount === 0/u); assert.match(harness, /receipt\?\.skippedDuplicateCount === 8/u); assert.match(harness, /initialDestinationMode = isFresh \? "fresh" : "alreadyImported"/u); assert.match(wrapper, /\$script:DestinationBaselineMode = if \(\$isFresh\)/u); assert.match(wrapper, /Test-JsonEquivalent \$files\.destination \$script:InitialDestinationState/u); assert.equal((harness.match( /allowBusy: true, allowDialog: true, timeoutMilliseconds: 90_000/g) || []).length, 2); assert.match(harness, /secondImportIdempotent = true/u); assert.match(harness, /rowId: pair\.rowId/u); assert.match(harness, /displayLabel: pair\.displayLabel/u); assert.match(harness, /initialPair\.displayLabel !== "KRX100지수 ↔ 코스피 지수"/u); assert.doesNotMatch(harness, /pair\.first\?\.displayName|pair\.second\?\.displayName/u); assert.match(wrapper, /second import changed the comparison file/u); }); test("tracked harness cannot synthesize WebView clicks or close the app", () => { assert.match(harness, /"Input\.dispatchMouseEvent"/u); assert.doesNotMatch(harness, /rpc\("Input\.dispatchMouseEvent"/u); assert.doesNotMatch(harness, /rpc\("Input\.dispatchKeyEvent"/u); assert.doesNotMatch(harness, /rpc\("(?:Browser|Page)\.close"/u); assert.match(shared, /\[switch\]\$DefinitionsOnly/u); assert.match(shared, /public static void SendApplicationClick\(/u); assert.match(shared, /public static void SendEscapeToForegroundWindow\(/u); assert.match(shared, /Key-up only releases the/u); assert.match(shared, /caller separately proves that this exact/u); assert.doesNotMatch(shared, /lost foreground before Escape was released/u); }); test("initial native-state race is input-free and stdin cannot hold the helper open", () => { assert.match(harness, /process\.stdin\.unref/u); assert.match(harness, /label !== "DryRun IDLE preflight"[\s\S]*Only the input-free initial preflight/u); assert.match(harness, /\{ allowBusy: false, allowMissingState: true \}/u); assert.match(harness, /last\.safety\.outboundMessages\.map\(row => row\.type\)/u); assert.match(harness, /last\.safety\.blockedOutboundMessages\.length/u); assert.match(harness, /last\.dom\.connectionText !== "DRY RUN"/u); });