From 7f828cbcf829f529b671b251f91704a7c2e1c0bb Mon Sep 17 00:00:00 2001 From: Alex Southwell Date: Sun, 25 Oct 2026 00:35:48 +0000 Subject: [PATCH] Compare Windows wireless snapshots after dropouts (#184) Co-authored-by: SAPHID --- CHANGELOG.md | 5 ++++ docs/windows-wireless-doctor.md | 10 +++++++ tests/wireless.cjs | 27 +++++++++++++++++++ ui/index.html | 46 +++++++++++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae0adf5..a9bc04f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +- Compare two explicit Windows Wireless Adapter doctor reads in local memory. + Highlight exact PnP instances and known state changes after a dropout; + incomplete inventories stay unknown. A Forget button clears the comparison. + No adapter setting changes or report uploads are made. + - Add recovery steps to the Windows Wireless Adapter doctor for streams that drop as they start and dongles that will not reconnect. Compare exact PnP IDs and test one connection condition at a time. In-app disable/re-enable remains diff --git a/docs/windows-wireless-doctor.md b/docs/windows-wireless-doctor.md index b8819ba..0112d77 100644 --- a/docs/windows-wireless-doctor.md +++ b/docs/windows-wireless-doctor.md @@ -56,6 +56,16 @@ whether the PC's own Wi-Fi drops too. A new `#2` name is not proof that this instance caused the failure. Keep the time of the drop and the two snapshots for Steam Support; the doctor does not save or upload them. +The app shows **Changes since previous read** after the second click. It +compares exact PnP IDs, known status fields and reported channels/bands; an +unknown value is never treated as a state change. If the PnP source was +unavailable in either read, it declines to compare devices. Each successful +read becomes the baseline for the next one. **Forget previous read** clears the +baseline and comparison; closing the app clears them too. The before/after +comparison stays in local memory and is not uploaded or added to telemetry. +Reported changes can reflect sequential query timing or a service recovering, +not a fault or permission to disable any instance. + To narrow a drop at stream start, try one condition at a time: wired PC networking instead of PC Wi-Fi, wired headphones instead of 2.4 GHz audio, and spacing the USB radio dongles apart. Recheck the stream after each change. The diff --git a/tests/wireless.cjs b/tests/wireless.cjs index cf817a5..48c8ec0 100644 --- a/tests/wireless.cjs +++ b/tests/wireless.cjs @@ -37,6 +37,33 @@ test('click reads once, disables repeated clicks and renders partial inventory', assert.match(f.el('wirelessResult').innerHTML,/distinct Wi-Fi Direct/); assert.match(f.el('wirelessStatus').textContent,/Partial PC snapshot/); }); +test('two explicit reads compare exact identities and known state changes without claiming a repair',async()=>{ + const f=fixture(); + const first={...sample,sources:{pnp:'ok'},devices:[{...sample.devices[0],id:'SWD\\WIFIDIRECT\\one', + name:'Adapter ',present:true,problemCode:0}]}; + const second={...first,observedAt:'2026-10-24T12:01:00Z',devices:[ + {...first.devices[0],present:false,problemCode:22}, + {...first.devices[0],id:'SWD\\WIFIDIRECT\\two',name:'Adapter '}]}; + let calls=0; f.context.api=async()=> ++calls===1 ? first : second; + await f.el('wirelessRead').onclick(); + assert.match(f.el('wirelessComparison').innerHTML,/Read PC adapters again/); + assert.equal(f.el('wirelessForget').disabled,false); + await f.el('wirelessRead').onclick(); + const change=f.el('wirelessComparison').innerHTML; + for(const phrase of ['Changes since previous read','Newly listed','presence Yes → No', + 'problem code 0 → 22','not a safe disable target','<one>','<two>']) assert.ok(change.includes(phrase),phrase); + assert.doesNotMatch(change,/|/); + f.el('wirelessForget').onclick(); + assert.equal(f.el('wirelessComparison').textContent,''); + assert.equal(f.el('wirelessForget').disabled,true); +}); +test('incomplete PnP reads cannot imply a device appeared or vanished',()=>{ + const f=fixture(); f.context.before={...sample,sources:{pnp:'unavailable'}}; + f.context.after={...sample,sources:{pnp:'ok'},devices:[]}; + const out=f.run('compareWireless(before,after)'); + assert.match(out,/comparison unavailable/); + assert.doesNotMatch(out,/No longer listed|Newly listed/); +}); test('unsupported, busy and failed probes leave no stale inventory and allow retry',async()=>{ for(const result of [{state:'unsupported',message:'Windows only'},{state:'busy',message:'Try again'},new Error('Denied')]) { const f=fixture();f.el('wirelessResult').textContent='stale inventory'; diff --git a/ui/index.html b/ui/index.html index e05ca08..bfa85e4 100644 --- a/ui/index.html +++ b/ui/index.html @@ -1441,8 +1441,9 @@