diff --git a/src/Components/Blazor/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs b/src/Components/Blazor/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs new file mode 100644 index 0000000000000000000000000000000000000000..95e20270466a0d183e5719684ce446945940675e --- /dev/null +++ b/src/Components/Blazor/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs @@ -0,0 +1,82 @@ +// 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.IO; +using System.Linq; +using System.Runtime.Serialization.Json; +using System.Text; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Microsoft.AspNetCore.Blazor.Build +{ + public class GenerateServiceWorkerAssetsManifest : Task + { + [Required] + public string Version { get; set; } + + [Required] + public ITaskItem[] AssetsWithHashes { get; set; } + + [Required] + public string OutputPath { get; set; } + + public override bool Execute() + { + using var fileStream = File.Create(OutputPath); + WriteFile(fileStream); + return true; + } + + internal void WriteFile(Stream stream) + { + var data = new AssetsManifestFile + { + version = Version, + assets = AssetsWithHashes.Select(item => new AssetsManifestFileEntry + { + url = item.GetMetadata("AssetUrl"), + hash = $"sha256-{item.GetMetadata("FileHash")}", + }).ToArray() + }; + + using var streamWriter = new StreamWriter(stream, Encoding.UTF8, bufferSize: 50, leaveOpen: true); + streamWriter.Write("self.assetsManifest = "); + streamWriter.Flush(); + + using var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, ownsStream: false, indent: true); + new DataContractJsonSerializer(typeof(AssetsManifestFile)).WriteObject(jsonWriter, data); + jsonWriter.Flush(); + + streamWriter.WriteLine(";"); + } + +#pragma warning disable IDE1006 // Naming Styles + public class AssetsManifestFile + { + /// <summary> + /// Gets or sets a version string. + /// </summary> + public string version { get; set; } + + /// <summary> + /// Gets or sets the assets. Keys are URLs; values are base-64-formatted SHA256 content hashes. + /// </summary> + public AssetsManifestFileEntry[] assets { get; set; } + } + + public class AssetsManifestFileEntry + { + /// <summary> + /// Gets or sets the asset URL. Normally this will be relative to the application's base href. + /// </summary> + public string url { get; set; } + + /// <summary> + /// Gets or sets the file content hash. This should be the base-64-formatted SHA256 value. + /// </summary> + public string hash { get; set; } + } +#pragma warning restore IDE1006 // Naming Styles + } +} diff --git a/src/Components/Blazor/Build/src/targets/All.targets b/src/Components/Blazor/Build/src/targets/All.targets index 6c69e85a40113d3f0fd58291407c1b14d0144cf8..f44a825c23574365296be3dd4a5fb3ad95b2762e 100644 --- a/src/Components/Blazor/Build/src/targets/All.targets +++ b/src/Components/Blazor/Build/src/targets/All.targets @@ -21,6 +21,7 @@ <Import Project="Blazor.MonoRuntime.targets" /> <Import Project="Publish.targets" /> <Import Project="StaticWebAssets.targets" /> + <Import Project="ServiceWorkerAssetsManifest.targets" /> <Target Name="GenerateBlazorMetadataFile" BeforeTargets="GetCopyToOutputDirectoryItems"> diff --git a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets b/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets index 911c6167c89ee9c748948c319c01c96d34280c52..f5fea05473bf90b5026e8293203f7b5ef1148b91 100644 --- a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets +++ b/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets @@ -21,7 +21,7 @@ <Target Name="_BlazorCopyFilesToOutputDirectory" - DependsOnTargets="PrepareBlazorOutputs" + DependsOnTargets="PrepareBlazorOutputs;$(_BlazorCopyFilesToOutputDirectoryDependsOn)" AfterTargets="CopyFilesToOutputDirectory" Condition="'$(OutputType.ToLowerInvariant())'=='exe'"> @@ -133,7 +133,7 @@ ReferenceCopyLocalPaths includes all files that are part of the build out with CopyLocalLockFileAssemblies on. Remove assemblies that are inputs to calculating the assembly closure. Instead use the resolved outputs, since it is the minimal set. --> - <_BlazorCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" /> + <_BlazorCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)' == '.dll'" /> <_BlazorCopyLocalPaths Remove="@(_BlazorManagedRuntimeAssemby)" /> <BlazorOutputWithTargetPath Include="@(_BlazorCopyLocalPaths)"> diff --git a/src/Components/Blazor/Build/src/targets/ServiceWorkerAssetsManifest.targets b/src/Components/Blazor/Build/src/targets/ServiceWorkerAssetsManifest.targets new file mode 100644 index 0000000000000000000000000000000000000000..c92c8af17e56e753e19de9e40fe9e1d765ded5ff --- /dev/null +++ b/src/Components/Blazor/Build/src/targets/ServiceWorkerAssetsManifest.targets @@ -0,0 +1,98 @@ +<Project> + + <PropertyGroup> + <_BlazorCopyFilesToOutputDirectoryDependsOn> + $(_BlazorCopyFilesToOutputDirectoryDependsOn); + _ComputeServiceWorkerAssetsManifestInputs; + _WriteServiceWorkerAssetsManifest; + </_BlazorCopyFilesToOutputDirectoryDependsOn> + </PropertyGroup> + + <Target Name="_ComputeServiceWorkerAssetsManifestInputs" + Condition="'$(ServiceWorkerAssetsManifest)' != ''" + DependsOnTargets="PrepareBlazorOutputs"> + + <PropertyGroup> + <_ServiceWorkerAssetsManifestIntermediateOutputPath>$(BlazorIntermediateOutputPath)serviceworkerassets.js</_ServiceWorkerAssetsManifestIntermediateOutputPath> + </PropertyGroup> + + <ItemGroup> + <!-- Include _framework/* content --> + <ServiceWorkerAssetsManifestItem + Include="@(BlazorOutputWithTargetPath)" + Condition="$([System.String]::Copy('%(BlazorOutputWithTargetPath.TargetOutputPath)').Replace('\','/').StartsWith('dist/'))"> + <AssetUrl>$([System.String]::Copy('%(BlazorOutputWithTargetPath.TargetOutputPath)').Replace('\','/').Substring(5))</AssetUrl> + </ServiceWorkerAssetsManifestItem> + + <!-- Include content from wwwroot --> + <ServiceWorkerAssetsManifestItem + Include="@(ContentWithTargetPath)" + Condition=" + ('%(ContentWithTargetPath.CopyToPublishDirectory)' == 'Always' OR '%(ContentWithTargetPath.CopyToPublishDirectory)' == 'PreserveNewest') + AND $([System.String]::Copy('%(ContentWithTargetPath.TargetPath)').Replace('\','/').StartsWith('wwwroot/'))"> + <AssetUrl>$([System.String]::Copy('%(ContentWithTargetPath.TargetPath)').Replace('\','/').Substring(8))</AssetUrl> + </ServiceWorkerAssetsManifestItem> + + <!-- Include SWA from references --> + <ServiceWorkerAssetsManifestItem + Include="@(StaticWebAsset)" + Condition="'%(StaticWebAsset.SourceType)' != ''"> + <AssetUrl>%(StaticWebAsset.BasePath)/%(StaticWebAsset.RelativePath)</AssetUrl> + </ServiceWorkerAssetsManifestItem> + </ItemGroup> + + </Target> + + <UsingTask TaskName="GenerateServiceWorkerAssetsManifest" AssemblyFile="$(BlazorTasksPath)" /> + + <Target Name="_WriteServiceWorkerAssetsManifest" + Inputs="@(ServiceWorkerAssetsManifestItem)" + Outputs="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" + DependsOnTargets="_ComputeServiceWorkerAssetsManifestFileHashes; _ComputeDefaultServiceWorkerAssetsManifestVersion"> + + <GenerateServiceWorkerAssetsManifest + Version="$(ServiceWorkerAssetsManifestVersion)" + AssetsWithHashes="@(_ServiceWorkerAssetsManifestItemWithHash)" + OutputPath="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" /> + + <ItemGroup> + <BlazorOutputWithTargetPath + Include="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" + TargetOutputPath="$(BaseBlazorDistPath)$(ServiceWorkerAssetsManifest)" /> + + <FileWrites Include="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" /> + </ItemGroup> + + </Target> + + <Target Name="_ComputeServiceWorkerAssetsManifestFileHashes"> + <GetFileHash Files="@(ServiceWorkerAssetsManifestItem)" Algorithm="SHA256" HashEncoding="base64"> + <Output TaskParameter="Items" ItemName="_ServiceWorkerAssetsManifestItemWithHash" /> + </GetFileHash> + </Target> + + <!-- + If no ServiceWorkerAssetsManifestVersion was specified, we compute a default value by combining all the asset hashes. + This is useful because then clients will only have to repopulate caches if the contents have changed. + --> + <Target Name="_ComputeDefaultServiceWorkerAssetsManifestVersion" + Condition="'$(ServiceWorkerAssetsManifestVersion)' == ''"> + <PropertyGroup> + <_CombinedHashIntermediatePath>$(BlazorIntermediateOutputPath)serviceworkerhashes.txt</_CombinedHashIntermediatePath> + </PropertyGroup> + + <WriteLinesToFile + File="$(_CombinedHashIntermediatePath)" + Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(FileHash)')" + Overwrite="true" /> + + <GetFileHash Files="$(_CombinedHashIntermediatePath)" Algorithm="SHA256" HashEncoding="base64"> + <Output TaskParameter="Items" ItemName="_ServiceWorkerAssetsManifestCombinedHash" /> + </GetFileHash> + + <PropertyGroup> + <ServiceWorkerAssetsManifestVersion>$([System.String]::Copy('%(_ServiceWorkerAssetsManifestCombinedHash.FileHash)').Substring(0, 8))</ServiceWorkerAssetsManifestVersion> + </PropertyGroup> + </Target> + +</Project> diff --git a/src/Components/startvs.cmd b/src/Components/startvs.cmd index 1eb52561227a9e9103115a1fa11b9791a47c34b3..962cc73686e3152c15c9e2ed8f837d0665f62a5b 100644 --- a/src/Components/startvs.cmd +++ b/src/Components/startvs.cmd @@ -1,3 +1,3 @@ @ECHO OFF -%~dp0..\..\startvs.cmd %~dp0Components.sln +%~dp0..\..\startvs.cmd %~dp0Blazor.sln diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Client.csproj.in b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Client.csproj.in index 70927b08e331758b3feaaf68cea816fd3023bddd..d1a3d37097a0c64765d7270e856faeca9db0af68 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Client.csproj.in +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/BlazorWasm-CSharp.Client.csproj.in @@ -3,6 +3,7 @@ <PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> <RazorLangVersion>3.0</RazorLangVersion> + <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> </PropertyGroup> <ItemGroup> @@ -11,10 +12,22 @@ <PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="${MicrosoftAspNetCoreBlazorDevServerPackageVersion}" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="${MicrosoftAspNetCoreBlazorHttpClientPackageVersion}" /> </ItemGroup> + <!--#if Hosted --> <ItemGroup> <ProjectReference Include="..\Shared\BlazorWasm-CSharp.Shared.csproj" /> </ItemGroup> + <!--#endif --> + <!--#if PWA --> + <ItemGroup> + <!-- When publishing, swap service-worker.published.js in place of service-worker.js --> + <Content Update="wwwroot\service-worker*.js" CopyToPublishDirectory="false" /> + <ContentWithTargetPath Include="wwwroot\service-worker.published.js"> + <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> + <TargetPath>wwwroot\service-worker.js</TargetPath> + </ContentWithTargetPath> + </ItemGroup> + <!--#endif --> </Project> diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/dotnetcli.host.json index 4e89e1d2dca8c123c267df4fa69cac184f00b0a8..be1ce91d6613f67856d7043dcef7e32df9e9c126 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/dotnetcli.host.json +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/dotnetcli.host.json @@ -5,9 +5,12 @@ "longName": "no-restore", "shortName": "" }, - "Hosted": { - "longName": "hosted" - }, + "Hosted": { + "longName": "hosted" + }, + "PWA": { + "longName": "pwa" + }, "Framework": { "longName": "framework" } diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json index 1c18d08504aef31d3dd0e97a0e4e18062cd10cab..73de9b1a06d136fa35789d58a1eac5e61ed1f26c 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json @@ -74,6 +74,14 @@ "exclude": [ "*.sln" ] + }, + { + "condition": "(!PWA)", + "exclude": [ + "Client/wwwroot/service-worker*.js", + "Client/wwwroot/manifest.json", + "Client/wwwroot/icon-512.png" + ] } ] } @@ -147,6 +155,12 @@ "fallbackVariableName": "HttpsPortGenerated" }, "replaces": "44300" + }, + "PWA": { + "type": "parameter", + "datatype": "bool", + "defaultValue": "false", + "description": "If specified, produces a Progressive Web Application (PWA) supporting installation and offline use." } }, "tags": { diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json index 5cb50d10a519f7fa886acab48452f5d78295dd2c..b87413a03ff6311121383ccd40fd7194bfd547e7 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json @@ -25,6 +25,13 @@ "text": "ASP.NET Core _hosted" }, "isVisible": "true" + }, + { + "id": "PWA", + "name": { + "text": "_Progressive Web Application" + }, + "isVisible": "true" } ] } diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/icon-512.png b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..370c2082b633c88ad9b4a0ee617933ab847bdaab Binary files /dev/null and b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/icon-512.png differ diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html index 7c402d8073716addf06f6d17e1376ad5caab73f9..124cae83165f07fb24dfdc4c060fa976062fb40a 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html @@ -8,6 +8,9 @@ <base href="/" /> <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="css/site.css" rel="stylesheet" /> + <!--#if PWA --> + <link href="manifest.json" rel="manifest" /> + <!--#endif --> </head> <body> @@ -19,6 +22,9 @@ <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.webassembly.js"></script> + <!--#if PWA --> + <script>navigator.serviceWorker.register('service-worker.js');</script> + <!--#endif --> </body> </html> diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/manifest.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..d986d96b028f00edaa8eb7ea21344faafb3bb9b2 --- /dev/null +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "BlazorWasm-CSharp", + "short_name": "BlazorWasm-CSharp", + "start_url": "/", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#03173d", + "icons": [ + { + "src": "icon-512.png", + "type": "image/png", + "sizes": "512x512" + } + ] +} diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.js b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.js new file mode 100644 index 0000000000000000000000000000000000000000..fe614daee090c3308424ce6733afdeb094840740 --- /dev/null +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.js @@ -0,0 +1,4 @@ +// In development, always fetch from the network and do not enable offline support. +// This is because caching would make development more difficult (changes would not +// be reflected on the first load after each change). +self.addEventListener('fetch', () => { }); diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.published.js b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.published.js new file mode 100644 index 0000000000000000000000000000000000000000..220bba532eabc5c9e1e2c0bee724548c886e60da --- /dev/null +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/service-worker.published.js @@ -0,0 +1,48 @@ +// Caution! Be sure you understand the caveats before publishing an application with +// offline support. See https://aka.ms/blazor-offline-considerations + +self.importScripts('./service-worker-assets.js'); +self.addEventListener('install', event => event.waitUntil(onInstall(event))); +self.addEventListener('activate', event => event.waitUntil(onActivate(event))); +self.addEventListener('fetch', event => event.respondWith(onFetch(event))); + +const cacheNamePrefix = 'offline-cache-'; +const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; +const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/ ]; +const offlineAssetsExclude = [ /^service-worker\.js$/ ]; + +async function onInstall(event) { + console.info('Service worker: Install'); + + // Fetch and cache all matching items from the assets manifest + const assetsRequests = self.assetsManifest.assets + .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) + .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) + .map(asset => new Request(asset.url, { integrity: asset.hash })); + await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); +} + +async function onActivate(event) { + console.info('Service worker: Activate'); + + // Delete unused caches + const cacheKeys = await caches.keys(); + await Promise.all(cacheKeys + .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) + .map(key => caches.delete(key))); +} + +async function onFetch(event) { + let cachedResponse = null; + if (event.request.method === 'GET') { + // For all navigation requests, try to serve index.html from cache + // If you need some URLs to be server-rendered, edit the following check to exclude those URLs + const shouldServeIndexHtml = event.request.mode === 'navigate'; + + const request = shouldServeIndexHtml ? 'index.html' : event.request; + const cache = await caches.open(cacheName); + cachedResponse = await cache.match(request); + } + + return cachedResponse || fetch(event.request); +} diff --git a/src/ProjectTemplates/test/BaselineTest.cs b/src/ProjectTemplates/test/BaselineTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..3da015f69185251a6d6c0dc39bbf339a7748a307 --- /dev/null +++ b/src/ProjectTemplates/test/BaselineTest.cs @@ -0,0 +1,150 @@ +// 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.Text.RegularExpressions; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class BaselineTest + { + private static readonly Regex TemplateNameRegex = new Regex( + "new (?<template>[a-zA-Z]+)", + RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline, + TimeSpan.FromSeconds(1)); + + private static readonly Regex AuthenticationOptionRegex = new Regex( + "-au (?<auth>[a-zA-Z]+)", + RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline, + TimeSpan.FromSeconds(1)); + + private static readonly Regex LanguageRegex = new Regex( + "--language (?<language>\\w+)", + RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline, + TimeSpan.FromSeconds(1)); + + public BaselineTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public static TheoryData<string, string[]> TemplateBaselines + { + get + { + using (var stream = typeof(BaselineTest).Assembly.GetManifestResourceStream("ProjectTemplates.Tests.template-baselines.json")) + { + using (var jsonReader = new JsonTextReader(new StreamReader(stream))) + { + var baseline = JObject.Load(jsonReader); + var data = new TheoryData<string, string[]>(); + foreach (var template in baseline) + { + foreach (var authOption in (JObject)template.Value) + { + data.Add( + (string)authOption.Value["Arguments"], + ((JArray)authOption.Value["Files"]).Select(s => (string)s).ToArray()); + } + } + + return data; + } + } + } + } + + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Theory] + [MemberData(nameof(TemplateBaselines))] + public async Task Template_Produces_The_Right_Set_Of_FilesAsync(string arguments, string[] expectedFiles) + { + Project = await ProjectFactory.GetOrCreateProject("baseline" + SanitizeArgs(arguments), Output); + var createResult = await Project.RunDotNetNewRawAsync(arguments); + Assert.True(createResult.ExitCode == 0, createResult.GetFormattedOutput()); + + foreach (var file in expectedFiles) + { + AssertFileExists(Project.TemplateOutputDir, file, shouldExist: true); + } + + var filesInFolder = Directory.EnumerateFiles(Project.TemplateOutputDir, "*", SearchOption.AllDirectories); + foreach (var file in filesInFolder) + { + var relativePath = file.Replace(Project.TemplateOutputDir, "").Replace("\\", "/").Trim('/'); + if (relativePath.EndsWith(".csproj", StringComparison.Ordinal) || + relativePath.EndsWith(".fsproj", StringComparison.Ordinal) || + relativePath.EndsWith(".props", StringComparison.Ordinal) || + relativePath.EndsWith(".sln", StringComparison.Ordinal) || + relativePath.EndsWith(".targets", StringComparison.Ordinal) || + relativePath.StartsWith("bin/", StringComparison.Ordinal) || + relativePath.StartsWith("obj/", StringComparison.Ordinal) || + relativePath.Contains("/bin/", StringComparison.Ordinal) || + relativePath.Contains("/obj/", StringComparison.Ordinal)) + { + continue; + } + Assert.Contains(relativePath, expectedFiles); + } + } + + private string SanitizeArgs(string arguments) + { + var text = TemplateNameRegex.Match(arguments) + .Groups.TryGetValue("template", out var template) ? template.Value : ""; + + text += AuthenticationOptionRegex.Match(arguments) + .Groups.TryGetValue("auth", out var auth) ? auth.Value : ""; + + text += arguments.Contains("--uld") ? "uld" : ""; + + text += LanguageRegex.Match(arguments) + .Groups.TryGetValue("language", out var language) ? language.Value.Replace("#", "Sharp") : ""; + + if (arguments.Contains("--support-pages-and-views true")) + { + text += "supportpagesandviewstrue"; + } + + if (arguments.Contains("-ho")) + { + text += "hosted"; + } + + if (arguments.Contains("--pwa")) + { + text += "pwa"; + } + + return text; + } + + 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); + } + } + } +} \ No newline at end of file diff --git a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs index 41cb82ac21ec2a38987876bf8392f37d887d344d..0ac806a6858ffe82844821c80b9c6ffb0b6eff55 100644 --- a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs +++ b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs @@ -1,6 +1,7 @@ // 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.Net; using System.Threading; @@ -24,6 +25,11 @@ namespace Templates.Test public ProjectFactoryFixture ProjectFactory { get; set; } + public override Task InitializeAsync() + { + return InitializeAsync(isolationContext: Guid.NewGuid().ToString()); + } + [Fact] public async Task BlazorWasmStandaloneTemplate_Works() { @@ -90,6 +96,51 @@ namespace Templates.Test } } + [Fact] + public async Task BlazorWasmPwaTemplate_Works() + { + var project = await ProjectFactory.GetOrCreateProject("blazorpwa", Output); + project.TargetFramework = "netstandard2.1"; + + var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--pwa" }); + 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)); + + await BuildAndRunTest(project.ProjectName, project); + + var publishDir = Path.Combine(project.TemplatePublishDir, project.ProjectName, "dist"); + AspNetProcess.EnsureDevelopmentCertificates(); + + // When publishing the PWA template, we generate an assets manifest + // and move service-worker.published.js to overwrite service-worker.js + Assert.False(File.Exists(Path.Combine(publishDir, "service-worker.published.js")), "service-worker.published.js should not be published"); + Assert.True(File.Exists(Path.Combine(publishDir, "service-worker.js")), "service-worker.js should be published"); + Assert.True(File.Exists(Path.Combine(publishDir, "service-worker-assets.js")), "service-worker-assets.js should be published"); + + // Todo: Use dynamic port assignment: https://github.com/natemcmaster/dotnet-serve/pull/40/files + var listeningUri = "https://localhost:8080"; + + Output.WriteLine("Running dotnet serve on published output..."); + using (var serveProcess = ProcessEx.Run(Output, publishDir, DotNetMuxer.MuxerPathOrDefault(), "serve -S")) + { + Output.WriteLine($"Opening browser at {listeningUri}..."); + Browser.Navigate().GoToUrl(listeningUri); + TestBasicNavigation(project.ProjectName); + } + + // The PWA template supports offline use. By now, the browser should have cached everything it needs, + // so we can continue working even without the server. + Browser.Navigate().GoToUrl("about:blank"); // Be sure we're really reloading + Output.WriteLine($"Opening browser without corresponding server at {listeningUri}..."); + Browser.Navigate().GoToUrl(listeningUri); + TestBasicNavigation(project.ProjectName); + } + protected async Task BuildAndRunTest(string appName, Project project) { using var aspNetProcess = project.StartBuiltProjectAsync(); diff --git a/src/ProjectTemplates/test/template-baselines.json b/src/ProjectTemplates/test/template-baselines.json index d934d8b54567007003393d8f33635d41568f19cb..aac6a24eec70383101853a0fab1f43bfa9736c36 100644 --- a/src/ProjectTemplates/test/template-baselines.json +++ b/src/ProjectTemplates/test/template-baselines.json @@ -1,1273 +1,101 @@ { - "razor": { - "Individual": { - "Template": "razor", - "Arguments": "new razor -au Individual", - "Files": [ - "app.db", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Areas/Identity/Pages/_ViewStart.cshtml", - "Data/ApplicationDbContext.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs", - "Data/Migrations/ApplicationDbContextModelSnapshot.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_LoginPartial.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "Individual" - }, - "Windows": { - "Template": "razor", - "Arguments": "new razor -au Windows", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "Windows" - }, - "SingleOrg": { - "Template": "razor", - "Arguments": "new razor -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_LoginPartial.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "SingleOrg" - }, - "IndividualB2C": { - "Template": "razor", - "Arguments": "new razor -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn -rp B2C_1_SSPR -ep B2C_1_SiPe", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_LoginPartial.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "IndividualB2C" - }, + "blazorwasm": { "None": { - "Template": "razor", - "Arguments": "new razor -au None", + "Template": "blazorwasm", + "Arguments": "new blazorwasm", "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "None" - }, - "MultiOrg": { - "Template": "razor", - "Arguments": "new razor -au MultiOrg --aad-instance https://login.microsoftonline.com/ --client-id bac81cbb-9fab-4a4e-9521-be07290c3a51", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Pages/Index.cshtml", - "Pages/Index.cshtml.cs", - "Pages/Privacy.cshtml", - "Pages/Privacy.cshtml.cs", - "Pages/_ViewImports.cshtml", - "Pages/_ViewStart.cshtml", - "Pages/Shared/_Layout.cshtml", - "Pages/Shared/_LoginPartial.cshtml", - "Pages/Shared/_ValidationScriptsPartial.cshtml", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "MultiOrg" - } - }, - "web": { - "CSharp": { - "Template": "web", - "Arguments": "new web", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Properties/launchSettings.json" - ], - "AuthOption": "None" - }, - "FSharp": { - "Template": "web", - "Arguments": "new web --language F#", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.fs", - "Startup.fs", - "Properties/launchSettings.json" - ], - "AuthOption": "None" - } - }, - "webapi": { - "IndividualB2C": { - "Template": "webapi", - "Arguments": "new webapi -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Properties/launchSettings.json" - ], - "AuthOption": "IndividualB2C" - }, - "SingleOrg": { - "Template": "webapi", - "Arguments": "new webapi -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Properties/launchSettings.json" - ], - "AuthOption": "SingleOrg" - }, - "None": { - "Template": "webapi", - "Arguments": "new webapi -au None", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Properties/launchSettings.json" - ], - "AuthOption": "None" - }, - "Windows": { - "Template": "webapi", - "Arguments": "new webapi -au Windows", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Properties/launchSettings.json" - ], - "AuthOption": "Windows" - }, - "FSharp": { - "Template": "webapi", - "Arguments": "new webapi --language F#", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.fs", - "Startup.fs", - "WeatherForecast.fs", - "Controllers/WeatherForecastController.fs", - "Properties/launchSettings.json" - ] - } - }, - "mvc": { - "Individual": { - "Template": "mvc", - "Arguments": "new mvc -au Individual", - "Files": [ - "app.db", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Areas/Identity/Pages/_ViewStart.cshtml", - "Controllers/HomeController.cs", - "Data/ApplicationDbContext.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs", - "Data/Migrations/ApplicationDbContextModelSnapshot.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_LoginPartial.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "Individual" - }, - "Windows": { - "Template": "mvc", - "Arguments": "new mvc -au Windows", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Controllers/HomeController.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "Windows" - }, - "SingleOrg": { - "Template": "mvc", - "Arguments": "new mvc -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Controllers/HomeController.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_LoginPartial.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "SingleOrg" - }, - "IndividualB2C": { - "Template": "mvc", - "Arguments": "new mvc -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn -rp B2C_1_SSPR -ep B2C_1_SiPe", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Controllers/HomeController.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_LoginPartial.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "IndividualB2C" - }, - "None": { - "Template": "mvc", - "Arguments": "new mvc -au None", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Controllers/HomeController.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "None" - }, - "MultiOrg": { - "Template": "mvc", - "Arguments": "new mvc -au MultiOrg --aad-instance https://login.microsoftonline.com/ --client-id bac81cbb-9fab-4a4e-9521-be07290c3a51", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "Controllers/HomeController.cs", - "Models/ErrorViewModel.cs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_LoginPartial.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ], - "AuthOption": "MultiOrg" - }, - "FSharp": { - "Template": "mvc", - "Arguments": "new mvc --language F#", - "Files": [ - "appsettings.Development.json", - "appsettings.json", - "Program.fs", - "Startup.fs", - "Controllers/HomeController.fs", - "Models/ErrorViewModel.fs", - "Properties/launchSettings.json", - "Views/_ViewImports.cshtml", - "Views/_ViewStart.cshtml", - "Views/Home/Index.cshtml", - "Views/Home/Privacy.cshtml", - "Views/Shared/Error.cshtml", - "Views/Shared/_Layout.cshtml", - "Views/Shared/_ValidationScriptsPartial.cshtml", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/js/site.js", - "wwwroot/lib/bootstrap/LICENSE", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css", - "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js", - "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", - "wwwroot/lib/jquery/LICENSE.txt", - "wwwroot/lib/jquery/dist/jquery.js", - "wwwroot/lib/jquery/dist/jquery.min.js", - "wwwroot/lib/jquery/dist/jquery.min.map", - "wwwroot/lib/jquery-validation/LICENSE.md", - "wwwroot/lib/jquery-validation/dist/additional-methods.js", - "wwwroot/lib/jquery-validation/dist/additional-methods.min.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.js", - "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js", - "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", - "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" - ] - } - }, - "razorclasslib": { - "ComponentsOnly": { - "Template": "razorclasslib", - "Arguments": "new razorclasslib", - "Files": [ - "wwwroot/background.png", - "wwwroot/exampleJsInterop.js", - "wwwroot/styles.css", - "_Imports.razor", - "Component1.razor", - "ExampleJsInterop.cs" - ] - }, - "ViewsOnly": { - "Template": "razorclasslib", - "Arguments": "new razorclasslib --support-pages-and-views true", - "Files": [ - "Areas/MyFeature/Pages/Page1.cshtml", - "Areas/MyFeature/Pages/Page1.cshtml.cs" - ] - } - }, - "blazorserver": { - "Individual": { - "Template": "blazorserver", - "Arguments": "new blazorserver -au Individual", - "Files": [ - "app.db", "App.razor", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "_Imports.razor", - "Areas/Identity/Pages/Account/LogOut.cshtml", - "Areas/Identity/Pages/Shared/_LoginPartial.cshtml", - "Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs", - "Data/ApplicationDbContext.cs", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.cs", - "Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs", - "Data/Migrations/ApplicationDbContextModelSnapshot.cs", "Pages/Counter.razor", - "Pages/Error.razor", "Pages/FetchData.razor", "Pages/Index.razor", - "Pages/_Host.cshtml", - "Properties/launchSettings.json", - "Shared/LoginDisplay.razor", - "Shared/MainLayout.razor", - "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/css/bootstrap/bootstrap.min.css", - "wwwroot/css/bootstrap/bootstrap.min.css.map", - "wwwroot/css/open-iconic/FONT-LICENSE", - "wwwroot/css/open-iconic/ICON-LICENSE", - "wwwroot/css/open-iconic/README.md", - "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", - "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", - "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", - "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" - ] - }, - "IndividualB2C": { - "Template": "blazorserver", - "Arguments": "new blazorserver -au IndividualB2C", - "Files": [ - "App.razor", - "appsettings.Development.json", - "appsettings.json", "Program.cs", - "Startup.cs", - "_Imports.razor", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", - "Pages/Counter.razor", - "Pages/Error.razor", - "Pages/FetchData.razor", - "Pages/Index.razor", - "Pages/_Host.cshtml", "Properties/launchSettings.json", - "Shared/LoginDisplay.razor", "Shared/MainLayout.razor", "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", + "Shared/SurveyPrompt.razor", "wwwroot/css/bootstrap/bootstrap.min.css", "wwwroot/css/bootstrap/bootstrap.min.css.map", - "wwwroot/css/open-iconic/FONT-LICENSE", - "wwwroot/css/open-iconic/ICON-LICENSE", - "wwwroot/css/open-iconic/README.md", "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" - ] - }, - "MultiOrg": { - "Template": "blazorserver", - "Arguments": "new blazorserver -au MultiOrg", - "Files": [ - "App.razor", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "_Imports.razor", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", - "Pages/Counter.razor", - "Pages/Error.razor", - "Pages/FetchData.razor", - "Pages/Index.razor", - "Pages/_Host.cshtml", - "Properties/launchSettings.json", - "Shared/LoginDisplay.razor", - "Shared/MainLayout.razor", - "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/css/bootstrap/bootstrap.min.css", - "wwwroot/css/bootstrap/bootstrap.min.css.map", + "wwwroot/css/open-iconic/font/fonts/open-iconic.woff", "wwwroot/css/open-iconic/FONT-LICENSE", "wwwroot/css/open-iconic/ICON-LICENSE", "wwwroot/css/open-iconic/README.md", - "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", - "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", - "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", - "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" + "wwwroot/css/site.css", + "wwwroot/index.html", + "wwwroot/sample-data/weather.json", + "_Imports.razor" ] }, - "None": { - "Template": "blazorserver", - "Arguments": "new blazorserver", - "Files": [ - "App.razor", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "_Imports.razor", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", - "Pages/Error.razor", - "Pages/Counter.razor", - "Pages/FetchData.razor", - "Pages/Index.razor", - "Pages/_Host.cshtml", - "Properties/launchSettings.json", - "Shared/MainLayout.razor", - "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/css/bootstrap/bootstrap.min.css", - "wwwroot/css/bootstrap/bootstrap.min.css.map", - "wwwroot/css/open-iconic/FONT-LICENSE", - "wwwroot/css/open-iconic/ICON-LICENSE", - "wwwroot/css/open-iconic/README.md", - "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", - "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", - "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", - "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" + "Hosted": { + "Template": "blazorwasm", + "Arguments": "new blazorwasm -ho", + "Files": [ + "Client/App.razor", + "Client/Pages/Counter.razor", + "Client/Pages/FetchData.razor", + "Client/Pages/Index.razor", + "Client/Program.cs", + "Client/Properties/launchSettings.json", + "Client/Shared/MainLayout.razor", + "Client/Shared/NavMenu.razor", + "Client/Shared/SurveyPrompt.razor", + "Client/wwwroot/css/bootstrap/bootstrap.min.css", + "Client/wwwroot/css/bootstrap/bootstrap.min.css.map", + "Client/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", + "Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot", + "Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf", + "Client/wwwroot/css/open-iconic/font/fonts/open-iconic.svg", + "Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", + "Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff", + "Client/wwwroot/css/open-iconic/FONT-LICENSE", + "Client/wwwroot/css/open-iconic/ICON-LICENSE", + "Client/wwwroot/css/open-iconic/README.md", + "Client/wwwroot/css/site.css", + "Client/wwwroot/index.html", + "Client/_Imports.razor", + "Server/Controllers/WeatherForecastController.cs", + "Server/Program.cs", + "Server/Properties/launchSettings.json", + "Server/Startup.cs", + "Shared/WeatherForecast.cs" ] }, - "SingleOrg": { - "Template": "blazorserver", - "Arguments": "new blazorserver -au SingleOrg", + "PWA": { + "Template": "blazorwasm", + "Arguments": "new blazorwasm --pwa", "Files": [ "App.razor", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "_Imports.razor", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", "Pages/Counter.razor", - "Pages/Error.razor", "Pages/FetchData.razor", "Pages/Index.razor", - "Pages/_Host.cshtml", + "Program.cs", "Properties/launchSettings.json", - "Shared/LoginDisplay.razor", "Shared/MainLayout.razor", "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", + "Shared/SurveyPrompt.razor", "wwwroot/css/bootstrap/bootstrap.min.css", "wwwroot/css/bootstrap/bootstrap.min.css.map", - "wwwroot/css/open-iconic/FONT-LICENSE", - "wwwroot/css/open-iconic/ICON-LICENSE", - "wwwroot/css/open-iconic/README.md", "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" - ] - }, - "Windows": { - "Template": "blazorserver", - "Arguments": "new blazorserver -au Windows", - "Files": [ - "App.razor", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs", - "_Imports.razor", - "Data/WeatherForecast.cs", - "Data/WeatherForecastService.cs", - "Pages/Counter.razor", - "Pages/Error.razor", - "Pages/FetchData.razor", - "Pages/Index.razor", - "Pages/_Host.cshtml", - "Properties/launchSettings.json", - "Shared/LoginDisplay.razor", - "Shared/MainLayout.razor", - "Shared/NavMenu.razor", - "wwwroot/favicon.ico", - "wwwroot/css/site.css", - "wwwroot/css/bootstrap/bootstrap.min.css", - "wwwroot/css/bootstrap/bootstrap.min.css.map", + "wwwroot/css/open-iconic/font/fonts/open-iconic.woff", "wwwroot/css/open-iconic/FONT-LICENSE", "wwwroot/css/open-iconic/ICON-LICENSE", "wwwroot/css/open-iconic/README.md", - "wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css", - "wwwroot/css/open-iconic/font/fonts/open-iconic.eot", - "wwwroot/css/open-iconic/font/fonts/open-iconic.otf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.svg", - "wwwroot/css/open-iconic/font/fonts/open-iconic.ttf", - "wwwroot/css/open-iconic/font/fonts/open-iconic.woff" - ] - } - }, - "worker": { - "None": { - "Template": "worker", - "Arguments": "new worker", - "Files": [ - "Properties/launchSettings.json", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Worker.cs" - ] - } - }, - "angular": { - "None": { - "Template": "angular", - "Arguments": "new angular", - "Files": [ - "ClientApp/e2e/src/app.e2e-spec.ts", - "ClientApp/e2e/src/app.po.ts", - "ClientApp/e2e/protractor.conf.js", - "ClientApp/e2e/tsconfig.e2e.json", - "ClientApp/src/app/counter/counter.component.html", - "ClientApp/src/app/counter/counter.component.spec.ts", - "ClientApp/src/app/counter/counter.component.ts", - "ClientApp/src/app/fetch-data/fetch-data.component.html", - "ClientApp/src/app/fetch-data/fetch-data.component.ts", - "ClientApp/src/app/home/home.component.html", - "ClientApp/src/app/home/home.component.ts", - "ClientApp/src/app/nav-menu/nav-menu.component.css", - "ClientApp/src/app/nav-menu/nav-menu.component.html", - "ClientApp/src/app/nav-menu/nav-menu.component.ts", - "ClientApp/src/app/app.component.html", - "ClientApp/src/app/app.component.ts", - "ClientApp/src/app/app.module.ts", - "ClientApp/src/app/app.server.module.ts", - "ClientApp/src/assets/.gitkeep", - "ClientApp/src/environments/environment.prod.ts", - "ClientApp/src/environments/environment.ts", - "ClientApp/browserslist", - "ClientApp/src/index.html", - "ClientApp/src/karma.conf.js", - "ClientApp/src/main.ts", - "ClientApp/src/polyfills.ts", - "ClientApp/src/styles.css", - "ClientApp/src/test.ts", - "ClientApp/src/tsconfig.app.json", - "ClientApp/src/tsconfig.server.json", - "ClientApp/src/tsconfig.spec.json", - "ClientApp/src/tslint.json", - "ClientApp/.editorconfig", - "ClientApp/.gitignore", - "ClientApp/angular.json", - "ClientApp/package-lock.json", - "ClientApp/package.json", - "ClientApp/README.md", - "ClientApp/tsconfig.json", - "ClientApp/tslint.json", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Pages/_ViewImports.cshtml", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Properties/launchSettings.json", - "wwwroot/favicon.ico", - ".gitignore", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs" - ] - } - }, - "react": { - "None": { - "Template": "react", - "Arguments": "new react", - "Files": [ - "ClientApp/public/favicon.ico", - "ClientApp/public/index.html", - "ClientApp/public/manifest.json", - "ClientApp/src/components/Counter.js", - "ClientApp/src/components/FetchData.js", - "ClientApp/src/components/Home.js", - "ClientApp/src/components/Layout.js", - "ClientApp/src/components/NavMenu.css", - "ClientApp/src/components/NavMenu.js", - "ClientApp/src/custom.css", - "ClientApp/src/App.js", - "ClientApp/src/App.test.js", - "ClientApp/src/index.js", - "ClientApp/src/registerServiceWorker.js", - "ClientApp/.gitignore", - "ClientApp/package-lock.json", - "ClientApp/package.json", - "ClientApp/README.md", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Pages/_ViewImports.cshtml", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Properties/launchSettings.json", - ".gitignore", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs" - ] - } - }, - "reactredux": { - "None": { - "Template": "reactredux", - "Arguments": "new reactredux", - "Files": [ - "ClientApp/public/favicon.ico", - "ClientApp/public/index.html", - "ClientApp/public/manifest.json", - "ClientApp/src/components/Counter.tsx", - "ClientApp/src/components/FetchData.tsx", - "ClientApp/src/components/Home.tsx", - "ClientApp/src/components/Layout.tsx", - "ClientApp/src/components/NavMenu.css", - "ClientApp/src/components/NavMenu.tsx", - "ClientApp/src/store/configureStore.ts", - "ClientApp/src/store/Counter.ts", - "ClientApp/src/store/index.ts", - "ClientApp/src/store/WeatherForecasts.ts", - "ClientApp/src/App.tsx", - "ClientApp/src/App.test.tsx", - "ClientApp/src/custom.css", - "ClientApp/src/index.tsx", - "ClientApp/src/react-app-env.d.ts", - "ClientApp/src/registerServiceWorker.ts", - "ClientApp/.eslintrc.json", - "ClientApp/.gitignore", - "ClientApp/package-lock.json", - "ClientApp/package.json", - "ClientApp/README.md", - "ClientApp/tsconfig.json", - "WeatherForecast.cs", - "Controllers/WeatherForecastController.cs", - "Pages/_ViewImports.cshtml", - "Pages/Error.cshtml", - "Pages/Error.cshtml.cs", - "Properties/launchSettings.json", - ".gitignore", - "appsettings.Development.json", - "appsettings.json", - "Program.cs", - "Startup.cs" + "wwwroot/css/site.css", + "wwwroot/icon-512.png", + "wwwroot/index.html", + "wwwroot/manifest.json", + "wwwroot/sample-data/weather.json", + "wwwroot/service-worker.js", + "wwwroot/service-worker.published.js", + "_Imports.razor" ] } } diff --git a/src/Shared/E2ETesting/BrowserFixture.cs b/src/Shared/E2ETesting/BrowserFixture.cs index bf8b31d29426246cba07b46833ef108c44b2f266..a00c1410978b59cc549dc24fbdff095a36616d2e 100644 --- a/src/Shared/E2ETesting/BrowserFixture.cs +++ b/src/Shared/E2ETesting/BrowserFixture.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Concurrent; using System.Diagnostics; +using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -68,6 +69,15 @@ namespace Microsoft.AspNetCore.E2ETesting { browser.Dispose(); } + + foreach (var context in _browsers.Keys) + { + var userProfileDirectory = UserProfileDirectory(context); + if (!string.IsNullOrEmpty(userProfileDirectory) && Directory.Exists(userProfileDirectory)) + { + Directory.Delete(userProfileDirectory, recursive: true); + } + } } public Task<(IWebDriver, ILogs)> GetOrCreateBrowserAsync(ITestOutputHelper output, string isolationContext = "") @@ -116,6 +126,13 @@ namespace Microsoft.AspNetCore.E2ETesting output.WriteLine($"Set {nameof(ChromeOptions)}.{nameof(opts.BinaryLocation)} to {binaryLocation}"); } + var userProfileDirectory = UserProfileDirectory(context); + if (!string.IsNullOrEmpty(userProfileDirectory)) + { + Directory.CreateDirectory(userProfileDirectory); + opts.AddArgument($"--user-data-dir={userProfileDirectory}"); + } + var instance = await SeleniumStandaloneServer.GetInstanceAsync(output); var attempt = 0; @@ -155,6 +172,16 @@ namespace Microsoft.AspNetCore.E2ETesting throw new InvalidOperationException("Couldn't create a Selenium remote driver client. The server is irresponsive"); } + private string UserProfileDirectory(string context) + { + if (string.IsNullOrEmpty(context)) + { + return null; + } + + return Path.Combine(Path.GetTempPath(), "BrowserFixtureUserProfiles", context); + } + private async Task<(IWebDriver browser, ILogs log)> CreateSauceBrowserAsync(string context, ITestOutputHelper output) { var sauce = E2ETestOptions.Instance.Sauce;