Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
node --check src/bootstrap.js
node --check src/main.js
- run: npm test
- name: Smoke-test real USB v3 native enumeration
run: node scripts/smoke-usb.cjs
- name: Smoke-test electron-store ESM with real Electron
run: npx --no-install electron scripts/smoke-electron-store.cjs

Expand Down Expand Up @@ -158,6 +160,30 @@ jobs:
- name: Build Windows installer
run: npm run make

- name: Smoke-test USB v3 from packaged Electron
shell: pwsh
run: |
$packageDirs = @(Get-ChildItem -LiteralPath 'out' -Directory | Where-Object { $_.Name -like '*-win32-x64' })
if ($packageDirs.Count -ne 1) {
throw "Expected exactly one packaged win32-x64 directory; found $($packageDirs.Count)"
}
$packageRoot = $packageDirs[0].FullName
$exe = Join-Path $packageRoot 'razerautopollingrate.exe'
$script = Join-Path $packageRoot 'resources\app\scripts\smoke-usb.cjs'
if (-not (Test-Path -LiteralPath $script -PathType Leaf)) {
throw "Packaged USB smoke script missing: $script"
}
$env:ELECTRON_RUN_AS_NODE = '1'
try {
$process = Start-Process -FilePath $exe -ArgumentList ('"' + $script + '"') -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Packaged USB v3 smoke test failed with exit code $($process.ExitCode)"
}
}
finally {
Remove-Item Env:ELECTRON_RUN_AS_NODE -ErrorAction SilentlyContinue
}

- name: Generate SHA256 hashes
shell: pwsh
run: |
Expand Down Expand Up @@ -204,6 +230,15 @@ jobs:
if-no-files-found: error
retention-days: 14

- name: Upload portable Windows test build
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: RazerAutoPollingRate-Windows-portable-${{ github.sha }}
path: out/*-win32-x64/**
if-no-files-found: error
retention-days: 14

- name: Upload Scoop package
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.rolling.outputs.rolling_release == 'true'
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
Expand Down
37 changes: 37 additions & 0 deletions docs/usb-v3-hardware-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# USB v3 test build

The migration uses `usb.getDevices()` for asynchronous enumeration and keeps
the current selection rules and hardware transports. Windows CrazyLight
communication continues through the existing HID bridge. Razer devices using
Windows' HID driver send the same feature reports through node-hid; devices
bound to WinUSB retain WebUSB. USB enumeration returns only vendor/product IDs,
without invoking native getters that open devices. No USB v2 fallback is shipped.

## Run the portable build

Download the `RazerAutoPollingRate-Windows-portable-<commit>` artifact from the
PR's successful CI run. Exit the installed app from its tray menu, extract the
ZIP completely, and run `razerautopollingrate.exe` in the extracted directory.
It uses the existing saved settings. Run only one copy at a time.

## Pulsar X2 CrazyLight checks

1. Wireless: verify the receiver and active mouse are recognized; read the
profile, polling rate, battery and Turbo status. Confirm no `listDevices`
or native-module load error appears.
2. Exercise an existing game rule, then return to the desktop. Verify the
polling rate changes and reads back correctly, and Turbo behaves as before.
Record the starting rate and restore it after testing.
3. Disconnect and reconnect the receiver. Confirm background checks recover
and the tray reflects the mouse again after movement.
4. Sleep and wake the mouse and the PC. Confirm detection and automation resume.
5. Wired: confirm the wired mouse takes priority over its attached receiver;
its reported rate and battery remain visible, with the existing read-only
behavior. Unplug the cable and confirm wireless selection resumes.

If a Razer mouse is available, also check its discovery, rate readback, rate
changes, reconnect and sleep/wake. CI cannot validate physical USB transfers.

To return to the stable build, exit the portable copy and start the installed
app again. Report the tested commit, connection mode and diagnostic log if any
check fails. Keep the PR unmerged until hardware testing succeeds.
4 changes: 3 additions & 1 deletion forge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module.exports = {
icon: 'src/assets/app',
electronZipDir: process.env.ELECTRON_ZIP_DIR || undefined
},
rebuildConfig: {},
// USB v3 ships its platform N-API binary in an optional dependency.
// Keep node-hid's existing rebuild behavior, but do not recompile USB.
rebuildConfig: { ignoreModules: ['usb'] },
makers: [
{
name: '@electron-forge/maker-squirrel',
Expand Down
198 changes: 178 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"electron-squirrel-startup": "^1.0.0",
"electron-store": "^11.0.2",
"node-hid": "3.4.0",
"usb": "^2.11.0"
"usb": "^3.2.1"
},
"devDependencies": {
"@electron-forge/cli": "8.0.1",
Expand All @@ -44,7 +44,6 @@
"extract-zip": "npm:@electron-internal/extract-zip@^1.0.4"
},
"allowScripts": {
"usb@2.18.0": true,
"electron-winstaller@5.4.0": true
}
}
Loading
Loading