Adding more logging for the test
Adding some helper methods for hosting variation Divided the Utility class by the purpose of the helpers.
This commit is contained in:
parent
a16d9b41d8
commit
01210af151
|
|
@ -0,0 +1,99 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace E2ETests
|
||||||
|
{
|
||||||
|
internal class DeploymentUtility
|
||||||
|
{
|
||||||
|
private static string GetIISExpressPath()
|
||||||
|
{
|
||||||
|
var iisExpressPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "IIS Express", "iisexpress.exe");
|
||||||
|
|
||||||
|
//If X86 version does not exist
|
||||||
|
if (!File.Exists(iisExpressPath))
|
||||||
|
{
|
||||||
|
iisExpressPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "IIS Express", "iisexpress.exe");
|
||||||
|
|
||||||
|
if (!File.Exists(iisExpressPath))
|
||||||
|
{
|
||||||
|
throw new Exception("Unable to find IISExpress on the machine");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iisExpressPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copy AspNet.Loader.dll to bin folder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="applicationPath"></param>
|
||||||
|
private static void CopyAspNetLoader(string applicationPath)
|
||||||
|
{
|
||||||
|
string packagesDirectory = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\Packages"));
|
||||||
|
var aspNetLoaderSrcPath = Path.Combine(Directory.GetDirectories(packagesDirectory, "Microsoft.AspNet.Loader.IIS.Interop.*").First(), @"tools\AspNet.Loader.dll");
|
||||||
|
var aspNetLoaderDestPath = Path.Combine(applicationPath, @"bin\AspNet.Loader.dll");
|
||||||
|
if (!File.Exists(aspNetLoaderDestPath))
|
||||||
|
{
|
||||||
|
File.Copy(aspNetLoaderSrcPath, aspNetLoaderDestPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string APP_RELATIVE_PATH = @"..\..\src\MusicStore\";
|
||||||
|
|
||||||
|
public static Process StartApplication(HostType hostType, KreFlavor kreFlavor)
|
||||||
|
{
|
||||||
|
string applicationPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, APP_RELATIVE_PATH));
|
||||||
|
|
||||||
|
if (hostType == HostType.Helios)
|
||||||
|
{
|
||||||
|
return StartHeliosHost(applicationPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Self-Host variation not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Process StartHeliosHost(string applicationPath)
|
||||||
|
{
|
||||||
|
CopyAspNetLoader(applicationPath);
|
||||||
|
|
||||||
|
var startInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = GetIISExpressPath(),
|
||||||
|
Arguments = string.Format("/port:5001 /path:{0}", applicationPath),
|
||||||
|
UseShellExecute = true,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var hostProcess = Process.Start(startInfo);
|
||||||
|
Console.WriteLine("Started iisexpress. Process Id : {0}", hostProcess.Id);
|
||||||
|
Thread.Sleep(2 * 1000);
|
||||||
|
|
||||||
|
return hostProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private static Process StartSelfHost(string applicationPath)
|
||||||
|
//{
|
||||||
|
// var klrPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @".kre\packges", "KRE-svr50-x86.0.1-alpha-build-0450", @"bin\klr.exe");
|
||||||
|
// Console.WriteLine(klrPath);
|
||||||
|
|
||||||
|
// var startInfo = new ProcessStartInfo
|
||||||
|
// {
|
||||||
|
// FileName = klrPath,
|
||||||
|
// Arguments = string.Format("--appbase {0} \"Microsoft.Framework.ApplicationHost\" web", applicationPath),
|
||||||
|
// UseShellExecute = true,
|
||||||
|
// CreateNoWindow = true
|
||||||
|
// };
|
||||||
|
|
||||||
|
// var hostProcess = Process.Start(startInfo);
|
||||||
|
// Console.WriteLine("Started klr.exe. Process Id : {0}", hostProcess.Id);
|
||||||
|
// Thread.Sleep(10 * 1000);
|
||||||
|
|
||||||
|
// return hostProcess;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace System.Net
|
||||||
|
{
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static Cookie GetCookieWithName(this CookieCollection cookieCollection, string cookieName)
|
||||||
|
{
|
||||||
|
foreach (Cookie cookie in cookieCollection)
|
||||||
|
{
|
||||||
|
if (cookie.Name == cookieName)
|
||||||
|
{
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace E2ETests
|
||||||
|
{
|
||||||
|
public enum HostType
|
||||||
|
{
|
||||||
|
Helios,
|
||||||
|
SelfHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace E2ETests
|
||||||
|
{
|
||||||
|
public class HtmlDOMHelper
|
||||||
|
{
|
||||||
|
public static string RetrieveAntiForgeryToken(string htmlContent, string actionUrl)
|
||||||
|
{
|
||||||
|
int startSearchIndex = 0;
|
||||||
|
|
||||||
|
while (startSearchIndex < htmlContent.Length)
|
||||||
|
{
|
||||||
|
var antiForgeryToken = RetrieveAntiForgeryToken(htmlContent, actionUrl, ref startSearchIndex);
|
||||||
|
|
||||||
|
if (antiForgeryToken != null)
|
||||||
|
{
|
||||||
|
return antiForgeryToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string RetrieveAntiForgeryToken(string htmlContent, string actionLocation, ref int startIndex)
|
||||||
|
{
|
||||||
|
var formStartIndex = htmlContent.IndexOf("<form", startIndex, StringComparison.OrdinalIgnoreCase);
|
||||||
|
var formEndIndex = htmlContent.IndexOf("</form>", startIndex, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (formStartIndex == -1 || formEndIndex == -1)
|
||||||
|
{
|
||||||
|
//Unable to find the form start or end - finish the search
|
||||||
|
startIndex = htmlContent.Length;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
formEndIndex = formEndIndex + "</form>".Length;
|
||||||
|
startIndex = formEndIndex + 1;
|
||||||
|
|
||||||
|
var htmlDocument = new XmlDocument();
|
||||||
|
htmlDocument.LoadXml(htmlContent.Substring(formStartIndex, formEndIndex - formStartIndex));
|
||||||
|
|
||||||
|
foreach (XmlAttribute attribute in htmlDocument.DocumentElement.Attributes)
|
||||||
|
{
|
||||||
|
if (string.Compare(attribute.Name, "action", true) == 0 && attribute.Value.EndsWith(actionLocation, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (XmlNode input in htmlDocument.GetElementsByTagName("input"))
|
||||||
|
{
|
||||||
|
if (input.Attributes["name"].Value == "__RequestVerificationToken" && input.Attributes["type"].Value == "hidden")
|
||||||
|
{
|
||||||
|
return input.Attributes["value"].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace E2ETests
|
||||||
|
{
|
||||||
|
public enum KreFlavor
|
||||||
|
{
|
||||||
|
DesktopClr,
|
||||||
|
CoreClr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -9,44 +8,45 @@ namespace E2ETests
|
||||||
{
|
{
|
||||||
public class SmokeTests
|
public class SmokeTests
|
||||||
{
|
{
|
||||||
private const string APP_BASE_URL = "http://localhost:5001/";
|
[Theory]
|
||||||
private const string APP_RELATIVE_PATH = @"..\..\src\MusicStore\";
|
[InlineData(HostType.Helios, KreFlavor.DesktopClr, "http://localhost:5001/")]
|
||||||
|
//[InlineData(HostType.SelfHost, KreFlavor.DesktopClr, "http://localhost:5002/")]
|
||||||
[Fact]
|
public void SmokeTestSuite(HostType hostType, KreFlavor kreFlavor, string applicationBaseUrl)
|
||||||
public void SmokeTestSuite()
|
|
||||||
{
|
{
|
||||||
string applicationPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, APP_RELATIVE_PATH));
|
var hostProcess = DeploymentUtility.StartApplication(hostType, kreFlavor);
|
||||||
Utility.CopyAspNetLoader(applicationPath);
|
|
||||||
var hostProcess = Utility.StartHeliosHost(applicationPath);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var httpClientHandler = new HttpClientHandler();
|
var httpClientHandler = new HttpClientHandler();
|
||||||
var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(APP_BASE_URL) };
|
var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) };
|
||||||
|
|
||||||
//Request to base address and check if various parts of the body are rendered
|
//Request to base address and check if various parts of the body are rendered
|
||||||
var response = httpClient.GetAsync(string.Empty).Result;
|
var response = httpClient.GetAsync(string.Empty).Result;
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
var responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Console.WriteLine("Response from the server: {0}", responseContent);
|
Console.WriteLine("Home page content : {0}", responseContent);
|
||||||
Assert.Equal<HttpStatusCode>(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal<HttpStatusCode>(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Contains("ASP.NET MVC Music Store", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("ASP.NET MVC Music Store", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Register", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Register", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Login", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Login", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Console.WriteLine("Application initialization successful.");
|
||||||
|
|
||||||
//Making a request to a protected resource should automatically redirect to login page
|
//Making a request to a protected resource should automatically redirect to login page
|
||||||
|
Console.WriteLine("Trying to access StoreManager without signing in..");
|
||||||
response = httpClient.GetAsync("/StoreManager/").Result;
|
response = httpClient.GetAsync("/StoreManager/").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Contains("<h4>Use a local account to log in.</h4>", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("<h4>Use a local account to log in.</h4>", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Equal<string>(APP_BASE_URL + "Account/Login?ReturnUrl=%2FStoreManager%2F", response.RequestMessage.RequestUri.AbsoluteUri);
|
Assert.Equal<string>(applicationBaseUrl + "Account/Login?ReturnUrl=%2FStoreManager%2F", response.RequestMessage.RequestUri.AbsoluteUri);
|
||||||
|
Console.WriteLine("Redirected to login page as expected.");
|
||||||
|
|
||||||
//Register a user - Need a way to get the antiforgery token and send it in the request as a form encoded parameter
|
//Register a user - Need a way to get the antiforgery token and send it in the request as a form encoded parameter
|
||||||
response = httpClient.GetAsync("/Account/Register").Result;
|
response = httpClient.GetAsync("/Account/Register").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
var antiForgeryToken = Utility.RetrieveAntiForgeryToken(responseContent, "/Account/Register");
|
var antiForgeryToken = HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/Account/Register");
|
||||||
|
|
||||||
var generatedUserName = Guid.NewGuid().ToString().Replace("-", string.Empty);
|
var generatedUserName = Guid.NewGuid().ToString().Replace("-", string.Empty);
|
||||||
|
Console.WriteLine("Creating a new user with name '{0}'", generatedUserName);
|
||||||
var formParameters = new List<KeyValuePair<string, string>>
|
var formParameters = new List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("UserName", generatedUserName),
|
new KeyValuePair<string, string>("UserName", generatedUserName),
|
||||||
|
|
@ -60,18 +60,21 @@ namespace E2ETests
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Contains(string.Format("Hello {0}!", generatedUserName), responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains(string.Format("Hello {0}!", generatedUserName), responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
//Verify cookie sent
|
//Verify cookie sent
|
||||||
Assert.NotNull(Utility.GetCookieWithName(httpClientHandler.CookieContainer.GetCookies(new Uri(APP_BASE_URL)), ".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
Assert.NotNull(httpClientHandler.CookieContainer.GetCookies(new Uri(applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
||||||
|
Console.WriteLine("Successfully registered user '{0}' and signed in", generatedUserName);
|
||||||
|
|
||||||
//Making a request to a protected resource that this user does not have access to - should automatically redirect to login page again
|
//Making a request to a protected resource that this user does not have access to - should automatically redirect to login page again
|
||||||
|
Console.WriteLine("Trying to access StoreManager that needs special permissions that {0} does not claim", generatedUserName);
|
||||||
response = httpClient.GetAsync("/StoreManager/").Result;
|
response = httpClient.GetAsync("/StoreManager/").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Contains("<h4>Use a local account to log in.</h4>", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("<h4>Use a local account to log in.</h4>", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Equal<string>(APP_BASE_URL + "Account/Login?ReturnUrl=%2FStoreManager%2F", response.RequestMessage.RequestUri.AbsoluteUri);
|
Assert.Equal<string>(applicationBaseUrl + "Account/Login?ReturnUrl=%2FStoreManager%2F", response.RequestMessage.RequestUri.AbsoluteUri);
|
||||||
|
Console.WriteLine("Redirected to login page as expected.");
|
||||||
|
|
||||||
//Logout from this user session - This should take back to the home page
|
//Logout from this user session - This should take back to the home page
|
||||||
antiForgeryToken = Utility.RetrieveAntiForgeryToken(responseContent, "/Account/LogOff");
|
Console.WriteLine("Signing out from '{0}''s session", generatedUserName);
|
||||||
|
antiForgeryToken = HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/Account/LogOff");
|
||||||
formParameters = new List<KeyValuePair<string, string>>
|
formParameters = new List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
||||||
|
|
@ -86,12 +89,14 @@ namespace E2ETests
|
||||||
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
//Verify cookie cleared on logout
|
//Verify cookie cleared on logout
|
||||||
Assert.Null(Utility.GetCookieWithName(httpClientHandler.CookieContainer.GetCookies(new Uri(APP_BASE_URL)), ".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
Assert.Null(httpClientHandler.CookieContainer.GetCookies(new Uri(applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
||||||
|
Console.WriteLine("Successfully signed out of '{0}''s session");
|
||||||
|
|
||||||
//Login as an admin user
|
//Login as an admin user
|
||||||
|
Console.WriteLine("Signing in as '{0}'", "Administrator");
|
||||||
response = httpClient.GetAsync("/Account/Login").Result;
|
response = httpClient.GetAsync("/Account/Login").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
antiForgeryToken = Utility.RetrieveAntiForgeryToken(responseContent, "/Account/Login");
|
antiForgeryToken = HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/Account/Login");
|
||||||
formParameters = new List<KeyValuePair<string, string>>
|
formParameters = new List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("UserName", "Administrator"),
|
new KeyValuePair<string, string>("UserName", "Administrator"),
|
||||||
|
|
@ -104,17 +109,21 @@ namespace E2ETests
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Contains(string.Format("Hello {0}!", "Administrator"), responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains(string.Format("Hello {0}!", "Administrator"), responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Console.WriteLine("Successfully signed in as '{0}'", "Administrator");
|
||||||
|
|
||||||
//Now navigating to the store manager should work fine as this user has the necessary permission to administer the store.
|
//Now navigating to the store manager should work fine as this user has the necessary permission to administer the store.
|
||||||
|
Console.WriteLine("Trying to access the store inventory..");
|
||||||
response = httpClient.GetAsync("/StoreManager/").Result;
|
response = httpClient.GetAsync("/StoreManager/").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Equal<string>(APP_BASE_URL + "StoreManager/", response.RequestMessage.RequestUri.AbsoluteUri);
|
Assert.Equal<string>(applicationBaseUrl + "StoreManager/", response.RequestMessage.RequestUri.AbsoluteUri);
|
||||||
|
Console.WriteLine("Successfully acccessed the store inventory");
|
||||||
|
|
||||||
//Create an album
|
//Create an album
|
||||||
var albumName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 12);
|
var albumName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 12);
|
||||||
|
Console.WriteLine("Trying to create an album with name '{0}'", albumName);
|
||||||
response = httpClient.GetAsync("/StoreManager/create").Result;
|
response = httpClient.GetAsync("/StoreManager/create").Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
antiForgeryToken = Utility.RetrieveAntiForgeryToken(responseContent, "/StoreManager/create");
|
antiForgeryToken = HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/StoreManager/create");
|
||||||
formParameters = new List<KeyValuePair<string, string>>
|
formParameters = new List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
||||||
|
|
@ -128,11 +137,13 @@ namespace E2ETests
|
||||||
content = new FormUrlEncodedContent(formParameters.ToArray());
|
content = new FormUrlEncodedContent(formParameters.ToArray());
|
||||||
response = httpClient.PostAsync("/StoreManager/create", content).Result;
|
response = httpClient.PostAsync("/StoreManager/create", content).Result;
|
||||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
Assert.Equal<string>(APP_BASE_URL + "StoreManager", response.RequestMessage.RequestUri.AbsoluteUri);
|
Assert.Equal<string>(applicationBaseUrl + "StoreManager", response.RequestMessage.RequestUri.AbsoluteUri);
|
||||||
Assert.Contains(albumName, responseContent);
|
Assert.Contains(albumName, responseContent);
|
||||||
|
Console.WriteLine("Successfully created an album with name '{0}' in the store", albumName);
|
||||||
|
|
||||||
//Logout from this user session - This should take back to the home page
|
//Logout from this user session - This should take back to the home page
|
||||||
antiForgeryToken = Utility.RetrieveAntiForgeryToken(responseContent, "/Account/LogOff");
|
Console.WriteLine("Signing out of '{0}''s session", "Administrator");
|
||||||
|
antiForgeryToken = HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/Account/LogOff");
|
||||||
formParameters = new List<KeyValuePair<string, string>>
|
formParameters = new List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
new KeyValuePair<string, string>("__RequestVerificationToken", antiForgeryToken),
|
||||||
|
|
@ -147,7 +158,8 @@ namespace E2ETests
|
||||||
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("mvcmusicstore.codeplex.com", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("/Images/home-showcase.png", responseContent, StringComparison.OrdinalIgnoreCase);
|
||||||
//Verify cookie cleared on logout
|
//Verify cookie cleared on logout
|
||||||
Assert.Null(Utility.GetCookieWithName(httpClientHandler.CookieContainer.GetCookies(new Uri(APP_BASE_URL)), ".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
Assert.Null(httpClientHandler.CookieContainer.GetCookies(new Uri(applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Security.Application"));
|
||||||
|
Console.WriteLine("Successfully signed out of '{0}''s session", "Administrator");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
namespace E2ETests
|
|
||||||
{
|
|
||||||
internal class Utility
|
|
||||||
{
|
|
||||||
public static string GetIISExpressPath()
|
|
||||||
{
|
|
||||||
var iisExpressPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "IIS Express", "iisexpress.exe");
|
|
||||||
|
|
||||||
//If X86 version does not exist
|
|
||||||
if (!File.Exists(iisExpressPath))
|
|
||||||
{
|
|
||||||
iisExpressPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "IIS Express", "iisexpress.exe");
|
|
||||||
|
|
||||||
if (!File.Exists(iisExpressPath))
|
|
||||||
{
|
|
||||||
throw new Exception("Unable to find IISExpress on the machine");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return iisExpressPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cookie GetCookieWithName(CookieCollection cookieCollection, string cookieName)
|
|
||||||
{
|
|
||||||
foreach (Cookie cookie in cookieCollection)
|
|
||||||
{
|
|
||||||
if (cookie.Name == cookieName)
|
|
||||||
{
|
|
||||||
return cookie;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string RetrieveAntiForgeryToken(string htmlContent, string actionUrl)
|
|
||||||
{
|
|
||||||
int startSearchIndex = 0;
|
|
||||||
|
|
||||||
while (startSearchIndex < htmlContent.Length)
|
|
||||||
{
|
|
||||||
var antiForgeryToken = RetrieveAntiForgeryToken(htmlContent, actionUrl, ref startSearchIndex);
|
|
||||||
|
|
||||||
if (antiForgeryToken != null)
|
|
||||||
{
|
|
||||||
return antiForgeryToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string RetrieveAntiForgeryToken(string htmlContent, string actionLocation, ref int startIndex)
|
|
||||||
{
|
|
||||||
var formStartIndex = htmlContent.IndexOf("<form", startIndex, StringComparison.OrdinalIgnoreCase);
|
|
||||||
var formEndIndex = htmlContent.IndexOf("</form>", startIndex, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (formStartIndex == -1 || formEndIndex == -1)
|
|
||||||
{
|
|
||||||
//Unable to find the form start or end - finish the search
|
|
||||||
startIndex = htmlContent.Length;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
formEndIndex = formEndIndex + "</form>".Length;
|
|
||||||
startIndex = formEndIndex + 1;
|
|
||||||
|
|
||||||
var htmlDocument = new XmlDocument();
|
|
||||||
htmlDocument.LoadXml(htmlContent.Substring(formStartIndex, formEndIndex - formStartIndex));
|
|
||||||
|
|
||||||
foreach (XmlAttribute attribute in htmlDocument.DocumentElement.Attributes)
|
|
||||||
{
|
|
||||||
if (string.Compare(attribute.Name, "action", true) == 0 && attribute.Value.EndsWith(actionLocation, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
foreach (XmlNode input in htmlDocument.GetElementsByTagName("input"))
|
|
||||||
{
|
|
||||||
if (input.Attributes["name"].Value == "__RequestVerificationToken" && input.Attributes["type"].Value == "hidden")
|
|
||||||
{
|
|
||||||
return input.Attributes["value"].Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copy AspNet.Loader.dll to bin folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="applicationPath"></param>
|
|
||||||
public static void CopyAspNetLoader(string applicationPath)
|
|
||||||
{
|
|
||||||
string packagesDirectory = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\Packages"));
|
|
||||||
var aspNetLoaderSrcPath = Path.Combine(Directory.GetDirectories(packagesDirectory, "Microsoft.AspNet.Loader.IIS.Interop.*").First(), @"tools\AspNet.Loader.dll");
|
|
||||||
var aspNetLoaderDestPath = Path.Combine(applicationPath, @"bin\AspNet.Loader.dll");
|
|
||||||
if (!File.Exists(aspNetLoaderDestPath))
|
|
||||||
{
|
|
||||||
File.Copy(aspNetLoaderSrcPath, aspNetLoaderDestPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Process StartHeliosHost(string applicationPath)
|
|
||||||
{
|
|
||||||
var startInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = Utility.GetIISExpressPath(),
|
|
||||||
Arguments = string.Format("/port:5001 /path:{0}", applicationPath),
|
|
||||||
UseShellExecute = true,
|
|
||||||
CreateNoWindow = true
|
|
||||||
};
|
|
||||||
|
|
||||||
var hostProcess = Process.Start(startInfo);
|
|
||||||
Console.WriteLine("Started iisexpress. Process Id : {0}", hostProcess.Id);
|
|
||||||
Thread.Sleep(2 * 1000);
|
|
||||||
|
|
||||||
return hostProcess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue