Split template tests into parallel jobs (#24080)

This commit is contained in:
Matthew Leibowitz 2024-08-08 16:50:39 +08:00 коммит произвёл GitHub
Родитель d5881c0d82
Коммит 9729b02c1a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
22 изменённых файлов: 981 добавлений и 860 удалений

Просмотреть файл

@ -45,6 +45,7 @@ Information("Android SDK Root: {0}", androidSdkRoot);
Information("Project File: {0}", projectPath);
Information("Build Binary Log (binlog): {0}", binlogDirectory);
Information("Build Configuration: {0}", configuration);
Information("Build Target Framework: {0}", targetFramework);
var avdSettings = new AndroidAvdManagerToolSettings { SdkRoot = androidSdkRoot };
var adbSettings = new AdbToolSettings { SdkRoot = androidSdkRoot };

Просмотреть файл

@ -1,6 +1,6 @@
//This assumes that this is always running from a mac with global workloads
const string DotnetToolPathDefault = "/usr/local/share/dotnet/dotnet";
const string DotnetVersion = "net9.0";
string DotnetVersion = Argument("targetFrameworkVersion", EnvironmentVariable("TARGET_FRAMEWORK_VERSION") ?? "net9.0");
const string TestFramework = "net472";
// Map project types to specific subdirectories under artifacts

Просмотреть файл

@ -6,7 +6,6 @@ using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
const string defaultVersion = "10.0.19041";
const string dotnetVersion = "net9.0";
// required
string DEFAULT_WINDOWS_PROJECT = "../../src/Controls/tests/TestCases.WinUI.Tests/Controls.TestCases.WinUI.Tests.csproj";
@ -19,7 +18,7 @@ var PACKAGEID = Argument("packageid", EnvironmentVariable("WINDOWS_TEST_PACKAGE_
// optional
var DOTNET_PATH = Argument("dotnet-path", EnvironmentVariable("DOTNET_PATH"));
var DOTNET_ROOT = Argument("dotnet-root", EnvironmentVariable("DOTNET_ROOT"));
var TARGET_FRAMEWORK = Argument("tfm", EnvironmentVariable("TARGET_FRAMEWORK") ?? $"{dotnetVersion}-windows{defaultVersion}");
var TARGET_FRAMEWORK = Argument("tfm", EnvironmentVariable("TARGET_FRAMEWORK") ?? $"{DotnetVersion}-windows{defaultVersion}");
var BINLOG_ARG = Argument("binlog", EnvironmentVariable("WINDOWS_TEST_BINLOG") ?? "");
DirectoryPath BINLOG_DIR = string.IsNullOrEmpty(BINLOG_ARG) && !string.IsNullOrEmpty(PROJECT.FullPath) ? PROJECT.GetDirectory() : BINLOG_ARG;
var TEST_APP = Argument("app", EnvironmentVariable("WINDOWS_TEST_APP") ?? "");
@ -57,6 +56,7 @@ Information("Build Binary Log (binlog): {0}", BINLOG_DIR);
Information("Build Platform: {0}", PLATFORM);
Information("Build Configuration: {0}", CONFIGURATION);
Information("Target Framework: {0}", TARGET_FRAMEWORK);
Information("Windows version: {0}", windowsVersion);
Setup(context =>
@ -439,7 +439,7 @@ Task("SetupTestPaths")
throw new Exception("If no app was specified, an app must be provided.");
}
var winVersion = $"{dotnetVersion}-windows{windowsVersion}";
var winVersion = $"{DotnetVersion}-windows{windowsVersion}";
var binDir = TEST_APP_PROJECT.GetDirectory().Combine("Controls.TestCases.HostApp").Combine(CONFIGURATION + "/" + winVersion).Combine(DOTNET_PLATFORM);
Information("BinDir: {0}", binDir);
var apps = GetFiles(binDir + "/*.exe").Where(c => !c.FullPath.EndsWith("createdump.exe"));

Просмотреть файл

@ -13,6 +13,9 @@ parameters:
artifactItemPattern: '**/*.nupkg'
checkoutDirectory: $(System.DefaultWorkingDirectory)
useArtifacts: false
targetFrameworkVersion:
- tfm: ''
dependsOn: ''
projects:
- name: name
desc: Human Description
@ -21,14 +24,18 @@ parameters:
catalyst: /optional/path/to/catalyst.csproj
stages:
- stage: android_device_tests
displayName: Android Device Tests
dependsOn: []
- stage: android_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
displayName: ${{ parameters.targetFrameworkVersion.tfm }} Android Device Tests
${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
dependsOn:
- android_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
${{ else }}:
dependsOn: []
jobs:
- job: android_device_tests
- job: android_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
displayName: "Android emulator tests"
displayName: "Android"
pool: ${{ parameters.androidPool }}
timeoutInMinutes: 60
strategy:
@ -41,6 +48,7 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_API_${{ api }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.android }}
TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if eq(api, 27) }}:
DEVICE: android-emulator-32_${{ api }}
APIVERSION: ${{ api }}
@ -63,14 +71,18 @@ stages:
useArtifacts: ${{ parameters.useArtifacts }}
poolName: ${{ parameters.androidPool.name }}
- stage: ios_device_tests
displayName: iOS Device Tests
dependsOn: []
- stage: ios_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
displayName: ${{ parameters.targetFrameworkVersion.tfm }} iOS Device Tests
${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
dependsOn:
- ios_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
${{ else }}:
dependsOn: []
jobs:
- job: ios_device_tests
- job: ios_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
displayName: "iOS tests"
displayName: "iOS"
pool: ${{ parameters.iosPool }}
timeoutInMinutes: 120
strategy:
@ -83,6 +95,7 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_V_${{ version }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.ios }}
TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if contains(version, 'device') }}:
DEVICE: ios-device
APIVERSION: ${{ replace(version, 'device-', '') }}
@ -105,14 +118,18 @@ stages:
useArtifacts: ${{ parameters.useArtifacts }}
poolName: 'Azure Pipelines'
- stage: catalyst_device_tests
displayName: macOS Device Tests
dependsOn: []
- stage: catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
displayName: ${{ parameters.targetFrameworkVersion.tfm }} macOS Device Tests
${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
dependsOn:
- catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
${{ else }}:
dependsOn: []
jobs:
- job: catalyst_device_tests
- job: catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
displayName: "macOS tests"
displayName: "macOS"
pool: ${{ parameters.catalystPool }}
timeoutInMinutes: 240
strategy:
@ -125,6 +142,7 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_V_${{ version }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.catalyst }}
TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if eq(version, 'latest') }}:
DEVICE: maccatalyst
${{ else }}:
@ -146,14 +164,18 @@ stages:
poolName: 'Azure Pipelines'
- stage: windows_device_tests
displayName: Windows Device Tests
dependsOn: []
- stage: windows_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
displayName: ${{ parameters.targetFrameworkVersion.tfm }} Windows Device Tests
${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
dependsOn:
- windows_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
${{ else }}:
dependsOn: []
jobs:
- job: windows_device_tests
- job: windows_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
displayName: "Windows device tests"
displayName: "Windows"
pool: ${{ parameters.windowsPool }}
timeoutInMinutes: 240 # how long to run the job before automatically cancelling
strategy:
@ -166,6 +188,7 @@ stages:
PROJECT_PATH: ${{ project.windows }}
PACKAGE_ID: ${{ project.windowsPackageId }}
DEVICE: ${{ version }}
TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
steps:
- template: device-tests-steps.yml
parameters:

Просмотреть файл

@ -20,120 +20,107 @@ parameters:
- name: BuildPlatforms
type: object
- name: BuildCategories
type: object
default:
- name: Windows
poolName: $(windowsVmPool)
vmImage: $(windowsVmImage)
artifact: templates-windows
- name: macOS
poolName: $(macOSXVmPool)
vmImage: $(macOSXVmImage)
artifact: templates-macos
- WindowsTemplates
- macOSTemplates
- Build
- Blazor
- MultiProject
- AOT
- name: RunPlatforms
type: object
default:
- name: $(androidTestsVmPool)
vmImage: $(androidTestsVmImage)
demands:
- macOS.Name -equals Sonoma
- macOS.Architecture -equals x64
testName: RunOnAndroid
artifact: templates-run-android
- name: $(iosTestsVmPool)
vmImage: $(iosTestsVmImage)
demands:
- macOS.Name -equals Sonoma
- macOS.Architecture -equals x64
testName: RunOniOS
artifact: templates-run-ios
- name: prepareSteps
type: stepList
default: []
jobs:
- job: build_maui_templates
workspace:
clean: all
displayName: 'Build platform:'
timeoutInMinutes: 240
condition: ${{ parameters.condition}}
strategy:
matrix:
${{ each BuildPlatform in parameters.BuildPlatforms }}:
${{ BuildPlatform.name }}:
POOL_NAME: ${{ BuildPlatform.poolName }}
POOL_VIMAGE: ${{ BuildPlatform.vmImage }}
PLATFORM_NAME: ${{ lower(BuildPlatform.name) }}
- ${{ each category in parameters.BuildCategories }}:
- job: build_maui_templates_${{ category }}
workspace:
clean: all
displayName: 'Build ${{ category }}: '
timeoutInMinutes: 240
condition: ${{ parameters.condition}}
strategy:
matrix:
${{ each BuildPlatform in parameters.BuildPlatforms }}:
${{ BuildPlatform.name }}:
POOL_NAME: ${{ BuildPlatform.poolName }}
POOL_VIMAGE: ${{ BuildPlatform.vmImage }}
PLATFORM_NAME: ${{ lower(BuildPlatform.name) }}
pool:
name: $(POOL_NAME)
vmImage: $(POOL_VIMAGE)
demands:
- macOS.Name -equals Sonoma
- macOS.Architecture -equals x64
steps:
pool:
name: $(POOL_NAME)
vmImage: $(POOL_VIMAGE)
demands:
- macOS.Name -equals Sonoma
- macOS.Architecture -equals x64
steps:
- ${{ each step in parameters.prepareSteps }}:
- ${{ each pair in step }}:
${{ pair.key }}: ${{ pair.value }}
- ${{ each step in parameters.prepareSteps }}:
- ${{ each pair in step }}:
${{ pair.key }}: ${{ pair.value }}
- template: provision.yml
parameters:
checkoutDirectory: ${{ parameters.checkoutDirectory }}
- template: provision.yml
parameters:
checkoutDirectory: ${{ parameters.checkoutDirectory }}
- task: DownloadBuildArtifacts@0
displayName: 'Download Packages'
inputs:
artifactName: ${{ parameters.artifactName }}
itemPattern: ${{ parameters.artifactItemPattern }}
downloadPath: $(System.DefaultWorkingDirectory)/artifacts
- task: DownloadBuildArtifacts@0
displayName: 'Download Packages'
inputs:
artifactName: ${{ parameters.artifactName }}
itemPattern: ${{ parameters.artifactItemPattern }}
downloadPath: $(System.DefaultWorkingDirectory)/artifacts
- pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
displayName: Move the downloaded artifacts
- pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
displayName: Move the downloaded artifacts
- pwsh: |
Get-ChildItem artifacts -Filter 'Microsoft.Maui.Controls.*.nupkg' | Where-Object { $_.Name -match '^Microsoft\.Maui\.Controls\.([\d\.]+.*)\.nupkg$' }
$version = $Matches.1
if (!$version) {
Write-Error "Failed to extract the version from the nupkgs"
exit 1
}
Write-Host "Found .NET MAUI version (MAUI_PACKAGE_VERSION): $version"
Write-Host "##vso[task.setvariable variable=MAUI_PACKAGE_VERSION]$version"
displayName: Read the .NET MAUI version from the nugets
- pwsh: |
Get-ChildItem artifacts -Filter 'Microsoft.Maui.Controls.*.nupkg' | Where-Object { $_.Name -match '^Microsoft\.Maui\.Controls\.([\d\.]+.*)\.nupkg$' }
$version = $Matches.1
if (!$version) {
Write-Error "Failed to extract the version from the nupkgs"
exit 1
}
Write-Host "Found .NET MAUI version (MAUI_PACKAGE_VERSION): $version"
Write-Host "##vso[task.setvariable variable=MAUI_PACKAGE_VERSION]$version"
displayName: Read the .NET MAUI version from the nugets
- pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
displayName: 'Install .NET (Local Workloads)'
retryCountOnTaskFailure: 3
workingDirectory: ${{ parameters.checkoutDirectory }}
env:
DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
PRIVATE_BUILD: $(PrivateBuild)
- pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
displayName: 'Install .NET (Local Workloads)'
retryCountOnTaskFailure: 3
workingDirectory: ${{ parameters.checkoutDirectory }}
env:
DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
PRIVATE_BUILD: $(PrivateBuild)
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
workingDirectory: ${{ parameters.checkoutDirectory }}
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
workingDirectory: ${{ parameters.checkoutDirectory }}
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="FullyQualifiedName=Microsoft.Maui.IntegrationTests.TemplateTests" --resultsfilename="integration-tests" --verbosity=diagnostic
displayName: Run $(PLATFORM_NAME) templates build tests
workingDirectory: ${{ parameters.checkoutDirectory }}
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=${{ category }}" --resultsfilename="integration-tests" --verbosity=diagnostic
displayName: Run $(PLATFORM_NAME) templates build tests
workingDirectory: ${{ parameters.checkoutDirectory }}
- task: PublishTestResults@2
displayName: Publish the $(PLATFORM_NAME) templates build tests
condition: always()
inputs:
testRunner: VSTest
testResultsFiles: '$(build.artifactstagingdirectory)/**/*.trx'
testRunTitle: $(PLATFORM_NAME) templates build tests
- task: PublishTestResults@2
displayName: Publish the $(PLATFORM_NAME) templates build tests
condition: always()
inputs:
testRunner: VSTest
testResultsFiles: '$(build.artifactstagingdirectory)/**/*.trx'
testRunTitle: $(PLATFORM_NAME) templates build tests
- pwsh: |
Write-Host "Current job status is: $env:AGENT_JOBSTATUS"
if ($env:AGENT_JOBSTATUS -eq "SucceededWithIssues") {
Write-Host "##vso[task.complete result=Failed;]DONE"
}
displayName: Fail if any issues occurred
- pwsh: |
Write-Host "Current job status is: $env:AGENT_JOBSTATUS"
if ($env:AGENT_JOBSTATUS -eq "SucceededWithIssues") {
Write-Host "##vso[task.complete result=Failed;]DONE"
}
displayName: Fail if any issues occurred
- ${{ each RunPlatform in parameters.RunPlatforms }}:
- job: run_${{ RunPlatform.testName }}
@ -173,6 +160,17 @@ jobs:
- pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
displayName: Move the downloaded artifacts
- pwsh: |
Get-ChildItem artifacts -Filter 'Microsoft.Maui.Controls.*.nupkg' | Where-Object { $_.Name -match '^Microsoft\.Maui\.Controls\.([\d\.]+.*)\.nupkg$' }
$version = $Matches.1
if (!$version) {
Write-Error "Failed to extract the version from the nupkgs"
exit 1
}
Write-Host "Found .NET MAUI version (MAUI_PACKAGE_VERSION): $version"
Write-Host "##vso[task.setvariable variable=MAUI_PACKAGE_VERSION]$version"
displayName: Read the .NET MAUI version from the nugets
- pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
displayName: 'Install .NET (Local Workloads)'
retryCountOnTaskFailure: 3
@ -194,7 +192,7 @@ jobs:
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Name=${{ RunPlatform.testName }}" --resultsfilename="integration-run-${{ RunPlatform.testName }}" --verbosity=diagnostic
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=${{ RunPlatform.testName }}" --resultsfilename="integration-run-${{ RunPlatform.testName }}" --verbosity=diagnostic
displayName: Run $(PLATFORM_NAME) templates run tests
continueOnError: true
# TODO: pass properly device type/version from top-level yml

Просмотреть файл

@ -87,6 +87,11 @@ parameters:
name: $(windowsTestsVmPool)
vmImage: $(windowsTestsVmImage)
- name: targetFrameworkVersions
type: object
default:
- tfm: net9.0
resources:
repositories:
- repository: yaml-templates
@ -96,7 +101,7 @@ resources:
ref: refs/heads/main
stages:
- ${{ each targetFrameworkVersion in parameters.targetFrameworkVersions }}:
- template: common/device-tests.yml
parameters:
androidPool: ${{ parameters.androidPool }}
@ -104,14 +109,15 @@ stages:
catalystPool: ${{ parameters.catalystPool }}
windowsPool: ${{ parameters.windowsPool }}
agentPoolAccessToken: $(AgentPoolAccessToken)
targetFrameworkVersion: ${{ targetFrameworkVersion }}
${{ if or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv'))) }}:
androidApiLevels: [ 33, 30, 29, 28, 27, 26, 25, 24, 23 ]
iosVersions: [ 'simulator-17.2']
catalystVersions: [ 'latest' ]
windowsVersions: ['packaged', 'unpackaged']
provisionatorChannel: ${{ parameters.provisionatorChannel }}
${{ if not(or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv')))) }}:
androidApiLevels: [ 33, 23 ]
${{ else }}:
androidApiLevels: [ 33 ]
iosVersions: [ 'simulator-17.2' ]
catalystVersions: [ 'latest' ]
windowsVersions: ['packaged', 'unpackaged']

Просмотреть файл

@ -88,7 +88,7 @@ parameters:
vmImage: $(macOSXVmImage)
artifact: nuget-macos
- name: BuilTemplatePlatforms
- name: BuildTemplatePlatforms
type: object
default:
- name: Windows
@ -273,7 +273,7 @@ stages:
PRIVATE_BUILD: $(PrivateBuild)
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="FullyQualifiedName=Microsoft.Maui.IntegrationTests.SampleTests" --resultsfilename="integration-samples" --verbosity=diagnostic
- pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=Samples" --resultsfilename="integration-samples" --verbosity=diagnostic
displayName: Run ${{ BuildPlatform.name }} sample build tests
- task: PublishTestResults@2
displayName: Publish the ${{ BuildPlatform.name }} sample build tests
@ -295,7 +295,7 @@ stages:
- template: common/maui-templates.yml
parameters:
RunPlatforms: ${{ parameters.RunTemplatePlatforms }}
BuildPlatforms: ${{ parameters.BuilTemplatePlatforms }}
BuildPlatforms: ${{ parameters.BuildTemplatePlatforms }}
# - ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
# - template: common/localization-handoff.yml # Process outgoing strings [Localization Handoff]

Просмотреть файл

@ -0,0 +1,92 @@
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.AOT)]
public class AOTTemplateTest : BaseTemplateTests
{
[Test]
[TestCase("maui", $"{DotNetCurrent}-ios", "ios-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-x64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-arm64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-x64")]
public void PublishNativeAOT(string id, string framework, string runtimeIdentifier)
{
if (!TestEnvironment.IsMacOS)
Assert.Ignore("Publishing a MAUI iOS app with NativeAOT is only supported on a host MacOS system.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
var extendedBuildProps = PrepareNativeAotBuildProps();
string binLogFilePath = $"publish-{DateTime.UtcNow.ToFileTimeUtc()}.binlog";
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", framework: framework, properties: extendedBuildProps, runtimeIdentifier: runtimeIdentifier, binlogPath: binLogFilePath),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var actualWarnings = BuildWarningsUtilities.ReadNativeAOTWarningsFromBinLog(binLogFilePath);
actualWarnings.AssertNoWarnings();
}
[Test]
[TestCase("maui", $"{DotNetCurrent}-ios", "ios-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-x64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-arm64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-x64")]
public void PublishNativeAOTRootAllMauiAssemblies(string id, string framework, string runtimeIdentifier)
{
// This test follows the following guide: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/#publishing-a-test-application-for-aot
if (!TestEnvironment.IsMacOS)
Assert.Ignore("Publishing a MAUI iOS app with NativeAOT is only supported on a host MacOS system.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
var extendedBuildProps = PrepareNativeAotBuildProps();
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"""
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls.Foldable" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Controls.Maps" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Graphics.Skia" Version="$(MauiVersion)" />
</ItemGroup>
<ItemGroup>
<TrimmerRootAssembly Include="Microsoft.Maui" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Foldable" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Maps" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Xaml" />
<TrimmerRootAssembly Include="Microsoft.Maui.Essentials" />
<TrimmerRootAssembly Include="Microsoft.Maui.Graphics" />
<TrimmerRootAssembly Include="Microsoft.Maui.Graphics.Skia" />
<TrimmerRootAssembly Include="Microsoft.Maui.Maps" />
</ItemGroup>
</Project>
""");
string binLogFilePath = $"publish-{DateTime.UtcNow.ToFileTimeUtc()}.binlog";
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", framework: framework, properties: extendedBuildProps, runtimeIdentifier: runtimeIdentifier, binlogPath: binLogFilePath),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var actualWarnings = BuildWarningsUtilities.ReadNativeAOTWarningsFromBinLog(binLogFilePath);
actualWarnings.AssertNoWarnings();
}
private List<string> PrepareNativeAotBuildProps()
{
var extendedBuildProps = new List<string>(BuildProps);
extendedBuildProps.Add("PublishAot=true");
extendedBuildProps.Add("PublishAotUsingRuntimePack=true"); // TODO: This parameter will become obsolete https://github.com/dotnet/runtime/issues/87060 in net9
extendedBuildProps.Add("_IsPublishing=true"); // This makes 'dotnet build -r iossimulator-x64' equivalent to 'dotnet publish -r iossimulator-x64'
extendedBuildProps.Add("IlcTreatWarningsAsErrors=false");
extendedBuildProps.Add("TrimmerSingleWarn=false");
return extendedBuildProps;
}
}

Просмотреть файл

@ -4,6 +4,7 @@ using Microsoft.Maui.IntegrationTests.Android;
namespace Microsoft.Maui.IntegrationTests
{
[Category(Categories.RunOnAndroid)]
public class AndroidTemplateTests : BaseBuildTest
{
Emulator TestAvd = new Emulator();

Просмотреть файл

@ -3,6 +3,7 @@ using Microsoft.Maui.IntegrationTests.Apple;
namespace Microsoft.Maui.IntegrationTests
{
[Category(Categories.RunOniOS)]
public class AppleTemplateTests : BaseBuildTest
{
Simulator TestSimulator = new Simulator();

Просмотреть файл

@ -8,7 +8,7 @@ namespace Microsoft.Maui.IntegrationTests
NativeAOT
}
public class BaseBuildTest
public abstract class BaseBuildTest
{
public const string DotNetCurrent = "net9.0";
public const string DotNetPrevious = "net8.0";

Просмотреть файл

@ -0,0 +1,22 @@
namespace Microsoft.Maui.IntegrationTests;
public abstract class BaseTemplateTests : BaseBuildTest
{
[SetUp]
public void TemplateTestsSetUp()
{
File.Copy(Path.Combine(TestEnvironment.GetMauiDirectory(), "src", "Templates", "tests", "Directory.Build.props"),
Path.Combine(TestDirectory, "Directory.Build.props"), true);
File.Copy(Path.Combine(TestEnvironment.GetMauiDirectory(), "src", "Templates", "tests", "Directory.Build.targets"),
Path.Combine(TestDirectory, "Directory.Build.targets"), true);
}
protected void EnableTizen(string projectFile)
{
FileUtilities.ReplaceInFile(projectFile, new Dictionary<string, string>()
{
{ "<!-- <TargetFrameworks>", "<TargetFrameworks>" },
{ "</TargetFrameworks> -->", "</TargetFrameworks>" },
});
}
}

Просмотреть файл

@ -0,0 +1,77 @@
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.Blazor)]
public class BlazorTemplateTest : BaseTemplateTests
{
[Test]
// Parameters: target framework, build config, dotnet new additional parameters
// First, default scenarios
[TestCase(DotNetCurrent, "Debug", "", false)]
[TestCase(DotNetCurrent, "Release", "", false)]
// Then, scenarios with additional template parameters:
// - Interactivity Location: None/WASM/Server/Auto
// - Empty vs. With Sample Content
// - ProgramMain vs. TopLevel statements
// And alternately testing other options for a healthy mix.
[TestCase(DotNetCurrent, "Debug", "-I None --Empty", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --Empty", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --Empty", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --Empty", false)]
[TestCase(DotNetCurrent, "Debug", "-I None", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto", false)]
[TestCase(DotNetCurrent, "Debug", "-I None --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I None --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --UseProgramMain", false)]
// Then, some scenarios with tricky names in Debug builds only
// This doesn't work on Android in Release, so we skip that for now
// See https://github.com/dotnet/android/issues/9107
[TestCase(DotNetCurrent, "Debug", "", true)]
[TestCase(DotNetCurrent, "Debug", "-I Server --UseProgramMain", true)]
public void BuildMauiBlazorWebSolution(string framework, string config, string additionalDotNetNewParams, bool useTrickyProjectName)
{
const string templateShortName = "maui-blazor-web";
var solutionProjectDir = TestDirectory;
if (useTrickyProjectName)
{
solutionProjectDir += "&More";
}
var webAppProjectDir = Path.Combine(solutionProjectDir, Path.GetFileName(solutionProjectDir) + ".Web");
var webAppProjectFile = Path.Combine(webAppProjectDir, $"{Path.GetFileName(webAppProjectDir)}.csproj");
var mauiAppProjectDir = Path.Combine(solutionProjectDir, Path.GetFileName(solutionProjectDir));
var mauiAppProjectFile = Path.Combine(mauiAppProjectDir, $"{Path.GetFileName(mauiAppProjectDir)}.csproj");
TestContext.WriteLine($"Creating project in {solutionProjectDir}");
Assert.IsTrue(DotnetInternal.New(templateShortName, outputDirectory: solutionProjectDir, framework: framework, additionalDotNetNewParams: additionalDotNetNewParams),
$"Unable to create template {templateShortName}. Check test output for errors.");
TestContext.WriteLine($"Solution directory: {solutionProjectDir} (exists? {Directory.Exists(solutionProjectDir)})");
TestContext.WriteLine($"Blazor Web app project directory: {webAppProjectDir} (exists? {Directory.Exists(webAppProjectDir)})");
TestContext.WriteLine($"Blazor Web app project file: {webAppProjectFile} (exists? {File.Exists(webAppProjectFile)})");
TestContext.WriteLine($"MAUI app project directory: {mauiAppProjectDir} (exists? {Directory.Exists(mauiAppProjectDir)})");
TestContext.WriteLine($"MAUI app project file: {mauiAppProjectFile} (exists? {File.Exists(mauiAppProjectFile)})");
EnableTizen(mauiAppProjectFile);
TestContext.WriteLine($"Building Blazor Web app: {webAppProjectFile}");
Assert.IsTrue(DotnetInternal.Build(webAppProjectFile, config, target: "", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(webAppProjectFile)} failed to build. Check test output/attachments for errors.");
TestContext.WriteLine($"Building .NET MAUI app: {mauiAppProjectFile}");
Assert.IsTrue(DotnetInternal.Build(mauiAppProjectFile, config, target: "", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(mauiAppProjectFile)} failed to build. Check test output/attachments for errors.");
}
}

Просмотреть файл

@ -0,0 +1,111 @@
using Microsoft.Maui.IntegrationTests.Apple;
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.macOSTemplates)]
public class MacTemplateTest : BaseTemplateTests
{
[Test]
[TestCase("maui", "ios")]
[TestCase("maui", "maccatalyst")]
[TestCase("maui-blazor", "ios")]
[TestCase("maui-blazor", "maccatalyst")]
public void BuildWithCustomBundleResource(string id, string framework)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
File.WriteAllText(Path.Combine(projectDir, "Resources", "testfile.txt"), "Something here :)");
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"""
<ItemGroup>
<BundleResource Include="Resources\testfile.txt" />
</ItemGroup>
</Project>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-{framework}");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui-blazor", "Debug", DotNetCurrent)]
[TestCase("maui-blazor", "Release", DotNetCurrent)]
public void CheckEntitlementsForMauiBlazorOnMacCatalyst(string id, string config, string framework)
{
if (TestEnvironment.IsWindows)
Assert.Ignore("Running MacCatalyst templates is only supported on Mac.");
string projectDir = TestDirectory;
string projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
// Note: Debug app is stored in the maccatalyst-x64 folder, while the Release is in parent directory
string appLocation = config == "Release" ?
Path.Combine(projectDir, "bin", config, $"{framework}-maccatalyst", $"{Path.GetFileName(projectDir)}.app") :
Path.Combine(projectDir, "bin", config, $"{framework}-maccatalyst", "maccatalyst-x64", $"{Path.GetFileName(projectDir)}.app");
string entitlementsPath = Path.Combine(projectDir, "x.xml");
List<string> buildWithCodeSignProps = new List<string>(BuildProps)
{
"EnableCodeSigning=true"
};
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework), $"Unable to create template {id}. Check test output for errors.");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, framework: $"{framework}-maccatalyst", properties: buildWithCodeSignProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
List<string> expectedEntitlements =
new() { "com.apple.security.app-sandbox", "com.apple.security.network.client" };
List<string> foundEntitlements = Codesign.SearchForExpectedEntitlements(entitlementsPath, appLocation, expectedEntitlements);
CollectionAssert.AreEqual(expectedEntitlements, foundEntitlements, "Entitlements missing from executable.");
}
[Test]
[TestCase("maui-blazor", "Debug", DotNetCurrent)]
[TestCase("maui-blazor", "Release", DotNetCurrent)]
[TestCase("maui", "Debug", DotNetCurrent)]
[TestCase("maui", "Release", DotNetCurrent)]
[TestCase("maui-multiproject", "Debug", DotNetCurrent)]
[TestCase("maui-multiproject", "Release", DotNetCurrent)]
public void CheckPrivacyManifestForiOS(string id, string config, string framework)
{
if (TestEnvironment.IsWindows)
{
Assert.Ignore("Running iOS templates is only supported on Mac.");
}
string projectDir = TestDirectory;
string projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
string appFileName = $"{Path.GetFileName(projectDir)}.app";
string appLocation =
Path.Combine(projectDir, "bin", config, $"{framework}-ios", "iossimulator-x64", appFileName);
// Multi-project is in a .iOS subfolder and csproj is *.iOS.csproj
if (id.EndsWith("multiproject"))
{
projectFile =
Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.iOS", $"{Path.GetFileName(projectDir)}.iOS.csproj");
appFileName = $"{Path.GetFileName(projectDir)}.iOS.app";
appLocation =
Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.iOS", "bin", config, $"{framework}-ios", "iossimulator-x64", appFileName);
}
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework), $"Unable to create template {id}. Check test output for errors.");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, framework: $"{framework}-ios", msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
string manifestLocation = Path.Combine(appLocation, "PrivacyInfo.xcprivacy");
Assert.IsTrue(File.Exists(manifestLocation), $"Privacy Manifest not found in {manifestLocation}.");
}
}

Просмотреть файл

@ -0,0 +1,53 @@
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.MultiProject)]
public class MultiProjectTemplateTest : BaseTemplateTests
{
[Test]
[TestCase("Debug", "simplemulti")]
[TestCase("Release", "simplemulti")]
[TestCase("Debug", "MultiProject@Symbol & More")]
[TestCase("Release", "MultiProject@Symbol & More")]
public void BuildMultiProject(string config, string projectName)
{
var projectDir = Path.Combine(TestDirectory, projectName);
var name = Path.GetFileName(projectDir);
var solutionFile = Path.Combine(projectDir, $"{name}.sln");
Assert.IsTrue(DotnetInternal.New("maui-multiproject", projectDir, DotNetCurrent),
$"Unable to create template maui-multiproject. Check test output for errors.");
if (!TestEnvironment.IsWindows)
{
Assert.IsTrue(DotnetInternal.Run("sln", $"\"{solutionFile}\" remove \"{projectDir}/{name}.WinUI/{name}.WinUI.csproj\""),
$"Unable to remove WinUI project from solution. Check test output for errors.");
}
Assert.IsTrue(DotnetInternal.Build(solutionFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Solution {name} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("Debug", "--android")]
[TestCase("Debug", "--ios")]
[TestCase("Debug", "--windows")]
[TestCase("Debug", "--macos")]
public void BuildMultiProjectSinglePlatform(string config, string platformArg)
{
var projectDir = TestDirectory;
var name = Path.GetFileName(projectDir);
var solutionFile = Path.Combine(projectDir, $"{name}.sln");
Assert.IsTrue(DotnetInternal.New($"maui-multiproject {platformArg}", projectDir, DotNetCurrent),
$"Unable to create template maui-multiproject. Check test output for errors.");
if (!TestEnvironment.IsWindows)
{
Assert.IsTrue(DotnetInternal.Run("sln", $"{solutionFile} remove {projectDir}/{name}.WinUI/{name}.WinUI.csproj"),
$"Unable to remove WinUI project from solution. Check test output for errors.");
}
Assert.IsTrue(DotnetInternal.Build(solutionFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Solution {name} failed to build. Check test output/attachments for errors.");
}
}

Просмотреть файл

@ -1,7 +1,6 @@
using Microsoft.Maui.IntegrationTests.Apple;
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.Build)]
public class ResizetizerTests : BaseBuildTest
{
const string BlankSvgContents =
@ -25,6 +24,10 @@ public class ResizetizerTests : BaseBuildTest
[TestCase("maui-blazor", "mauilib", false)] // net9.0-xxx
public void CollectsAssets(string id, string libid, bool unpackaged)
{
// TODO: fix the tests as they have been disabled too long!
if (!TestEnvironment.IsWindows)
Assert.Ignore("Running Windows templates is only supported on Windows.");
// new app
var appDir = Path.Combine(TestDirectory, "theapp");
var appFile = Path.Combine(appDir, $"{Path.GetFileName(appDir)}.csproj");

Просмотреть файл

@ -4,6 +4,7 @@ using Newtonsoft.Json;
namespace Microsoft.Maui.IntegrationTests
{
[Category(Categories.Samples)]
public class SampleTests : BaseBuildTest
{
public static IEnumerable SampleTestMatrix

Просмотреть файл

@ -0,0 +1,277 @@
using System.Xml.Linq;
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.Build)]
public class SimpleTemplateTest : BaseTemplateTests
{
[Test]
// Parameters: short name, target framework, build config, use pack target, additionalDotNetNewParams
[TestCase("maui", DotNetPrevious, "Debug", false, "")]
[TestCase("maui", DotNetPrevious, "Release", false, "")]
[TestCase("maui", DotNetCurrent, "Debug", false, "")]
[TestCase("maui", DotNetCurrent, "Release", false, "")]
[TestCase("maui-blazor", DotNetPrevious, "Debug", false, "")]
[TestCase("maui-blazor", DotNetPrevious, "Release", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Release", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false, "--Empty")]
[TestCase("maui-blazor", DotNetCurrent, "Release", false, "--Empty")]
[TestCase("mauilib", DotNetPrevious, "Debug", true, "")]
[TestCase("mauilib", DotNetPrevious, "Release", true, "")]
[TestCase("mauilib", DotNetCurrent, "Debug", true, "")]
[TestCase("mauilib", DotNetCurrent, "Release", true, "")]
public void Build(string id, string framework, string config, bool shouldPack, string additionalDotNetNewParams)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework, additionalDotNetNewParams),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
// with spaces
[TestCase("maui", "Project Space", "projectspace")]
[TestCase("maui-blazor", "Project Space", "projectspace")]
[TestCase("mauilib", "Project Space", "projectspace")]
// with invalid characters
[TestCase("maui", "Project@Symbol", "projectsymbol")]
[TestCase("maui-blazor", "Project@Symbol", "projectsymbol")]
[TestCase("mauilib", "Project@Symbol", "projectsymbol")]
public void BuildsWithSpecialCharacters(string id, string projectName, string expectedId)
{
var projectDir = Path.Combine(TestDirectory, projectName);
var projectFile = Path.Combine(projectDir, $"{projectName}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
// libraries do not have application IDs
if (id != "mauilib")
{
var doc = XDocument.Load(projectFile);
// Check the app ID got invalid characters removed
var appId = doc.Root!
.Elements("PropertyGroup")
.Elements("ApplicationId")
.Single()
.Value;
Assert.AreEqual($"com.companyname.{expectedId}", appId);
// Check the app title matches the project name exactly (it might have been XML-encoded, but loading the document decodes that)
var appTitle = doc.Root!
.Elements("PropertyGroup")
.Elements("ApplicationTitle")
.Single()
.Value;
Assert.AreEqual(projectName, appTitle);
}
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
// Parameters: short name, target framework, build config, use pack target
[TestCase("maui", DotNetPrevious, "Debug", false)]
[TestCase("maui", DotNetPrevious, "Release", false)]
[TestCase("maui", DotNetCurrent, "Debug", false)]
[TestCase("maui", DotNetCurrent, "Release", false)]
[TestCase("maui-blazor", DotNetPrevious, "Debug", false)]
[TestCase("maui-blazor", DotNetPrevious, "Release", false)]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false)]
[TestCase("maui-blazor", DotNetCurrent, "Release", false)]
[TestCase("mauilib", DotNetPrevious, "Debug", true)]
[TestCase("mauilib", DotNetPrevious, "Release", true)]
[TestCase("mauilib", DotNetCurrent, "Debug", true)]
[TestCase("mauilib", DotNetCurrent, "Release", true)]
public void BuildWithMauiVersion(string id, string framework, string config, bool shouldPack)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
// set <MauiVersion> in the csproj as that is the reccommended place
var mv = framework == DotNetPrevious ? MauiVersionPrevious : MauiVersionCurrent;
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"<PropertyGroup><MauiVersion>{mv}</MauiVersion></PropertyGroup></Project>");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", "Debug", false)]
[TestCase("maui", "Release", false)]
[TestCase("maui-blazor", "Debug", false)]
[TestCase("maui-blazor", "Release", false)]
[TestCase("mauilib", "Debug", true)]
[TestCase("mauilib", "Release", true)]
public void PreviousDotNetCanUseLatestMaui(string id, string config, bool shouldPack)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetPrevious),
$"Unable to create template {id}. Check test output for errors.");
// TODO: fix this as we should be able to build tizen net8
// EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
// set <MauiVersion> in the csproj as that is the reccommended place
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"""
<PropertyGroup>
<MauiVersion>{MauiPackageVersion}</MauiVersion>
<NoWarn>$(NoWarn);CS0618</NoWarn>
</PropertyGroup>
</Project>
""");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
public void BuildHandlesBadFilesInImages()
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New("maui", projectDir, DotNetCurrent),
$"Unable to create template maui. Check test output for errors.");
EnableTizen(projectFile);
File.WriteAllText(Path.Combine(projectDir, "Resources", "Images", ".DS_Store"), "Boom!");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
/// <summary>
/// Tests the scenario where a .NET MAUI Library specifically uses UseMauiCore instead of UseMaui.
/// </summary>
[Test]
[TestCase("mauilib", DotNetPrevious, "Debug")]
[TestCase("mauilib", DotNetPrevious, "Release")]
[TestCase("mauilib", DotNetCurrent, "Debug")]
[TestCase("mauilib", DotNetCurrent, "Release")]
public void PackCoreLib(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
var projectSectionsToReplace = new Dictionary<string, string>()
{
{ "UseMaui", "UseMauiCore" }, // This is the key part of the test
{ "SingleProject", "EnablePreviewMsixTooling" },
};
if (framework != "net7.0")
{
// On versions after net7.0 this package reference also has to be updated to ensure the version of the MAUI Core package
// is specified and avoids the MA002 warning.
projectSectionsToReplace.Add("Include=\"Microsoft.Maui.Controls\"", "Include=\"Microsoft.Maui.Core\"");
}
FileUtilities.ReplaceInFile(projectFile, projectSectionsToReplace);
Directory.Delete(Path.Combine(projectDir, "Platforms"), recursive: true);
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", DotNetCurrent, "Debug")]
[TestCase("mauilib", DotNetCurrent, "Debug")]
[TestCase("maui-blazor", DotNetCurrent, "Debug")]
public void BuildWithoutPackageReference(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><SkipValidateMauiImplicitPackageReferences>true</SkipValidateMauiImplicitPackageReferences></PropertyGroup></Project>");
FileUtilities.ReplaceInFile(projectFile,
"<PackageReference Include=\"Microsoft.Maui.Controls\" Version=\"$(MauiVersion)\" />",
"");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", "Debug", "2.0", "2")]
[TestCase("maui", "Release", "2.0", "2")]
[TestCase("maui", "Release", "0.3", "3")]
[TestCase("maui-blazor", "Debug", "2.0", "2")]
[TestCase("maui-blazor", "Release", "2.0", "2")]
[TestCase("maui-blazor", "Release", "0.3", "3")]
public void BuildWithDifferentVersionNumber(string id, string config, string display, string version)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
$"<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>",
$"<ApplicationDisplayVersion>{display}</ApplicationDisplayVersion>");
FileUtilities.ReplaceInFile(projectFile,
$"<ApplicationVersion>1</ApplicationVersion>",
$"<ApplicationVersion>{version}</ApplicationVersion>");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
}

Просмотреть файл

@ -1,732 +0,0 @@
using System.Xml.Linq;
using Microsoft.Maui.IntegrationTests.Apple;
namespace Microsoft.Maui.IntegrationTests
{
public class TemplateTests : BaseBuildTest
{
[SetUp]
public void TemplateTestsSetUp()
{
File.Copy(Path.Combine(TestEnvironment.GetMauiDirectory(), "src", "Templates", "tests", "Directory.Build.props"),
Path.Combine(TestDirectory, "Directory.Build.props"), true);
File.Copy(Path.Combine(TestEnvironment.GetMauiDirectory(), "src", "Templates", "tests", "Directory.Build.targets"),
Path.Combine(TestDirectory, "Directory.Build.targets"), true);
}
[Test]
// Parameters: short name, target framework, build config, use pack target, additionalDotNetNewParams
[TestCase("maui", DotNetPrevious, "Debug", false, "")]
[TestCase("maui", DotNetPrevious, "Release", false, "")]
[TestCase("maui", DotNetCurrent, "Debug", false, "")]
[TestCase("maui", DotNetCurrent, "Release", false, "")]
[TestCase("maui-blazor", DotNetPrevious, "Debug", false, "")]
[TestCase("maui-blazor", DotNetPrevious, "Release", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Release", false, "")]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false, "--Empty")]
[TestCase("maui-blazor", DotNetCurrent, "Release", false, "--Empty")]
[TestCase("mauilib", DotNetPrevious, "Debug", true, "")]
[TestCase("mauilib", DotNetPrevious, "Release", true, "")]
[TestCase("mauilib", DotNetCurrent, "Debug", true, "")]
[TestCase("mauilib", DotNetCurrent, "Release", true, "")]
public void Build(string id, string framework, string config, bool shouldPack, string additionalDotNetNewParams)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework, additionalDotNetNewParams),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
// Parameters: target framework, build config, dotnet new additional parameters
// First, default scenarios
[TestCase(DotNetCurrent, "Debug", "", false)]
[TestCase(DotNetCurrent, "Release", "", false)]
// Then, scenarios with additional template parameters:
// - Interactivity Location: None/WASM/Server/Auto
// - Empty vs. With Sample Content
// - ProgramMain vs. TopLevel statements
// And alternately testing other options for a healthy mix.
[TestCase(DotNetCurrent, "Debug", "-I None --Empty", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --Empty", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --Empty", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --Empty", false)]
[TestCase(DotNetCurrent, "Debug", "-I None", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto", false)]
[TestCase(DotNetCurrent, "Debug", "-I None --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --Empty --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I None --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I WebAssembly --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Debug", "-I Server --UseProgramMain", false)]
[TestCase(DotNetCurrent, "Release", "-I Auto --UseProgramMain", false)]
// Then, some scenarios with tricky names in Debug builds only
// This doesn't work on Android in Release, so we skip that for now
// See https://github.com/dotnet/android/issues/9107
[TestCase(DotNetCurrent, "Debug", "", true)]
[TestCase(DotNetCurrent, "Debug", "-I Server --UseProgramMain", true)]
public void BuildMauiBlazorWebSolution(string framework, string config, string additionalDotNetNewParams, bool useTrickyProjectName)
{
const string templateShortName = "maui-blazor-web";
var solutionProjectDir = TestDirectory;
if (useTrickyProjectName)
{
solutionProjectDir += "&More";
}
var webAppProjectDir = Path.Combine(solutionProjectDir, Path.GetFileName(solutionProjectDir) + ".Web");
var webAppProjectFile = Path.Combine(webAppProjectDir, $"{Path.GetFileName(webAppProjectDir)}.csproj");
var mauiAppProjectDir = Path.Combine(solutionProjectDir, Path.GetFileName(solutionProjectDir));
var mauiAppProjectFile = Path.Combine(mauiAppProjectDir, $"{Path.GetFileName(mauiAppProjectDir)}.csproj");
TestContext.WriteLine($"Creating project in {solutionProjectDir}");
Assert.IsTrue(DotnetInternal.New(templateShortName, outputDirectory: solutionProjectDir, framework: framework, additionalDotNetNewParams: additionalDotNetNewParams),
$"Unable to create template {templateShortName}. Check test output for errors.");
TestContext.WriteLine($"Solution directory: {solutionProjectDir} (exists? {Directory.Exists(solutionProjectDir)})");
TestContext.WriteLine($"Blazor Web app project directory: {webAppProjectDir} (exists? {Directory.Exists(webAppProjectDir)})");
TestContext.WriteLine($"Blazor Web app project file: {webAppProjectFile} (exists? {File.Exists(webAppProjectFile)})");
TestContext.WriteLine($"MAUI app project directory: {mauiAppProjectDir} (exists? {Directory.Exists(mauiAppProjectDir)})");
TestContext.WriteLine($"MAUI app project file: {mauiAppProjectFile} (exists? {File.Exists(mauiAppProjectFile)})");
EnableTizen(mauiAppProjectFile);
TestContext.WriteLine($"Building Blazor Web app: {webAppProjectFile}");
Assert.IsTrue(DotnetInternal.Build(webAppProjectFile, config, target: "", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(webAppProjectFile)} failed to build. Check test output/attachments for errors.");
TestContext.WriteLine($"Building .NET MAUI app: {mauiAppProjectFile}");
Assert.IsTrue(DotnetInternal.Build(mauiAppProjectFile, config, target: "", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(mauiAppProjectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("Debug", "simplemulti")]
[TestCase("Release", "simplemulti")]
[TestCase("Debug", "MultiProject@Symbol & More")]
[TestCase("Release", "MultiProject@Symbol & More")]
public void BuildMultiProject(string config, string projectName)
{
var projectDir = Path.Combine(TestDirectory, projectName);
var name = Path.GetFileName(projectDir);
var solutionFile = Path.Combine(projectDir, $"{name}.sln");
Assert.IsTrue(DotnetInternal.New("maui-multiproject", projectDir, DotNetCurrent),
$"Unable to create template maui-multiproject. Check test output for errors.");
if (!TestEnvironment.IsWindows)
{
Assert.IsTrue(DotnetInternal.Run("sln", $"\"{solutionFile}\" remove \"{projectDir}/{name}.WinUI/{name}.WinUI.csproj\""),
$"Unable to remove WinUI project from solution. Check test output for errors.");
}
Assert.IsTrue(DotnetInternal.Build(solutionFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Solution {name} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("Debug", "--android")]
[TestCase("Debug", "--ios")]
[TestCase("Debug", "--windows")]
[TestCase("Debug", "--macos")]
public void BuildMultiProjectSinglePlatform(string config, string platformArg)
{
var projectDir = TestDirectory;
var name = Path.GetFileName(projectDir);
var solutionFile = Path.Combine(projectDir, $"{name}.sln");
Assert.IsTrue(DotnetInternal.New($"maui-multiproject {platformArg}", projectDir, DotNetCurrent),
$"Unable to create template maui-multiproject. Check test output for errors.");
if (!TestEnvironment.IsWindows)
{
Assert.IsTrue(DotnetInternal.Run("sln", $"{solutionFile} remove {projectDir}/{name}.WinUI/{name}.WinUI.csproj"),
$"Unable to remove WinUI project from solution. Check test output for errors.");
}
Assert.IsTrue(DotnetInternal.Build(solutionFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Solution {name} failed to build. Check test output/attachments for errors.");
}
[Test]
// with spaces
[TestCase("maui", "Project Space", "projectspace")]
[TestCase("maui-blazor", "Project Space", "projectspace")]
[TestCase("mauilib", "Project Space", "projectspace")]
// with invalid characters
[TestCase("maui", "Project@Symbol", "projectsymbol")]
[TestCase("maui-blazor", "Project@Symbol", "projectsymbol")]
[TestCase("mauilib", "Project@Symbol", "projectsymbol")]
public void BuildsWithSpecialCharacters(string id, string projectName, string expectedId)
{
var projectDir = Path.Combine(TestDirectory, projectName);
var projectFile = Path.Combine(projectDir, $"{projectName}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
// libraries do not have application IDs
if (id != "mauilib")
{
var doc = XDocument.Load(projectFile);
// Check the app ID got invalid characters removed
var appId = doc.Root!
.Elements("PropertyGroup")
.Elements("ApplicationId")
.Single()
.Value;
Assert.AreEqual($"com.companyname.{expectedId}", appId);
// Check the app title matches the project name exactly (it might have been XML-encoded, but loading the document decodes that)
var appTitle = doc.Root!
.Elements("PropertyGroup")
.Elements("ApplicationTitle")
.Single()
.Value;
Assert.AreEqual(projectName, appTitle);
}
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
// Parameters: short name, target framework, build config, use pack target
[TestCase("maui", DotNetPrevious, "Debug", false)]
[TestCase("maui", DotNetPrevious, "Release", false)]
[TestCase("maui", DotNetCurrent, "Debug", false)]
[TestCase("maui", DotNetCurrent, "Release", false)]
[TestCase("maui-blazor", DotNetPrevious, "Debug", false)]
[TestCase("maui-blazor", DotNetPrevious, "Release", false)]
[TestCase("maui-blazor", DotNetCurrent, "Debug", false)]
[TestCase("maui-blazor", DotNetCurrent, "Release", false)]
[TestCase("mauilib", DotNetPrevious, "Debug", true)]
[TestCase("mauilib", DotNetPrevious, "Release", true)]
[TestCase("mauilib", DotNetCurrent, "Debug", true)]
[TestCase("mauilib", DotNetCurrent, "Release", true)]
public void BuildWithMauiVersion(string id, string framework, string config, bool shouldPack)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
// set <MauiVersion> in the csproj as that is the reccommended place
var mv = framework == DotNetPrevious ? MauiVersionPrevious : MauiVersionCurrent;
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"<PropertyGroup><MauiVersion>{mv}</MauiVersion></PropertyGroup></Project>");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", "Debug", false)]
[TestCase("maui", "Release", false)]
[TestCase("maui-blazor", "Debug", false)]
[TestCase("maui-blazor", "Release", false)]
[TestCase("mauilib", "Debug", true)]
[TestCase("mauilib", "Release", true)]
public void PreviousDotNetCanUseLatestMaui(string id, string config, bool shouldPack)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetPrevious),
$"Unable to create template {id}. Check test output for errors.");
// TODO: fix this as we should be able to build tizen net8
// EnableTizen(projectFile);
if (shouldPack)
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><Version>1.0.0-preview.1</Version></PropertyGroup></Project>");
// set <MauiVersion> in the csproj as that is the reccommended place
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"""
<PropertyGroup>
<MauiVersion>{MauiPackageVersion}</MauiVersion>
<NoWarn>$(NoWarn);CS0618</NoWarn>
</PropertyGroup>
</Project>
""");
string target = shouldPack ? "Pack" : "";
Assert.IsTrue(DotnetInternal.Build(projectFile, config, target: target, properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", DotNetPrevious, "Debug")]
[TestCase("maui", DotNetPrevious, "Release")]
[TestCase("maui", DotNetCurrent, "Debug")]
[TestCase("maui", DotNetCurrent, "Release")]
[TestCase("maui-blazor", DotNetPrevious, "Debug")]
[TestCase("maui-blazor", DotNetPrevious, "Release")]
[TestCase("maui-blazor", DotNetCurrent, "Debug")]
[TestCase("maui-blazor", DotNetCurrent, "Release")]
public void BuildUnpackaged(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
"<UseMaui>true</UseMaui><WindowsPackageType>None</WindowsPackageType>");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", true, true)]
[TestCase("maui", true, false)]
[TestCase("maui", false, true)]
public void BuildWindowsAppSDKSelfContained(string id, bool wasdkself, bool netself)
{
if (TestEnvironment.IsMacOS)
Assert.Ignore("This test is designed for testing a windows build.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
$"""
<UseMaui>true</UseMaui>
<WindowsAppSDKSelfContained>{wasdkself}</WindowsAppSDKSelfContained>
<SelfContained>{netself}</SelfContained>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-windows10.0.19041.0");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", true, "None")]
[TestCase("maui", true, "MSIX")]
[TestCase("maui", false, "None")]
[TestCase("maui", false, "MSIX")]
public void BuildWindowsRidGraph(string id, bool useridgraph, string packageType)
{
if (TestEnvironment.IsMacOS)
Assert.Ignore("This test is designed for testing a windows build.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
$"""
<UseMaui>true</UseMaui>
<UseRidGraph>{useridgraph}</UseRidGraph>
<WindowsPackageType>{packageType}</WindowsPackageType>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-windows10.0.19041.0");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", "ios")]
[TestCase("maui", "maccatalyst")]
[TestCase("maui-blazor", "ios")]
[TestCase("maui-blazor", "maccatalyst")]
public void BuildWithCustomBundleResource(string id, string framework)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
File.WriteAllText(Path.Combine(projectDir, "Resources", "testfile.txt"), "Something here :)");
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
$"""
<ItemGroup>
<BundleResource Include="Resources\testfile.txt" />
</ItemGroup>
</Project>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-{framework}");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", $"{DotNetCurrent}-ios", "ios-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-x64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-arm64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-x64")]
public void PublishNativeAOT(string id, string framework, string runtimeIdentifier)
{
if (!TestEnvironment.IsMacOS)
Assert.Ignore("Publishing a MAUI iOS app with NativeAOT is only supported on a host MacOS system.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
var extendedBuildProps = PrepareNativeAotBuildProps();
string binLogFilePath = $"publish-{DateTime.UtcNow.ToFileTimeUtc()}.binlog";
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", framework: framework, properties: extendedBuildProps, runtimeIdentifier: runtimeIdentifier, binlogPath: binLogFilePath),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var actualWarnings = BuildWarningsUtilities.ReadNativeAOTWarningsFromBinLog(binLogFilePath);
actualWarnings.AssertNoWarnings();
}
[Test]
[TestCase("maui", $"{DotNetCurrent}-ios", "ios-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-arm64")]
[TestCase("maui", $"{DotNetCurrent}-ios", "iossimulator-x64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-arm64")]
[TestCase("maui", $"{DotNetCurrent}-maccatalyst", "maccatalyst-x64")]
public void PublishNativeAOTRootAllMauiAssemblies(string id, string framework, string runtimeIdentifier)
{
// This test follows the following guide: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/#publishing-a-test-application-for-aot
if (!TestEnvironment.IsMacOS)
Assert.Ignore("Publishing a MAUI iOS app with NativeAOT is only supported on a host MacOS system.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
var extendedBuildProps = PrepareNativeAotBuildProps();
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"""
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls.Foldable" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Controls.Maps" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Graphics.Skia" Version="$(MauiVersion)" />
</ItemGroup>
<ItemGroup>
<TrimmerRootAssembly Include="Microsoft.Maui" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Foldable" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Maps" />
<TrimmerRootAssembly Include="Microsoft.Maui.Controls.Xaml" />
<TrimmerRootAssembly Include="Microsoft.Maui.Essentials" />
<TrimmerRootAssembly Include="Microsoft.Maui.Graphics" />
<TrimmerRootAssembly Include="Microsoft.Maui.Graphics.Skia" />
<TrimmerRootAssembly Include="Microsoft.Maui.Maps" />
</ItemGroup>
</Project>
""");
string binLogFilePath = $"publish-{DateTime.UtcNow.ToFileTimeUtc()}.binlog";
Assert.IsTrue(DotnetInternal.Build(projectFile, "Release", framework: framework, properties: extendedBuildProps, runtimeIdentifier: runtimeIdentifier, binlogPath: binLogFilePath),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var actualWarnings = BuildWarningsUtilities.ReadNativeAOTWarningsFromBinLog(binLogFilePath);
actualWarnings.AssertNoWarnings();
}
private List<string> PrepareNativeAotBuildProps()
{
var extendedBuildProps = new List<string>(BuildProps);
extendedBuildProps.Add("PublishAot=true");
extendedBuildProps.Add("PublishAotUsingRuntimePack=true"); // TODO: This parameter will become obsolete https://github.com/dotnet/runtime/issues/87060 in net9
extendedBuildProps.Add("_IsPublishing=true"); // This makes 'dotnet build -r iossimulator-x64' equivalent to 'dotnet publish -r iossimulator-x64'
extendedBuildProps.Add("IlcTreatWarningsAsErrors=false");
extendedBuildProps.Add("TrimmerSingleWarn=false");
return extendedBuildProps;
}
[Test]
[TestCase("maui", DotNetCurrent, "Release")]
public void PublishUnpackaged(string id, string framework, string config)
{
if (!TestEnvironment.IsWindows)
Assert.Ignore("Running Windows templates is only supported on Windows.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
BuildProps.Add("WindowsPackageType=None");
Assert.IsTrue(DotnetInternal.Publish(projectFile, config, framework: $"{framework}-windows10.0.19041.0", properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var assetsRoot = Path.Combine(projectDir, $"bin/{config}/{framework}-windows10.0.19041.0/win10-x64/publish");
AssetExists("dotnet_bot.scale-100.png");
AssetExists("appiconLogo.scale-100.png");
AssetExists("OpenSans-Regular.ttf");
AssetExists("splashSplashScreen.scale-100.png");
AssetExists("AboutAssets.txt");
void AssetExists(string filename)
{
var fullpath = Path.Combine(assetsRoot!, filename);
Assert.IsTrue(File.Exists(fullpath),
$"Unable to find expected asset: {fullpath}");
}
}
/// <summary>
/// Tests the scenario where a .NET MAUI Library specifically uses UseMauiCore instead of UseMaui.
/// </summary>
[Test]
[TestCase("mauilib", DotNetPrevious, "Debug")]
[TestCase("mauilib", DotNetPrevious, "Release")]
[TestCase("mauilib", DotNetCurrent, "Debug")]
[TestCase("mauilib", DotNetCurrent, "Release")]
public void PackCoreLib(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
var projectSectionsToReplace = new Dictionary<string, string>()
{
{ "UseMaui", "UseMauiCore" }, // This is the key part of the test
{ "SingleProject", "EnablePreviewMsixTooling" },
};
if (framework != "net7.0")
{
// On versions after net7.0 this package reference also has to be updated to ensure the version of the MAUI Core package
// is specified and avoids the MA002 warning.
projectSectionsToReplace.Add("Include=\"Microsoft.Maui.Controls\"", "Include=\"Microsoft.Maui.Core\"");
}
FileUtilities.ReplaceInFile(projectFile, projectSectionsToReplace);
Directory.Delete(Path.Combine(projectDir, "Platforms"), recursive: true);
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", DotNetCurrent, "Debug")]
[TestCase("mauilib", DotNetCurrent, "Debug")]
[TestCase("maui-blazor", DotNetCurrent, "Debug")]
public void BuildWithoutPackageReference(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
"</Project>",
"<PropertyGroup><SkipValidateMauiImplicitPackageReferences>true</SkipValidateMauiImplicitPackageReferences></PropertyGroup></Project>");
FileUtilities.ReplaceInFile(projectFile,
"<PackageReference Include=\"Microsoft.Maui.Controls\" Version=\"$(MauiVersion)\" />",
"");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", "Debug", "2.0", "2")]
[TestCase("maui", "Release", "2.0", "2")]
[TestCase("maui", "Release", "0.3", "3")]
[TestCase("maui-blazor", "Debug", "2.0", "2")]
[TestCase("maui-blazor", "Release", "2.0", "2")]
[TestCase("maui-blazor", "Release", "0.3", "3")]
public void BuildWithDifferentVersionNumber(string id, string config, string display, string version)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir),
$"Unable to create template {id}. Check test output for errors.");
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
$"<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>",
$"<ApplicationDisplayVersion>{display}</ApplicationDisplayVersion>");
FileUtilities.ReplaceInFile(projectFile,
$"<ApplicationVersion>1</ApplicationVersion>",
$"<ApplicationVersion>{version}</ApplicationVersion>");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui-blazor", "Debug", DotNetCurrent)]
[TestCase("maui-blazor", "Release", DotNetCurrent)]
public void CheckEntitlementsForMauiBlazorOnMacCatalyst(string id, string config, string framework)
{
if (TestEnvironment.IsWindows)
Assert.Ignore("Running MacCatalyst templates is only supported on Mac.");
string projectDir = TestDirectory;
string projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
// Note: Debug app is stored in the maccatalyst-x64 folder, while the Release is in parent directory
string appLocation = config == "Release" ?
Path.Combine(projectDir, "bin", config, $"{framework}-maccatalyst", $"{Path.GetFileName(projectDir)}.app") :
Path.Combine(projectDir, "bin", config, $"{framework}-maccatalyst", "maccatalyst-x64", $"{Path.GetFileName(projectDir)}.app");
string entitlementsPath = Path.Combine(projectDir, "x.xml");
List<string> buildWithCodeSignProps = new List<string>(BuildProps)
{
"EnableCodeSigning=true"
};
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework), $"Unable to create template {id}. Check test output for errors.");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, framework: $"{framework}-maccatalyst", properties: buildWithCodeSignProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
List<string> expectedEntitlements =
new() { "com.apple.security.app-sandbox", "com.apple.security.network.client" };
List<string> foundEntitlements = Codesign.SearchForExpectedEntitlements(entitlementsPath, appLocation, expectedEntitlements);
CollectionAssert.AreEqual(expectedEntitlements, foundEntitlements, "Entitlements missing from executable.");
}
[Test]
[TestCase("maui-blazor", "Debug", DotNetCurrent)]
[TestCase("maui-blazor", "Release", DotNetCurrent)]
[TestCase("maui", "Debug", DotNetCurrent)]
[TestCase("maui", "Release", DotNetCurrent)]
[TestCase("maui-multiproject", "Debug", DotNetCurrent)]
[TestCase("maui-multiproject", "Release", DotNetCurrent)]
public void CheckPrivacyManifestForiOS(string id, string config, string framework)
{
if (TestEnvironment.IsWindows)
{
Assert.Ignore("Running iOS templates is only supported on Mac.");
}
string projectDir = TestDirectory;
string projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
string appFileName = $"{Path.GetFileName(projectDir)}.app";
string appLocation =
Path.Combine(projectDir, "bin", config, $"{framework}-ios", "iossimulator-x64", appFileName);
// Multi-project is in a .iOS subfolder and csproj is *.iOS.csproj
if (id.EndsWith("multiproject"))
{
projectFile =
Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.iOS", $"{Path.GetFileName(projectDir)}.iOS.csproj");
appFileName = $"{Path.GetFileName(projectDir)}.iOS.app";
appLocation =
Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.iOS", "bin", config, $"{framework}-ios", "iossimulator-x64", appFileName);
}
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework), $"Unable to create template {id}. Check test output for errors.");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, framework: $"{framework}-ios", msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
string manifestLocation = Path.Combine(appLocation, "PrivacyInfo.xcprivacy");
Assert.IsTrue(File.Exists(manifestLocation), $"Privacy Manifest not found in {manifestLocation}.");
}
[Test]
public void BuildHandlesBadFilesInImages()
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New("maui", projectDir, DotNetCurrent),
$"Unable to create template maui. Check test output for errors.");
EnableTizen(projectFile);
File.WriteAllText(Path.Combine(projectDir, "Resources", "Images", ".DS_Store"), "Boom!");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
void EnableTizen(string projectFile)
{
FileUtilities.ReplaceInFile(projectFile, new Dictionary<string, string>()
{
{ "<!-- <TargetFrameworks>", "<TargetFrameworks>" },
{ "</TargetFrameworks> -->", "</TargetFrameworks>" },
});
}
}
}

Просмотреть файл

@ -1,7 +1,6 @@
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging.StructuredLogger;
using static Microsoft.Maui.IntegrationTests.TemplateTests;
namespace Microsoft.Maui.IntegrationTests
{

Просмотреть файл

@ -0,0 +1,19 @@
namespace Microsoft.Maui.IntegrationTests;
static class Categories
{
// this is a special job that runs on the samples
public const string Samples = nameof(Samples);
// these are special run on "device" jobs
public const string RunOnAndroid = nameof(RunOnAndroid);
public const string RunOniOS = nameof(RunOniOS);
// these are normal jobs
public const string WindowsTemplates = nameof(WindowsTemplates);
public const string macOSTemplates = nameof(macOSTemplates);
public const string Build = nameof(Build);
public const string Blazor = nameof(Blazor);
public const string MultiProject = nameof(MultiProject);
public const string AOT = nameof(AOT);
}

Просмотреть файл

@ -0,0 +1,169 @@
namespace Microsoft.Maui.IntegrationTests;
[Category(Categories.WindowsTemplates)]
public class WindowsTemplateTest : BaseTemplateTests
{
[Test]
[TestCase("maui", DotNetPrevious, "Debug")]
[TestCase("maui", DotNetPrevious, "Release")]
[TestCase("maui", DotNetCurrent, "Debug")]
[TestCase("maui", DotNetCurrent, "Release")]
[TestCase("maui-blazor", DotNetPrevious, "Debug")]
[TestCase("maui-blazor", DotNetPrevious, "Release")]
[TestCase("maui-blazor", DotNetCurrent, "Debug")]
[TestCase("maui-blazor", DotNetCurrent, "Release")]
public void BuildUnpackaged(string id, string framework, string config)
{
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
// TODO: remove this if as we should be able to build tizen net8
if (framework != DotNetPrevious)
EnableTizen(projectFile);
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
"""
<UseMaui>true</UseMaui>
<WindowsPackageType>None</WindowsPackageType>
""");
Assert.IsTrue(DotnetInternal.Build(projectFile, config, properties: BuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", true, true, "None")]
[TestCase("maui", true, true, "MSIX")]
[TestCase("maui", true, false, "None")]
[TestCase("maui", true, false, "MSIX")]
[TestCase("maui", false, true, "None")]
[TestCase("maui", false, true, "MSIX")]
[TestCase("maui", false, false, "None")]
[TestCase("maui", false, false, "MSIX")]
public void BuildWindowsAppSDKSelfContained(string id, bool wasdkself, bool netself, string packageType)
{
if (TestEnvironment.IsMacOS)
Assert.Ignore("This test is designed for testing a windows build.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
$"""
<UseMaui>true</UseMaui>
<WindowsAppSDKSelfContained>{wasdkself}</WindowsAppSDKSelfContained>
<SelfContained>{netself}</SelfContained>
<WindowsPackageType>{packageType}</WindowsPackageType>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-windows10.0.19041.0");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", true, "None")]
[TestCase("maui", true, "MSIX")]
[TestCase("maui", false, "None")]
[TestCase("maui", false, "MSIX")]
public void BuildWindowsRidGraph(string id, bool useridgraph, string packageType)
{
if (TestEnvironment.IsMacOS)
Assert.Ignore("This test is designed for testing a windows build.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, DotNetCurrent),
$"Unable to create template {id}. Check test output for errors.");
FileUtilities.ReplaceInFile(projectFile,
"<UseMaui>true</UseMaui>",
$"""
<UseMaui>true</UseMaui>
<UseRidGraph>{useridgraph}</UseRidGraph>
<WindowsPackageType>{packageType}</WindowsPackageType>
""");
var extendedBuildProps = BuildProps;
extendedBuildProps.Add($"TargetFramework={DotNetCurrent}-windows10.0.19041.0");
Assert.IsTrue(DotnetInternal.Build(projectFile, "Debug", properties: extendedBuildProps, msbuildWarningsAsErrors: true),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
}
[Test]
[TestCase("maui", DotNetCurrent, "Release")]
[TestCase("maui-blazor", DotNetCurrent, "Release")]
public void PublishUnpackaged(string id, string framework, string config)
{
if (!TestEnvironment.IsWindows)
Assert.Ignore("Running Windows templates is only supported on Windows.");
var projectDir = TestDirectory;
var projectFile = Path.Combine(projectDir, $"{Path.GetFileName(projectDir)}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
BuildProps.Add("WindowsPackageType=None");
Assert.IsTrue(DotnetInternal.Publish(projectFile, config, framework: $"{framework}-windows10.0.19041.0", properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var assetsRoot = Path.Combine(projectDir, $"bin/{config}/{framework}-windows10.0.19041.0/win10-x64/publish");
AssetExists("dotnet_bot.scale-100.png");
AssetExists("appiconLogo.scale-100.png");
AssetExists("OpenSans-Regular.ttf");
AssetExists("splashSplashScreen.scale-100.png");
AssetExists("AboutAssets.txt");
void AssetExists(string filename)
{
var fullpath = Path.Combine(assetsRoot!, filename);
Assert.IsTrue(File.Exists(fullpath),
$"Unable to find expected asset: {fullpath}");
}
}
[Test]
[TestCase("maui", DotNetCurrent, "Release")]
[TestCase("maui-blazor", DotNetCurrent, "Release")]
public void PublishPackaged(string id, string framework, string config)
{
if (!TestEnvironment.IsWindows)
Assert.Ignore("Running Windows templates is only supported on Windows.");
var projectDir = TestDirectory;
var name = Path.GetFileName(projectDir);
var projectFile = Path.Combine(projectDir, $"{name}.csproj");
Assert.IsTrue(DotnetInternal.New(id, projectDir, framework),
$"Unable to create template {id}. Check test output for errors.");
Assert.IsTrue(DotnetInternal.Publish(projectFile, config, framework: $"{framework}-windows10.0.19041.0", properties: BuildProps),
$"Project {Path.GetFileName(projectFile)} failed to build. Check test output/attachments for errors.");
var assetsRoot = Path.Combine(projectDir, $"bin/{config}/{framework}-windows10.0.19041.0/win10-x64/AppPackages/{name}_1.0.0.1_Test");
AssetExists($"{name}_1.0.0.1_x64.msix");
void AssetExists(string filename)
{
var fullpath = Path.Combine(assetsRoot!, filename);
Assert.IsTrue(File.Exists(fullpath),
$"Unable to find expected asset: {fullpath}");
}
}
}