Conversation
- Created `index.template.html` for the main testing interface, including category selection and suite display. - Added `run-all.template.html` for running all test suites with worker management and result reporting. - Introduced `run-suite.template.html` for individual suite execution with QUnit integration and CSP support.
There was a problem hiding this comment.
Pull request overview
This PR removes the .NET (ASP.NET Core) dependency from the DevExtreme QUnit browser runner and replaces it with a functionally equivalent Node.js implementation. The legacy runner required a .NET 8 toolchain solely for QUnit test execution, making CI/setup unnecessarily complex.
Changes:
- Replaces the ASP.NET Core runner (C# controllers, models, Razor views,
runner.csproj,build-dotnet.sln) with a new Node.js runner (index.js+ modularlib/files), preserving all existing HTTP routes and behavior. - Migrates inline Razor HTML to standalone
.template.htmlfiles with a custom{{{raw}}}/{{escaped}}template engine and adds safe HTML escaping. - Updates CI workflows, scripts, and
package.jsonto remove all.NETbuild steps.
Reviewed changes
Copilot reviewed 44 out of 44 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
packages/devextreme/testing/runner/index.js |
New Node.js server replacing the entire .NET runner |
packages/devextreme/testing/runner/lib/vectormap.js |
Vector map service (spawning helper server, console app) |
packages/devextreme/testing/runner/lib/utils.js |
Shared utilities (parsing, escaping, file I/O) |
packages/devextreme/testing/runner/lib/templates.js |
Template renderer with escaping support |
packages/devextreme/testing/runner/lib/suites.js |
Test suite/category discovery |
packages/devextreme/testing/runner/lib/static.js |
Static file serving with directory listings |
packages/devextreme/testing/runner/lib/results.js |
XML results generation and text reporting |
packages/devextreme/testing/runner/lib/pages.js |
Page renderers (index, run-all, run-suite) |
packages/devextreme/testing/runner/lib/logger.js |
Colored console + file logger |
packages/devextreme/testing/runner/lib/http.js |
HTTP response helpers |
packages/devextreme/testing/runner/templates/*.template.html |
HTML templates for runner UI pages |
.github/actions/run-qunit-tests/action.yml |
Removed dotnet build CI step |
.github/workflows/qunit_tests.yml |
Removed DOTNET env variables |
packages/devextreme/package.json |
Removed dotnet build from dev script |
packages/devextreme/project.json |
Removed DOTNET_* env pass-throughs |
packages/devextreme/docker-ci.sh |
Updated runner startup command |
packages/devextreme/testing/launch |
Updated to launch Node.js runner |
| All deleted C# files | Legacy .NET runner source removed |
packages/devextreme/testing/runner/templates/run-suite.template.html
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| export function isContinuousIntegration(): boolean { | ||
| return Boolean(process.env.CCNetWorkingDirectory ?? process.env.DEVEXTREME_TEST_CI); |
There was a problem hiding this comment.
The isContinuousIntegration function uses the nullish coalescing operator ?? to check the two environment variables: Boolean(process.env.CCNetWorkingDirectory ?? process.env.DEVEXTREME_TEST_CI). The ?? operator only falls through to the right-hand side when the left side is null or undefined. If CCNetWorkingDirectory is set but empty (""), "" ?? process.env.DEVEXTREME_TEST_CI evaluates to "", and Boolean("") is false — so CI mode would not be detected even if DEVEXTREME_TEST_CI is also set.
The old C# implementation used an explicit OR: !IsNullOrEmpty(CCNetWorkingDirectory) || !IsNullOrEmpty(DEVEXTREME_TEST_CI), which correctly falls through to check DEVEXTREME_TEST_CI whenever CCNetWorkingDirectory is null, undefined, or empty.
The fix is to use the logical OR || operator instead: Boolean(process.env.CCNetWorkingDirectory || process.env.DEVEXTREME_TEST_CI).
| function executeVectorMapConsoleApp( | ||
| arg: string, | ||
| searchParams: URLSearchParams, | ||
| ): VectorMapOutputItem[] { | ||
| const inputDirectory = `${path.join(packageRoot, 'testing', 'content', 'VectorMapData')}${path.sep}`; | ||
| const outputDirectory = path.join(inputDirectory, '__Output'); | ||
| const settingsPath = path.join(inputDirectory, '_settings.js'); | ||
| const processFileContentPath = path.join(inputDirectory, '_processFileContent.js'); | ||
| const vectorMapUtilsNodePath = path.resolve(path.join(packageRoot, 'artifacts/js/vectormap-utils/dx.vectormaputils.node.js')); | ||
|
|
||
| const args = [vectorMapUtilsNodePath, inputDirectory]; | ||
| const fileArgument = searchParams.get('file'); | ||
| if (fileArgument !== null) { | ||
| args[1] += fileArgument; | ||
| } | ||
|
|
There was a problem hiding this comment.
The executeVectorMapConsoleApp function in vectormap.ts accepts an arg: string parameter (from the URL path) but never uses it in the function body. The function only uses searchParams and packageRoot to construct paths. While this matches the old C# controller behavior (the arg route parameter was also unused there), having an unused parameter in the function signature is misleading and may create confusion.
|
@copilot open a new pull request to apply changes based on the comments in this thread |
|
@nightskylark I've opened a new pull request, #32809, to work on those changes. Once the pull request is ready, I'll request review from you. |
…32809) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nightskylark <2280467+nightskylark@users.noreply.github.com>
Summary
This PR removes the
.NETdependency from the DevExtreme QUnit browser runner by replacing the legacy ASP.NET Core runner with a Node.js implementation, while preserving the existing runner behavior and endpoint contract.Motivation
The previous runner required a
.NETtoolchain only for QUnit execution. This increased CI/setup complexity and made long-term maintenance harder.The new implementation keeps the same workflow but runs fully on Node.js.
What was changed
1. Replaced legacy
.NETQUnit runner with Node.jspackages/devextreme/testing/runner/index.js./run,/main/runall,/main/runsuite),Results.xml, misc/raw logs),2. Removed
.NETartifacts and configurationpackages/devextreme/testing/runner/**/*.cspackages/devextreme/testing/runner/runner.csprojpackages/devextreme/build/build-dotnet.slnpackages/devextreme/testing/runner/.vscode/*3. Updated scripts and CI to be Node-only
packages/devextreme/testing/launch: now startsnode testing/runner/index.js.packages/devextreme/docker-ci.sh: runner startup switched fromrunner.dllto Node runner.packages/devextreme/package.json: removeddotnet buildfromdevscript..github/actions/run-qunit-tests/action.yml: removed.NETbuild step..github/workflows/qunit_tests.ymlandpackages/devextreme/project.json: removedDOTNET_*env usage.4. Security and robustness improvements
packages/devextreme/testing/runner/templates/*.template.htmlgetJSONwith query params object for suite loading.DX_HTTP_CACHE) by URL-encoding values.5. CI fixes after migration
HEADhandling for run endpoints used by readiness checks.@preact/signals-core.;/ assignment parsing).6. Maintainability refactor
packages/devextreme/testing/runner/lib/:http,logger,pages,results,static,suites,templates,utils,vectormap.index.jsfrom ~1550 lines to an orchestration layer (~446 lines).Compatibility notes