diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index 2d9fa95fb4..926e0b934a 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -69,26 +69,11 @@ variables: # used for post-build phases, internal builds only - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - group: DotNet-AspNet-SDLValidation-Params - + stages: - stage: build displayName: Build jobs: - # Code check - - template: jobs/default-build.yml - parameters: - jobName: Code_check - jobDisplayName: Code check - agentOs: Windows - steps: - - powershell: ./eng/scripts/CodeCheck.ps1 -ci - displayName: Run eng/scripts/CodeCheck.ps1 - artifacts: - - name: Code_Check_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - # Build Windows (x64/x86) - template: jobs/default-build.yml parameters: @@ -114,34 +99,11 @@ stages: -arch x64 -pack -all - -buildNative + -NoBuildNative /bl:artifacts/log/build.x64.binlog $(_BuildArgs) displayName: Build x64 - # Build the x86 shared framework - # TODO: make it possible to build for one Windows architecture at a time - # This is going to actually build x86 native assets. See https://github.com/aspnet/AspNetCore/issues/7196 - - script: ./build.cmd - -ci - -arch x86 - -pack - -all - -buildNative - -noBuildJava - /p:OnlyPackPlatformSpecificPackages=true - /bl:artifacts/log/build.x86.binlog - $(_BuildArgs) - displayName: Build x86 - - # This is in a separate build step with -forceCoreMsbuild to workaround MAX_PATH limitations - https://github.com/Microsoft/msbuild/issues/53 - - script: .\src\SiteExtensions\build.cmd - -ci - -pack - -noBuildDeps - $(_BuildArgs) - displayName: Build SiteExtension - # This runs code-signing on all packages, zips, and jar files as defined in build/CodeSign.targets. If https://github.com/dotnet/arcade/issues/1957 is resolved, # consider running code-signing inline with the other previous steps. # Sign check is disabled because it is run in a separate step below, after installers are built. @@ -155,29 +117,6 @@ stages: $(_BuildArgs) displayName: Code sign packages - # Windows installers bundle both x86 and x64 assets - - script: ./build.cmd - -ci - -sign - -buildInstallers - /bl:artifacts/log/installers.msbuild.binlog - /p:DotNetSignType=$(_SignType) - /p:AssetManifestFileName=aspnetcore-win-x64-x86.xml - $(_BuildArgs) - $(_PublishArgs) - /p:PublishInstallerBaseVersion=true - displayName: Build Installers - - # A few files must also go to the VS package feed. - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: NuGetCommand@2 - displayName: Push Visual Studio packages - inputs: - command: push - packagesToPush: 'artifacts/packages/**/VS.Redist.Common.AspNetCore.*.nupkg' - nuGetFeedType: external - publishFeedCredentials: 'DevDiv - VS package feed' - artifacts: - name: Windows_Logs path: artifacts/log/ @@ -186,251 +125,6 @@ stages: - name: Windows_Packages path: artifacts/packages/ - # Build Windows ARM - - template: jobs/default-build.yml - parameters: - codeSign: true - jobName: Windows_arm_build - jobDisplayName: "Build: Windows ARM" - agentOs: Windows - buildArgs: - -arch arm - -sign - -pack - -noBuildNodeJS - -noBuildJava - /bl:artifacts/log/build.win-arm.binlog - /p:DotNetSignType=$(_SignType) - /p:OnlyPackPlatformSpecificPackages=true - /p:AssetManifestFileName=aspnetcore-win-arm.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: Windows_arm_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Windows_arm_Packages - path: artifacts/packages/ - - # Build MacOS - - template: jobs/default-build.yml - parameters: - jobName: MacOs_x64_build - jobDisplayName: "Build: macOS" - agentOs: macOs - buildArgs: - --pack - --all - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.macos.binlog - -p:AssetManifestFileName=aspnetcore-MacOS_x64.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: MacOS_x64_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: MacOS_x64_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: MacOS_x64 - - # Build Linux x64 - - template: jobs/default-build.yml - parameters: - jobName: Linux_x64_build - jobDisplayName: "Build: Linux x64" - agentOs: Linux - steps: - - script: ./build.sh - --ci - --arch x64 - --pack - --all - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.linux-x64.binlog - $(_BuildArgs) - displayName: Run build.sh - - script: | - git clean -xfd src/**/obj/ - ./dockerbuild.sh bionic \ - --ci \ - --arch x64 \ - --build-installers \ - --no-build-deps \ - --no-build-nodejs \ - -p:OnlyPackPlatformSpecificPackages=true \ - -p:BuildRuntimeArchive=false \ - -p:LinuxInstallerType=deb \ - -bl:artifacts/log/build.deb.binlog \ - $(_BuildArgs) - displayName: Build Debian installers - - script: | - git clean -xfd src/**/obj/ - ./dockerbuild.sh rhel \ - --ci \ - --arch x64 \ - --build-installers \ - --no-build-deps \ - --no-build-nodejs \ - -p:OnlyPackPlatformSpecificPackages=true \ - -p:BuildRuntimeArchive=false \ - -p:LinuxInstallerType=rpm \ - -bl:artifacts/log/build.rpm.binlog \ - -p:AssetManifestFileName=aspnetcore-Linux_x64.xml \ - $(_BuildArgs) \ - $(_PublishArgs) - displayName: Build RPM installers - installNodeJs: false - installJdk: false - artifacts: - - name: Linux_x64_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Linux_x64_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: Linux_x64 - - # Build Linux ARM - - template: jobs/default-build.yml - parameters: - jobName: Linux_arm_build - jobDisplayName: "Build: Linux ARM" - agentOs: Linux - buildArgs: - --arch arm - --pack - --all - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.linux-arm.binlog - -p:AssetManifestFileName=aspnetcore-Linux_arm.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: Linux_arm_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Linux_arm_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: Linux_arm - - # Build Linux ARM64 - - template: jobs/default-build.yml - parameters: - jobName: Linux_arm64_build - jobDisplayName: "Build: Linux ARM64" - agentOs: Linux - buildArgs: - --arch arm64 - --all - --pack - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.arm64.binlog - -p:AssetManifestFileName=aspnetcore-Linux_arm64.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: Linux_arm64_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Linux_arm64_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: Linux_arm64 - - # Build Linux Musl x64 - - template: jobs/default-build.yml - parameters: - jobName: Linux_musl_x64_build - jobDisplayName: "Build: Linux Musl x64" - agentOs: Linux - buildScript: ./dockerbuild.sh alpine - buildArgs: - --ci - --arch x64 - --os-name linux-musl - --pack - --all - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.musl.binlog - -p:AssetManifestFileName=aspnetcore-Linux_musl_x64.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: Linux_musl_x64_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Linux_musl_x64_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: Linux_musl_x64 - - # Build Linux Musl ARM64 - - template: jobs/default-build.yml - parameters: - jobName: Linux_musl_arm64_build - jobDisplayName: "Build: Linux Musl ARM64" - agentOs: Linux - buildScript: ./dockerbuild.sh ubuntu-alpine37 - buildArgs: - --ci - --arch arm64 - --os-name linux-musl - --pack - --all - --no-build-nodejs - --no-build-java - -p:OnlyPackPlatformSpecificPackages=true - -bl:artifacts/log/build.musl.binlog - -p:AssetManifestFileName=aspnetcore-Linux_musl_arm64.xml - $(_BuildArgs) - $(_PublishArgs) - installNodeJs: false - installJdk: false - artifacts: - - name: Linux_musl_arm64_Logs - path: artifacts/log/ - publishOnError: true - includeForks: true - - name: Linux_musl_arm64_Packages - path: artifacts/packages/ - - template: jobs/codesign-xplat.yml - parameters: - inputName: Linux_musl_arm64 - # Test jobs - template: jobs/default-build.yml parameters: @@ -567,63 +261,15 @@ stages: publishOnError: true includeForks: true - # Source build - - job: Source_Build - displayName: 'Test: Linux Source Build' - container: centos:7 - pool: - vmImage: 'ubuntu-16.04' - variables: - DotNetCoreSdkDir: $(Agent.ToolsDirectory)/dotnet - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true - steps: - - script: | - source eng/common/native/common-library.sh - mkdir -p $HOME/bin - GetFile https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 $HOME/bin/jq - chmod +x $HOME/bin/jq - echo "##vso[task.prependpath]$HOME/bin" - displayName: Install jq - - script: ./eng/scripts/ci-source-build.sh --ci --configuration Release /p:BuildManaged=true /p:BuildNodeJs=false - displayName: Run ci-source-build.sh - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: always() - continueOnError: true - inputs: - pathtoPublish: artifacts/log/ - artifactName: Source_Build_Logs - artifactType: Container - parallel: true - - task: PublishBuildArtifacts@1 - displayName: Upload package artifacts - # Only capture source build artifacts in PRs for the sake of inspecting - # changes that impact source-build. The artifacts from this build pipeline are never actually used. - condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) - inputs: - pathtoPublish: artifacts/packages/ - artifactName: Source_Build_Packages - artifactType: Container - parallel: true - # Publish to the BAR - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: /eng/common/templates/job/publish-build-assets.yml parameters: dependsOn: - Windows_build - - Windows_arm_build - - CodeSign_Xplat_MacOS_x64 - - CodeSign_Xplat_Linux_x64 - - CodeSign_Xplat_Linux_arm - - CodeSign_Xplat_Linux_arm64 - - CodeSign_Xplat_Linux_musl_x64 - - CodeSign_Xplat_Linux_musl_arm64 # In addition to the dependencies above, ensure the build was successful overall. - - Code_check - Linux_Test - MacOS_Test - - Source_Build - Windows_Templates_Test - Windows_Test pool: diff --git a/eng/Build.props b/eng/Build.props index f8a3b7027a..3378e22c39 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -50,6 +50,11 @@ " /> + + + $(RepoRoot)src\Components\**\*.csproj;$(RepoRoot)src\ProjectTemplates\**\*.csproj + + diff --git a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs deleted file mode 100644 index 463b710ac3..0000000000 --- a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.E2ETesting; -using Microsoft.AspNetCore.Testing; -using OpenQA.Selenium; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class BlazorServerTemplateTest : BrowserTestBase - { - public BlazorServerTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) : base(browserFixture, output) - { - ProjectFactory = projectFactory; - } - - public ProjectFactoryFixture ProjectFactory { get; set; } - - public Project Project { get; private set; } - - [Fact] - public async Task BlazorServerTemplateWorks_NoAuth() - { - Project = await ProjectFactory.GetOrCreateProject("blazorservernoauth", Output); - - var createResult = await Project.RunDotNetNewAsync("blazorserver"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - if (BrowserFixture.IsHostAutomationSupported()) - { - aspNetProcess.VisitInBrowser(Browser); - TestBasicNavigation(); - } - else - { - BrowserFixture.EnforceSupportedConfigurations(); - } - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - if (BrowserFixture.IsHostAutomationSupported()) - { - aspNetProcess.VisitInBrowser(Browser); - TestBasicNavigation(); - } - else - { - BrowserFixture.EnforceSupportedConfigurations(); - } - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB) - { - Project = await ProjectFactory.GetOrCreateProject("blazorserverindividual" + (useLocalDB ? "uld" : ""), Output); - - var createResult = await Project.RunDotNetNewAsync("blazorserver", auth: "Individual", useLocalDB: useLocalDB); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - if (BrowserFixture.IsHostAutomationSupported()) - { - aspNetProcess.VisitInBrowser(Browser); - TestBasicNavigation(); - } - else - { - BrowserFixture.EnforceSupportedConfigurations(); - } - } - - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - if (BrowserFixture.IsHostAutomationSupported()) - { - aspNetProcess.VisitInBrowser(Browser); - TestBasicNavigation(); - } - } - } - - private void TestBasicNavigation() - { - // Give components.server enough time to load so that it can replace - // the prerendered content before we start making assertions. - Thread.Sleep(5000); - Browser.Exists(By.TagName("ul")); - // element gets project ID injected into it during template execution - Browser.Equal(Project.ProjectName.Trim(), () => Browser.Title.Trim()); - - // Initially displays the home page - Browser.Equal("Hello, world!", () => Browser.FindElement(By.TagName("h1")).Text); - - // Can navigate to the counter page - Browser.FindElement(By.PartialLinkText("Counter")).Click(); - Browser.Contains("counter", () => Browser.Url); - Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text); - - // Clicking the counter button works - Browser.Equal("Current count: 0", () => Browser.FindElement(By.CssSelector("h1 + p")).Text); - Browser.FindElement(By.CssSelector("p+button")).Click(); - Browser.Equal("Current count: 1", () => Browser.FindElement(By.CssSelector("h1 + p")).Text); - - // Can navigate to the 'fetch data' page - Browser.FindElement(By.PartialLinkText("Fetch data")).Click(); - Browser.Contains("fetchdata", () => Browser.Url); - Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text); - - // Asynchronously loads and displays the table of weather forecasts - Browser.Exists(By.CssSelector("table>tbody>tr")); - Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count); - } - } -} diff --git a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs deleted file mode 100644 index 56e2e8c105..0000000000 --- a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class EmptyWebTemplateTest - { - public EmptyWebTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; } - - public ITestOutputHelper Output { get; } - - [Fact] - public async Task EmptyWebTemplateCSharp() - { - await EmtpyTemplateCore(languageOverride: null); - } - - [Fact] - public async Task EmptyWebTemplateFSharp() - { - await EmtpyTemplateCore("F#"); - } - - private async Task EmtpyTemplateCore(string languageOverride) - { - Project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); - - var createResult = await Project.RunDotNetNewAsync("web", language: languageOverride); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertOk("/"); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertOk("/"); - } - } - } -} diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs deleted file mode 100644 index 4713a7a9c4..0000000000 --- a/src/ProjectTemplates/test/GrpcTemplateTest.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class GrpcTemplateTest - { - public GrpcTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; } - public ITestOutputHelper Output { get; } - - [Fact] - public async Task GrpcTemplate() - { - Project = await ProjectFactory.GetOrCreateProject("grpc", Output); - - var createResult = await Project.RunDotNetNewAsync("grpc"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var serverProcess = Project.StartBuiltProjectAsync()) - { - // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support. - // https://github.com/aspnet/AspNetCore/issues/11061 - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - Assert.True(serverProcess.Process.HasExited, "built"); - Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.", - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2)) - { - Assert.True(serverProcess.Process.HasExited, "built"); - Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.", - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); - } - else - { - Assert.False( - serverProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); - } - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support. - // https://github.com/aspnet/AspNetCore/issues/11061 - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - Assert.True(aspNetProcess.Process.HasExited, "published"); - Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.", - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2)) - { - Assert.True(aspNetProcess.Process.HasExited, "published"); - Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.", - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); - } - else - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); - } - } - } - } -} diff --git a/src/ProjectTemplates/test/IdentityUIPackageTest.cs b/src/ProjectTemplates/test/IdentityUIPackageTest.cs deleted file mode 100644 index deede64521..0000000000 --- a/src/ProjectTemplates/test/IdentityUIPackageTest.cs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class IdentityUIPackageTest - { - public IdentityUIPackageTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; set; } - - public ITestOutputHelper Output { get; } - - public static TheoryData<IDictionary<string, string>, string, string[]> MSBuildIdentityUIPackageOptions - { - get - { - var data = new TheoryData<IDictionary<string, string>, string, string[]>(); - - data.Add(new Dictionary<string, string> - { - ["IdentityUIFrameworkVersion"] = "Bootstrap3" - }, - "Bootstrap v3.4.1", - Bootstrap3ContentFiles); - - data.Add(new Dictionary<string, string>(), "Bootstrap v4.3.1", Bootstrap4ContentFiles); - - return data; - } - } - - public static string[] Bootstrap3ContentFiles { get; } = new string[] - { - "Identity/css/site.css", - "Identity/js/site.js", - "Identity/lib/bootstrap/dist/css/bootstrap-theme.css", - "Identity/lib/bootstrap/dist/css/bootstrap-theme.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css", - "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap.css", - "Identity/lib/bootstrap/dist/css/bootstrap.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap.min.css", - "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map", - "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot", - "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg", - "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf", - "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff", - "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2", - "Identity/lib/bootstrap/dist/js/bootstrap.js", - "Identity/lib/bootstrap/dist/js/bootstrap.min.js", - "Identity/lib/bootstrap/dist/js/npm.js", - "Identity/lib/jquery/LICENSE.txt", - "Identity/lib/jquery/dist/jquery.js", - "Identity/lib/jquery/dist/jquery.min.js", - "Identity/lib/jquery/dist/jquery.min.map", - "Identity/lib/jquery-validation/LICENSE.md", - "Identity/lib/jquery-validation/dist/additional-methods.js", - "Identity/lib/jquery-validation/dist/additional-methods.min.js", - "Identity/lib/jquery-validation/dist/jquery.validate.js", - "Identity/lib/jquery-validation/dist/jquery.validate.min.js", - "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js", - "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt", - }; - - public static string[] Bootstrap4ContentFiles { get; } = new string[] - { - "Identity/favicon.ico", - "Identity/css/site.css", - "Identity/js/site.js", - "Identity/lib/bootstrap/dist/css/bootstrap-grid.css", - "Identity/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css", - "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap.css", - "Identity/lib/bootstrap/dist/css/bootstrap.css.map", - "Identity/lib/bootstrap/dist/css/bootstrap.min.css", - "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map", - "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js", - "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "Identity/lib/bootstrap/dist/js/bootstrap.js", - "Identity/lib/bootstrap/dist/js/bootstrap.js.map", - "Identity/lib/bootstrap/dist/js/bootstrap.min.js", - "Identity/lib/bootstrap/dist/js/bootstrap.min.js.map", - "Identity/lib/jquery/LICENSE.txt", - "Identity/lib/jquery/dist/jquery.js", - "Identity/lib/jquery/dist/jquery.min.js", - "Identity/lib/jquery/dist/jquery.min.map", - "Identity/lib/jquery-validation/LICENSE.md", - "Identity/lib/jquery-validation/dist/additional-methods.js", - "Identity/lib/jquery-validation/dist/additional-methods.min.js", - "Identity/lib/jquery-validation/dist/jquery.validate.js", - "Identity/lib/jquery-validation/dist/jquery.validate.min.js", - "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js", - "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt", - }; - - [Theory] - [MemberData(nameof(MSBuildIdentityUIPackageOptions))] - public async Task IdentityUIPackage_WorksWithDifferentOptions(IDictionary<string, string> packageOptions, string versionValidator, string[] expectedFiles) - { - Project = await ProjectFactory.GetOrCreateProject("identityuipackage" + string.Concat(packageOptions.Values), Output); - var useLocalDB = false; - - var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, environmentVariables: packageOptions); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); - Assert.Contains(".db", projectFileContents); - - var publishResult = await Project.RunDotNetPublishAsync(packageOptions: packageOptions); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(packageOptions: packageOptions); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("razorpages"); - Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); - Project.AssertEmptyMigration("razorpages"); - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css"); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync()); - await ValidatePublishedFiles(aspNetProcess, expectedFiles); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css"); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync()); - await ValidatePublishedFiles(aspNetProcess, expectedFiles); - } - } - - private async Task ValidatePublishedFiles(AspNetProcess aspNetProcess, string[] expectedContentFiles) - { - foreach (var file in expectedContentFiles) - { - var response = await aspNetProcess.SendRequest(file); - Assert.True(response?.StatusCode == HttpStatusCode.OK, $"Couldn't find file '{file}'"); - } - } - - private string ReadFile(string basePath, string path) - { - var fullPath = Path.Combine(basePath, path); - var doesExist = File.Exists(fullPath); - - Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}"); - return File.ReadAllText(Path.Combine(basePath, path)); - } - } -} diff --git a/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs b/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs deleted file mode 100644 index 842ce8a5d9..0000000000 --- a/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Items.Test -{ - public class BlazorServerTest - { - public BlazorServerTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; } - public ITestOutputHelper Output { get; } - - [Fact] - public async Task BlazorServerItemTemplate() - { - Project = await ProjectFactory.GetOrCreateProject("razorcomponentitem", Output); - - var createResult = await Project.RunDotNetNewAsync("razorcomponent --name Different"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create", Project, createResult)); - - Project.AssertFileExists("Different.razor", shouldExist: true); - Assert.Contains("<h3>Different</h3>", Project.ReadFile("Different.razor")); - } - } -} diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs deleted file mode 100644 index af43914ed2..0000000000 --- a/src/ProjectTemplates/test/MvcTemplateTest.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Templates.Test.Helpers; -using System.Linq; -using Xunit; -using Xunit.Abstractions; -using Microsoft.AspNetCore.Testing; - -namespace Templates.Test -{ - public class MvcTemplateTest - { - public MvcTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; } - public ITestOutputHelper Output { get; } - - [Fact] - public async Task MvcTemplate_NoAuthFSharp() => await MvcTemplateCore(languageOverride: "F#"); - - [Fact] - public async Task MvcTemplate_NoAuthCSharp() => await MvcTemplateCore(languageOverride: null); - - private async Task MvcTemplateCore(string languageOverride) - { - Project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); - - var createResult = await Project.RunDotNetNewAsync("mvc", language: languageOverride); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var projectExtension = languageOverride == "F#" ? "fsproj" : "csproj"; - var projectFileContents = Project.ReadFile($"{Project.ProjectName}.{projectExtension}"); - Assert.DoesNotContain(".db", projectFileContents); - Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); - Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); - Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); - Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - IEnumerable<string> menuLinks = new List<string> { - PageUrls.HomeUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyFullUrl - }; - - var footerLinks = new string[] { PageUrls.PrivacyFullUrl }; - - var pages = new List<Page> - { - new Page - { - Url = PageUrls.HomeUrl, - Links = menuLinks.Append(PageUrls.DocsUrl).Concat(footerLinks) - }, - new Page - { - Url = PageUrls.PrivacyFullUrl, - Links = menuLinks.Concat(footerLinks) - } - }; - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task MvcTemplate_IndividualAuth(bool useLocalDB) - { - Project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output); - - var createResult = await Project.RunDotNetNewAsync("mvc", auth: "Individual", useLocalDB: useLocalDB); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var projectFileContents = Project.ReadFile($"{Project.ProjectName}.csproj"); - if (!useLocalDB) - { - Assert.Contains(".db", projectFileContents); - } - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("mvc"); - Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); - Project.AssertEmptyMigration("mvc"); - - var pages = new List<Page> { - new Page - { - Url = PageUrls.ForgotPassword, - Links = new string [] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.HomeUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.DocsUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.PrivacyFullUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.LoginUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.ForgotPassword, - PageUrls.RegisterUrl, - PageUrls.ExternalArticle, - PageUrls.PrivacyUrl } - }, - new Page - { - Url = PageUrls.RegisterUrl, - Links = new string [] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.ExternalArticle, - PageUrls.PrivacyUrl - } - } - }; - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - } - } -} diff --git a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs deleted file mode 100644 index 0d02a56f8f..0000000000 --- a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class RazorClassLibraryTemplateTest - { - public RazorClassLibraryTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; } - public ITestOutputHelper Output { get; } - - [Fact] - public async Task RazorClassLibraryTemplate_WithViews_Async() - { - Project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output); - - var createResult = await Project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" }); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - } - - [Fact] - public async Task RazorClassLibraryTemplateAsync() - { - Project = await ProjectFactory.GetOrCreateProject("razorclasslib", Output); - - var createResult = await Project.RunDotNetNewAsync("razorclasslib"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - } - } -} diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs deleted file mode 100644 index 7cd41d56b2..0000000000 --- a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class RazorPagesTemplateTest - { - public RazorPagesTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - - public ProjectFactoryFixture ProjectFactory { get; set; } - - public ITestOutputHelper Output { get; } - - [Fact] - public async Task RazorPagesTemplate_NoAuth() - { - Project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output); - - var createResult = await Project.RunDotNetNewAsync("razor"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("razor", Project, createResult)); - - var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); - Assert.DoesNotContain(".db", projectFileContents); - Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); - Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); - Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); - Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, createResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, createResult)); - - var pages = new List<Page> - { - new Page - { - Url = PageUrls.HomeUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.DocsUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.PrivacyUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.PrivacyUrl } - } - }; - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB) - { - Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output); - - var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); - if (!useLocalDB) - { - Assert.Contains(".db", projectFileContents); - } - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("razorpages"); - Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); - Project.AssertEmptyMigration("razorpages"); - - var pages = new List<Page> { - new Page - { - Url = PageUrls.ForgotPassword, - Links = new string [] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.HomeUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.DocsUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.PrivacyUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.PrivacyUrl - } - }, - new Page - { - Url = PageUrls.LoginUrl, - Links = new string[] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.ForgotPassword, - PageUrls.RegisterUrl, - PageUrls.ExternalArticle, - PageUrls.PrivacyUrl } - }, - new Page - { - Url = PageUrls.RegisterUrl, - Links = new string [] { - PageUrls.HomeUrl, - PageUrls.RegisterUrl, - PageUrls.LoginUrl, - PageUrls.HomeUrl, - PageUrls.PrivacyUrl, - PageUrls.ExternalArticle, - PageUrls.PrivacyUrl - } - } - }; - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertPagesOk(pages); - } - } - - - private string ReadFile(string basePath, string path) - { - var fullPath = Path.Combine(basePath, path); - var doesExist = File.Exists(fullPath); - - Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}"); - return File.ReadAllText(Path.Combine(basePath, path)); - } - } -} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs deleted file mode 100644 index e1d5db1338..0000000000 --- a/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.AspNetCore.E2ETesting; -using Microsoft.AspNetCore.Testing; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test.SpaTemplateTest -{ - public class AngularTemplateTest : SpaTemplateTestBase - { - public AngularTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) - : base(projectFactory, browserFixture, output) { } - - [Fact] - public Task AngularTemplate_Works() - => SpaTemplateImplAsync("angularnoauth", "angular", useLocalDb: false, usesAuth: false); - - [Fact] - public Task AngularTemplate_IndividualAuth_Works() - => SpaTemplateImplAsync("angularindividual", "angular", useLocalDb: false, usesAuth: true); - - [Fact] - public Task AngularTemplate_IndividualAuth_Works_LocalDb() - => SpaTemplateImplAsync("angularindividualuld", "angular", useLocalDb: true, usesAuth: true); - } -} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs deleted file mode 100644 index 44d6b67f32..0000000000 --- a/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.AspNetCore.E2ETesting; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test.SpaTemplateTest -{ - public class ReactReduxTemplateTest : SpaTemplateTestBase - { - public ReactReduxTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) - : base(projectFactory, browserFixture, output) - { - } - - [Fact] - public Task ReactReduxTemplate_Works_NetCore() - => SpaTemplateImplAsync("reactredux", "reactredux", useLocalDb: false, usesAuth: false); - } -} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs deleted file mode 100644 index 469e87acd5..0000000000 --- a/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.AspNetCore.E2ETesting; -using Microsoft.AspNetCore.Testing; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test.SpaTemplateTest -{ - public class ReactTemplateTest : SpaTemplateTestBase - { - public ReactTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) - : base(projectFactory, browserFixture, output) - { - } - - [Fact] - public Task ReactTemplate_Works_NetCore() - => SpaTemplateImplAsync("reactnoauth", "react", useLocalDb: false, usesAuth: false); - - [Fact] - public Task ReactTemplate_IndividualAuth_NetCore() - => SpaTemplateImplAsync("reactindividual", "react", useLocalDb: false, usesAuth: true); - - [Fact] - public Task ReactTemplate_IndividualAuth_NetCore_LocalDb() - => SpaTemplateImplAsync("reactindividualuld", "react", useLocalDb: true, usesAuth: true); - } -} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs b/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs deleted file mode 100644 index fa2c3fb9fa..0000000000 --- a/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.AspNetCore.E2ETesting; -using Newtonsoft.Json.Linq; -using OpenQA.Selenium; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -// Turn off parallel test run for Edge as the driver does not support multiple Selenium tests at the same time -#if EDGE -[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] -#endif -namespace Templates.Test.SpaTemplateTest -{ - public class SpaTemplateTestBase : BrowserTestBase - { - public SpaTemplateTestBase( - ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) : base(browserFixture, output) - { - ProjectFactory = projectFactory; - } - - public ProjectFactoryFixture ProjectFactory { get; set; } - - public Project Project { get; set; } - - // Rather than using [Theory] to pass each of the different values for 'template', - // it's important to distribute the SPA template tests over different test classes - // so they can be run in parallel. Xunit doesn't parallelize within a test class. - protected async Task SpaTemplateImplAsync( - string key, - string template, - bool useLocalDb = false, - bool usesAuth = false) - { - Project = await ProjectFactory.GetOrCreateProject(key, Output); - - using var createResult = await Project.RunDotNetNewAsync(template, auth: usesAuth ? "Individual" : null, language: null, useLocalDb); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - // We shouldn't have to do the NPM restore in tests because it should happen - // automatically at build time, but by doing it up front we can avoid having - // multiple NPM installs run concurrently which otherwise causes errors when - // tests run in parallel. - var clientAppSubdirPath = Path.Combine(Project.TemplateOutputDir, "ClientApp"); - ValidatePackageJson(clientAppSubdirPath); - - var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); - if (usesAuth && !useLocalDb) - { - Assert.Contains(".db", projectFileContents); - } - - using var npmRestoreResult = await Project.RestoreWithRetryAsync(Output, clientAppSubdirPath); - Assert.True(0 == npmRestoreResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm restore", Project, npmRestoreResult)); - - using var lintResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, "npm run lint"); - Assert.True(0 == lintResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm run lint", Project, lintResult)); - - // The default behavior of angular tests is watch mode, which leaves the test process open after it finishes, which leads to delays/hangs. - var testcommand = "npm run test" + template == "angular" ? "-- --watch=false" : ""; - - using var testResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, testcommand); - Assert.True(0 == testResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm run test", Project, testResult)); - - using var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - using var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - // localdb is not installed on the CI machines, so skip it. - var shouldVisitFetchData = !(useLocalDb && Project.IsCIEnvironment); - - if (usesAuth) - { - using var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync(template); - Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); - Project.AssertEmptyMigration(template); - - if (shouldVisitFetchData) - { - using var dbUpdateResult = await Project.RunDotNetEfUpdateDatabaseAsync(); - Assert.True(0 == dbUpdateResult.ExitCode, ErrorMessages.GetFailedProcessMessage("update database", Project, dbUpdateResult)); - } - } - - if (template == "react" || template == "reactredux") - { - await CleanupReactClientAppBuildFolder(clientAppSubdirPath); - } - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await WarmUpServer(aspNetProcess); - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - - if (BrowserFixture.IsHostAutomationSupported()) - { - var (browser, logs) = await BrowserFixture.GetOrCreateBrowserAsync(Output, $"{Project.ProjectName}.build"); - aspNetProcess.VisitInBrowser(browser); - TestBasicNavigation(visitFetchData: shouldVisitFetchData, usesAuth, browser, logs); - } - else - { - BrowserFixture.EnforceSupportedConfigurations(); - } - } - - if (usesAuth) - { - UpdatePublishedSettings(); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - await WarmUpServer(aspNetProcess); - await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); - - if (BrowserFixture.IsHostAutomationSupported()) - { - var (browser, logs) = await BrowserFixture.GetOrCreateBrowserAsync(Output, $"{Project.ProjectName}.publish"); - aspNetProcess.VisitInBrowser(browser); - TestBasicNavigation(visitFetchData: shouldVisitFetchData, usesAuth, browser, logs); - } - else - { - BrowserFixture.EnforceSupportedConfigurations(); - } - } - } - - private async Task CleanupReactClientAppBuildFolder(string clientAppSubdirPath) - { - ProcessEx testResult = null; - int? testResultExitCode = null; - for (int i = 0; i < 3; i++) - { - try - { - testResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, "npx rimraf ./build"); - testResultExitCode = testResult.ExitCode; - if (testResultExitCode == 0) - { - return; - } - } - catch - { - } - finally - { - testResult.Dispose(); - } - - await Task.Delay(3000); - } - - Assert.True(testResultExitCode == 0, ErrorMessages.GetFailedProcessMessage("npx rimraf ./build", Project, testResult)); - } - - private void ValidatePackageJson(string clientAppSubdirPath) - { - Assert.True(File.Exists(Path.Combine(clientAppSubdirPath, "package.json")), "Missing a package.json"); - var packageJson = JObject.Parse(ReadFile(clientAppSubdirPath, "package.json")); - - // NPM package names must match ^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$ - var packageName = (string)packageJson["name"]; - Regex regex = new Regex("^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$"); - Assert.True(regex.IsMatch(packageName), "package.json name is invalid format"); - } - - private static async Task WarmUpServer(AspNetProcess aspNetProcess) - { - var attempt = 0; - var maxAttempts = 3; - do - { - try - { - attempt++; - var response = await aspNetProcess.SendRequest("/"); - if (response.StatusCode == HttpStatusCode.OK) - { - break; - } - } - catch (OperationCanceledException) - { - } - catch (HttpRequestException ex) when (ex.Message.StartsWith("The SSL connection could not be established")) - { - } - await Task.Delay(TimeSpan.FromSeconds(5 * attempt)); - } while (attempt < maxAttempts); - } - - private void UpdatePublishedSettings() - { - // Hijack here the config file to use the development key during publish. - var appSettings = JObject.Parse(File.ReadAllText(Path.Combine(Project.TemplateOutputDir, "appsettings.json"))); - var appSettingsDevelopment = JObject.Parse(File.ReadAllText(Path.Combine(Project.TemplateOutputDir, "appsettings.Development.json"))); - ((JObject)appSettings["IdentityServer"]).Merge(appSettingsDevelopment["IdentityServer"]); - ((JObject)appSettings["IdentityServer"]).Merge(new - { - IdentityServer = new - { - Key = new - { - FilePath = "./tempkey.json" - } - } - }); - var testAppSettings = appSettings.ToString(); - File.WriteAllText(Path.Combine(Project.TemplatePublishDir, "appsettings.json"), testAppSettings); - } - - private void TestBasicNavigation(bool visitFetchData, bool usesAuth, IWebDriver browser, ILogs logs) - { - browser.Exists(By.TagName("ul")); - // <title> element gets project ID injected into it during template execution - browser.Contains(Project.ProjectGuid.Replace(".", "._"), () => browser.Title); - - // Initially displays the home page - browser.Equal("Hello, world!", () => browser.FindElement(By.TagName("h1")).Text); - - // Can navigate to the counter page - browser.FindElement(By.PartialLinkText("Counter")).Click(); - browser.Contains("counter", () => browser.Url); - - browser.Equal("Counter", () => browser.FindElement(By.TagName("h1")).Text); - - // Clicking the counter button works - browser.Equal("0", () => browser.FindElement(By.CssSelector("p>strong")).Text); - browser.FindElement(By.CssSelector("p+button")).Click(); - browser.Equal("1", () => browser.FindElement(By.CssSelector("p>strong")).Text); - - if (visitFetchData) - { - browser.FindElement(By.PartialLinkText("Fetch data")).Click(); - - if (usesAuth) - { - // We will be redirected to the identity UI - browser.Contains("/Identity/Account/Login", () => browser.Url); - browser.FindElement(By.PartialLinkText("Register as a new user")).Click(); - - var userName = $"{Guid.NewGuid()}@example.com"; - var password = $"!Test.Password1$"; - browser.Exists(By.Name("Input.Email")); - browser.FindElement(By.Name("Input.Email")).SendKeys(userName); - browser.FindElement(By.Name("Input.Password")).SendKeys(password); - browser.FindElement(By.Name("Input.ConfirmPassword")).SendKeys(password); - browser.FindElement(By.Id("registerSubmit")).Click(); - - // We will be redirected to the RegisterConfirmation - browser.Contains("/Identity/Account/RegisterConfirmation", () => browser.Url); - browser.FindElement(By.PartialLinkText("Click here to confirm your account")).Click(); - - // We will be redirected to the ConfirmEmail - browser.Contains("/Identity/Account/ConfirmEmail", () => browser.Url); - - // Now we can login - browser.FindElement(By.PartialLinkText("Login")).Click(); - browser.Exists(By.Name("Input.Email")); - browser.FindElement(By.Name("Input.Email")).SendKeys(userName); - browser.FindElement(By.Name("Input.Password")).SendKeys(password); - browser.FindElement(By.Id("login-submit")).Click(); - - // Need to navigate to fetch page - browser.FindElement(By.PartialLinkText("Fetch data")).Click(); - } - - // Can navigate to the 'fetch data' page - browser.Contains("fetch-data", () => browser.Url); - browser.Equal("Weather forecast", () => browser.FindElement(By.TagName("h1")).Text); - - // Asynchronously loads and displays the table of weather forecasts - browser.Exists(By.CssSelector("table>tbody>tr")); - browser.Equal(5, () => browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count); - } - - foreach (var logKind in logs.AvailableLogTypes) - { - var entries = logs.GetLog(logKind); - var badEntries = entries.Where(e => new LogLevel[] { LogLevel.Warning, LogLevel.Severe }.Contains(e.Level)); - - badEntries = badEntries.Where(e => - !e.Message.Contains("failed: WebSocket is closed before the connection is established.") - && !e.Message.Contains("[WDS] Disconnected!") - && !e.Message.Contains("Timed out connecting to Chrome, retrying")); - - Assert.True(badEntries.Count() == 0, "There were Warnings or Errors from the browser." + Environment.NewLine + string.Join(Environment.NewLine, badEntries)); - } - } - - private void AssertFileExists(string basePath, string path, bool shouldExist) - { - var fullPath = Path.Combine(basePath, path); - var doesExist = File.Exists(fullPath); - - if (shouldExist) - { - Assert.True(doesExist, "Expected file to exist, but it doesn't: " + path); - } - else - { - Assert.False(doesExist, "Expected file not to exist, but it does: " + path); - } - } - - private string ReadFile(string basePath, string path) - { - AssertFileExists(basePath, path, shouldExist: true); - return File.ReadAllText(Path.Combine(basePath, path)); - } - } -} diff --git a/src/ProjectTemplates/test/WebApiTemplateTest.cs b/src/ProjectTemplates/test/WebApiTemplateTest.cs deleted file mode 100644 index 89d047a06e..0000000000 --- a/src/ProjectTemplates/test/WebApiTemplateTest.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class WebApiTemplateTest - { - public WebApiTemplateTest(ProjectFactoryFixture factoryFixture, ITestOutputHelper output) - { - FactoryFixture = factoryFixture; - Output = output; - } - - public ProjectFactoryFixture FactoryFixture { get; } - - public ITestOutputHelper Output { get; } - - public Project Project { get; set; } - - [Fact] - public async Task WebApiTemplateFSharp() => await WebApiTemplateCore(languageOverride: "F#"); - - [Fact] - public async Task WebApiTemplateCSharp() => await WebApiTemplateCore(languageOverride: null); - - private async Task WebApiTemplateCore(string languageOverride) - { - Project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); - - var createResult = await Project.RunDotNetNewAsync("webapi", language: languageOverride); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var aspNetProcess = Project.StartBuiltProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - - await aspNetProcess.AssertOk("weatherforecast"); - await aspNetProcess.AssertNotFound("/"); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync()) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - - - await aspNetProcess.AssertOk("weatherforecast"); - await aspNetProcess.AssertNotFound("/"); - } - } - } -} diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs deleted file mode 100644 index 738eafc61d..0000000000 --- a/src/ProjectTemplates/test/WorkerTemplateTest.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Templates.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Templates.Test -{ - public class WorkerTemplateTest - { - public WorkerTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) - { - ProjectFactory = projectFactory; - Output = output; - } - - public Project Project { get; set; } - public ProjectFactoryFixture ProjectFactory { get; } - public ITestOutputHelper Output { get; } - - [Fact] - public async Task WorkerTemplateAsync() - { - Project = await ProjectFactory.GetOrCreateProject("worker", Output); - - var createResult = await Project.RunDotNetNewAsync("worker"); - Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); - - var publishResult = await Project.RunDotNetPublishAsync(); - Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); - - // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release - // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build - // later, while the opposite is not true. - - var buildResult = await Project.RunDotNetBuildAsync(); - Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); - - using (var aspNetProcess = Project.StartBuiltProjectAsync(hasListeningUri: false)) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); - } - - using (var aspNetProcess = Project.StartPublishedProjectAsync(hasListeningUri: false)) - { - Assert.False( - aspNetProcess.Process.HasExited, - ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); - } - } - } -}