Skip to content

Fix reader and Go Live validation regressions#5

Merged
KSemenenko merged 5 commits intomainfrom
codex/fix-validation-regressions
Apr 2, 2026
Merged

Fix reader and Go Live validation regressions#5
KSemenenko merged 5 commits intomainfrom
codex/fix-validation-regressions

Conversation

@KSemenenko
Copy link
Copy Markdown
Member

Summary

  • stabilize Settings custom-select tests with shared bUnit and Playwright drivers
  • align Go Live shell, destination, live-indicator, and layout contracts with the current runtime
  • fix Learn sentence-boundary context handling, teleprompter stylesheet detection, and reader timing assertions

Verification

  • dotnet format ./PrompterOne.slnx
  • dotnet build ./PrompterOne.slnx -warnaserror
  • dotnet test ./PrompterOne.slnx
  • dotnet test ./PrompterOne.slnx --collect:"XPlat Code Coverage"

@KSemenenko KSemenenko marked this pull request as ready for review April 2, 2026 07:52
Copilot AI review requested due to automatic review settings April 2, 2026 07:52
@KSemenenko KSemenenko merged commit 6cd3eb8 into main Apr 2, 2026
3 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a cluster of regressions across the reader (Learn + Teleprompter) and Go Live flows, while stabilizing UI test interactions (notably Settings custom-select behavior) and aligning runtime contracts (stylesheets, navigation, destinations) with current behavior.

Changes:

  • Introduces a shared SettingsSelect component (plus Playwright/bUnit drivers) to stabilize Settings select interactions in tests.
  • Refactors Go Live destination modeling toward persisted ExternalDestinations, updates routing normalization, and adds live/idle indicator coverage.
  • Fixes reader-related regressions: Learn sentence-boundary context windows + RSVP layout contract, teleprompter stylesheet load timing, punctuation token attachment, and timing assertions.

Reviewed changes

Copilot reviewed 130 out of 130 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/TestData/Scripts/test-reader-timing.tps Adds a TPS fixture for reader timing probes with speed offsets.
tests/TestData/Scripts/test-learn-wpm-boundary.tps Adds a TPS fixture to probe Learn WPM boundary transitions.
tests/PrompterOne.Core.Tests/Workspace/LearnSettingsDefaultsTests.cs Verifies Learn settings default construction aligns with workspace defaults.
tests/PrompterOne.Core.Tests/Tps/TpsRoundTripTests.cs Adds coverage for attaching punctuation-only tokens to adjacent words.
tests/PrompterOne.Core.Tests/Streaming/GoLiveDestinationRoutingTests.cs Updates tests for ExternalDestinations-driven target normalization/routing.
tests/PrompterOne.App.UITests/Teleprompter/TeleprompterStylesheetFlowTests.cs Ensures teleprompter stylesheet is registered before entering teleprompter route.
tests/PrompterOne.App.UITests/Teleprompter/TeleprompterSettingsFlowTests.cs Uses shared select driver and updates default reader width seed.
tests/PrompterOne.App.UITests/Teleprompter/TeleprompterFullFlowTests.cs Updates rendering assertions for new card/word styling contracts.
tests/PrompterOne.App.UITests/Teleprompter/TeleprompterFidelityTests.cs Adds fidelity checks for emphasis grouping, width max, and punctuation tokenization.
tests/PrompterOne.App.UITests/Support/SettingsSelectDriver.cs Playwright helper for interacting with the custom Settings select.
tests/PrompterOne.App.UITests/Support/BrowserTestLibrarySeedData.cs Seeds additional scripts for UI tests (timing + Learn WPM boundary).
tests/PrompterOne.App.UITests/Support/BrowserTestConstants.ScreenFlows.cs Adds constants for reader timing probes and adjusts expected values.
tests/PrompterOne.App.UITests/Support/BrowserTestConstants.cs Expands routes/scripts/constants for new probes and Go Live destination modeling.
tests/PrompterOne.App.UITests/Settings/SettingsCloudStorageFlowTests.cs Migrates to custom select driver + value attribute assertion.
tests/PrompterOne.App.UITests/Scenarios/StudioWorkflowScenarioTests.cs Migrates camera resolution selection to custom select driver.
tests/PrompterOne.App.UITests/Media/synthetic-media-harness.js Adds label override support to simulate empty device labels in UI tests.
tests/PrompterOne.App.UITests/Media/MediaRuntimeIntegrationTests.cs Adds integration coverage for blank browser device labels.
tests/PrompterOne.App.UITests/Media/BrowserTestConstants.Media.cs Adds constants/scripts for label clearing and fabricated label assertions.
tests/PrompterOne.App.UITests/Learn/LearnWordLaneStabilityTests.cs Updates Learn stability measurement to ORP anchoring + visible context gaps.
tests/PrompterOne.App.UITests/Learn/LearnFidelityTests.cs Replaces “advance count” timing probe with duration-to-word measurement.
tests/PrompterOne.App.UITests/Learn/EditorLearnScreenFlowTests.cs Aligns expected speed text with centralized constants.
tests/PrompterOne.App.UITests/GoLive/GoLiveShellSessionFlowTests.cs Aligns navigation expectations with the new Go Live back behavior.
tests/PrompterOne.App.UITests/GoLive/GoLiveLiveIndicatorsFlowTests.cs Adds Playwright coverage for idle vs recording live indicators.
tests/PrompterOne.App.UITests/GoLive/GoLiveFlowTests.cs Updates Go Live flow assertions (operational toggles, back routing, provider surface).
tests/PrompterOne.App.UITests/Editor/EditorFloatingToolbarLayoutTests.cs Adds a helper to reliably navigate/wait for editor input before actions.
tests/PrompterOne.App.Tests/Teleprompter/TeleprompterFidelityTests.cs Adds bUnit fidelity checks: max width default, emphasis grouping, visible letter-spacing.
tests/PrompterOne.App.Tests/Support/TestSupport.cs Registers StreamingPublishDescriptorResolver for tests.
tests/PrompterOne.App.Tests/Support/BunitSettingsSelectDriver.cs bUnit helper for interacting with the custom Settings select.
tests/PrompterOne.App.Tests/Support/AppTestLibrarySeedData.cs Seeds additional documents for app tests (timing + Learn WPM boundary).
tests/PrompterOne.App.Tests/Support/AppTestData.cs Adds routes and builders for streaming destinations in app tests.
tests/PrompterOne.App.Tests/Settings/SettingsInteractionTests.cs Migrates Settings tests to use custom select interactions; adds external destination rendering test.
tests/PrompterOne.App.Tests/Reader/ReaderStylesheetContractTests.cs Updates stylesheet ownership expectations (teleprompter host-loaded).
tests/PrompterOne.App.Tests/Reader/ReaderStartupStateTests.cs Tightens startup assertions to avoid placeholder text reliance.
tests/PrompterOne.App.Tests/GoLive/GoLiveSessionInteractionTests.cs Moves tests to ExternalDestinations and covers relay-only “not live” session behavior.
tests/PrompterOne.App.Tests/GoLive/GoLiveLiveIndicatorsTests.cs Adds bUnit coverage for idle vs recording indicator state.
tests/PrompterOne.App.Tests/GoLive/GoLiveCameraPreviewTests.cs Updates empty-scene primary chip fallback label behavior.
tests/PrompterOne.App.Tests/AppShell/ScreenShellContractTests.cs Updates shell contract expectations for teleprompter + Go Live provider cards.
tests/PrompterOne.App.Tests/AppShell/AppBootstrapperMediaSceneTests.cs Verifies bootstrapper sanitizes persisted media scene labels.
tests/PrompterOne.App.Tests/AppShell/AppBootstrapperLearnSettingsTests.cs Verifies bootstrapper migrates legacy Learn WPM defaults correctly.
src/PrompterOne.Shared/wwwroot/media/browser-media.js Removes fabricated fallback device names; normalizes device DTOs toward empty labels.
src/PrompterOne.Shared/wwwroot/learn/learn-rsvp-layout.js Moves layout contract strings out of JS and into C# parameters; updates extent-based layout.
src/PrompterOne.Shared/wwwroot/design/modules/settings/20-reference.css Adjusts preview opacity styling for Settings panels.
src/PrompterOne.Shared/wwwroot/design/modules/reader/00-shell.css Updates reader visuals (gradient, max width, color tuning, letter-spacing ranges).
src/PrompterOne.Shared/wwwroot/design/modules/30-rsvp.css Refactors RSVP row layout to grid + extent-based context spacing.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderWordStyling.cs Updates letter-spacing constants for visible speed styling.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderRendering.cs Adds gradient class builder and group-level emphasis styling.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderPlayback.cs Aligns activation/alignment sequencing to avoid visible “settling” drift.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderModels.cs Updates chunk models to carry emphasis at group level.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderContent.cs Implements continuous emphasis groups and adjusts emotion class fallback behavior.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.ReaderAlignment.cs Adds deferred transition restoration for instant alignment operations.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.razor.cs Defaults reader width to max; removes placeholder “empty card” behavior; manages gradient transition enablement.
src/PrompterOne.Shared/Teleprompter/Pages/TeleprompterPage.razor Removes route-time teleprompter stylesheet injection; uses gradient class builder.
src/PrompterOne.Shared/Settings/Models/SettingsStreamingText.cs Adds centralized labels/messages for streaming settings UI.
src/PrompterOne.Shared/Settings/Models/SettingsStreamingLocalTargetCatalog.cs Defines local output targets for streaming settings cards.
src/PrompterOne.Shared/Settings/Models/SettingsStreamingCardIds.cs Adds stable IDs for streaming cards (local + external).
src/PrompterOne.Shared/Settings/Models/SettingsNavigationText.cs Centralizes Settings navigation labels.
src/PrompterOne.Shared/Settings/Components/SettingsStreamingSourcePicker.razor Sanitizes camera source labels when displayed in Settings routing pickers.
src/PrompterOne.Shared/Settings/Components/SettingsStreamingPanel.razor.cs Implements settings-side streaming panel logic around local targets + external destinations.
src/PrompterOne.Shared/Settings/Components/SettingsSelectOption.cs Adds an option model for the custom Settings select component.
src/PrompterOne.Shared/Settings/Components/SettingsSelect.razor.css Adds styling for the custom Settings select component.
src/PrompterOne.Shared/Settings/Components/SettingsSelect.razor Implements a custom select UI used across Settings panels.
src/PrompterOne.Shared/Settings/Components/SettingsRecordingSection.razor Migrates multiple <select> elements to SettingsSelect.
src/PrompterOne.Shared/Settings/Components/SettingsMicrophoneLevelCard.razor Sanitizes microphone label display.
src/PrompterOne.Shared/Settings/Components/SettingsFilesSection.razor Migrates <select> elements to SettingsSelect and centralizes section title text.
src/PrompterOne.Shared/Settings/Components/SettingsCloudSection.razor.cs Builds options lists for custom selects; adds change handlers for CloudKit fields.
src/PrompterOne.Shared/Settings/Components/SettingsCloudSection.razor Migrates cloud provider/environment/database selects to SettingsSelect.
src/PrompterOne.Shared/Settings/Components/SettingsCameraPreviewCard.razor Sanitizes camera label display.
src/PrompterOne.Shared/Settings/Components/SettingsAppearanceSection.razor Migrates teleprompter font select to SettingsSelect.
src/PrompterOne.Shared/Settings/Components/SettingsAiSection.razor Migrates AI model selects to SettingsSelect and centralizes section title text.
src/PrompterOne.Shared/Services/StreamingPublishDescriptorResolver.cs Adds resolver to map streaming profiles to provider descriptors.
src/PrompterOne.Shared/Services/StreamingPlatformPresentationCatalog.cs Adds presentation metadata for streaming platforms (labels/tone/icons).
src/PrompterOne.Shared/Media/Services/MediaDeviceLabelSanitizer.cs Adds reusable sanitizer for vendor/product suffixes in device labels.
src/PrompterOne.Shared/Media/Services/BrowserMediaDeviceService.cs Uses sanitization and removes fabricated “Unnamed device” fallback labels.
src/PrompterOne.Shared/Media/Components/CameraPreviewTile.razor Sanitizes camera labels in preview tiles.
src/PrompterOne.Shared/Learn/Services/LearnRsvpLayoutInterop.cs Passes explicit contract strings and focus refs into RSVP layout JS.
src/PrompterOne.Shared/Learn/Services/LearnRsvpLayoutContract.cs Centralizes RSVP layout JS contract string constants.
src/PrompterOne.Shared/Learn/Pages/LearnPage.razor.cs Aligns defaults to LearnSettingsDefaults, fixes context window logic, and uses new layout interop signature.
src/PrompterOne.Shared/Learn/Pages/LearnPage.razor Adds refs needed for layout interop and wraps context lanes for new layout CSS.
src/PrompterOne.Shared/Learn/Pages/LearnPage.Playback.cs Persists HasCustomizedWordsPerMinute on speed changes; refactors delay computation.
src/PrompterOne.Shared/Learn/Pages/LearnPage.DisplayState.cs Switches sentence range resolution to precomputed indices + bounded context windows.
src/PrompterOne.Shared/GoLive/Services/GoLiveOutputRequestFactory.cs Resolves LiveKit destination from external destinations (with legacy migration).
src/PrompterOne.Shared/GoLive/Pages/GoLivePage.Runtime.cs Uses session title for recording stem and removes unused constant set.
src/PrompterOne.Shared/GoLive/Pages/GoLivePage.razor.cs Refactors text/constants toward GoLiveText, adds back routing via shell tracking.
src/PrompterOne.Shared/GoLive/Pages/GoLivePage.razor Implements back routing + screen title test id; updates sources/preview to include live state.
src/PrompterOne.Shared/GoLive/Pages/GoLivePage.Descriptors.cs Uses GoLiveText for route target labels.
src/PrompterOne.Shared/GoLive/Pages/GoLivePage.Bootstrap.cs Updates diagnostics messages/ops to GoLiveText; simplifies shell metadata.
src/PrompterOne.Shared/GoLive/Models/GoLiveText.cs Centralizes Go Live UI copy and operational strings.
src/PrompterOne.Shared/GoLive/Components/GoLiveStudioSidebar.razor.css Adds dot styling for new tones (twitch/relay).
src/PrompterOne.Shared/GoLive/Components/GoLiveSourcesCard.razor.css Improves rail flex/overflow behavior.
src/PrompterOne.Shared/GoLive/Components/GoLiveSourcesCard.razor Sanitizes labels and adds explicit badge/live-state contract for sources.
src/PrompterOne.Shared/GoLive/Components/GoLiveProgramFeedCard.razor.css Adjusts layout to fixed aspect ratio for program monitor/feed.
src/PrompterOne.Shared/GoLive/Components/GoLiveDestinationSourcePicker.razor Sanitizes labels in Go Live destination source picker.
src/PrompterOne.Shared/GoLive/Components/GoLiveCameraPreviewCard.razor.css Refines preview live dot styling and transitions.
src/PrompterOne.Shared/GoLive/Components/GoLiveCameraPreviewCard.razor Adds live-state contract/test ids and sanitizes preview camera label.
src/PrompterOne.Shared/Contracts/UiTestIds.cs Adds IDs for new Settings select options and Go Live back/live indicator elements.
src/PrompterOne.Shared/AppShell/Services/PrompterOneServiceCollectionExtensions.cs Registers StreamingPublishDescriptorResolver in DI.
src/PrompterOne.Shared/AppShell/Services/GoLiveSessionState.cs Extracts Start/Stop APIs and reimplements toggles via them.
src/PrompterOne.Shared/AppShell/Services/AppShellService.cs Tracks navigation to support “Back” behavior from Go Live to prior screen.
src/PrompterOne.Shared/AppShell/Services/AppBootstrapper.cs Normalizes legacy Learn settings and sanitizes persisted media scene labels.
src/PrompterOne.Shared/AppShell/Layout/MainLayout.razor.cs Tracks navigation via shell service; updates Go Live shell metadata sync.
src/PrompterOne.Core/Workspace/Models/StudioSettings.cs Adds ExternalDestinations to streaming settings.
src/PrompterOne.Core/Workspace/Models/ReaderSettingsDefaults.cs Defaults reader text width to full width.
src/PrompterOne.Core/Workspace/Models/LearnSettingsDefaults.cs Introduces centralized Learn defaults (including legacy default).
src/PrompterOne.Core/Workspace/Models/LearnSettings.cs Adds HasCustomizedWordsPerMinute and uses defaults catalog.
src/PrompterOne.Core/Workspace/Models/GoLiveTargetCatalog.cs Splits local target IDs/definitions from external destinations.
src/PrompterOne.Core/Tps/Services/TpsTokenTextRules.cs Adds rules for detecting/attaching punctuation-only tokens.
src/PrompterOne.Core/Tps/Services/ScriptCompiler.cs Attaches standalone punctuation tokens to adjacent words during compilation.
src/PrompterOne.Core/Streaming/Services/GoLiveDestinationRouting.cs Normalizes routing based on local targets + persisted external destination IDs.
src/PrompterOne.Core/Streaming/Models/StreamingProfile.cs Expands platform modeling (platform kind, catalog, destination helpers).
src/PrompterOne.Core/Streaming/Models/StreamingDestinationFieldIds.cs Centralizes field IDs for external destination editing.
src/PrompterOne.App/wwwroot/index.html Loads teleprompter stylesheet from host document head (first-paint contract).
docs/Features/ReaderRuntime.md Documents updated reader contracts (stylesheet timing, explicit word emotion styling, punctuation handling).
docs/Features/GoLiveRuntime.md Documents updated Go Live contracts (idle/live indicators, external destinations).
docs/Architecture.md Documents shell route tracking for Go Live back navigation.
design/rsvp.html Updates design reference default WPM to 250.
design/app.js Updates design reference default Learn WPM to 250.
AGENTS.md Updates repo rules around JS contracts, fallback device labels, reader timing, and Go Live navigation/indicators.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

previousWord.CleanText += TpsTokenTextRules.BuildStandalonePunctuationSuffix(punctuationToken);
previousWord.CharacterCount = previousWord.CleanText.Length;
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

AttachStandalonePunctuation mutates the previous word’s CleanText/CharacterCount but leaves ORPPosition and DisplayDuration computed from the pre-attachment text. This can skew ORP alignment and timing (e.g., short words like "No" becoming "No!" should cross ORP thresholds and may need duration recompute). Consider recomputing ORPPosition/DisplayDuration after appending punctuation, or folding standalone punctuation into the word before initial CompiledWord creation so all derived fields stay consistent.

Suggested change
previousWord.CharacterCount = previousWord.CleanText.Length;
previousWord.CharacterCount = previousWord.CleanText.Length;
// Recalculate ORP position and display duration now that the word text has changed.
var metadata = previousWord.Metadata;
var effectiveWpm = metadata?.SpeedOverride
?? ClampWpm((int)Math.Round(DefaultWpm * (metadata?.SpeedMultiplier ?? 1f)));
previousWord.ORPPosition = CalculateORP(previousWord.CleanText);
previousWord.DisplayDuration = CalculateDisplayDuration(previousWord.CleanText, effectiveWpm);

Copilot uses AI. Check for mistakes.

- the routed `Go Live` page owns its own studio chrome and suppresses the shared app header while the route is active, so `design/golive.html` remains the only topbar on that screen
- top session bar follows `design/golive.html`: back to Read, script title + session badge, centered session timer, panel toggles, mode switch, settings shortcut, REC, and the main stream action on the far right
- top session bar follows `design/golive.html`: back to Library, script title + session badge, centered session timer, panel toggles, mode switch, settings shortcut, REC, and the main stream action on the far right
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This section says the Go Live top bar goes “back to Library”, but the implementation now tracks the previous in-app route and returns there when valid (falling back to Library only when unknown). Updating this description would keep the doc aligned with the runtime navigation contract.

Suggested change
- top session bar follows `design/golive.html`: back to Library, script title + session badge, centered session timer, panel toggles, mode switch, settings shortcut, REC, and the main stream action on the far right
- top session bar follows `design/golive.html`: back to the previous in-app location when known (falling back to Library when unknown), script title + session badge, centered session timer, panel toggles, mode switch, settings shortcut, REC, and the main stream action on the far right

Copilot uses AI. Check for mistakes.
@KSemenenko KSemenenko deleted the codex/fix-validation-regressions branch April 2, 2026 08:07
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.

2 participants