Testing and troubleshooting
Build and package
The build also launches the ASP.NET sample from its project directory with ASPNETCORE_ENVIRONMENT=Development, matching Visual Studio's startup environment. To repeat that regression check independently, run dotnet build samples/CODE.Editor.Sample.AspNetCore -c Debug, then ./build/test-aspnet.ps1. A physical project-local wwwroot is unnecessary: the shared distribution is copied into the output/published wwwroot, and the sample uses its explicit file provider. Rebuilding removes obsolete SDK runtime asset manifests from earlier sample builds.
From the repository root:
./build/build.ps1
This generates assets, validates documentation/paths, runs Node tests, builds CODE.Editor.sln in Release, creates the NuGet package, restores a separate package-only consumer into an isolated cache, builds/runs that consumer, and runs browser fixtures/sample initialization in WebView2. The local package cache is refreshed before each consumer restore so a rebuilt preview package cannot silently reuse an older DLL. Nothing is published. Use -SkipNative when native execution is unavailable; that skips native/browser execution explicitly, while still building the package consumer.
Requirements: Node.js, stable .NET 10 SDK and access to nuget.org for WebView2. Native execution also requires Windows Desktop runtime and WebView2. No JavaScript dependencies or bundler installation are required. The optional artifacts/dotnet SDK takes precedence over PATH. Direct repository project builds need generated assets first.
Individual commands:
node build/assets.cjs
node build/validate.cjs
node --test tests/web/*.test.cjs
dotnet build CODE.Editor.sln -c Release -m:1
dotnet pack src/CODE.Editor.WinForms/CODE.Editor.WinForms.csproj -c Release --no-build -o artifacts/packages
node build/serve.cjs
Browser fixtures are at http://127.0.0.1:8091/tests/web/browser-checks.html, feature-browser-checks.html and interaction-browser-checks.html in the same folder. The build runs these pages in a local WebView2 harness, exercising DOM selection, iframe layout and pointer/keyboard dispatch. These are synthetic fixtures, not real IME/device acceptance.
The package consumer has a PackageReference and no library ProjectReference. Its NuGet.Config maps CODE.Editor.WinForms exclusively to artifacts/packages. All referenced HTML/JS/CSS resources are read from the packaged assembly, then its editor initializes and runs bridge regression checks. Browser fixtures run separately from this isolated consumer check.
Verified migration results
The native focus regression can be run with ./build/build.ps1 -FocusChecks. It uses visible test windows and briefly switches activation, so run it when it will not interrupt other typing. Its assertions cover WinForms Tab/Shift+Tab routing, native/DOM focus, selected-text replacement after window reactivation, internal search, sibling native controls, and backward Visual selections. This automates the activation transitions; real Alt+Tab keyboard testing remains useful on target Windows/WebView2 versions.
- Before migration: 100/100 existing Node checks passed.
- After migration: 108 Node checks, focused on original behavior, confirmed defects, manifest initialization and generated asset references.
- Release solution, library and WinForms/ASP.NET Core samples: builds succeeded with zero warnings/errors.
- Package-only native consumer: 28 assertions covering editor initialization, every shell resource, Unicode/CRLF, explicit source formatting, optional/stale revisions, empty clipboard and JavaScript wire round trip verified. Exact assertions are recorded in artifacts/verification/package-consumer.json.
- WebView2 browser suites: 15/15 input/selection, 8/8 structured editing and 14/14 interaction/preview checks passed.
- Source demo, generated distribution and one-file demo: each initialized in WebView2.
- Published ASP.NET sample: shared index and runtime asset returned successfully over HTTP.
Logs and JSON results are under artifacts/verification. Historical counts in docs/history and tests/fixtures describe earlier deliveries and are not current acceptance evidence. The automated legacy input fixtures were repaired to address text children inside decoration spans rather than assigning data to an element.
Outputs and deployment
- artifacts/browser: flat shared runtime, sample page and CODE.Editor.Demo.html.
- artifacts/packages/CODE.Editor.WinForms.0.4.0-preview.2.nupkg: self-contained editor assembly plus WebView2 dependency metadata.
- artifacts/backup: pre-migration source ZIP, SHA256 inventory and copy comparisons.
- artifacts/verification: build logs and actual test results.
ASP.NET Core consumes the generated browser distribution and includes it in published wwwroot. Photino consumes the same distribution in an existing host; no runnable Photino application is claimed. Consumers of the WinForms NuGet package need no repository, Node.js, loose editor files or editor-asset download. License approval/publication metadata remain an owner release decision; no license is invented.
Acceptance scenarios still needed
- Real IME composition: CJK input, accents/dead keys, mobile prediction, undo after composition, switching focus mid-composition.
- Accessibility: screen-reader reading order and editing; headings/lists/tables; high contrast; focus escape; divider labels.
- Mobile: iOS Safari and Android Chrome with real on-screen keyboards, touch selection, scrolling and viewport changes.
- Cross-application clipboard: Word, Outlook, browsers and spreadsheet tables; mixed HTML/text/image items; real paste/drop gestures.
- Photino: actual bridge callbacks, lifecycle, image transport, native web engines and platform differences.
- Document corpus: real Olympus notes, long SQL lines, nested lists, table escaping, unsupported HTML, malformed Markdown, mixed line endings and Unicode boundaries.
- Deployment: clean Windows machine, package-only consumer, chosen architecture/runtime, writable profile/assets, offline startup and controlled failure recovery.
Troubleshooting
| Symptom | Likely cause / action |
|---|---|
| Blank or noneditable browser area | Check the asset manifest order, load the public editor.js last, verify element dimensions and browser console |
| Surface exists but no preview | Provide iframe, call setPreviewVisible(true), and size sibling panes correctly |
| Images not visible though URL is saved | Check image origins/CSP and whether the URL is reachable in this host |
| Paste/drop image reports missing handler | Supply onImageImport or ImageImportRequested Result task |
| Save blocked by images | Inspect pending/failed items; retry or remove before snapshot |
| Save blocked after Preserve import | Preserve retains unsupported source but diagnostics still prevent validated save |
| “Finish composition” error | Wait for native text composition to commit; do not force a view/load during it |
| EditorText differs from very recent editing | It is a synchronous cache; await committed retrieval/snapshot and handle unresolved content |
| Setting a property did not take effect | Await queue/error handling; invalid browser-side configuration can leave desired and accepted state different |
| Source SQL/JS edits are being parsed as Markdown | Choose PlainText storage as well as source language |
| Native JavaScript comment toggle is a no-op | Verify PlainText storage, JavaScript language and Source mode; the native wire mapping is javascript |
| ReplaceRangeAsync rejects even without edits | An omitted revision is unguarded; explicit stale guards reject. Capture a fresh snapshot for delayed edits |
| Preview hook changes are missing | Assign async Result synchronously, or return a Promise in JS; call RefreshPreview when only external data/hook changed |
| Old async preview appears to finish late | Obsolete results are ignored; ensure host cancellation is honored to avoid wasted work |
| Preview CSS cannot load a font/stylesheet | CSP intentionally blocks arbitrary remote resources; use stylesheet text and available fonts |
| Custom preview does not align line-for-line | Changed/custom output has proportional following, not a source map |
| Font selection changes the wrong thing | Distinguish DisplayFontFamily from SetContentFontAsync |
| Ctrl+F does nothing in custom web host | Bare component emits shortcut; host must provide find UI |
| Ctrl+G has no native popup | Implement host dialog and call GoToLineAsync |
| Search Replace All unavailable in Visual | Current implementation is Source-only |
| Selection/bookmark fails after load | Loads invalidate history/bookmarks; obtain new state |
| WebView2 initialization fails | Verify runtime/dependencies/profile directory and capture EditorError |
| WindowsBase reference-conflict build warning in a WinForms-only consumer | WebView2's transitive package also adds its WPF assembly; use the targeted unused-WPF-reference removal shown in the WinForms quick start |
| Unexpected native browser failure | Save/recover from application state and recreate control; automatic crash recovery is not implemented |
Reporting a reproducible problem
Capture the package/source revision, host/browser/runtime, format/view/language, effective policy, minimal input string, exact keystrokes/commands, and expected versus actual result. Include revision/session and diagnostics where relevant. Remove private document contents from shared logs.
Use the smallest fixture that exercises the real boundary. A pure model problem belongs in Node tests; selection/IME/scroll bugs need browser interaction; .NET queue/enum/event bugs need bridge/native coverage. Do not replace real input acceptance with tests that merely restate a helper's implementation.
Documentation checks
The manual is split into a main index and 18 topic files. The build validates local Markdown links and source HTML asset references; executable behavior is verified by the Node, browser and native suites. Documentation/path validation does not count as runtime acceptance.