diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 6acc029e186a13..9af74955c577b2 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -965,6 +965,8 @@ extends: extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) scenarios: - WasmTestOnChrome + - WasmTestOnFirefox + - WasmTestOnV8 # EAT Library tests - only run on linux - template: /eng/pipelines/common/templates/wasm-library-aot-tests.yml diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs index 57a037b0d45ba1..62313837dfdbb9 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs @@ -297,7 +297,7 @@ public void Properties_SetOptionsAndGetTheirValue_NotSet_EnableStreamingResponse Assert.False(streamingEnabledValue); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupportedOrNodeJS))] // not V8 shell public async Task HttpStreamingDisabledBy_WasmEnableStreamingResponse_InProject() { using var client = new HttpClient(); @@ -309,7 +309,7 @@ public async Task HttpStreamingDisabledBy_WasmEnableStreamingResponse_InProject( Assert.True(stream.CanSeek); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupportedOrNodeJS))] // not V8 shell public async Task HttpStreamingEnabledBy_WebAssemblyEnableStreamingResponse_Option() { using var client = new HttpClient(); diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportTest.cs index 2a8cbc1b8fe006..8e5e51f66ba9e9 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportTest.cs @@ -20,7 +20,7 @@ public unsafe void StructSize() Assert.Equal(32, sizeof(JSMarshalerArgument)); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupportedOrNodeJS))] // not V8 shell public unsafe void PrototypeNotEqual() { using var temp1 = JSHost.GlobalThis.GetPropertyAsJSObject("EventTarget"); diff --git a/src/libraries/sendtohelix-browser.targets b/src/libraries/sendtohelix-browser.targets index 2107f66ed254c7..0729da3fb808d7 100644 --- a/src/libraries/sendtohelix-browser.targets +++ b/src/libraries/sendtohelix-browser.targets @@ -60,7 +60,7 @@ false true true - true + true true true diff --git a/src/mono/browser/runtime/http.ts b/src/mono/browser/runtime/http.ts index 149c3c05a473f6..321bbba4c2e3a1 100644 --- a/src/mono/browser/runtime/http.ts +++ b/src/mono/browser/runtime/http.ts @@ -15,8 +15,8 @@ import { mono_log_debug } from "./logging"; function verifyEnvironment () { if (typeof globalThis.fetch !== "function" || typeof globalThis.AbortController !== "function") { const message = ENVIRONMENT_IS_NODE - ? "Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support. See also https://aka.ms/dotnet-wasm-features" - : "This browser doesn't support fetch API. Please use a modern browser. See also https://aka.ms/dotnet-wasm-features"; + ? "Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support." + : "This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"; throw new Error(message); } } diff --git a/src/mono/browser/runtime/loader/polyfills.ts b/src/mono/browser/runtime/loader/polyfills.ts index bfa4a8c99b2ea3..6f999bc42ef298 100644 --- a/src/mono/browser/runtime/loader/polyfills.ts +++ b/src/mono/browser/runtime/loader/polyfills.ts @@ -19,8 +19,8 @@ const URLPolyfill = class URL { }; export function verifyEnvironment () { - mono_assert(ENVIRONMENT_IS_SHELL || typeof globalThis.URL === "function", "This browser/engine doesn't support URL API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - mono_assert(typeof globalThis.BigInt64Array === "function", "This browser/engine doesn't support BigInt64Array API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + mono_assert(ENVIRONMENT_IS_SHELL || typeof globalThis.URL === "function", "This browser/engine doesn't support URL API. Please use a modern version."); + mono_assert(typeof globalThis.BigInt64Array === "function", "This browser/engine doesn't support BigInt64Array API. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); mono_assert(globalThis.performance && typeof globalThis.performance.now === "function", "This browser/engine doesn't support performance.now. Please use a modern version."); mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.subtle === "object", "This engine doesn't support crypto.subtle. Please use a modern version."); mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.getRandomValues === "function", "This engine doesn't support crypto.getRandomValues. Please use a modern version."); @@ -28,9 +28,9 @@ export function verifyEnvironment () { mono_assert(typeof process.exit === "function", "This engine doesn't support process.exit. Please use a modern version."); } if (WasmEnableThreads) { - mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS. See also https://aka.ms/dotnet-wasm-features"); - mono_assert(globalThis.SharedArrayBuffer !== undefined, "SharedArrayBuffer is not enabled on this page. Please use a modern browser and set Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy http headers. See also https://aka.ms/dotnet-wasm-features"); - mono_assert(typeof globalThis.EventTarget === "function", "This browser/engine doesn't support EventTarget API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS."); + mono_assert(globalThis.SharedArrayBuffer !== undefined, "SharedArrayBuffer is not enabled on this page. Please use a modern browser and set Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy http headers."); + mono_assert(typeof globalThis.EventTarget === "function", "This browser/engine doesn't support EventTarget API. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); } } @@ -41,7 +41,7 @@ export async function detect_features_and_polyfill (module: DotnetModuleInternal const process = await import(/*! webpackIgnore: true */"process"); const minNodeVersion = 14; if (process.versions.node.split(".")[0] < minNodeVersion) { - throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}', please use at least ${minNodeVersion}. See also https://aka.ms/dotnet-wasm-features`); + throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}', please use at least ${minNodeVersion}.`); } } diff --git a/src/mono/browser/runtime/loader/run.ts b/src/mono/browser/runtime/loader/run.ts index ccdaf60f668ad1..c6bfeab4c26d01 100644 --- a/src/mono/browser/runtime/loader/run.ts +++ b/src/mono/browser/runtime/loader/run.ts @@ -395,7 +395,7 @@ async function initializeModules (es6Modules: [RuntimeModuleExportsInternal, Nat }); result.catch((error) => { if (error.message && error.message.toLowerCase().includes("out of memory")) { - throw new Error(".NET runtime has failed to start, because too much memory was requested. Please decrease the memory by adjusting EmccMaximumHeapSize. See also https://aka.ms/dotnet-wasm-features"); + throw new Error(".NET runtime has failed to start, because too much memory was requested. Please decrease the memory by adjusting EmccMaximumHeapSize."); } throw error; }); diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts index 7b2a3e20d3b5d6..a3210d5ac94239 100644 --- a/src/mono/browser/runtime/startup.ts +++ b/src/mono/browser/runtime/startup.ts @@ -80,10 +80,10 @@ export function configureEmscriptenStartup (module: DotnetModuleInternal): void mono_log_warn(`The threads of dotnet.native.js ${runtimeHelpers.emscriptenBuildOptions.wasmEnableThreads} is different from the version of dotnet.runtime.js ${WasmEnableThreads}!`); } if (runtimeHelpers.emscriptenBuildOptions.wasmEnableSIMD) { - mono_assert(runtimeHelpers.featureWasmSimd, "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + mono_assert(runtimeHelpers.featureWasmSimd, "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); } if (runtimeHelpers.emscriptenBuildOptions.wasmEnableEH) { - mono_assert(runtimeHelpers.featureWasmEh, "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + mono_assert(runtimeHelpers.featureWasmEh, "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); } module.mainScriptUrlOrBlob = loaderHelpers.scriptUrl;// this is needed by worker threads diff --git a/src/mono/browser/runtime/web-socket.ts b/src/mono/browser/runtime/web-socket.ts index f15bd0668f2135..a56e05ce6fb223 100644 --- a/src/mono/browser/runtime/web-socket.ts +++ b/src/mono/browser/runtime/web-socket.ts @@ -38,8 +38,8 @@ function verifyEnvironment () { } if (typeof globalThis.WebSocket !== "function") { const message = ENVIRONMENT_IS_NODE - ? "Please install `ws` npm package to enable networking support. See also https://aka.ms/dotnet-wasm-features" - : "This browser doesn't support WebSocket API. Please use a modern browser. See also https://aka.ms/dotnet-wasm-features"; + ? "Please install `ws` npm package to enable networking support." + : "This browser doesn't support WebSocket API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"; throw new Error(message); } } diff --git a/src/native/libs/Common/JavaScript/loader/bootstrap.ts b/src/native/libs/Common/JavaScript/loader/bootstrap.ts index 77fa053c4e328d..0db95274d705cc 100644 --- a/src/native/libs/Common/JavaScript/loader/bootstrap.ts +++ b/src/native/libs/Common/JavaScript/loader/bootstrap.ts @@ -3,7 +3,7 @@ import { exceptions, simd } from "wasm-feature-detect"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL } from "./per-module"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, globalThisAny } from "./per-module"; import { dotnetAssert } from "./cross-module"; const scriptUrlQuery = /*! webpackIgnore: true */import.meta.url; @@ -13,8 +13,18 @@ const scriptUrl = normalizeFileUrl(scriptUrlQuery); const scriptDirectory = normalizeDirectoryUrl(scriptUrl); export async function validateWasmFeatures(): Promise { - dotnetAssert.check(await exceptions, "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); - dotnetAssert.check(await simd, "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); + dotnetAssert.check(await exceptions(), "This browser/engine doesn't support WASM exception handling. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); + dotnetAssert.check(await simd(), "This browser/engine doesn't support WASM SIMD. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"); + if (ENVIRONMENT_IS_NODE) { + const nodeMajorVersion = parseInt(globalThisAny.process.versions.node.split(".")[0], 10); + dotnetAssert.check(nodeMajorVersion >= 18, `Node.js version ${globalThisAny.process.versions.node} is not supported. Please use Node.js 18 or later.`); + } else if (ENVIRONMENT_IS_SHELL) { + if (typeof globalThisAny.version === "function" && globalThisAny.d8) { + const v8v = globalThisAny.version(); + const v8MajorVersion = parseInt(v8v.split(".")[0], 10); + dotnetAssert.check(v8MajorVersion >= 14, "This V8 shell is too old. Please use a modern version."); + } + } } export function locateFile(path: string, isModule = false): string { diff --git a/src/native/libs/Common/JavaScript/loader/exit.ts b/src/native/libs/Common/JavaScript/loader/exit.ts index 111c85919999fa..09c2c9b7ef63b7 100644 --- a/src/native/libs/Common/JavaScript/loader/exit.ts +++ b/src/native/libs/Common/JavaScript/loader/exit.ts @@ -131,7 +131,7 @@ export function exit(exitCode: number, reason: any): void { } } if (!runtimeState.dotnetReady) { - dotnetLogger.debug(() => `Aborting startup, reason: ${reason}`); + dotnetLogger.info(`Aborting startup, reason: ${reason}`); dotnetLoaderExports.abortStartup(reason); } } catch (err) { diff --git a/src/native/libs/Common/JavaScript/loader/polyfills.ts b/src/native/libs/Common/JavaScript/loader/polyfills.ts index aebf928b616a9f..72febf17d0ff33 100644 --- a/src/native/libs/Common/JavaScript/loader/polyfills.ts +++ b/src/native/libs/Common/JavaScript/loader/polyfills.ts @@ -100,7 +100,7 @@ export async function fetchLike(url: string, init?: RequestInit, expectedContent } else if (hasFetch) { return globalThis.fetch(url, init || { credentials: "same-origin" }); } else if (typeof (read) === "function") { - const isText = expectedContentType === "application/json" || expectedContentType === "text/plain"; + const isText = expectedContentType && (expectedContentType.startsWith("application/json") || expectedContentType.startsWith("text/plain")); const arrayBuffer = read(url, isText ? "utf8" : "binary"); return responseLike(url, arrayBuffer, { status: 200, diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts index a51d1125df3ede..0376efbb0ab49b 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts @@ -15,8 +15,8 @@ import { dotnetLogger, dotnetAssert } from "./cross-module"; function verifyEnvironment() { if (typeof globalThis.fetch !== "function" || typeof globalThis.AbortController !== "function") { const message = ENVIRONMENT_IS_NODE - ? "Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support. See also https://aka.ms/dotnet-wasm-features" - : "This browser doesn't support fetch API. Please use a modern browser. See also https://aka.ms/dotnet-wasm-features"; + ? "Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support." + : "This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"; throw new Error(message); } } diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts index 825e10a9407206..285909704eb1e6 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts @@ -496,8 +496,8 @@ function verifyEnvironment() { } if (typeof globalThis.WebSocket !== "function") { const message = ENVIRONMENT_IS_NODE - ? "Please install `ws` npm package to enable networking support. See also https://aka.ms/dotnet-wasm-features" - : "This browser doesn't support WebSocket API. Please use a modern browser. See also https://aka.ms/dotnet-wasm-features"; + ? "Please install `ws` npm package to enable networking support." + : "This browser doesn't support WebSocket API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms"; throw new Error(message); } }