Skip to content

Commit 93feb35

Browse files
committed
test(e2e): add comprehensive E2E test suite for SDK features
- Add 14 E2E test projects covering all SDK features: - E2E.Minimal: Core SDK defaults - E2E.AutoIncludes: VSCT and VSPackage.resx auto-inclusion - E2E.SourceGenerators: VsixInfo and VsctGuids generation - E2E.VersionOverride: Version handling and SetVsixVersion - E2E.CustomPkgDef: Auto-generated + custom pkgdef files - E2E.ManualPkgDef: Manual pkgdef without auto-generation - E2E.ImageAndContentManifest: imagemanifest and ContentManifest.json - E2E.Validation: Build warnings for common issues - E2E.ValidationNoManifest: Missing manifest warning - E2E.Templates.AutoDiscovery: Template auto-discovery - E2E.Templates.PreBuiltZip: VsixTemplateZip support - E2E.Templates.SharedSource: Helper project for cross-ref - E2E.Templates.CrossProjectRef: VsixTemplateReference - E2E.Templates.ManualWithSubPath: Explicit templates with TargetSubPath - E2E.AllFeatures: Comprehensive test combining all features - Update CI/CD workflow to build all E2E projects - Add VSIX content verification steps Closes #32
1 parent f012121 commit 93feb35

File tree

91 files changed

+1775
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1775
-0
lines changed

.github/workflows/build.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ on:
66
paths:
77
- 'src/**'
88
- 'samples/**'
9+
- 'tests/**'
910
- '.github/workflows/build.yml'
1011
pull_request:
1112
branches: [main]
1213
paths:
1314
- 'src/**'
1415
- 'samples/**'
16+
- 'tests/**'
1517
- '.github/workflows/build.yml'
1618

1719
jobs:
@@ -39,6 +41,83 @@ jobs:
3941
- name: Build Sample Extension
4042
run: dotnet build samples/SampleExtension/SampleExtension.csproj -c Release
4143

44+
# E2E Tests - Build all test projects
45+
- name: Build E2E.Minimal
46+
run: dotnet build tests/e2e/E2E.Minimal/E2E.Minimal.csproj -c Release
47+
48+
- name: Build E2E.AutoIncludes
49+
run: dotnet build tests/e2e/E2E.AutoIncludes/E2E.AutoIncludes.csproj -c Release
50+
51+
- name: Build E2E.SourceGenerators
52+
run: dotnet build tests/e2e/E2E.SourceGenerators/E2E.SourceGenerators.csproj -c Release
53+
54+
- name: Build E2E.VersionOverride
55+
run: dotnet build tests/e2e/E2E.VersionOverride/E2E.VersionOverride.csproj -c Release
56+
57+
- name: Build E2E.VersionOverride with SetVsixVersion
58+
run: dotnet build tests/e2e/E2E.VersionOverride/E2E.VersionOverride.csproj -c Release -p:SetVsixVersion=2.0.0
59+
60+
- name: Build E2E.CustomPkgDef
61+
run: dotnet build tests/e2e/E2E.CustomPkgDef/E2E.CustomPkgDef.csproj -c Release
62+
63+
- name: Build E2E.ManualPkgDef
64+
run: dotnet build tests/e2e/E2E.ManualPkgDef/E2E.ManualPkgDef.csproj -c Release
65+
66+
- name: Build E2E.ImageAndContentManifest
67+
run: dotnet build tests/e2e/E2E.ImageAndContentManifest/E2E.ImageAndContentManifest.csproj -c Release
68+
69+
- name: Build E2E.Validation (expect warnings)
70+
run: dotnet build tests/e2e/E2E.Validation/E2E.Validation.csproj -c Release
71+
72+
- name: Build E2E.ValidationNoManifest (expect warnings)
73+
run: dotnet build tests/e2e/E2E.ValidationNoManifest/E2E.ValidationNoManifest.csproj -c Release
74+
75+
- name: Build E2E.Templates.AutoDiscovery
76+
run: dotnet build tests/e2e/E2E.Templates.AutoDiscovery/E2E.Templates.AutoDiscovery.csproj -c Release
77+
78+
- name: Build E2E.Templates.PreBuiltZip
79+
run: dotnet build tests/e2e/E2E.Templates.PreBuiltZip/E2E.Templates.PreBuiltZip.csproj -c Release
80+
81+
- name: Build E2E.Templates.CrossProjectRef
82+
run: dotnet build tests/e2e/E2E.Templates.CrossProjectRef/E2E.Templates.CrossProjectRef.csproj -c Release
83+
84+
- name: Build E2E.Templates.ManualWithSubPath
85+
run: dotnet build tests/e2e/E2E.Templates.ManualWithSubPath/E2E.Templates.ManualWithSubPath.csproj -c Release
86+
87+
- name: Build E2E.AllFeatures
88+
run: dotnet build tests/e2e/E2E.AllFeatures/E2E.AllFeatures.csproj -c Release
89+
90+
# VSIX Verification - Check that VSIX files contain expected content
91+
- name: Verify E2E.Minimal VSIX
92+
run: |
93+
$vsix = "tests/e2e/E2E.Minimal/bin/Release/E2E.Minimal.vsix"
94+
if (!(Test-Path $vsix)) { throw "VSIX not found: $vsix" }
95+
Expand-Archive -Path $vsix -DestinationPath "tests/e2e/E2E.Minimal/vsix-contents" -Force
96+
$files = Get-ChildItem -Path "tests/e2e/E2E.Minimal/vsix-contents" -Recurse -File | Select-Object -ExpandProperty Name
97+
if ($files -notcontains "extension.vsixmanifest") { throw "Missing extension.vsixmanifest" }
98+
if ($files -notcontains "E2E.Minimal.dll") { throw "Missing E2E.Minimal.dll" }
99+
Write-Host "E2E.Minimal VSIX verified successfully"
100+
101+
- name: Verify E2E.Templates.AutoDiscovery VSIX
102+
run: |
103+
$vsix = "tests/e2e/E2E.Templates.AutoDiscovery/bin/Release/E2E.Templates.AutoDiscovery.vsix"
104+
if (!(Test-Path $vsix)) { throw "VSIX not found: $vsix" }
105+
Expand-Archive -Path $vsix -DestinationPath "tests/e2e/E2E.Templates.AutoDiscovery/vsix-contents" -Force
106+
$files = Get-ChildItem -Path "tests/e2e/E2E.Templates.AutoDiscovery/vsix-contents" -Recurse | Select-Object -ExpandProperty Name
107+
if ($files -notcontains "ConsoleApp.zip") { throw "Missing ProjectTemplates/ConsoleApp.zip" }
108+
if ($files -notcontains "NewClass.zip") { throw "Missing ItemTemplates/NewClass.zip" }
109+
Write-Host "E2E.Templates.AutoDiscovery VSIX verified successfully"
110+
111+
- name: Verify E2E.AllFeatures VSIX
112+
run: |
113+
$vsix = "tests/e2e/E2E.AllFeatures/bin/Release/E2E.AllFeatures.vsix"
114+
if (!(Test-Path $vsix)) { throw "VSIX not found: $vsix" }
115+
Expand-Archive -Path $vsix -DestinationPath "tests/e2e/E2E.AllFeatures/vsix-contents" -Force
116+
$files = Get-ChildItem -Path "tests/e2e/E2E.AllFeatures/vsix-contents" -Recurse | Select-Object -ExpandProperty Name
117+
if ($files -notcontains "extension.vsixmanifest") { throw "Missing extension.vsixmanifest" }
118+
if ($files -notcontains "E2E.AllFeatures.dll") { throw "Missing E2E.AllFeatures.dll" }
119+
Write-Host "E2E.AllFeatures VSIX verified successfully"
120+
42121
- name: Test Template - Install
43122
run: dotnet new install artifacts/packages/CodingWithCalvin.VsixSdk.Templates.1.0.0.nupkg
44123

tests/e2e/Directory.Build.props

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project>
2+
<!--
3+
For E2E testing, we add VSIX SDK behavior on top of Microsoft.NET.Sdk.
4+
The E2E test projects use Sdk="Microsoft.NET.Sdk" directly.
5+
-->
6+
7+
<PropertyGroup>
8+
<!-- Path to local SDK files -->
9+
<CodingWithCalvinVsixSdkRoot>$(MSBuildThisFileDirectory)..\..\src\CodingWithCalvin.VsixSdk\</CodingWithCalvinVsixSdkRoot>
10+
11+
<!-- Signal that we're running in local development mode -->
12+
<CodingWithCalvinVsixSdkLocalDev>true</CodingWithCalvinVsixSdkLocalDev>
13+
</PropertyGroup>
14+
15+
<!-- Import VSIX-specific properties (after Microsoft.NET.Sdk.props is imported by the project) -->
16+
<Import Project="$(CodingWithCalvinVsixSdkRoot)Sdk\Sdk.Vsix.props" />
17+
18+
</Project>

tests/e2e/Directory.Build.targets

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project>
2+
<!--
3+
For E2E testing, import the VSIX-specific targets.
4+
These add VSIX build behavior without importing Microsoft.NET.Sdk again.
5+
-->
6+
7+
<!-- Import VSIX-specific item includes and targets -->
8+
<Import Project="$(CodingWithCalvinVsixSdkRoot)Sdk\Sdk.Vsix.targets" />
9+
10+
<!-- Reference the source generators for local development -->
11+
<ItemGroup Condition="'$(CodingWithCalvinVsixSdkLocalDev)' == 'true'">
12+
<Analyzer Include="$(CodingWithCalvinVsixSdkRoot)..\CodingWithCalvin.VsixSdk.Generators\bin\$(Configuration)\netstandard2.0\CodingWithCalvin.VsixSdk.Generators.dll" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
4+
<Extern href="stdidcmd.h"/>
5+
<Extern href="vsshlids.h"/>
6+
7+
<Commands package="guidAllFeaturesPackage">
8+
<Groups>
9+
<Group guid="guidAllFeaturesCommandSet" id="AllFeaturesMenuGroup" priority="0x0600">
10+
<Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
11+
</Group>
12+
</Groups>
13+
14+
<Buttons>
15+
<Button guid="guidAllFeaturesCommandSet" id="AllFeaturesCommand" priority="0x0100" type="Button">
16+
<Parent guid="guidAllFeaturesCommandSet" id="AllFeaturesMenuGroup" />
17+
<Strings>
18+
<ButtonText>All Features Command</ButtonText>
19+
</Strings>
20+
</Button>
21+
</Buttons>
22+
</Commands>
23+
24+
<Symbols>
25+
<GuidSymbol name="guidAllFeaturesPackage" value="{DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD}" />
26+
<GuidSymbol name="guidAllFeaturesCommandSet" value="{EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE}">
27+
<IDSymbol name="AllFeaturesMenuGroup" value="0x1020" />
28+
<IDSymbol name="AllFeaturesCommand" value="0x0100" />
29+
</GuidSymbol>
30+
</Symbols>
31+
32+
</CommandTable>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; Custom pkgdef settings for AllFeatures test
2+
3+
[$RootKey$\E2E\AllFeatures]
4+
"AllFeaturesEnabled"=dword:00000001
5+
"CustomSetting"="AllFeaturesValue"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<!--
2+
E2E.AllFeatures - Comprehensive test combining ALL SDK features.
3+
4+
Validates:
5+
- All features work together without conflicts
6+
- VSCT + templates + generators + version all coexist
7+
- Complete VSIX package produced
8+
-->
9+
<Project Sdk="Microsoft.NET.Sdk">
10+
11+
<PropertyGroup>
12+
<Version>1.0.0</Version>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.*" />
17+
</ItemGroup>
18+
19+
<!-- Pre-built template zip -->
20+
<ItemGroup>
21+
<VsixTemplateZip Include="PreBuilt\PreBuilt.zip" TemplateType="Project" />
22+
</ItemGroup>
23+
24+
<!-- Cross-project template reference -->
25+
<ItemGroup>
26+
<VsixTemplateReference Include="..\E2E.Templates.SharedSource\E2E.Templates.SharedSource.csproj"
27+
TemplateType="Project"
28+
TemplatePath="Templates\SharedProject" />
29+
</ItemGroup>
30+
31+
<!-- Manual template with subpath -->
32+
<ItemGroup>
33+
<VsixProjectTemplate Include="ManualTemplates\ManualProject" TargetSubPath="Manual" />
34+
</ItemGroup>
35+
36+
<!-- Custom pkgdef files -->
37+
<ItemGroup>
38+
<PkgDefToMerge Include="CustomSettings.pkgdef" />
39+
</ItemGroup>
40+
41+
<!-- Target to create pre-built zip if needed -->
42+
<Target Name="CreatePreBuiltZip" BeforeTargets="PrepareForBuild">
43+
<MakeDir Directories="PreBuilt" Condition="!Exists('PreBuilt')" />
44+
<ZipDirectory SourceDirectory="PreBuiltSource\PreBuiltProject"
45+
DestinationFile="PreBuilt\PreBuilt.zip"
46+
Overwrite="true"
47+
Condition="Exists('PreBuiltSource\PreBuiltProject') and !Exists('PreBuilt\PreBuilt.zip')" />
48+
</Target>
49+
50+
</Project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Threading;
4+
using Microsoft.VisualStudio.Shell;
5+
using Task = System.Threading.Tasks.Task;
6+
7+
namespace E2E.AllFeatures
8+
{
9+
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
10+
[Guid("00000000-0000-0000-0000-00000000000D")]
11+
public sealed class E2EAllFeaturesPackage : AsyncPackage
12+
{
13+
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
14+
{
15+
await base.InitializeAsync(cancellationToken, progress);
16+
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
17+
}
18+
}
19+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This file uses generated constants to verify all generators work together.
2+
3+
using System;
4+
5+
namespace E2E.AllFeatures
6+
{
7+
/// <summary>
8+
/// Consumes generated constants to verify all features work together.
9+
/// </summary>
10+
public static class FeatureConsumer
11+
{
12+
// VsixInfo constants
13+
public static string ExtensionId => VsixInfo.Id;
14+
public static string ExtensionDisplayName => VsixInfo.DisplayName;
15+
16+
// VSCT constants
17+
public static Guid PackageGuid => AllCommandsVsct.guidAllFeaturesPackage;
18+
public static int CommandId => AllCommandsVsct.guidAllFeaturesCommandSet.AllFeaturesCommand;
19+
20+
/// <summary>
21+
/// Validates that all generated constants are available.
22+
/// </summary>
23+
public static void ValidateAllFeatures()
24+
{
25+
if (string.IsNullOrEmpty(ExtensionId))
26+
throw new InvalidOperationException("VsixInfo.Id is empty");
27+
28+
if (PackageGuid == Guid.Empty)
29+
throw new InvalidOperationException("Package GUID is empty");
30+
31+
if (CommandId != 0x0100)
32+
throw new InvalidOperationException("Command ID has wrong value");
33+
}
34+
}
35+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
3+
<TemplateData>
4+
<Name>Auto-Discovered Item</Name>
5+
<Description>Auto-discovered item template in AllFeatures</Description>
6+
<ProjectType>CSharp</ProjectType>
7+
<DefaultName>AutoItem.cs</DefaultName>
8+
</TemplateData>
9+
<TemplateContent>
10+
<ProjectItem ReplaceParameters="true" TargetFileName="$fileinputname$.cs">Item.cs</ProjectItem>
11+
</TemplateContent>
12+
</VSTemplate>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace $rootnamespace$
2+
{
3+
public class $safeitemname$ { }
4+
}

0 commit comments

Comments
 (0)