From e9988319fc60117fbd7c254f7f1236d1272f85ae Mon Sep 17 00:00:00 2001
From: Josh Lozensky <joshlozensky@microsoft.com>
Date: Wed, 30 Oct 2024 18:23:19 -0700
Subject: [PATCH 1/3] Create test for hybrid flow sample

---
 .../2-5-HybridFlow/appsettings.json           | Bin 1988 -> 970 bytes
 .../AnyOrgOrPersonalTest.cs                   |   1 -
 UiTests/HybridFlowUiTest/HybridFlowTest.cs    | 141 ++++++++++++++++++
 .../HybridFlowUiTest/HybridFlowUiTest.csproj  |  31 ++++
 UiTests/HybridFlowUiTest/appsettings.json     |  28 ++++
 UiTests/UiTests.sln                           |  10 +-
 6 files changed, 208 insertions(+), 3 deletions(-)
 create mode 100644 UiTests/HybridFlowUiTest/HybridFlowTest.cs
 create mode 100644 UiTests/HybridFlowUiTest/HybridFlowUiTest.csproj
 create mode 100644 UiTests/HybridFlowUiTest/appsettings.json

diff --git a/2-WebApp-graph-user/2-5-HybridFlow/appsettings.json b/2-WebApp-graph-user/2-5-HybridFlow/appsettings.json
index 5321a5906c07f8545e910c505138107911864a05..1a4512ff58e2413a27ab590e42b58da1390ac792 100644
GIT binary patch
literal 970
zcmaJ=OK;mS48HeQ2)<++YA1HwhkMJCVhd29L$jcVq6bEzZDERN$V!X0$bTQDH14*;
zE{6Sy`W`g-b|OSFd)+ylspLw$@h1aI+k3DQ8A)32yZ&lCHq>aFZMAgNQ|-wbZ84Ly
z9Ve%UTMOEPw&Bjhwe{$PZ&9cS3aZ5m?HED})}IQ@noLNtp2;$@18pFDJQDtl#mivq
zNIBy3E!okjASXuT8nF5mye8X^0u&?<*ThnZPq!P-mQab>(Ka5&tfC|5!DM2E2BjCH
zYpXia)-%aaIhu8yaM<YHyQ9L!fI<OQiCvG8@7sF05ZW^K5<&+3_1#VX`8}e7GB3(A
zI7{<<Gfk`NT&9x=T&AU}Du;Ph7gaF?o*RwU{}nh89^e>=JsB;d9l^r%-+V_C8@MPh
zE^}F=XH$NZWdUh*!EaM_K5<wUbvc>-V`7EUp^u%PQ}+^s$!JgX@koGD+*nWX2)I{6
z=l<;R2Q3)00r~3(_%_gvd)-)VQ_@NvfA}Hj9G%y7NQpgHK0Ln9*S+@bs)O0iw{ucq
zIKA5;&)z;1BsbLXgf<MnPcZ{G_=ILaxM+bj>`csc503SlBo6O>pqUv%&#1mr?}K{s
zh0P@kdghgI2-{hw2fpMh^tg6GU|5sJLDzn)NnDVpJewRNt|WCaR>BkHGNx2<4?y}p
keg!{=K%Dgsm3BO#YZp`p5knG8%MP!~a$4l$<Ya&H8=rP8nE(I)

literal 1988
zcmbuAT~8BH5QgX4#Q(6_o2rr0mO_O)1fwJ*8Y<y}c(HW1uyJ8Y*=o@6*VX4er>DDg
zi(Z(M_I%C9JMYYy{r&5wJ-25TF=E@dA2zp{Wvo*6dz{wyUgpSd?9M7nm?ubjso1VK
ztL&D$J=<gyR@$ZINOkR+d4k=N+tQ}Um7EvuHsgN6{u-UwUN6yjZ-?$CagxE)xxGWX
z!uJe(6`nKZv>_R>o^p22tav1qp(D%{J|cEq&~;hKw@y8_uG_Wo28>_UVEo*$eYE5)
zw#PU-izu(1hmJ#0I&2+IW}p$eoD3wO$(_`lbwKE)LYz%+k;z|VFYKdTpyheW+}RYH
zVzp+d&Td4WWK|l4V_{4T1-}Vr5njb`>ZFvxio6L)+h&JKxn)FH%Ur%y8?#mn7g$fQ
zs7xtNp`K$^`w-cCJ0+e&PUO?e-81`K2B}j!v12q}uH-Sr?$G)+;D4L-wr#NM!^;+{
zUB(X4ZCH<y*c(<uQ0QF9`^-~xcloW$@qw#W)llU)|9dSqrRyAdrd0J45QH4-UNM*d
zk-=3iF0el$z7cWu@irjZZFumjAvXgg#L8%KwgneEFe5H>JLSKJ#=p2w-RNa!#8Y!}
zKs2|!zB;#)27i&ud(cvzQ--fvy~A27S=3g$?w+dU^>|g~1^gyp{c4|>RZRi!CU|mc
zSFi5|R!Zg+$#yqt=Jf!?dO<l{g^Xrc@>b7bZnc-4At%3MqDpu-bGH*$ir(w#?abMQ
zp8U|T5>xl;slKaTE;LsAvzIx>#y5V&TB*=mGq5N4D?k$1IOAlt;6gqE66riFcaL%H
zJAO<1j>ptKfKpu`a1q-p?07a}YF%>v8=|^N=uvtZ`C6p0y+uNO;uKUNn)cV`l3P{F
z72WLV?!5^oeI$BIJc`P*F(%`x+B%2vqC?Hl@JQ9Q!uLY8q!{bFnybg`_<Wx@ZgOWy
inu;gH+>S?IPj!ich&-EnyvQLhazF(7QYtS#AAbOrhcCeZ

diff --git a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs
index 563f6218..3df45d55 100644
--- a/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs
+++ b/UiTests/AnyOrgOrPersonalUiTest/AnyOrgOrPersonalTest.cs
@@ -134,6 +134,5 @@ public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds
                 playwright.Dispose();
             }
         }
-
     }
 }
\ No newline at end of file
diff --git a/UiTests/HybridFlowUiTest/HybridFlowTest.cs b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
new file mode 100644
index 00000000..b36165a0
--- /dev/null
+++ b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Runtime.Versioning;
+using System.Text;
+using System.Threading.Tasks;
+using Common;
+using Microsoft.Identity.Lab.Api;
+using Microsoft.Playwright;
+using Xunit;
+using Xunit.Abstractions;
+using static System.Net.Mime.MediaTypeNames;
+using Process = System.Diagnostics.Process;
+using TC = Common.TestConstants;
+
+namespace HybridFlowUiTest
+{
+    public class HybridFlowTest : IClassFixture<InstallPlaywrightBrowserFixture>
+    {
+        private const string SignOutPageUriPath = @"/MicrosoftIdentity/Account/SignedOut";
+        private const uint ClientPort = 44321;
+        private const string TraceFileClassName = "OpenIDConnect-HybridFlow";
+        private const uint NumProcessRetries = 3;
+        private const string SampleSlnFileName = "2-5-HybridFlow.sln";
+        private const string SampleExeFileName = "\\2-5-HybridFlow.exe";
+        private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 };
+        private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-5-HybridFlow" + Path.DirectorySeparatorChar.ToString();
+        private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "HybridFlowUiTest" + Path.DirectorySeparatorChar.ToString() + TC.AppSetttingsDotJson;
+        private readonly string _testAssemblyLocation = typeof(HybridFlowTest).Assembly.Location;
+        private readonly ITestOutputHelper _output;
+
+        public HybridFlowTest(ITestOutputHelper output)
+        {
+            _output = output;
+        }
+
+        [Fact]
+        [SupportedOSPlatform("windows")]
+        public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds_LoginLogout()
+        {
+            // Setup web app and api environmental variables.
+            var clientEnvVars = new Dictionary<string, string>
+            {
+                {"ASPNETCORE_ENVIRONMENT", "Development"},
+                {TC.KestrelEndpointEnvVar, TC.HttpsStarColon + ClientPort}
+            };
+
+            Dictionary<string, Process>? processes = null;
+
+            // Arrange Playwright setup, to see the browser UI set Headless = false.
+            const string TraceFileName = TraceFileClassName + "_LoginLogout";
+            using IPlaywright playwright = await Playwright.CreateAsync();
+            IBrowser browser = await playwright.Chromium.LaunchAsync(new() { Headless = false });
+            IBrowserContext context = await browser.NewContextAsync(new BrowserNewContextOptions { IgnoreHTTPSErrors = true });
+            await context.Tracing.StartAsync(new() { Screenshots = true, Snapshots = true, Sources = true });
+            IPage page = await context.NewPageAsync();
+            string uriWithPort = TC.LocalhostUrl + ClientPort;
+
+            try
+            {
+                // Build the sample app with correct appsettings file.
+                UiTestHelpers.BuildSampleUsingTestAppsettings(_testAssemblyLocation, _sampleAppPath, _testAppsettingsPath, SampleSlnFileName);
+
+                // Start the web app and api processes.
+                // The delay before starting client prevents transient devbox issue where the client fails to load the first time after rebuilding
+                var clientProcessOptions = new ProcessStartOptions(_testAssemblyLocation, _sampleAppPath, SampleExeFileName, clientEnvVars);
+
+                bool areProcessesRunning = UiTestHelpers.StartAndVerifyProcessesAreRunning([clientProcessOptions], out processes, NumProcessRetries);
+
+                if (!areProcessesRunning)
+                {
+                    _output.WriteLine($"Process not started after {NumProcessRetries} attempts.");
+                    StringBuilder runningProcesses = new StringBuilder();
+                    foreach (var process in processes)
+                    {
+#pragma warning disable CA1305 // Specify IFormatProvider
+                        runningProcesses.AppendLine($"Is {process.Key} running: {UiTestHelpers.ProcessIsAlive(process.Value)}");
+#pragma warning restore CA1305 // Specify IFormatProvider
+                    }
+                    Assert.Fail(TC.WebAppCrashedString + " " + runningProcesses.ToString());
+                }
+
+                LabResponse labResponse = await LabUserHelper.GetSpecificUserAsync(TC.MsidLab4User);
+
+                // Initial sign in
+                _output.WriteLine("Starting web app sign-in flow.");
+                string email = labResponse.User.Upn;
+                await UiTestHelpers.NavigateToWebApp(uriWithPort, page);
+                await page.GetByRole(AriaRole.Link, new() { Name = "Sign in" }).ClickAsync();
+                await UiTestHelpers.FirstLogin_MicrosoftIdFlow_ValidEmailPassword(page, email, labResponse.User.GetOrFetchPassword(), _output);
+                await Assertions.Expect(page.GetByText("SPA Authorization Code")).ToBeVisibleAsync(_assertVisibleOptions);
+                await Assertions.Expect(page.GetByText(email)).ToBeVisibleAsync(_assertVisibleOptions);
+                _output.WriteLine("Web app sign-in flow successful.");
+
+                // Sign out
+                _output.WriteLine("Starting web app sign-out flow.");
+                await page.GetByRole(AriaRole.Link, new() { Name = "Sign out" }).ClickAsync();
+                await UiTestHelpers.PerformSignOut_MicrosoftIdFlow(page, email, TC.LocalhostUrl + ClientPort + SignOutPageUriPath, _output);
+                _output.WriteLine("Web app sign out successful.");
+            }
+            catch (Exception ex)
+            {
+                // Adding guid in case of multiple test runs. This will allow screenshots to be matched to their appropriate test runs.
+                var guid = Guid.NewGuid().ToString();
+                try
+                {
+                    if (page != null)
+                    {
+                        await page.ScreenshotAsync(new PageScreenshotOptions() { Path = $"ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds_TodoAppFunctionsCorrectlyScreenshotFail{guid}.png", FullPage = true });
+                    }
+                }
+                catch
+                {
+                    _output.WriteLine("No Screenshot.");
+                }
+
+                string runningProcesses = UiTestHelpers.GetRunningProcessAsString(processes);
+                Assert.Fail($"the UI automation failed: {ex} output: {ex.Message}.\n{runningProcesses}\nTest run: {guid}");
+            }
+            finally
+            {
+                // Make sure all processes and their children are stopped.
+                UiTestHelpers.EndProcesses(processes);
+
+                // Stop tracing and export it into a zip archive.
+                string path = UiTestHelpers.GetTracePath(_testAssemblyLocation, TraceFileName);
+                await context.Tracing.StopAsync(new() { Path = path });
+                _output.WriteLine($"Trace data for {TraceFileName} recorded to {path}.");
+
+                // Close the browser and stop Playwright.
+                await browser.CloseAsync();
+                playwright.Dispose();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/UiTests/HybridFlowUiTest/HybridFlowUiTest.csproj b/UiTests/HybridFlowUiTest/HybridFlowUiTest.csproj
new file mode 100644
index 00000000..56b7a9b5
--- /dev/null
+++ b/UiTests/HybridFlowUiTest/HybridFlowUiTest.csproj
@@ -0,0 +1,31 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>net8.0</TargetFrameworks>
+    <IsPackable>false</IsPackable>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(MicrosoftAspNetCoreMvcTestingVersion)" />
+    <PackageReference Include="Microsoft.Identity.Lab.Api" Version="$(MicrosoftIdentityLabApiVersion)" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
+    <PackageReference Include="Microsoft.Playwright" Version="$(MicrosoftPlaywrightVersion)" />
+    <PackageReference Include="System.Management" Version="$(SystemManagementVersion)" />
+    <PackageReference Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
+    <PackageReference Include="xunit" Version="$(XunitVersion)" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioVersion)">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+    <PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Common\Common.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/UiTests/HybridFlowUiTest/appsettings.json b/UiTests/HybridFlowUiTest/appsettings.json
new file mode 100644
index 00000000..5b999da1
--- /dev/null
+++ b/UiTests/HybridFlowUiTest/appsettings.json
@@ -0,0 +1,28 @@
+{
+  "AzureAd": {
+    "Instance": "https://login.microsoftonline.com/",
+    "Domain": "msidlab4.onmicrosoft.com",
+    "TenantId": "f645ad92-e38d-4d1a-b510-d1b09a74a8ca",
+    "ClientId": "9a192b78-6580-4f8a-aace-f36ffea4f7be",
+    "CallbackPath": "/signin-oidc",
+    "SignedOutCallbackPath": "/signout-callback-oidc",
+    "ClientCertificates": [
+      {
+        "SourceType": "KeyVault",
+        "KeyVaultUrl": "https://webappsapistests.vault.azure.net",
+        "KeyVaultCertificateName": "Self-Signed-5-5-22"
+      }
+    ]
+  },
+  "Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  "DownstreamApi": {
+    "BaseUrl": "https://graph.microsoft.com/v1.0",
+    "Scopes": "user.read contacts.read"
+  },
+  "SpaRedirectUri": "https://localhost:44321/"
+}
diff --git a/UiTests/UiTests.sln b/UiTests/UiTests.sln
index af7897cc..b8f997db 100644
--- a/UiTests/UiTests.sln
+++ b/UiTests/UiTests.sln
@@ -12,9 +12,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		Directory.Build.props = Directory.Build.props
 	EndProjectSection
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "B2CUiTest", "B2CUiTest\B2CUiTest.csproj", "{BF7D9973-9B92-4BED-ADE2-09087DDA9C85}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "B2CUiTest", "B2CUiTest\B2CUiTest.csproj", "{BF7D9973-9B92-4BED-ADE2-09087DDA9C85}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphUserTokenCache", "GraphUserTokenCache\GraphUserTokenCache.csproj", "{B083D288-AB6E-4849-9AC2-E1DA1F727483}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphUserTokenCache", "GraphUserTokenCache\GraphUserTokenCache.csproj", "{B083D288-AB6E-4849-9AC2-E1DA1F727483}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HybridFlowUiTest", "HybridFlowUiTest\HybridFlowUiTest.csproj", "{344CD55E-14C7-4999-A040-6C049F0070CB}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -38,6 +40,10 @@ Global
 		{B083D288-AB6E-4849-9AC2-E1DA1F727483}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{B083D288-AB6E-4849-9AC2-E1DA1F727483}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{B083D288-AB6E-4849-9AC2-E1DA1F727483}.Release|Any CPU.Build.0 = Release|Any CPU
+		{344CD55E-14C7-4999-A040-6C049F0070CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{344CD55E-14C7-4999-A040-6C049F0070CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{344CD55E-14C7-4999-A040-6C049F0070CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{344CD55E-14C7-4999-A040-6C049F0070CB}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

From 8d1f19cc1ca95b142d4620cd1e8cbacb93afc38c Mon Sep 17 00:00:00 2001
From: Josh Lozensky <joshlozensky@microsoft.com>
Date: Wed, 30 Oct 2024 18:25:24 -0700
Subject: [PATCH 2/3] remove unneeded usings

---
 UiTests/HybridFlowUiTest/HybridFlowTest.cs | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/UiTests/HybridFlowUiTest/HybridFlowTest.cs b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
index b36165a0..8e660d78 100644
--- a/UiTests/HybridFlowUiTest/HybridFlowTest.cs
+++ b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
@@ -1,20 +1,17 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
+using Common;
+using Microsoft.Identity.Lab.Api;
+using Microsoft.Playwright;
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Linq;
-using System.Net;
 using System.Runtime.Versioning;
 using System.Text;
 using System.Threading.Tasks;
-using Common;
-using Microsoft.Identity.Lab.Api;
-using Microsoft.Playwright;
 using Xunit;
 using Xunit.Abstractions;
-using static System.Net.Mime.MediaTypeNames;
 using Process = System.Diagnostics.Process;
 using TC = Common.TestConstants;
 

From c0de050b50622889dba324e178e156352c47a1ab Mon Sep 17 00:00:00 2001
From: Josh Lozensky <joshlozensky@microsoft.com>
Date: Wed, 30 Oct 2024 18:29:56 -0700
Subject: [PATCH 3/3] minor cleanup

---
 UiTests/HybridFlowUiTest/HybridFlowTest.cs | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/UiTests/HybridFlowUiTest/HybridFlowTest.cs b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
index 8e660d78..bdab75bb 100644
--- a/UiTests/HybridFlowUiTest/HybridFlowTest.cs
+++ b/UiTests/HybridFlowUiTest/HybridFlowTest.cs
@@ -24,7 +24,7 @@ public class HybridFlowTest : IClassFixture<InstallPlaywrightBrowserFixture>
         private const string TraceFileClassName = "OpenIDConnect-HybridFlow";
         private const uint NumProcessRetries = 3;
         private const string SampleSlnFileName = "2-5-HybridFlow.sln";
-        private const string SampleExeFileName = "\\2-5-HybridFlow.exe";
+        private const string SampleExeFileName = "2-5-HybridFlow.exe";
         private readonly LocatorAssertionsToBeVisibleOptions _assertVisibleOptions = new() { Timeout = 25000 };
         private readonly string _sampleAppPath = "2-WebApp-graph-user" + Path.DirectorySeparatorChar + "2-5-HybridFlow" + Path.DirectorySeparatorChar.ToString();
         private readonly string _testAppsettingsPath = "UiTests" + Path.DirectorySeparatorChar + "HybridFlowUiTest" + Path.DirectorySeparatorChar.ToString() + TC.AppSetttingsDotJson;
@@ -52,7 +52,7 @@ public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds
             // Arrange Playwright setup, to see the browser UI set Headless = false.
             const string TraceFileName = TraceFileClassName + "_LoginLogout";
             using IPlaywright playwright = await Playwright.CreateAsync();
-            IBrowser browser = await playwright.Chromium.LaunchAsync(new() { Headless = false });
+            IBrowser browser = await playwright.Chromium.LaunchAsync(new() { Headless = true });
             IBrowserContext context = await browser.NewContextAsync(new BrowserNewContextOptions { IgnoreHTTPSErrors = true });
             await context.Tracing.StartAsync(new() { Screenshots = true, Snapshots = true, Sources = true });
             IPage page = await context.NewPageAsync();
@@ -65,7 +65,12 @@ public async Task ChallengeUser_MicrosoftIdFlow_LocalApp_ValidEmailPasswordCreds
 
                 // Start the web app and api processes.
                 // The delay before starting client prevents transient devbox issue where the client fails to load the first time after rebuilding
-                var clientProcessOptions = new ProcessStartOptions(_testAssemblyLocation, _sampleAppPath, SampleExeFileName, clientEnvVars);
+                var clientProcessOptions = new ProcessStartOptions(
+                    _testAssemblyLocation,
+                    _sampleAppPath,
+                    Path.DirectorySeparatorChar.ToString() + SampleExeFileName,
+                    clientEnvVars
+                    );
 
                 bool areProcessesRunning = UiTestHelpers.StartAndVerifyProcessesAreRunning([clientProcessOptions], out processes, NumProcessRetries);