Build fewer things in blazor-wasm (#17533)
This commit is contained in:
parent
40a0173e9d
commit
76ae0a2e21
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@
|
|||
" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- For the Blazor WASM branch, only build a subset of projects -->
|
||||
<ProjectToBuild>$(RepoRoot)src\Components\**\*.csproj;$(RepoRoot)src\ProjectTemplates\**\*.csproj</ProjectToBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
<!-- Project selection can be overridden on the command line by passing in -projects -->
|
||||
<When Condition="'$(ProjectToBuild)' != ''">
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
// <title> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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("/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue