Skip to content

chore: integration coverage for SD card logging mode#561

Merged
tylerkron merged 3 commits into
mainfrom
claude/sharp-herschel-49e0bb
Jun 3, 2026
Merged

chore: integration coverage for SD card logging mode#561
tylerkron merged 3 commits into
mainfrom
claude/sharp-herschel-49e0bb

Conversation

@tylerkron
Copy link
Copy Markdown
Contributor

Closes #553.

Adds the FlaUI hardware-in-the-loop scenario for SD card logging mode — one of the gaps surfaced during the Core 0.22.0 validation (#551) — plus the app change and AutomationIds needed to drive it.

What the test does

SdCardLoggingTests.SdCardLogging_LogsToSdCard_NotStream ([Ui] + [RequiresDevice]) drives the real GUI out-of-process:

  1. Connect over Serial/USB (SD logging is USB-only).
  2. Baseline the SD card file count (also asserts a card is present → inconclusive otherwise).
  3. Switch Stream to App → Log to Device via the Devices-pane drawer.
  4. Enable the analog channels + set a known rate.
  5. Start logging, run briefly, stop.
  6. Assert SD-card-side evidence: the device's Enabled/Disabled SD card logging log lines and a new file on the SD card (file count increased) — confirming SD-card mode was used, not an in-app stream session.

The app fix this surfaced (separate fix(ui) commit)

The logging-mode segmented selector bound its switch to a RadioButton Command. A ButtonBase.Command fires only on a real Click, which a background UI-automation host cannot raise — checking the button through the UIA SelectionItem/Toggle pattern raises Checked, not Click — so the device never switched mode under automation (same class of issue as the channel-tile gotcha).

Fix: forward each RadioButton's Checked event to SetLoggingModeCommand via a Microsoft.Xaml.Behaviors EventTrigger/InvokeCommandAction. Interactive behavior is unchanged (a click still raises Checked); the SelectedLoggingMode setter is idempotent, so the redundant Checked raised when the OneWay IsChecked binding refreshes is a harmless no-op. Controls already driven by IsChecked itself (StartLoggingToggle, the DeviceLogsTab sub-tab) were automatable as-is — now documented as README gotcha #12.

AutomationIds added (touched controls only)

LoggingModeStreamToApp / LoggingModeLogToDevice / SdCardFormatSelector (Devices drawer), DeviceLogsTab (Logged Data), and RefreshSdCardFilesButton / SdCardStatusText / SdCardFileList (DeviceLogsView). All documented in the README AutomationId map.

Verification

  • App + UITest build clean; dotnet format-consistent.
  • Unit gate: 274/274 pass.
  • Full device-gated UI suite on a real device with an SD card: 5/5 pass (~3m37s) — the new SD scenario plus the 4 existing ones, so the shared device-drawer change caused no regression.

🤖 Generated with Claude Code

claude added 2 commits June 2, 2026 13:52
…witch modes

The STREAM TO APP / LOG TO DEVICE segmented selector on the Devices pane drawer
bound its mode switch to a RadioButton Command. A ButtonBase Command fires only on
a real Click, which a background UI-automation host (the FlaUI integration harness)
cannot raise — checking the button through the UIA SelectionItem/Toggle pattern
raises Checked, not Click — so the device never switched logging mode under
automation.

Forward each RadioButton's Checked event to SetLoggingModeCommand via a
Microsoft.Xaml.Behaviors EventTrigger/InvokeCommandAction. Interactive behavior is
unchanged (a click still raises Checked); the SelectedLoggingMode setter is
idempotent, so the redundant Checked raised when the OneWay IsChecked binding
refreshes after a switch is a harmless no-op.

Add literal AutomationIds to the two mode RadioButtons (LoggingModeStreamToApp,
LoggingModeLogToDevice) and to the SD-card DATA FORMAT selector
(SdCardFormatSelector), whose presence is the independent confirmation that the
switch took effect. Surfaced while adding SD-card logging UI coverage (#553).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add SdCardLoggingTests (Ui + RequiresDevice): connect over USB, switch to Log to
Device (SD card) mode, enable channels, run a brief logging session, stop, and
assert the device logged to its SD card — the device's "Enabled/Disabled SD card
logging" log lines plus a new file on the SD card (file count increased) —
confirming SD-card mode was used rather than an in-app stream session.

- DaqifiAppFixture: SetLoggingMode(bool) and GetSdCardFileCount() helpers, plus the
  device-drawer / DEVICE-LOGS-sub-tab / refresh plumbing they need.
- AutomationIds on the touched SD surfaces: DeviceLogsView REFRESH button, SD status
  line, and file list; the Logged Data DEVICE LOGS sub-tab.
- README: new scenario row, AutomationId map entries, and a gotcha documenting why a
  RadioButton/ToggleButton bound Command is not drivable from automation (drive it
  through IsChecked instead).

Closes #553.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tylerkron tylerkron requested a review from a team as a code owner June 2, 2026 22:16
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add SD card logging integration test and fix automation-driven mode switching

🧪 Tests ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add SD card logging integration test with device automation helpers
• Fix logging-mode selector to work with UI automation via EventTrigger
• Add AutomationIds to SD card and logging-mode UI controls
• Document automation gotcha for RadioButton/ToggleButton Command binding
Diagram
flowchart LR
  A["UI Automation Test"] -->|SetLoggingMode| B["Logging-Mode RadioButtons"]
  B -->|EventTrigger on Checked| C["SetLoggingModeCommand"]
  C -->|Updates| D["Shell.IsLogToDeviceMode"]
  D -->|Visibility Binding| E["SdCardFormatSelector"]
  A -->|GetSdCardFileCount| F["DeviceLogsView"]
  F -->|Reads| G["SdCardStatusText"]
  A -->|Asserts| H["SD File Count Increased"]

Loading

Grey Divider

File Changes

1. Daqifi.Desktop.UITest/SdCardLoggingTests.cs 🧪 Tests +129/-0

New SD card logging integration test scenario

• New test class SdCardLoggingTests with scenario for SD card logging mode
• Test connects via USB, switches to Log-to-Device mode, enables channels, runs logging session
• Asserts device logged to SD card by checking "Enabled/Disabled SD card logging" log lines and file
 count increase
• Includes screenshot capture helper for test results

Daqifi.Desktop.UITest/SdCardLoggingTests.cs


2. Daqifi.Desktop.UITest/DaqifiAppFixture.cs 🧪 Tests +207/-0

Add SD card logging mode test helpers and AutomationIds

• Add SetLoggingMode(bool) helper to switch between Stream-to-App and Log-to-Device modes via UI
 automation
• Add GetSdCardFileCount() helper to navigate to Device Logs tab, refresh SD files, and parse file
 count from status line
• Add private helpers: EnsureDeviceSettingsDrawerOpen(), SelectDeviceLogsSubTab(),
 InvokeRefreshSdCardFiles()
• Add AutomationId constants for logging-mode selector, SD format selector, device logs tab, and SD
 file controls

Daqifi.Desktop.UITest/DaqifiAppFixture.cs


3. Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml 🐞 Bug fix +27/-6

Fix logging-mode selector for UI automation via EventTrigger

• Replace RadioButton Command binding with Microsoft.Xaml.Behaviors EventTrigger on Checked
 event
• Add AutomationProperties.AutomationId to both logging-mode RadioButtons:
 LoggingModeStreamToApp and LoggingModeLogToDevice
• Add AutomationProperties.AutomationId to SD card data-format ComboBox: SdCardFormatSelector
• Add detailed comment explaining why EventTrigger is needed for UI automation compatibility

Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml


View more (3)
4. Daqifi.Desktop/View/DeviceLogsView.xaml ✨ Enhancement +7/-1

Add AutomationIds to SD card view controls

• Add AutomationProperties.AutomationId="RefreshSdCardFilesButton" to refresh button
• Add AutomationProperties.AutomationId="SdCardStatusText" to SD card status TextBlock
• Add AutomationProperties.AutomationId="SdCardFileList" to file list ListView
• Add comment explaining that UIA Name mirrors the bound Text for test harness to read file count

Daqifi.Desktop/View/DeviceLogsView.xaml


5. Daqifi.Desktop.UITest/README.md 📝 Documentation +24/-1

Document SD card logging test and automation gotchas

• Update test coverage table to include new
 SdCardLoggingTests.SdCardLogging_LogsToSdCard_NotStream scenario
• Add AutomationId mappings for logging-mode selector, SD format selector, device logs tab, and SD
 file controls
• Add gotcha #12 documenting RadioButton/ToggleButton Command binding limitation and EventTrigger
 workaround
• Explain independent confirmation pattern for mode switch verification

Daqifi.Desktop.UITest/README.md


6. Daqifi.Desktop/View/Prototype/LoggedDataPanePrototype.xaml Additional files +1/-0

...

Daqifi.Desktop/View/Prototype/LoggedDataPanePrototype.xaml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Jun 2, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0)

Grey Divider


Action required

1. Public test method lacks XML 📘 Rule violation ✧ Quality
Description
The new public test method SdCardLogging_LogsToSdCard_NotStream has no XML documentation comment,
violating the requirement that all new/modified public members include /// <summary> docs.
Code

Daqifi.Desktop.UITest/SdCardLoggingTests.cs[R32-36]

Evidence
Rule 244813 requires XML documentation comments for all new/modified public members. The method is
public and has MSTest attributes but no preceding /// <summary> comment.

Rule 244813: Require XML documentation comments for all public API members
Daqifi.Desktop.UITest/SdCardLoggingTests.cs[32-36]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public member (`SdCardLogging_LogsToSdCard_NotStream`) was added without an XML documentation comment containing at least a `<summary>` element.

## Issue Context
The file already uses XML docs for the class, so adding a method-level `<summary>` keeps documentation consistent and meets the public-API documentation rule.

## Fix Focus Areas
- Daqifi.Desktop.UITest/SdCardLoggingTests.cs[32-36]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. SdCardLogging uses Thread.Sleep ✓ Resolved 📎 Requirement gap ☼ Reliability
Description
The new SD-card logging UI test uses a fixed Thread.Sleep duration, which goes against the harness
guideline to use retry/wait utilities instead of sleeps and can introduce flakiness across device
speeds.
Code

Daqifi.Desktop.UITest/SdCardLoggingTests.cs[R68-70]

Evidence
Rule 863849 requires retry/wait timing patterns and flags fixed sleeps as a failure condition. The
test explicitly calls System.Threading.Thread.Sleep(SdRunDuration) during the scenario run.

Follow UI harness interaction and timing guidelines to avoid flaky automation
Daqifi.Desktop.UITest/SdCardLoggingTests.cs[68-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SdCardLogging_LogsToSdCard_NotStream` uses `System.Threading.Thread.Sleep(SdRunDuration)` to wait during the logging run. The UI harness guidance requires using `Retry`/`WaitUntil*`-style waits instead of fixed sleeps to reduce flakiness.

## Issue Context
Even if the intent is a deliberate run window, the harness compliance rule for timing discourages fixed sleeps in favor of the shared wait/retry patterns.

## Fix Focus Areas
- Daqifi.Desktop.UITest/SdCardLoggingTests.cs[68-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. AAA asserts inside Act section ✓ Resolved 📘 Rule violation ▣ Testability
Description
The test’s Act phase contains multiple assertions (e.g., checking for SD logging log lines) before
the explicit Assert section, reducing clarity of Arrange-Act-Assert separation.
Code

Daqifi.Desktop.UITest/SdCardLoggingTests.cs[R57-78]

Evidence
Rule 244801 requires tests to be clearly separated into Arrange, Act, and Assert in order. In the
new test, assertions about enabled/disabled SD logging occur within the Act section prior to the
explicit Assert section header.

Rule 244801: Enforce Arrange-Act-Assert structure in unit tests
Daqifi.Desktop.UITest/SdCardLoggingTests.cs[57-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SdCardLogging_LogsToSdCard_NotStream` includes assertions during the commented `Act` portion, rather than keeping verification in the `Assert` section.

## Issue Context
The test already uses `// Arrange —`, `// Act —`, and `// Assert` comments, so it likely intends to follow AAA; moving/verifying assertions in the final assert block will make the structure unambiguous.

## Fix Focus Areas
- Daqifi.Desktop.UITest/SdCardLoggingTests.cs[57-78]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Nested retry breaks timeout ✓ Resolved 🐞 Bug ☼ Reliability
Description
SdCardLoggingTests wraps GetSdCardFileCount() in an outer 30s retry, but GetSdCardFileCount() itself
retries up to 45s (and throws on timeout), so a single polling attempt can block longer than the
outer timeout and make the test run unpredictably long/flaky.
Code

Daqifi.Desktop.UITest/SdCardLoggingTests.cs[R83-92]

Evidence
The test’s outer retry (30s) calls a helper that can block up to 45s per attempt, so the intended
30s cap is not enforced and the test can exceed expected runtime or fail unpredictably.

Daqifi.Desktop.UITest/SdCardLoggingTests.cs[79-92]
Daqifi.Desktop.UITest/DaqifiAppFixture.cs[831-866]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`SdCardLogging_LogsToSdCard_NotStream` uses an outer `Retry.WhileFalse(timeout: 30s)` to wait for the SD file count to increase, but the predicate calls `GetSdCardFileCount()` which internally waits up to **45 seconds** and throws on timeout. This makes the outer 30-second timeout ineffective and can greatly extend test duration.

### Issue Context
- Outer polling is intended to be bounded (30s) after stopping logging.
- Inner polling in `GetSdCardFileCount()` is appropriate when first establishing SD state, but too long when repeatedly called from an outer retry.

### Fix Focus Areas
- Daqifi.Desktop.UITest/SdCardLoggingTests.cs[79-92]
- Daqifi.Desktop.UITest/DaqifiAppFixture.cs[831-866]

### Suggested change
- Pass a smaller `timeoutSeconds` when `GetSdCardFileCount()` is called from the outer polling loop (e.g. `GetSdCardFileCount(timeoutSeconds: 8)`), or
- Refactor so only **one** retry layer exists (e.g. add `WaitForSdCardFileCountIncrease(beforeCount, timeout)` that performs refresh + parse with a single overall timeout).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
5. Implicit XAML Behaviors dependency ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
DevicesPanePrototype.xaml now uses i:Interaction/i:InvokeCommandAction, but
Daqifi.Desktop.csproj has no explicit reference to the XAML Behaviors package, making compilation
dependent on an untracked transitive dependency and risking clean-build failures.
Code

Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml[R658-678]

Evidence
The XAML file now directly uses Behaviors types via the xaml/behaviors schema, while the app
project’s package references do not include Microsoft.Xaml.Behaviors.Wpf, so the dependency is not
explicitly declared.

Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml[1-15]
Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml[644-679]
Daqifi.Desktop/Daqifi.Desktop.csproj[55-81]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The XAML now references `http://schemas.microsoft.com/xaml/behaviors` types (`Interaction`, `EventTrigger`, `InvokeCommandAction`). The app project does not explicitly reference `Microsoft.Xaml.Behaviors.Wpf`, so builds rely on a transitive dependency remaining present.

### Issue Context
Even if the library currently arrives transitively, it is brittle: dependency graph changes can break XAML compilation on a clean restore.

### Fix Focus Areas
- Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml[1-15]
- Daqifi.Desktop/View/Prototype/DevicesPanePrototype.xaml[651-679]
- Daqifi.Desktop/Daqifi.Desktop.csproj[55-81]

### Suggested change
Add an explicit package reference in `Daqifi.Desktop.csproj`, e.g.:
```xml
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="<appropriate_version>" />
```
(Use the repo’s existing versioning approach.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +32 to +36
[TestMethod]
[TestCategory("Ui")]
[TestCategory("RequiresDevice")]
public void SdCardLogging_LogsToSdCard_NotStream()
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Public test method lacks xml 📘 Rule violation ✧ Quality

The new public test method SdCardLogging_LogsToSdCard_NotStream has no XML documentation comment,
violating the requirement that all new/modified public members include /// <summary> docs.
Agent Prompt
## Issue description
A new public member (`SdCardLogging_LogsToSdCard_NotStream`) was added without an XML documentation comment containing at least a `<summary>` element.

## Issue Context
The file already uses XML docs for the class, so adding a method-level `<summary>` keeps documentation consistent and meets the public-API documentation rule.

## Fix Focus Areas
- Daqifi.Desktop.UITest/SdCardLoggingTests.cs[32-36]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in eb41051 — added an XML <summary> to SdCardLogging_LogsToSdCard_NotStream describing the end-to-end SD-card scenario, consistent with the existing class-level docs.

- Add an XML <summary> to the SdCardLogging_LogsToSdCard_NotStream test method.
- Replace the nested retry (an outer 30s loop wrapping GetSdCardFileCount, which itself
  waited up to 45s and threw on timeout) with WaitForSdCardFileCountAbove: a single
  overall timeout with a short, bounded per-attempt settle, so one slow attempt can no
  longer exceed the budget. Factored the shared refresh+parse into
  ReadSdCardFileCountAfterRefresh.
- Reference Microsoft.Xaml.Behaviors.Wpf explicitly in Daqifi.Desktop.csproj (1.1.19, the
  version MahApps.Metro 2.4.11 resolves) so the XAML EventTrigger no longer relies on an
  untracked transitive dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

📊 Code Coverage Report

Summary

Summary
Generated on: 6/2/2026 - 10:46:27 PM
Coverage date: 6/2/2026 - 10:45:50 PM - 6/2/2026 - 10:46:22 PM
Parser: MultiReport (5x Cobertura)
Assemblies: 3
Classes: 121
Files: 150
Line coverage: 19.4% (1666 of 8585)
Covered lines: 1666
Uncovered lines: 6919
Coverable lines: 8585
Total lines: 26689
Branch coverage: 19.6% (560 of 2852)
Covered branches: 560
Total branches: 2852
Method coverage: Feature is only available for sponsors

Coverage

DAQiFi - 19.1%
Name Line Branch
DAQiFi 19.1% 19.6%
Daqifi.Desktop.App 3.9% 0%
Daqifi.Desktop.Channel.AbstractChannel 40.9% 22.2%
Daqifi.Desktop.Channel.AnalogChannel 58.7% 12.5%
Daqifi.Desktop.Channel.Channel 11.5% 0%
Daqifi.Desktop.Channel.ChannelColorManager 100% 100%
Daqifi.Desktop.Channel.DataSample 91.6%
Daqifi.Desktop.Channel.DigitalChannel 65.2% 12.5%
Daqifi.Desktop.Commands.CompositeCommand 0% 0%
Daqifi.Desktop.Commands.HostCommands 0%
Daqifi.Desktop.Commands.WeakEventHandlerManager 0% 0%
Daqifi.Desktop.Configuration.FirewallConfiguration 90.6% 66.6%
Daqifi.Desktop.Configuration.WindowsFirewallWrapper 64% 68.4%
Daqifi.Desktop.ConnectionManager 42.4% 39.2%
Daqifi.Desktop.Converters.BoolToActiveStatusConverter 0% 0%
Daqifi.Desktop.Converters.BoolToConnectionStatusConverter 0% 0%
Daqifi.Desktop.Converters.BoolToStatusColorConverter 0% 0%
Daqifi.Desktop.Converters.BrushColorMatchConverter 0% 0%
Daqifi.Desktop.Converters.ConnectionTypeToColorConverter 0% 0%
Daqifi.Desktop.Converters.ConnectionTypeToUsbConverter 0% 0%
Daqifi.Desktop.Converters.InvertedBoolToVisibilityConverter 0% 0%
Daqifi.Desktop.Converters.ListToStringConverter 0% 0%
Daqifi.Desktop.Converters.NotNullToVisibilityConverter 0% 0%
Daqifi.Desktop.Converters.OxyColorToBrushConverter 0% 0%
Daqifi.Desktop.Device.AbstractStreamingDevice 42.8% 33.3%
Daqifi.Desktop.Device.DeviceMessage 0%
Daqifi.Desktop.Device.Firmware.BootloaderSessionStreamingDeviceAdapter 0% 0%
Daqifi.Desktop.Device.Firmware.WifiPromptDelayProcessRunner 0% 0%
Daqifi.Desktop.Device.NativeMethods 100%
Daqifi.Desktop.Device.SerialDevice.SerialStreamingDevice 27.6% 29.4%
Daqifi.Desktop.Device.WiFiDevice.DaqifiStreamingDevice 40.9% 39.4%
Daqifi.Desktop.DialogService.DialogService 0% 0%
Daqifi.Desktop.DialogService.ServiceLocator 0% 0%
Daqifi.Desktop.DiskSpace.DiskSpaceCheckResult 100%
Daqifi.Desktop.DiskSpace.DiskSpaceEventArgs 100%
Daqifi.Desktop.DiskSpace.DiskSpaceMonitor 88.2% 86.6%
Daqifi.Desktop.DuplicateDeviceCheckResult 100%
Daqifi.Desktop.Exporter.OptimizedLoggingSessionExporter 66.5% 60.9%
Daqifi.Desktop.Exporter.SampleData 100%
Daqifi.Desktop.Helpers.BooleanConverter`1 0% 0%
Daqifi.Desktop.Helpers.BooleanToInverseBoolConverter 0% 0%
Daqifi.Desktop.Helpers.BooleanToVisibilityConverter 0%
Daqifi.Desktop.Helpers.EnumDescriptionConverter 100% 100%
Daqifi.Desktop.Helpers.IntToVisibilityConverter 0% 0%
Daqifi.Desktop.Helpers.MinMaxDownsampler 98.6% 93.7%
Daqifi.Desktop.Helpers.MyMultiValueConverter 0%
Daqifi.Desktop.Helpers.NaturalSortHelper 100% 100%
Daqifi.Desktop.Helpers.OxyPlotDarkTheme 0%
Daqifi.Desktop.Helpers.VersionHelper 98.2% 66.2%
Daqifi.Desktop.Logger.DatabaseLogger 0% 0%
Daqifi.Desktop.Logger.DatabaseMigrator 0% 0%
Daqifi.Desktop.Logger.DeviceLegendGroup 100% 100%
Daqifi.Desktop.Logger.LoggedSeriesLegendItem 0% 0%
Daqifi.Desktop.Logger.LoggingContext 100%
Daqifi.Desktop.Logger.LoggingContextDesignTimeFactory 0%
Daqifi.Desktop.Logger.LoggingManager 0% 0%
Daqifi.Desktop.Logger.LoggingSession 16% 5%
Daqifi.Desktop.Logger.PlotLogger 0% 0%
Daqifi.Desktop.Logger.SessionDeviceMetadata 80%
Daqifi.Desktop.Logger.SummaryLogger 0% 0%
Daqifi.Desktop.Logger.TimestampGapDetector 95% 83.3%
Daqifi.Desktop.Loggers.ImportOptions 0%
Daqifi.Desktop.Loggers.ImportProgress 0% 0%
Daqifi.Desktop.Loggers.SdCardSessionImporter 0% 0%
Daqifi.Desktop.MainWindow 0% 0%
Daqifi.Desktop.Migrations.AddSamplesSessionTimeIndex 0%
Daqifi.Desktop.Migrations.AddSessionDeviceMetadata 0%
Daqifi.Desktop.Migrations.AddSessionSampleCount 0%
Daqifi.Desktop.Migrations.InitialSQLiteMigration 0%
Daqifi.Desktop.Migrations.LoggingContextModelSnapshot 0%
Daqifi.Desktop.Models.AddProfileModel 0%
Daqifi.Desktop.Models.DaqifiSettings 80.5% 83.3%
Daqifi.Desktop.Models.DebugDataCollection 6.6% 0%
Daqifi.Desktop.Models.DebugDataModel 0% 0%
Daqifi.Desktop.Models.Notifications 0%
Daqifi.Desktop.Models.SdCardFile 16.6% 0%
Daqifi.Desktop.Services.NoOpMessageBoxService 0%
Daqifi.Desktop.Services.WindowsPrincipalAdminChecker 0%
Daqifi.Desktop.Services.WpfMessageBoxService 0%
Daqifi.Desktop.UpdateVersion.VersionNotification 85.7% 54.1%
Daqifi.Desktop.View.ConnectionDialog 0% 0%
Daqifi.Desktop.View.DebugWindow 0% 0%
Daqifi.Desktop.View.DeviceLogsView 0% 0%
Daqifi.Desktop.View.DuplicateDeviceDialog 0% 0%
Daqifi.Desktop.View.ErrorDialog 0% 0%
Daqifi.Desktop.View.ExportDialog 0% 0%
Daqifi.Desktop.View.FirmwareDialog 0% 0%
Daqifi.Desktop.View.Flyouts.FirmwareFlyout 0% 0%
Daqifi.Desktop.View.Flyouts.LiveGraphFlyout 0% 0%
Daqifi.Desktop.View.Flyouts.NotificationsFlyout 0% 0%
Daqifi.Desktop.View.Flyouts.SummaryFlyout 0% 0%
Daqifi.Desktop.View.MigrationStatusWindow 0% 0%
Daqifi.Desktop.View.MinimapInteractionController 0% 0%
Daqifi.Desktop.View.ProfilesPane 0% 0%
Daqifi.Desktop.View.Prototype.ChannelsPanePrototype 0% 0%
Daqifi.Desktop.View.Prototype.DevicesPanePrototype 0% 0%
Daqifi.Desktop.View.Prototype.LiveGraphPane 0% 0%
Daqifi.Desktop.View.Prototype.LoggedDataPanePrototype 0% 0%
Daqifi.Desktop.View.SuccessDialog 0% 0%
Daqifi.Desktop.ViewModels.ChannelsPaneViewModel 0% 0%
Daqifi.Desktop.ViewModels.ChannelTileViewModel 0% 0%
Daqifi.Desktop.ViewModels.ConnectionDialogViewModel 37.3% 36.1%
Daqifi.Desktop.ViewModels.DaqifiViewModel 17.3% 10.5%
Daqifi.Desktop.ViewModels.DeviceLogsViewModel 53% 47%
Daqifi.Desktop.ViewModels.DevicesPaneViewModel 0% 0%
Daqifi.Desktop.ViewModels.DeviceTileViewModel 0% 0%
Daqifi.Desktop.ViewModels.DuplicateDeviceDialogViewModel 0%
Daqifi.Desktop.ViewModels.ErrorDialogViewModel 0%
Daqifi.Desktop.ViewModels.ExportDialogViewModel 0% 0%
Daqifi.Desktop.ViewModels.FirmwareDialogViewModel 0% 0%
Daqifi.Desktop.ViewModels.NewProfileChannelItem 0%
Daqifi.Desktop.ViewModels.NewProfileDeviceItem 0% 0%
Daqifi.Desktop.ViewModels.ProfilesPaneViewModel 0% 0%
Daqifi.Desktop.ViewModels.SettingsViewModel 0% 0%
Daqifi.Desktop.ViewModels.SuccessDialogViewModel 85.7%
Daqifi.Desktop.WindowViewModelMapping.IWindowViewModelMappingsContract 0%
Daqifi.Desktop.WindowViewModelMapping.WindowViewModelMappings 0%
Sentry.Generated.BuildPropertyInitializer 100%
Daqifi.Desktop.Common - 38.1%
Name Line Branch
Daqifi.Desktop.Common 38.1% 18.4%
Daqifi.Desktop.Common.AppDataPaths 81.2% 50%
Daqifi.Desktop.Common.Loggers.AppLogger 33.7% 16.6%
Daqifi.Desktop.Common.Loggers.NoOpLogger 0%
Daqifi.Desktop.IO - 100%
Name Line Branch
Daqifi.Desktop.IO 100% ****
Daqifi.Desktop.IO.Messages.MessageEventArgs`1 100%

Coverage report generated by ReportGeneratorView full report in build artifacts

@tylerkron
Copy link
Copy Markdown
Contributor Author

Responses to Qodo review

Thanks for the review. Addressed in eb41051:

1. Public test method lacks XML doc — ✅ Fixed. Added a <summary> to SdCardLogging_LogsToSdCard_NotStream.

4. Nested retry breaks timeout — ✅ Fixed. Good catch (I'd flagged the same in my own pass). Replaced the outer-30s-wrapping-inner-45s nesting with WaitForSdCardFileCountAbove(baseline, timeout): a single overall timeout where each attempt refreshes with a short bounded settle (10s, well under the outer budget), so one slow attempt can no longer exceed it. Shared refresh+parse logic is factored into ReadSdCardFileCountAfterRefresh.

5. Implicit XAML Behaviors dependency — ✅ Fixed. Added an explicit <PackageReference Include=\"Microsoft.Xaml.Behaviors.Wpf\" Version=\"1.1.19\" /> (the version MahApps.Metro 2.4.11 already resolves), so the new EventTrigger/InvokeCommandAction no longer depends on a transitive package surviving a clean restore.

2. Fixed Thread.Sleep run window — 🟡 Kept, by design. This isn't a readiness wait — it's a deliberate, fixed run duration. In SD-card mode the device logs to the card and the app receives no samples, and SD file operations are blocked while logging (EnsureSdOperationsQuiesced throws), so there is genuinely no in-app signal to poll mid-run. Correctness does not depend on the duration: the new file is asserted afterward via WaitForSdCardFileCountAbove, which polls under a bounded timeout — so the sleep is not a flakiness vector. This matches the harness README's explicit allowance for deliberate, documented sleeps (e.g. the frequency-slider Delay=500). The code comment documents the rationale.

3. Asserts inside the Act section (AAA) — 🟡 Kept, by design. This is a sequential integration scenario (start → run → stop), where some state is only observable at a specific moment: "LOGGING ON" must be asserted while logging is active (after stop it reads "LOGGING OFF"), and the "Enabled SD card logging" log line is checked right after start for failure localization. Hoisting these past the stop would be incorrect or lose locality. The primary outcome assertion (SD file count increased) is in the final Assert block. This mirrors the existing LoggingSessionTests pattern in the harness.

Verification: build clean; unit gate 274/274; the SD scenario was validated end-to-end on a real device with an SD card. The eb41051 count-wait change is a behavior-preserving refactor (same end state, same happy-path refresh count).

@tylerkron
Copy link
Copy Markdown
Contributor Author

Re-validated eb41051 on a real device with an SD card after the review fixes:

  • SdCardLoggingTests.SdCardLogging_LogsToSdCard_NotStream — ✅ green
  • Full TestCategory=RequiresDevice suite — ✅ 5/5 green (~3m34s)

So the count-wait refactor, the explicit Microsoft.Xaml.Behaviors.Wpf reference, and the XML-doc addition are all confirmed on hardware, and the shared Daqifi.Desktop change didn't regress the other scenarios.

@tylerkron tylerkron changed the title test(ui): integration coverage for SD card logging mode chore: integration coverage for SD card logging mode Jun 3, 2026
@tylerkron tylerkron merged commit 9f7da49 into main Jun 3, 2026
4 of 5 checks passed
@tylerkron tylerkron deleted the claude/sharp-herschel-49e0bb branch June 3, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(ui): integration coverage for SD card logging mode

2 participants