15 | {
16 | public MainShellThemeTest(Fixture fixture, ITestOutputHelper outputHelper) : base(fixture, outputHelper)
17 | {
18 | }
19 |
20 | [Fact]
21 | public void MainWindow()
22 | {
23 | // setup - dismiss start window
24 | _ = Retry.While(() => this.App.GetMainWindow(BaseTest.Automation).ModalWindows.Length, x => x > 0);
25 | Thread.Sleep(100);
26 | using (var s = this.Scenario(nameof(MainWindow)))
27 | {
28 | this.App.GetMainWindow(BaseTest.Automation).Click();
29 | s.Snapshot("EmptyEnvironment");
30 | }
31 | }
32 |
33 | [Fact]
34 | public void TopLevelMenus()
35 | {
36 | var mainWindow = this.App.GetMainWindow(BaseTest.Automation);
37 | var menuBar = mainWindow.FindFirstByXPath("//MenuBar[@AutomationId='MenuBar']").AsMenu();
38 | using (var s = this.Scenario(nameof(TopLevelMenus), menuBar))
39 | {
40 | s.Snapshot("MainMenu");
41 | var items = menuBar.Items.Select(s => s.AsMenuItem()).ToArray();
42 |
43 | // single item focused
44 | items[0].Focus();
45 | s.Snapshot($"MenuFocused", items[0]);
46 |
47 | // each menu expanded
48 | foreach (var item in items)
49 | {
50 | _ = item.Expand();
51 | // ensure the children items have rendered
52 | _ = Retry.WhileFalse(() => item.Items.All(y => !y.IsOffscreen));
53 | s.Snapshot($"{item.Name}.Opened", mainWindow);
54 | _ = item.Collapse();
55 | }
56 | }
57 | }
58 |
59 | [Fact]
60 | public void ErrorList()
61 | {
62 | var mainWindow = this.App.GetMainWindow(BaseTest.Automation);
63 | var viewMenuItem = mainWindow.FindFirstByXPath("//MenuItem[@Name='View']").AsMenuItem();
64 | var errorListMenuItem = viewMenuItem.Items.Single(x => x.Name == "Error List").AsMenuItem();
65 | _ = errorListMenuItem.Invoke();
66 |
67 | var errorList = Retry.WhileNull(() => mainWindow.FindFirstByXPath("//Pane[contains(@Name, 'Error List')]")).Result;
68 | using (var scenario = this.Scenario(nameof(ErrorList), errorList))
69 | {
70 | using (var s = this.Scenario("ScopeCombo", errorList))
71 | {
72 | var scopeCombo = errorList.FindFirstByXPath("//ComboBox[@Name='Show items contained by']").AsComboBox();
73 | s.Snapshot($"{nameof(scopeCombo)}.Default");
74 | scopeCombo.MoveToElement();
75 | s.Snapshot($"{nameof(scopeCombo)}.Hovered");
76 | scopeCombo.Expand();
77 | _ = Retry.WhileFalse(() => scopeCombo.Items.All(i => !i.IsOffscreen));
78 | s.Snapshot($"{nameof(scopeCombo)}.Expanded");
79 | scopeCombo.Items[1].Focus();
80 | var r = Retry.WhileFalse(() => scopeCombo.Items[1].Properties.HasKeyboardFocus);
81 | this.Logger.WriteInfo($"Retries: {r.Iterations}");
82 | s.Snapshot($"{nameof(scopeCombo)}.ItemFocus");
83 | // reset
84 | _ = scopeCombo.Items[0].Select();
85 | scopeCombo.Collapse();
86 | }
87 |
88 | using (var s = this.Scenario("ToolbarButton", errorList))
89 | {
90 | var errorButton = errorList.FindFirstByXPath("//Button[contains(@Name, 'Errors')]").AsToggleButton();
91 | s.Snapshot($"{nameof(errorButton)}.ToggleOn");
92 | errorButton.MoveToElement();
93 | s.Snapshot($"{nameof(errorButton)}.Hovered");
94 | // Seems there is a bug in UIA or maybe VS here - Toggle or Click doesn't update the UI, only
95 | // a full mouse move and click emulation does the trick
96 | errorButton.Click(moveMouse: true);
97 | s.Snapshot($"{nameof(errorButton)}.Clicked");
98 | errorList.MoveToElement();
99 | this.Logger.WriteInfo($"Toggle state: {errorButton.ToggleState}");
100 | s.Snapshot($"{nameof(errorButton)}.ToggleOff");
101 | errorButton.Toggle();
102 | this.Logger.WriteInfo($"Toggle state: {errorButton.ToggleState}");
103 | }
104 | }
105 | }
106 |
107 | [Fact]
108 | public void OutputWindow()
109 | {
110 | var mainWindow = this.App.GetMainWindow(BaseTest.Automation);
111 | try
112 | {
113 | // Open a solution so text appears in output window
114 | this.App.OpenSolution(@"CSharpApp\CSharpApp.sln");
115 |
116 | var viewMenuItem = mainWindow.FindFirstByXPath("//MenuItem[@Name='View']").AsMenuItem();
117 | var outputMenuItem = viewMenuItem.Items.Single(x => x.Name == "Output").AsMenuItem();
118 | _ = outputMenuItem.Invoke();
119 |
120 | var outputWindow = Retry.WhileNull(() => mainWindow.FindFirstByXPath("//Pane[contains(@Name, 'Output')]")).Result;
121 | using var scenario = this.Scenario(nameof(OutputWindow), outputWindow);
122 | scenario.Snapshot("OutputWindow");
123 | }
124 | finally
125 | {
126 | this.App.CloseSolution();
127 | }
128 | }
129 |
130 | [Fact]
131 | public void EditorLanguages()
132 | {
133 | var mainWindow = this.App.GetMainWindow(BaseTest.Automation);
134 | try
135 | {
136 | using var scenario = this.Scenario(nameof(EditorLanguages), mainWindow);
137 |
138 | this.App.OpenSolution(@"CSharpApp\CSharpApp.sln");
139 |
140 | // Open every file located in the Languages folder
141 | this.App.OpenSolutionExplorer();
142 | var solutionExplorer = this.App.GetSolutionExplorer();
143 | var languagesTreeItem = solutionExplorer.SelectFile("CSharpApp", "Languages");
144 | var fileNames = languagesTreeItem.FindAllChildren().Select(element => element.Name);
145 |
146 | foreach (var fileName in fileNames)
147 | {
148 | solutionExplorer.OpenFile("CSharpApp", "Languages", fileName);
149 | var editor = this.App.GetTextEditor();
150 | scenario.Snapshot(fileName, editor);
151 | this.App.CloseAllTabs();
152 | }
153 | }
154 | finally
155 | {
156 | this.App.CloseSolution();
157 | }
158 | }
159 |
160 | [Fact]
161 | public void ToolsOptionsDialog()
162 | {
163 | {
164 | var mainWindow = this.App.GetMainVSWindow();
165 | var toolsMenu = mainWindow.FindFirstDescendant(cf => cf.ByName("Tools").And(cf.ByControlType(FlaUI.Core.Definitions.ControlType.MenuItem))).AsMenuItem();
166 | toolsMenu.Click();
167 | var optionsMenu = toolsMenu.Items.Single(i => i.Name == "Options...");
168 | _ = optionsMenu.Invoke();
169 | var toolsOptions = this.App.GetOptionsDialogWindow();
170 | using (var scenario = this.Scenario(nameof(ToolsOptionsDialog), toolsOptions))
171 | {
172 | scenario.Snapshot("Tools Options");
173 | toolsOptions.Close();
174 | }
175 | }
176 | }
177 |
178 | public class Fixture : ThemeTestFixture
179 | {
180 | public Fixture(IMessageSink messageSink) : base(messageSink)
181 | {
182 | var window = this.App.GetGetToCodeWindow();
183 | window.PressContinueWithoutCodeButton();
184 | }
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/ManualTestFiles/BasicTests.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | This test plan is for verifying whether a theme converted by [Theme-Converter](https://github.com/microsoft/theme-converter/tree/main/ThemeConverter/ThemeConverter) will severely break the readability on common user workflows.
4 | For each step, observe if the UI is readable under default/selected/hovered situation, when the window has focus and doesn't have focus.
5 |
6 | # Prerequisites
7 |
8 | VS 2022 Preview 3 or later, with the theme to be tested installed.
9 | VS Code *(optional)*
10 |
11 | ### Note
12 |
13 | Scenarios marked with **VS Code compare** in the title should be compared with VS Code to see if there's any obvious color mismatch.
14 |
15 | # Scenarios
16 |
17 | ## Scenario 1: Create a new project from the Start Window
18 |
19 | 1. Open the Start Window: navigate to File -> Start Window; select the Start Window icon from the toolbar;
20 | 2. Select "Create a new project"
21 | 3. Create a new project using an available template
22 |
23 | ## Scenario 2: Editing a file (VS Code Compare)
24 |
25 | 1. Open different types of files ([sample files](https://github.com/kai-oswald/NightOwl-VS-Theme/tree/master/demo))
26 |
27 | ## Scenario 3: Debugging (VS Code Compare)
28 |
29 | 1. Open the project created earlier and place a breakpoint
30 | 2. Start debugging
31 | 3. Open different debug windows
32 |
33 | ### VS Code instruction:
34 |
35 | 1. Open the project's folder (File > Open Folder...)
36 | 2. Place a breakpoint at the same location
37 | 3. Select Run > Start Debugging
38 |
39 | ## Scenario 4: Install extension from extension manager
40 |
41 | 1. Open Extensions > Manage Extensions
42 | 2. Open different pages and try to scroll/select items
43 |
44 | ## Scenario 5: Run/debug unit tests
45 |
46 | 1. Create a unit test project with some basic test methods
47 | 2. Open Test > Test Explorer
48 | 3. Run/Debug/Select tests.
49 |
50 | ## Scenario 6: Solution Explorer (VS Code Compare)
51 |
52 | 1. Open a project and open the solution explorer
53 | 2. Try selecting/right clicking
54 | 3. Do a search
55 |
56 | ### VS Code instruction:
57 |
58 | 1. The corresponding page is the File Explorer
59 |
60 | 
61 |
62 | 2. The search window will be invoked by 'Ctrl + T`
63 |
64 | ## Scenario 7: Version Control (VS Code Compare)
65 |
66 | 1. Clone a git repo
67 | 2. Open View > Git Changes
68 | 3. Edit some files and check the window
69 |
70 | ### VS Code instruction:
71 |
72 | 1. Corresponding page is the Source Control window:
73 |
74 | 
75 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/README.md:
--------------------------------------------------------------------------------
1 | # ThemeTests README
2 |
3 | This project provides some basic infrastructure to make testing theme changes across UI surface area less tedious and more consistent.
4 |
5 | To run tests - build the project, then choose one or more tests or feature areas to capture UI for from Test Explorer.
6 |
7 | Each test will drive the UI and take screenshots of UI in various states. This uses UIA and keyboard/mouse emulation - so try not to multitask on the machine while the tests are running.
8 |
9 | When the tests are done, there will be a link to the output folder in the Test Explorer summary pane. You'll find a variety of screenshots for the scenarios you choose to run, and can look through these to make sure your changes look good or haven't regressed.
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/CSharpApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/CSharpApp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31513.29
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpApp", "CSharpApp.csproj", "{6B319BA9-1350-4862-8E1B-95104F3FF54B}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {6B319BA9-1350-4862-8E1B-95104F3FF54B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {6B319BA9-1350-4862-8E1B-95104F3FF54B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {6B319BA9-1350-4862-8E1B-95104F3FF54B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {6B319BA9-1350-4862-8E1B-95104F3FF54B}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {ADB6A56B-9B26-4F6B-82FB-5E77D01EC728}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/cplusplus.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "Calculator.h"
3 |
4 |
5 | ///
6 | /// Method description.
7 | ///
8 | /// First parameter.
9 | /// Second parameter.
10 | /// The sum.
11 | int Calculator::Add(int a, int b)
12 | {
13 | // TODO: Add your implementation code here.
14 | "text";
15 | return a + b;
16 | }
17 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/cplusplus.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | class Calculator
3 | {
4 | public:
5 | int Add(int a, int b);
6 | };
7 |
8 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/csharp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | class MyClass
4 | {
5 | private readonly int hundred = 100;
6 | private bool enabled = true;
7 | public static string Text => "string";
8 |
9 | ///
10 | /// Documentation comment for member method.
11 | ///
12 | /// Some output value.
13 | public void MyMethod(out int result)
14 | {
15 | try
16 | {
17 | foreach (var name in new string[] { "name1", "name2" })
18 | {
19 | Console.WriteLine(name);
20 | }
21 | }
22 | catch (Exception ex)
23 | {
24 | Console.WriteLine(ex.Message);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/css.css:
--------------------------------------------------------------------------------
1 | li a, h1 {
2 | font-family: 'Courier New', Courier, Serif;
3 | }
4 |
5 | a:hover {
6 | background-color: green;
7 | }
8 |
9 | nav {
10 | background-color: aliceblue;
11 | }
12 |
13 | .jumbotron {
14 | padding: 2rem 1rem;
15 | margin-bottom: 2rem;
16 | background-color: #e9ecef;
17 | border-radius: .3rem;
18 | }
19 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | The Title
6 |
7 |
8 | The Header
9 | The paragraph text goes here.
10 |
14 |
15 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/javascript.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT license.
3 |
4 | /*
5 | Setup: Enter your storage account name and shared key in main()
6 | */
7 |
8 | const { BlobServiceClient } = require("@azure/storage-blob");
9 |
10 | // Load the .env file if it exists
11 | require("dotenv").config();
12 |
13 | async function main() {
14 | // Create Blob Service Client from Account connection string or SAS connection string
15 | // Account connection string example - `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net`
16 | // SAS connection string example - `BlobEndpoint=https://myaccount.blob.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString`
17 | const STORAGE_CONNECTION_STRING = process.env.STORAGE_CONNECTION_STRING || "";
18 | // Note - Account connection string can only be used in node.
19 | const blobServiceClient = BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING);
20 |
21 | let index = 1;
22 | for await (const container of blobServiceClient.listContainers()) {
23 | console.log(`Container ${index++}: ${container.name}`);
24 | }
25 |
26 | // Create a container
27 | const containerName = `newcontainer${new Date().getTime()}`;
28 | const containerClient = blobServiceClient.getContainerClient(containerName);
29 |
30 | const createContainerResponse = await containerClient.create();
31 | console.log(`Create container ${containerName} successfully`, createContainerResponse.requestId);
32 |
33 | // Delete container
34 | await containerClient.delete();
35 |
36 | console.log("deleted container");
37 | }
38 |
39 | main().catch((err) => {
40 | console.error("Error running sample:", err.message);
41 | });
42 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/json.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "vscode://schemas/testing",
3 | "object": {
4 | "color": "#ffffff1a",
5 | "text": "hello world",
6 | "boolean": true,
7 | "array": [ 100, 200, 300 ]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/markdown.md:
--------------------------------------------------------------------------------
1 | # Header 1
2 | ## Header 2
3 | ### Header 3
4 |
5 | Another Header
6 | --------------
7 |
8 | Yet Another Header
9 | ==================
10 |
11 | - List 1
12 | - List 2
13 |
14 | 1. Numbered list 1
15 | 2. Numbered list 2
16 |
17 | ```
18 | code block no language
19 | ```
20 |
21 | javascript code block:
22 |
23 | ```javascript
24 | const constant = 100;
25 | var message = "hello world " + constant.toString();
26 | ```
27 |
28 | Inline `code block` here
29 |
30 | Some **bold** and *italic* text
31 |
32 | [Microsoft](https:///www.microsoft.com)
33 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/visualbasic.vb:
--------------------------------------------------------------------------------
1 | Public Class XmlSamples
2 |
3 | Public Sub Main()
4 | ' Initialize the objects.
5 |
6 | Dim phoneNumbers2 As Phone() = {
7 | New Phone("home", "206-555-0144"),
8 | New Phone("work", "425-555-0145")}
9 |
10 | ' Convert the data contained in phoneNumbers2 to XML.
11 |
12 | Dim contact2 =
13 |
14 | Patrick Hines
15 | <%= From p In phoneNumbers2
16 | Select ><%= p.Number %>
17 | %>
18 |
19 |
20 | Console.WriteLine(contact2)
21 | End Sub
22 |
23 | End Class
24 |
25 | Class Phone
26 | Public Type As String
27 | Public Number As String
28 | Public Sub New(ByVal t As String, ByVal n As String)
29 | Type = t
30 | Number = n
31 | End Sub
32 | End Class
33 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Languages/xml.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 | latest
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/TestFiles/CSharpApp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace CSharpApp
4 | {
5 | class Program
6 | {
7 | ///
8 | /// Main entry point.
9 | ///
10 | ///
11 | static void Main(string[] args)
12 | {
13 | Console.WriteLine("Hello World!");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/ThemeTestFixture.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation.
2 | // Licensed under the MIT License.
3 |
4 | namespace ThemeTests
5 | {
6 | using FlaUI.Core;
7 | using FlaUI.Core.Input;
8 |
9 | using Microsoft.VisualStudio.Setup.Configuration;
10 |
11 | using System;
12 | using System.IO;
13 |
14 | using Xunit.Abstractions;
15 | using Xunit.Sdk;
16 |
17 | public abstract class ThemeTestFixture : IDisposable
18 | {
19 | private readonly double storedMovePixelsPerMillisecond;
20 | private readonly Application app;
21 |
22 | public Application App => this.app;
23 |
24 | public ThemeTestFixture(IMessageSink messageSink)
25 | {
26 | string devenvPath = GetPathToTargetVisualStudioInstall(messageSink);
27 | this.app = Application.Launch(devenvPath);
28 | this.storedMovePixelsPerMillisecond = Mouse.MovePixelsPerMillisecond;
29 | Mouse.MovePixelsPerMillisecond = 10;
30 | }
31 |
32 | public static string GetPathToTargetVisualStudioInstall(IMessageSink messageSink)
33 | {
34 | string vsInstallDir = Environment.GetEnvironmentVariable("VSINSTALLDIR");
35 | string reason = string.Empty;
36 |
37 | if (!string.IsNullOrEmpty(vsInstallDir) && Directory.Exists(vsInstallDir))
38 | {
39 | reason = "VSINSTALLDIR environment variable.";
40 | }
41 | else
42 | {
43 | var setupConfig = new SetupConfiguration();
44 | var setupInstances = setupConfig.EnumAllInstances();
45 | var instances = new ISetupInstance[1];
46 |
47 | setupInstances.Next(instances.Length, instances, out int fetched);
48 |
49 | if (fetched != 1)
50 | {
51 | throw new Exception("Could not find a VS install to target");
52 | }
53 |
54 | vsInstallDir = instances[0].GetInstallationPath();
55 | reason = $"instance ID {instances[0].GetInstanceId()} being first in SetupConfiguration.";
56 | if (!Directory.Exists(vsInstallDir))
57 | {
58 | throw new Exception($"Could not find devenv.exe at {vsInstallDir}");
59 | }
60 | }
61 |
62 | var devenvPath = Path.Combine(vsInstallDir, @"Common7\IDE\devenv.exe");
63 | messageSink.OnMessage(new DiagnosticMessage($"Targeting {devenvPath} by way of {reason}"));
64 | return devenvPath;
65 | }
66 |
67 | public void Dispose()
68 | {
69 | _ = this.app?.Close();
70 | this.app?.Dispose();
71 | Mouse.MovePixelsPerMillisecond = this.storedMovePixelsPerMillisecond;
72 | }
73 |
74 | protected virtual void DisposeInternal()
75 | {
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/ThemeTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-windows
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | all
20 | runtime; build; native; contentfiles; analyzers; buildtransitive
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | $([MSBuild]::EnsureTrailingSlash(%(LinkBase)))
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/ThemeConverter/ThemeTests/xunit.runner.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
3 | "diagnosticMessages": true // set to true to see test diagnostics in the Test pane in output window
4 | }
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | name: $(date:yy)$(DayOfYear)$(rev:.r)
2 | trigger:
3 | branches:
4 | include:
5 | - main
6 | pr:
7 | branches:
8 | include:
9 | - main
10 | drafts: false
11 | variables:
12 | TeamName: VS Core - IDE Experience
13 | SolutionFile: ThemeConverter/ThemeConverter.sln
14 | Platform: Any CPU
15 | BuildConfiguration: Release
16 | ProductBinariesFolder: '$(System.DefaultWorkingDirectory)/ThemeConverter/ThemeConverter/bin/$(BuildConfiguration)/net6.0'
17 | VersionMajor: 0
18 | VersionMinor: 1
19 | AssemblyVersion: $(VersionMajor).$(VersionMinor).0.0
20 | ProductVersion: $(VersionMajor).$(VersionMinor).$(Build.BuildNumber)
21 | SignType: Test
22 | CodeQL.Enabled: true
23 | Codeql.TSAEnabled: false
24 | Codeql.TSAOptionsPath: $(Build.SourcesDirectory)/.config/tsaoptions.json
25 | resources:
26 | repositories:
27 | - repository: MicroBuildTemplate
28 | type: git
29 | name: 1ESPipelineTemplates/MicroBuildTemplate
30 | ref: refs/tags/release
31 | extends:
32 | template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
33 | parameters:
34 | sdl:
35 | policheck:
36 | enabled: true
37 | tsa:
38 | enabled: false
39 | pool:
40 | name: VSEngSS-MicroBuild2022-1ES
41 | demands:
42 | - msbuild
43 | - VisualStudio_17.0
44 | customBuildTags:
45 | - ES365AIMigrationTooling
46 | stages:
47 | - stage: Build
48 | jobs:
49 | - job: Build_And_Compliance
50 | displayName: Build and Compliance
51 | templateContext:
52 | mb:
53 | signing:
54 | enabled: true
55 | signType: $(SignType)
56 | feedSource: 'https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset/nuget/v3/index.json'
57 | sbom:
58 | enabled: true
59 | feedSource: 'https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset/nuget/v3/index.json'
60 | outputs:
61 | - output: pipelineArtifact
62 | displayName: 'Publish Staging Directory'
63 | targetPath: $(Build.StagingDirectory)
64 | steps:
65 | - checkout: self
66 | clean: true
67 | - task: NuGetCommand@2
68 | displayName: Restore NuGet Packages
69 | inputs:
70 | command: 'restore'
71 | restoreSolution: $(SolutionFile)
72 | - task: MSBuild@1
73 | displayName: Build Product
74 | inputs:
75 | solution: $(SolutionFile)
76 | platform: $(Platform)
77 | configuration: $(BuildConfiguration)
78 | msbuildArguments: /Property:Version=$(ProductVersion) /Property:FileVersion=$(ProductVersion) /Property:AssemblyVersion=$(AssemblyVersion) /Property:SignType=$(SignType)
79 | continueOnError: false
80 | - task: DotNetCoreCLI@2
81 | displayName: Run Tests
82 | inputs:
83 | command: 'test'
84 | projects: '**/ThemeConverterTests.csproj'
85 | arguments: '--configuration Release'
86 | - task: ArchiveFiles@2
87 | displayName: Archive Binaries
88 | inputs:
89 | rootFolderOrFile: '$(ProductBinariesFolder)'
90 | includeRootFolder: true
91 | archiveType: 'zip'
92 | archiveFile: '$(Build.StagingDirectory)/ThemeConverter-$(VersionMajor).$(VersionMinor).$(Build.BuildNumber).zip'
93 | replaceExistingArchive: true
94 | - task: ManifestGeneratorTask@0
95 | displayName: 'Generation Task'
96 | inputs:
97 | BuildDropPath: '$(Build.StagingDirectory)'
98 | - task: TSAUpload@2
99 | displayName: 'TSA upload to Codebase (Theme Converter for VS)'
100 | inputs:
101 | GdnPublishTsaOnboard: True
102 | GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)/.config/tsaoptions.json'
103 | condition: false
104 |
--------------------------------------------------------------------------------