@ -0,0 +1,9 @@ | |||
{ | |||
"tool": "Credential Scanner", | |||
"suppressions": [ | |||
{ | |||
"hash": "gmZyNUtHUH3jZ90l4ao3YrrcK6frytGMZmtSjpEkzIc=", | |||
"_justification": "Just a placeholder" | |||
} | |||
] | |||
} |
@ -0,0 +1,420 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<configSections> | |||
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" /> | |||
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" /> | |||
<section name="FirefoxPreferences" type="System.Configuration.AppSettingsSection" /> | |||
<section name="FirefoxExtensions" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromePreferences" type="System.Configuration.AppSettingsSection" /> | |||
<section name="InternetExplorerPreferences" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromeExtensions" type="System.Configuration.AppSettingsSection" /> | |||
<section name="DriverCapabilities" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromeArguments" type="System.Configuration.AppSettingsSection" /> | |||
<section name="Inputs" type="System.Configuration.AppSettingsSection" /> | |||
<section name="Outputs" type="System.Configuration.AppSettingsSection" /> | |||
<section name="keyVault" type="System.Configuration.AppSettingsSection" /> | |||
<section name="database" type="System.Configuration.AppSettingsSection" /> | |||
<section name="blobStorage" type="System.Configuration.AppSettingsSection" /> | |||
<section name="docDb" type="System.Configuration.AppSettingsSection" /> | |||
<section name="dataLake" type="System.Configuration.AppSettingsSection" /> | |||
<section name="tableStorage" type="System.Configuration.AppSettingsSection" /> | |||
<section name="appInsights" type="System.Configuration.AppSettingsSection" /> | |||
<section name="serviceBus" type="System.Configuration.AppSettingsSection" /> | |||
<section name="azureAd" type="System.Configuration.AppSettingsSection" /> | |||
<section name="adfpipeline" type="System.Configuration.AppSettingsSection" /> | |||
<section name="spex" type="System.Configuration.AppSettingsSection" /> | |||
<section name="reporting" type="System.Configuration.AppSettingsSection" /> | |||
<section name="chaosMonkey" type="System.Configuration.AppSettingsSection" /> | |||
<sectionGroup name="environments"> | |||
<section name="ChromeWindows" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromeWindowsMobile" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromeAndroid" type="System.Configuration.AppSettingsSection" /> | |||
<section name="ChromeMac" type="System.Configuration.AppSettingsSection" /> | |||
<section name="FirefoxWindows" type="System.Configuration.AppSettingsSection" /> | |||
<section name="SafariMac" type="System.Configuration.AppSettingsSection" /> | |||
<section name="SafariIPhone" type="System.Configuration.AppSettingsSection" /> | |||
<section name="SafariIPad" type="System.Configuration.AppSettingsSection" /> | |||
<section name="EdgeWindows" type="System.Configuration.AppSettingsSection" /> | |||
<section name="IEWindows" type="System.Configuration.AppSettingsSection" /> | |||
</sectionGroup> | |||
</configSections> | |||
<appSettings> | |||
<add key="Platform" value="Android" /> | |||
<add key="Env" value="dev" /> | |||
<add key="expectedResponseTimeInMs" value="5000" /> | |||
<add key="input" value="TestData\Input" /> | |||
<add key="output" value="TestData\Output" /> | |||
<add key="before" value="TestData\Before" /> | |||
<add key="after" value="TestData\After" /> | |||
<add key="DeploymentDate" value="" /> | |||
<add key="ReadFileUrl" value="" /> | |||
<!--mandatory keys--> | |||
<!-- URL Configuration--> | |||
<add key="protocol" value="http" /> | |||
<add key="host" value="eshop.31d164c105ec415cb0bc.eastus.aksapp.io" /> | |||
<add key="url" value="/" /> | |||
<!--<add key="browser" value="Safari" />--> | |||
<add key="SimulateMobileBrowser" value="false" /> | |||
<add key="browser" value="Chrome" /> | |||
<!--InternetExplorer, Firefox, FirefoxPortable, PhantomJs, RemoteWebDriver, Edge, BrowserStack--> | |||
<add key="DriverCapabilities" value="CloudProvider" /> | |||
<!--The browser to use, based on which the appropriate browser 'Preferences/Arguments/Extensions' get picked up from the config below and applied to the DriverContext--> | |||
<add key="CrossBrowserEnvironment" value="ChromeWindows" /> | |||
<add key="BuildNumber" value="" /> | |||
<add key="FirefoxUseLegacyImplementation" value="false" /> | |||
<add key="FireFoxPath" value="FirefoxPortable.exe" /> | |||
<add key="PhantomJsPath" value="" /> | |||
<add key="RemoteWebDriverHub" value="http://hub-cloud.browserstack.com/wd/hub" /> | |||
<!--<add key="proxy" value="127.0.0.1:9999" />--> | |||
<!--nlog trace level must be set to "trace" for at least one logger to see EventFiringWebDriver logs--> | |||
<add key="EnableEventFiringWebDriver" value="false" /> | |||
<!-- Used for ElementStyle Validations --> | |||
<!--timeouts--> | |||
<add key="longTimeout" value="9" /> | |||
<add key="mediumTimeout" value="6" /> | |||
<add key="shortTimeout" value="3" /> | |||
<add key="ImplicitlyWaitMilliseconds" value="5000" /> | |||
<!--Enable or disable synchronization with AngularJS--> | |||
<add key="SynchronizationWithAngularEnabled" value="false" /> | |||
<!--Downloaded files, screenshots and page source location--> | |||
<add key="UseCurrentDirectory" value="true" /> | |||
<add key="DownloadFolder" value="TestOutput\\Downloads" /> | |||
<add key="ScreenShotFolder" value="TestOutput\\Screenshots" /> | |||
<add key="PageSourceFolder" value="TestOutput\\PageSources" /> | |||
<!--Screenshots and logging--> | |||
<add key="FullDesktopScreenShotEnabled" value="false" /> | |||
<add key="SeleniumScreenShotEnabled" value="true" /> | |||
<add key="GetPageSourceEnabled" value="false" /> | |||
<!--JavaScript Error Logging--> | |||
<add key="JavaScriptErrorLogging" value="false"/> | |||
<add key="JavaScriptErrorTypes" value="SyntaxError,EvalError,ReferenceError,RangeError,TypeError,URIError,Refused to display,Internal Server Error,Cannot read property" /> | |||
<!--Use default firefox profile?--> | |||
<add key="UseDefaultFirefoxProfile" value="false" /> | |||
<add key="PathToFirefoxProfile" value="C:\Users\ci_objectivity\AppData\Roaming\Mozilla\Firefox\Profiles" /> | |||
<add key="ClientSettingsProvider.ServiceUri" value="" /> | |||
<!--Perf logging--> | |||
<add key="EnablePerfDebugLogging" value="false" /> | |||
<add key="EnablePerfTag" value="false"/> | |||
<add key="PerfExecutor" value="locust -f {1}.py --no-web --host={3} --num-request=40 --clients=20 --hatch-rate=20 --print-stats --csv={1} --logfile={1}.log" /> | |||
<!--<add key="PerfExecutor" value="abs -n 40 -s 20 -c 20 -e {1}.csv -g {1}.tsv -T "application/json" -H "Authorization:Bearer AUTH_TOKEN" -H "BusinessContext:BUSINESS_CONTEXT" -v 3 "{2}"" />--> | |||
<add key="TestProjectName" value="EShopApplicationWebSolution" /> | |||
<add key="DefaultKeyPrefix" value="" /> | |||
<!--Driver and Browser paths: Leave it blank to pick it from the default output directory--> | |||
<add key="PathToChromeDriverDirectory" value="" /> | |||
<!--<add key="PathToFirefoxDriverDirectory" value="" /> | |||
<add key="PathToInternetExplorerDriverDirectory" value="" /> | |||
<add key="PathToEdgeDriverDirectory" value="" /> | |||
<add key="ChromeBrowserExecutableLocation" value="" /> | |||
<add key="FireFoxBrowserExecutableLocation" value="" />--> | |||
</appSettings> | |||
<keyVault> | |||
<add key="ClientId" value="" /> | |||
<add key="ClientSecret" value="" /> <!-- TODO: Replace Client-secret with Cert based approach --> | |||
<add key="VaultUri" value="https://xyz-secrets-{Env}-kv.vault.azure.net/secrets/" /> <!-- The URL should end with "secrets/" --> | |||
<add key="CertThumbprint" value="" /> | |||
<add key="CertPath" value="" /> | |||
<add key="CertPwd" value="" /> | |||
<add key="SqlClientIdKey" value="DbClientId" /> <!-- Key from KeyVault --> | |||
<add key="SqlClientSecretKey" value="DbClientSecret" /> <!-- Key from KeyVault --> | |||
</keyVault> | |||
<database> | |||
<add key="AdTenant" value="" /> | |||
<add key="DbKey" value="xyz-storage-core-{Env}-db" /> <!-- Database name --> | |||
<add key="DbServer" value="xyz-storage-core-{Env}-ss.database.windows.net" /> <!-- Database Server name --> | |||
<add key="DbUser" value="" /> | |||
<add key="DbPwd" value="" /> | |||
</database> | |||
<blobStorage> | |||
<add key="ConnectionStringKey" value="SecretName" /> <!-- Key from KeyVault --> | |||
</blobStorage> | |||
<tableStorage> | |||
<add key="ConnectionStringKey" value="SecretName" /> <!-- Key from KeyVault --> | |||
</tableStorage> | |||
<serviceBus> | |||
<add key="ConnectionStringKey" value="SecretName" /> <!-- Key from KeyVault --> | |||
</serviceBus> | |||
<docDb> | |||
<add key="DatabaseName" value="" /> | |||
<add key="CollectionName" value="" /> | |||
<add key="EndPointUrl" value="https://xyz-{Env}-cosmos-sql.documents.azure.com:443" /> | |||
<add key="AuthorizationKey" value="" /> <!-- Ideally, the Key from KeyVault --> | |||
</docDb> | |||
<dataLake> | |||
<add key="ClientId" value="" /> | |||
<add key="ClientSecret" value="" /> | |||
<add key="TenantId" value="" /> | |||
<add key="AccountName" value="" /> | |||
<add key="DnsSuffix" value="" /> | |||
</dataLake> | |||
<appInsights> | |||
<add key="Url" value="https://api.applicationinsights.io/v1/apps/" /> | |||
<add key="ApiKey" value="x-api-key" /> | |||
<add key="ApiValue" value="" /> | |||
<add key="AppId" value="" /> | |||
</appInsights> | |||
<azureAd> | |||
<add key="IsB2C" value="true" /> | |||
<add key="AuthUrl" value="https://login.microsoftonline.com/{TenantName}/oauth2/v2.0/authorize?p={SignInPolicyName}&client_id={clientId}&redirect_uri={RedirectPath}{CallBackPath}&response_type=code%20id_token&scope=openid%20profile%20offline_access%20{ApiScopes}" /> | |||
<add key="TenantName" value="xxx.onmicrosoft.com" /> | |||
<add key="AzureAdB2CInstance" value="https://login.microsoftonline.com/tfp" /> | |||
<add key="SignInPolicyName" value="xxx{Env}{Company}" /> | |||
<add key="Authority" value="{AzureAdB2CInstance}/{TenantName}/{SignInPolicyName}/v2.0" /> | |||
<add key="ApiPath" value="https://{TenantName}/{Company}{Env}api" /> | |||
<add key="ApiScopes" value="{ApiPath}/read" /> | |||
<add key="RedirectPath" value="http://localhost:8704" /><!--https://{Company}portal{Env}.npgtssweb.com--> | |||
<add key="ApiUrl" value="https://xxx-{Env}-api-services.azurewebsites.net/" /> | |||
<add key="CallBackPath" value="/{Company}-signin-oidc" /> | |||
<add key="ClientId" value="clientid" /> | |||
<add key="ClientSecret" value="clientsecret" /> | |||
<add key="UserIdField" value="//*[@id='signInName']" /> | |||
<add key="PasswordField" value="//*[@id='password']" /> | |||
<add key="SubmitField" value="//*[@id='next']" /> | |||
<!--<add key="SignedOutCallbackPath" value="/{Company}-signout-callback-oidc" />--> | |||
<!--<add key="ResetPasswordPolicyName" value="xxx{Env}{Company}" />--> | |||
</azureAd> | |||
<adfpipeline> | |||
<add key="AdfTenantId" value="" /> | |||
<add key="AdfClientId" value="" /> | |||
<add key="AdfClientSecret" value="" /> | |||
<add key="AdfSubscriptionId" value="" /> | |||
<add key="AdfResourceGroupName" value="" /> | |||
<add key="DataFactoryName" value=""/> | |||
<add key="WaitTimeInMilliSeconds" value=""/> | |||
</adfpipeline> | |||
<specFlow> | |||
<stepAssemblies> | |||
<stepAssembly assembly="Ocaramba" /> | |||
<stepAssembly assembly="EShopApplicationWebSolution" /> | |||
<stepAssembly assembly="Bdd.Core" /> | |||
<stepAssembly assembly="Bdd.Core.Web" /> | |||
</stepAssemblies> | |||
<!-- https://specflow.org/2019/updating-to-specflow-3/ --> | |||
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config --> | |||
</specFlow> | |||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd" autoReload="true" throwExceptions="false" internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> | |||
<targets async="true"> | |||
<target name="logfile" xsi:type="File" fileName="${basedir}\EShopApplicationWebSolution_${date:format=ddMMMyyyy:universalTime=false:cached=True}.log" layout="${longdate}|${level}|${callsite}|${message}|${exception}" /> | |||
<target name="perf" xsi:type="File" fileName="${basedir}\EShopApplicationWebSolution.Perf_${date:format=ddMMMyyyy_hh.mm.ss.tt:universalTime=false:cached=True}.json" layout="${message}," /> | |||
<target name="console" xsi:type="ColoredConsole" layout="[${level}] ${message}|${exception}" /> | |||
<target name="debugger" xsi:type="Debugger" layout="[${level}] ${message}|${exception}" /> | |||
</targets> | |||
<rules> | |||
<logger name="Perf" minlevel="Debug" writeTo="perf" /> | |||
<logger name="*" minlevel="Debug" writeTo="debugger" /> | |||
<logger name="*" minlevel="Debug" writeTo="logfile" /> | |||
<logger name="*" minlevel="Debug" writeTo="console" /> | |||
</rules> | |||
</nlog> | |||
<FirefoxPreferences> | |||
<!--add key="PreferenceToBeOverride" value="NewValue" /--> | |||
</FirefoxPreferences> | |||
<FirefoxExtensions> | |||
<!-->add key="FirefoxPluginName.xpi" value=""/--> | |||
</FirefoxExtensions> | |||
<InternetExplorerPreferences> | |||
</InternetExplorerPreferences> | |||
<ChromePreferences> | |||
<add key="download.default_directory" value="TestData" /> | |||
<add key="download.prompt_for_download" value="false" /> | |||
</ChromePreferences> | |||
<ChromeExtensions> | |||
<!-->add key="ChromePluginName.crx" value=""/--> | |||
</ChromeExtensions> | |||
<ChromeArguments> | |||
<add key="incognito" value="true" /> | |||
<add key="no-sandbox" value="true" /> | |||
<!--<add key="headless" value="true" /> | |||
<add key="disable-gpu" value="true" /> | |||
<add key="disable-software-rasterizer" value="true" />--> | |||
</ChromeArguments> | |||
<DriverCapabilities> | |||
<add key="browserstack.user" value=""/> | |||
<add key="browserstack.key" value=""/> | |||
<add key="project" value="EShopApplicationWebSolution"/> | |||
<add key="browserstack.debug" value="true" /> | |||
<add key="browserstack.networkLogs" value="true" /> | |||
<add key="browserstack.console" value="warnings" /> | |||
<!--https://www.browserstack.com/automate/capabilities--> | |||
<add key="acceptSslCerts" value="true" /> | |||
<!--<add key="browserstack.local" value="false" />--> | |||
<!--<add key="browserstack.ie.enablePopups" value="true" />--> | |||
<!--<add key="browserstack.safari.enablePopups" value="true" />--> | |||
<!--<add key="browserstack.selenium_version" value="3.5.2" />--> | |||
<!--TestingBot related stuff--> | |||
<!--<add key="key" value="" /> | |||
<add key="secret" value="" /> | |||
<add key="server" value="" />--> | |||
</DriverCapabilities> | |||
<environments> | |||
<ChromeWindows> | |||
<!--<add key="browser_version" value="65.0" />--> | |||
<add key="browser" value="chrome" /> | |||
<add key="os" value="Windows"/> | |||
<add key="os_version" value="10"/> | |||
<add key="resolution" value="1366x768" /> | |||
<add key="name" value="" /> | |||
</ChromeWindows> | |||
<ChromeWindowsMobile> | |||
<!--<add key="browser_version" value="65.0" />--> | |||
<add key="browser" value="chrome" /> | |||
<add key="os" value="Windows"/> | |||
<add key="os_version" value="10"/> | |||
<add key="resolution" value="720x480" /> | |||
<add key="name" value="" /> | |||
</ChromeWindowsMobile> | |||
<ChromeMac> | |||
<add key="browser" value="chrome" /> | |||
<add key="os" value="OS X"/> | |||
<add key="os_version" value="High Sierra"/> | |||
<add key="name" value="" /> | |||
</ChromeMac> | |||
<ChromeAndroid> | |||
<add key="os_version" value="7.1"/> | |||
<add key="device" value="Google Pixel" /> | |||
<add key="real_mobile" value="true" /> | |||
<add key="name" value="" /> | |||
<!--<add key="deviceOrientation" value="landscape" />--> | |||
</ChromeAndroid> | |||
<SafariMac> | |||
<add key="browser" value="safari" /> | |||
<add key="os" value="OS X"/> | |||
<add key="os_version" value="High Sierra"/> | |||
</SafariMac> | |||
<SafariIPhone> | |||
<add key="device" value="iPhone 7" /> | |||
<add key="os_version" value="10.3"/> | |||
<add key="real_mobile" value="true" /> | |||
</SafariIPhone> | |||
<SafariIPad> | |||
<add key="device" value="iPad 5th" /> | |||
<add key="os_version" value="11.0"/> | |||
<add key="real_mobile" value="true" /> | |||
</SafariIPad> | |||
<EdgeWindows> | |||
<add key="browser" value="edge" /> | |||
<add key="os" value="Windows"/> | |||
<add key="os_version" value="10"/> | |||
</EdgeWindows> | |||
<IEWindows> | |||
<add key="browser" value="IE" /> | |||
<add key="browser_version" value="10.0" /> | |||
<add key="os" value="Windows"/> | |||
<add key="os_version" value="8"/> | |||
</IEWindows> | |||
<FirefoxWindows> | |||
<add key="browser" value="firefox" /> | |||
<add key="os" value="Windows"/> | |||
<add key="os_version" value="10"/> | |||
</FirefoxWindows> | |||
</environments> | |||
<!-- Docs: https://vamsitp.github.io/spexdocs/ --> | |||
<!-- Alternative to Spex.json --> | |||
<spex> | |||
<add key="Account" value="{account}" /> | |||
<add key="Project" value="{project}" /> | |||
<add key="PersonalAccessToken" value="{pat}" /> | |||
<add key="AreaPath" value="{areaPath}" /> | |||
<add key="IterationPath" value="{project}\{iteration-path}" /> | |||
<add key="DefaultAssignedTo" value="{default-user-email}" /> | |||
<add key="TestProjectPath" value=".\EShopApplicationWebSolution.csproj" /> | |||
<add key="TestAssemblyPath" value=".\bin\debug\EShopApplicationWebSolution.dll" /> | |||
<!-- Comma separated filters (e.g. Features,FeatureName1,path2/FeatureName2) --> | |||
<add key="FeatureFilters" value="" /> | |||
<!-- Comma separated filters (e.g. ScenarioName1,ScenarioName2) --> | |||
<add key="ScenarioFilters" value="" /> | |||
<!-- Comma separated tags (e.g. @attach,@input) --> | |||
<add key="AttachmentTags" value="@attach" /> | |||
<!-- Root folder for attachments --> | |||
<add key="AttachmentsPath" value="TestData" /> | |||
<!-- Comma separated fields (e.g. customField1=defaultValue1,customField2=defaultValue2) --> | |||
<add key="AdditionalFields" value="" /> | |||
<add key="BddThenAsExpectedResult" value="false" /> | |||
<add key="ScenarioOutlineExamplesInline" value="false" /> | |||
<!-- Valid values: blank, s, r, m --> | |||
<add key="QuiteMode" value="" /> | |||
</spex> | |||
<reporting> | |||
<add key="Path" value="TestOutput\Reports" /> | |||
<add key="Enabled" value="true" /> | |||
<add key="DarkTheme" value="true" /> | |||
<add key="ShowSteps" value="true" /> | |||
<add key="ShowLogs" value="true" /> | |||
</reporting> | |||
<chaosMonkey> | |||
<add key="Enabled" value="false" /> | |||
<add key="sqlDb" value="SqlConnectionString" /> | |||
<add key="blobStorage" value="BlobConnectionString" /> | |||
<add key="tableStorage" value="TableConnectionString" /> | |||
<add key="serviceBus" value="ServiceBusConnectionString" /> | |||
<add key="dataLake" value="DataLakeConnectionString" /> | |||
<add key="function" value="FunctionConnectionString" /> | |||
<add key="logicApp" value="LogicAppConnectionString" /> | |||
<add key="aks" value="AksConnectionString" /> | |||
<add key="appService" value="AppServiceConnectionString" /> | |||
</chaosMonkey> | |||
<system.web> | |||
<membership defaultProvider="ClientAuthenticationMembershipProvider"> | |||
<providers> | |||
<add name="ClientAuthenticationMembershipProvider" | |||
type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" | |||
serviceUri="" /> | |||
</providers> | |||
</membership> | |||
<roleManager defaultProvider="ClientRoleProvider" enabled="true"> | |||
<providers> | |||
<add name="ClientRoleProvider" | |||
type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" | |||
serviceUri="" cacheTimeout="86400" /> | |||
</providers> | |||
</roleManager> | |||
</system.web> | |||
</configuration> |
@ -0,0 +1,106 @@ | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// <copyright file="AppTestBase.cs" company="Microsoft"> | |||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
// OTHER DEALINGS IN THE SOFTWARE. | |||
// </copyright> | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
namespace Bdd.Core.Hooks | |||
{ | |||
using System.Threading.Tasks; | |||
using Bdd.Core.Web.Hooks; | |||
using TechTalk.SpecFlow; | |||
/// <summary> | |||
/// https://github.com/techtalk/SpecFlow/wiki/Hooks#supported-hook-attributes | |||
/// </summary> | |||
[Binding] | |||
public class AppTestBase : WebProjectTestBase | |||
{ | |||
private const int Order = 1; | |||
/// <summary> | |||
/// Assembly initialization code. | |||
/// </summary> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[BeforeTestRun(Order = Order)] | |||
public static async Task AssemblyInitialize() | |||
{ | |||
//// // If retrieval of AccessToken from AD isn't possible to connect to SQL DB, comment out the below line | |||
//// DataSources.SqlDataSource.AccessTokenCallback = SqlConnectionConfig.AccessTokenCallback; | |||
//// DataSources.SqlDataSource.ConnectionBuilderCallback = async key => | |||
//// { | |||
//// var connBuilder = await SqlConnectionConfig.ConnectionBuilderCallback(key).ConfigureAwait(false); | |||
//// //// Update the connection if required. E.g.: | |||
//// // connBuilder.UserId = "sqluser"; | |||
//// // connBuilder.Password = KeyVaultHelper.GetKeyVaultSecretAsync("SqlClientPwd"); | |||
//// return connBuilder; | |||
//// }; | |||
await InitializeAsync().ConfigureAwait(false); | |||
//// // Uncomment the below line to validate Styles for your Web-pages | |||
//// ElementStyles = (await new YamlDataSource().ReadAsync<IEnumerable<ElementStyle>>(input: @"TestData\Input\ElementStyles.yml").ConfigureAwait(false)).ToList(); | |||
} | |||
/// <summary> | |||
/// Assembly Unload code. | |||
/// </summary> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[AfterTestRun(Order = Order)] | |||
public static async Task AssemblyUnload() | |||
{ | |||
await TeardownAsync().ConfigureAwait(false); | |||
} | |||
/// <summary> | |||
/// After the class. | |||
/// </summary> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[AfterFeature(Order = Order)] | |||
public static async Task AfterClass() | |||
{ | |||
await AfterFeature().ConfigureAwait(false); | |||
} | |||
/// <summary> | |||
/// Before the class. | |||
/// </summary> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[BeforeFeature(Order = Order)] | |||
public static async Task BeforeClass() | |||
{ | |||
await BeforeFeature().ConfigureAwait(false); | |||
} | |||
/// <summary> | |||
/// After the test. | |||
/// </summary> | |||
/// <param name="featureContext">Feature Context.</param> | |||
/// <param name="scenarioContext">Scenario Context.</param> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[After(Order = Order)] | |||
public async Task AfterTest(FeatureContext featureContext, ScenarioContext scenarioContext) | |||
{ | |||
await this.AfterScenario(featureContext, scenarioContext).ConfigureAwait(false); | |||
} | |||
/// <summary> | |||
/// Before the test. | |||
/// </summary> | |||
/// <param name="featureContext">Feature Context.</param> | |||
/// <param name="scenarioContext">Scenario Context.</param> | |||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> | |||
[Before(Order = Order)] | |||
public async Task BeforeTest(FeatureContext featureContext, ScenarioContext scenarioContext) | |||
{ | |||
await this.BeforeScenario(featureContext, scenarioContext).ConfigureAwait(false); | |||
} | |||
} | |||
} |
@ -0,0 +1,137 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net471</TargetFramework> | |||
<Features>IOperation</Features> | |||
<Features>flow-analysis</Features> | |||
<RunCodeAnalysis>false</RunCodeAnalysis> | |||
<DebugType>pdbonly</DebugType> | |||
<AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects> | |||
<NoWarn>1701;1702;SA0001;SA1652;NU5100</NoWarn> | |||
<IsTestProject>true</IsTestProject> | |||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<SpecFlowFeatureFiles Remove="Features\RandomWebOperations2.feature" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<AdditionalFiles Include="stylecop.json" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<SpecFlowGeneratorPlugins Include="$(_BddCoreGeneratorPluginPath)" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Bdd.Core.Generator.SpecFlowPlugin" Version="3.0.15-preview" /> | |||
<PackageReference Include="Bdd.Core.Web" Version="3.0.15-preview" /> | |||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> | |||
<PackageReference Include="NLog" Version="4.7.6" /> | |||
<PackageReference Include="NUnit" Version="3.12.0" /> | |||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.11.1" /> | |||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
</PackageReference> | |||
<PackageReference Include="Ocaramba" Version="3.2.11" /> | |||
<PackageReference Include="Pickles" Version="2.21.0" /> | |||
<PackageReference Include="Selenium.Support" Version="3.141.0" /> | |||
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" /> | |||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="89.0.4389.2300" /> | |||
<PackageReference Include="Selenium.WebDriver.GeckoDriver" Version="0.28.0" /> | |||
<PackageReference Include="Selenium.WebDriver.GeckoDriver.Win64" Version="0.28.0" /> | |||
<PackageReference Include="Selenium.WebDriver.IEDriver" Version="3.150.1.2" /> | |||
<PackageReference Include="SpecFlow" Version="3.5.14" /> | |||
<PackageReference Include="SpecFlow.NUnit" Version="3.5.14" /> | |||
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.5.14" /> | |||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | |||
</PackageReference> | |||
<PackageReference Include="System.Net.Http" Version="4.3.4" /> | |||
<PackageReference Include="System.Security.Cryptography.Algorithms" Version="4.3.1" /> | |||
<PackageReference Include="System.Security.Cryptography.Encoding" Version="4.3.0" /> | |||
<PackageReference Include="System.Security.Cryptography.Primitives" Version="4.3.0" /> | |||
<PackageReference Include="System.Security.Cryptography.X509Certificates" Version="4.3.2" /> | |||
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> | |||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" /> | |||
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.CSharp" /> | |||
<Reference Include="System.Configuration" /> | |||
<Reference Include="System.IO.Compression" /> | |||
<Reference Include="System.ServiceModel" /> | |||
<Reference Include="System.Transactions" /> | |||
<Reference Include="System.Web" /> | |||
<Reference Include="System.Windows.Forms" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="App.config"> | |||
<SubType>Designer</SubType> | |||
<TransformOnBuild>true</TransformOnBuild> | |||
</None> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Update="Properties\Resources.Designer.cs"> | |||
<DesignTime>True</DesignTime> | |||
<AutoGen>True</AutoGen> | |||
<DependentUpon>Resources.resx</DependentUpon> | |||
</Compile> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Update="Properties\Resources.resx"> | |||
<Generator>ResXFileCodeGenerator</Generator> | |||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Entities\" /> | |||
<Folder Include="Hooks\" /> | |||
<Folder Include="TestData\Before\" /> | |||
<Folder Include="TestData\After\" /> | |||
<Folder Include="TestData\Output\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="EShopApplicationWebSolution.dev.runsettings"> | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
</None> | |||
<None Update="TestData\Input\Credentials.xlsx"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Remove="Executors\**" /> | |||
<Compile Remove="Spex\**" /> | |||
<EmbeddedResource Remove="Executors\**" /> | |||
<EmbeddedResource Remove="Spex\**" /> | |||
<None Remove="Executors\**" /> | |||
<None Remove="Spex\**" /> | |||
<SpecFlowFeatureFiles Remove="Executors\**" /> | |||
<SpecFlowFeatureFiles Remove="Spex\**" /> | |||
<SpecFlowObsoleteCodeBehindFiles Remove="Executors\**" /> | |||
<SpecFlowObsoleteCodeBehindFiles Remove="Spex\**" /> | |||
</ItemGroup> | |||
<PropertyGroup> | |||
<ShowTrace>true</ShowTrace> | |||
<OverwriteReadOnlyFiles>true</OverwriteReadOnlyFiles> | |||
<ForceGeneration>true</ForceGeneration> | |||
<VerboseOutput>true</VerboseOutput> | |||
</PropertyGroup> | |||
<!--<Import Project="%userprofile%\.nuget\packages\SpecFlow\2.4.0\tools\TechTalk.SpecFlow.tasks" Condition="Exists('%userprofile%\.nuget\packages\SpecFlow\2.4.0\tools\TechTalk.SpecFlow.tasks')" /> | |||
<Import Project="%userprofile%\.nuget\packages\SpecFlow\2.4.0\tools\TechTalk.SpecFlow.targets" Condition="Exists('%userprofile%\.nuget\packages\SpecFlow\2.4.0\tools\TechTalk.SpecFlow.targets')" />--> | |||
<Target Name="AfterUpdateFeatureFilesInProject"> | |||
<ItemGroup> | |||
<Compile Include="Features\**\*.feature.cs" /> | |||
</ItemGroup> | |||
</Target> | |||
</Project> |
@ -0,0 +1,110 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<!--https://docs.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file--> | |||
<RunSettings> | |||
<!-- Configurations that affect the Test Framework --> | |||
<RunConfiguration> | |||
<!-- 0 = Use all Cores --> | |||
<MaxCpuCount>0</MaxCpuCount> | |||
<!-- Path relative to solution directory --> | |||
<ResultsDirectory>.\TestResults</ResultsDirectory> | |||
<!-- x86 or x64 - You can also change it from menu Test, Test Settings, Default Processor Architecture --> | |||
<!--<TargetPlatform>x64</TargetPlatform>--> | |||
<!-- Framework35 | [Framework40] | Framework45 --> | |||
<!--<TargetFrameworkVersion>Framework45</TargetFrameworkVersion>--> | |||
<!-- Path to Test Adapters --> | |||
<!--<TestAdaptersPaths>.\</TestAdaptersPaths>--> | |||
<!--TestSessionTimeout is only available with Visual Studio 2017 version 15.5 and higher --> | |||
<!-- Specify timeout in milliseconds. A valid value should be greater than 0 --> | |||
<TestSessionTimeout>30000000</TestSessionTimeout> | |||
</RunConfiguration> | |||
<!-- Configurations for data collectors --> | |||
<!--<DataCollectionRunSettings> | |||
<DataCollectors> | |||
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||
<Configuration> | |||
<CodeCoverage> | |||
<ModulePaths> | |||
<Exclude> | |||
<ModulePath>.*CPPUnitTestFramework.*</ModulePath> | |||
</Exclude> | |||
</ModulePaths>--> | |||
<!-- We recommend you do not change the following values: --> | |||
<!--<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation> | |||
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses> | |||
<CollectFromChildProcesses>True</CollectFromChildProcesses> | |||
<CollectAspDotNet>False</CollectAspDotNet> | |||
</CodeCoverage> | |||
</Configuration> | |||
</DataCollector>--> | |||
<!--Video data collector is only available with Visual Studio 2017 version 15.5 and higher --> | |||
<!--<DataCollector uri="datacollector://microsoft/VideoRecorder/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.DataCollection.VideoRecorder.VideoRecorderDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.VideoRecorder, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Screen and Voice Recorder"> | |||
</DataCollector> | |||
</DataCollectors> | |||
</DataCollectionRunSettings>--> | |||
<!-- Parameters used by tests at runtime --> | |||
<TestRunParameters> | |||
<!-- Common --> | |||
<Parameter name="appSettings.browser" value="Chrome" /> <!--RemoteWebDriver--> | |||
<Parameter name="appSettings.DriverCapabilities" value="CloudProvider" /> <!--Only used when browser is set to RemoteWebDriver--> | |||
<Parameter name="appSettings.CrossBrowserEnvironment" value="ChromeWindows" /> <!--Only used when browser is set to RemoteWebDriver--> | |||
<Parameter name="appSettings.EnablePerfDebugLogging" value="false" /> | |||
<Parameter name="appSettings.BuildNumber" value="" /> | |||
<Parameter name="appSettings.EnableEventFiringWebDriver" value="true" /> | |||
<Parameter name="appSettings.SimulateMobileBrowser" value="false" /> | |||
<Parameter name="appSettings.PathToChromeDriverDirectory" value="" /> | |||
<Parameter name="DriverCapabilities.browserstack.user" value="" /> | |||
<Parameter name="DriverCapabilities.browserstack.key" value="" /> | |||
<Parameter name="database.DbUser" value="" /> | |||
<Parameter name="database.DbPwd" value="" /> | |||
<Parameter name="chaosMonkey.Enabled" value="false" /> | |||
<!-- Dev --> | |||
<Parameter name="appSettings.Env" value="dev" /> | |||
<!-- QA --> | |||
<!-- <Parameter name="appSettings.Env" value="qa" />--> | |||
<!-- UAT --> | |||
<!-- <Parameter name="appSettings.Env" value="uat" /> --> | |||
<!-- Perf --> | |||
<!-- <Parameter name="appSettings.Env" value="perf" /> --> | |||
</TestRunParameters> | |||
<!-- Adapter Specific sections --> | |||
<!-- MSTest adapter --> | |||
<!--<MSTest> | |||
<Parallelize> | |||
<Workers>8</Workers> | |||
<Scope>ClassLevel</Scope> | |||
</Parallelize> | |||
<MapInconclusiveToFailed>True</MapInconclusiveToFailed> | |||
<CaptureTraceOutput>false</CaptureTraceOutput> | |||
<DeleteDeploymentDirectoryAfterTestRunIsComplete>False</DeleteDeploymentDirectoryAfterTestRunIsComplete> | |||
<DeploymentEnabled>False</DeploymentEnabled> | |||
<AssemblyResolution> | |||
<Directory Path="D:\myfolder\bin\" includeSubDirectories="false"/> | |||
</AssemblyResolution> | |||
</MSTest>--> | |||
</RunSettings> |
@ -0,0 +1,33 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio 15 | |||
VisualStudioVersion = 15.0.28010.2041 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AA8F9F19-F125-409C-A3B5-F4DA4A536A58}" | |||
ProjectSection(SolutionItems) = preProject | |||
EShopApplicationWebSolution.runsettings = EShopApplicationWebSolution.runsettings | |||
azure-pipelines.yml = azure-pipelines.yml | |||
Nuget.config = Nuget.config | |||
stylecop.json = stylecop.json | |||
EndProjectSection | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EShopApplicationWebSolution", "EShopApplicationWebSolution.csproj", "{9CBE4BA5-9295-4CA6-9991-30A4D578DC0A}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
Release|Any CPU = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{9CBE4BA5-9295-4CA6-9991-30A4D578DC0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{9CBE4BA5-9295-4CA6-9991-30A4D578DC0A}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{9CBE4BA5-9295-4CA6-9991-30A4D578DC0A}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{9CBE4BA5-9295-4CA6-9991-30A4D578DC0A}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {DC51F25F-3DC2-403B-8A2A-0B17FF5ABB3C} | |||
EndGlobalSection | |||
EndGlobal |
@ -0,0 +1,25 @@ | |||
@ui @owner=kritsha @web @testplan= @testsuite= | |||
Feature: Login_EShopApplication | |||
As a user, I want to be able to login to the EShop application | |||
@bvt @priority=1 | |||
Scenario: Verify that a registered user is able to login into EShop application | |||
When user launches EShop application | |||
And user clicks on "Login" option | |||
And user enter Email and Password of "User1" | |||
And user click on "LOG IN" button | |||
Then verify if "User1" is logged-in | |||
@priority=2 | |||
Scenario Outline: Verify that the user is unable to login to EShop Application if user is not registered already | |||
Given the user is not registered to EShop application | |||
When user launches EShop application | |||
And user clicks on "Login" button | |||
And user enter Email and Password of "<user>" | |||
And user click on "LOG IN" button | |||
Then the user should not be able to login to the application | |||
Examples: | |||
| user | | |||
| InvalidUser1 | | |||
| InvalidUser2 | | |||
| InvalidUser3 | |
@ -0,0 +1,218 @@ | |||
// ------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by SpecFlow (https://www.specflow.org/). | |||
// SpecFlow Version:3.5.0.0 | |||
// SpecFlow Generator Version:3.5.0.0 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// </auto-generated> | |||
// ------------------------------------------------------------------------------ | |||
#region Designer generated code | |||
#pragma warning disable | |||
namespace EShopApplicationWebSolution.Features | |||
{ | |||
using TechTalk.SpecFlow; | |||
using System; | |||
using System.Linq; | |||
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.5.0.0")] | |||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
[NUnit.Framework.TestFixtureAttribute()] | |||
[NUnit.Framework.DescriptionAttribute("Login_EShopApplication")] | |||
[NUnit.Framework.CategoryAttribute("ui")] | |||
[NUnit.Framework.CategoryAttribute("owner=kritsha")] | |||
[NUnit.Framework.CategoryAttribute("web")] | |||
[NUnit.Framework.CategoryAttribute("testplan=")] | |||
[NUnit.Framework.CategoryAttribute("testsuite=")] | |||
public partial class Login_EShopApplicationFeature | |||
{ | |||
private TechTalk.SpecFlow.ITestRunner testRunner; | |||
private string[] _featureTags = new string[] { | |||
"ui", | |||
"owner=kritsha", | |||
"web", | |||
"testplan=", | |||
"testsuite="}; | |||
#line 1 "EShopApplication_Login.feature" | |||
#line hidden | |||
[NUnit.Framework.OneTimeSetUpAttribute()] | |||
public virtual void FeatureSetup() | |||
{ | |||
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); | |||
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "Login_EShopApplication", "\tAs a user, I want to be able to login to the EShop application", ProgrammingLanguage.CSharp, new string[] { | |||
"ui", | |||
"owner=kritsha", | |||
"web", | |||
"testplan=", | |||
"testsuite="}); | |||
testRunner.OnFeatureStart(featureInfo); | |||
} | |||
[NUnit.Framework.OneTimeTearDownAttribute()] | |||
public virtual void FeatureTearDown() | |||
{ | |||
testRunner.OnFeatureEnd(); | |||
testRunner = null; | |||
} | |||
[NUnit.Framework.SetUpAttribute()] | |||
public virtual void TestInitialize() | |||
{ | |||
} | |||
[NUnit.Framework.TearDownAttribute()] | |||
public virtual void TestTearDown() | |||
{ | |||
testRunner.OnScenarioEnd(); | |||
} | |||
public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) | |||
{ | |||
testRunner.OnScenarioInitialize(scenarioInfo); | |||
testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs<NUnit.Framework.TestContext>(NUnit.Framework.TestContext.CurrentContext); | |||
} | |||
public virtual void ScenarioStart() | |||
{ | |||
testRunner.OnScenarioStart(); | |||
} | |||
public virtual void ScenarioCleanup() | |||
{ | |||
testRunner.CollectScenarioErrors(); | |||
} | |||
[NUnit.Framework.TestAttribute()] | |||
[NUnit.Framework.DescriptionAttribute("Verify that a registered user is able to login into EShop application")] | |||
[NUnit.Framework.CategoryAttribute("bvt")] | |||
[NUnit.Framework.CategoryAttribute("priority=1")] | |||
public virtual void VerifyThatARegisteredUserIsAbleToLoginIntoEShopApplication() | |||
{ | |||
string[] tagsOfScenario = new string[] { | |||
"bvt", | |||
"priority=1"}; | |||
System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); | |||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Verify that a registered user is able to login into EShop application", null, tagsOfScenario, argumentsOfScenario); | |||
#line 6 | |||
this.ScenarioInitialize(scenarioInfo); | |||
#line hidden | |||
bool isScenarioIgnored = default(bool); | |||
bool isFeatureIgnored = default(bool); | |||
if ((tagsOfScenario != null)) | |||
{ | |||
isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); | |||
} | |||
if ((this._featureTags != null)) | |||
{ | |||
isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); | |||
} | |||
if ((isScenarioIgnored || isFeatureIgnored)) | |||
{ | |||
testRunner.SkipScenario(); | |||
} | |||
else | |||
{ | |||
this.ScenarioStart(); | |||
#line 7 | |||
testRunner.When("user launches EShop application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); | |||
#line hidden | |||
#line 8 | |||
testRunner.And("user clicks on \"Login\" option", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 9 | |||
testRunner.And("user enter Email and Password of \"User1\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 10 | |||
testRunner.And("user click on \"LOG IN\" button", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 11 | |||
testRunner.Then("verify if \"User1\" is logged-in", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); | |||
#line hidden | |||
} | |||
this.ScenarioCleanup(); | |||
} | |||
[NUnit.Framework.TestAttribute()] | |||
[NUnit.Framework.DescriptionAttribute("Verify that the user is unable to login to EShop Application if user is not regis" + | |||
"tered already")] | |||
[NUnit.Framework.CategoryAttribute("bddcore-ex")] | |||
[NUnit.Framework.CategoryAttribute("priority=2")] | |||
[NUnit.Framework.TestCaseAttribute("InvalidUser1", null)] | |||
[NUnit.Framework.TestCaseAttribute("InvalidUser2", null)] | |||
[NUnit.Framework.TestCaseAttribute("InvalidUser3", null)] | |||
public virtual void VerifyThatTheUserIsUnableToLoginToEShopApplicationIfUserIsNotRegisteredAlready(string user, string[] exampleTags) | |||
{ | |||
string[] @__tags = new string[] { | |||
"priority=2"}; | |||
if ((exampleTags != null)) | |||
{ | |||
@__tags = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.Concat(@__tags, exampleTags)); | |||
} | |||
string[] tagsOfScenario = @__tags; | |||
System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); | |||
argumentsOfScenario.Add("user", user); | |||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Verify that the user is unable to login to EShop Application if user is not regis" + | |||
"tered already", null, tagsOfScenario, argumentsOfScenario); | |||
#line 14 | |||
this.ScenarioInitialize(scenarioInfo); | |||
#line hidden | |||
bool isScenarioIgnored = default(bool); | |||
bool isFeatureIgnored = default(bool); | |||
if ((tagsOfScenario != null)) | |||
{ | |||
isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); | |||
} | |||
if ((this._featureTags != null)) | |||
{ | |||
isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); | |||
} | |||
if ((isScenarioIgnored || isFeatureIgnored)) | |||
{ | |||
testRunner.SkipScenario(); | |||
} | |||
else | |||
{ | |||
this.ScenarioStart(); | |||
#line 15 | |||
testRunner.Given("the user is not registered to EShop application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); | |||
#line hidden | |||
#line 16 | |||
testRunner.When("user launches EShop application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); | |||
#line hidden | |||
#line 17 | |||
testRunner.And("user clicks on \"Login\" button", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 18 | |||
testRunner.And(string.Format("user enter Email and Password of \"{0}\"", user), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 19 | |||
testRunner.And("user click on \"LOG IN\" button", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); | |||
#line hidden | |||
#line 20 | |||
testRunner.Then("the user should not be able to login to the application", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); | |||
#line hidden | |||
} | |||
this.ScenarioCleanup(); | |||
} | |||
[NUnit.Framework.TestAttribute()] | |||
[NUnit.Framework.DescriptionAttribute("Verify that the user is unable to login to EShop Application if user is not regis" + | |||
"tered already")] | |||
[NUnit.Framework.CategoryAttribute("priority=2")] | |||
[NUnit.Framework.CategoryAttribute("bddcore-wrapper")] | |||
public virtual void VerifyThatTheUserIsUnableToLoginToEShopApplicationIfUserIsNotRegisteredAlready() | |||
{ | |||
this.VerifyThatTheUserIsUnableToLoginToEShopApplicationIfUserIsNotRegisteredAlready("InvalidUser1", null); | |||
this.VerifyThatTheUserIsUnableToLoginToEShopApplicationIfUserIsNotRegisteredAlready("InvalidUser2", null); | |||
this.VerifyThatTheUserIsUnableToLoginToEShopApplicationIfUserIsNotRegisteredAlready("InvalidUser3", null); | |||
} | |||
} | |||
} | |||
#pragma warning restore | |||
#endregion |
@ -0,0 +1,18 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<packageSources> | |||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> | |||
<add key="CD-Bdd.Core" value="https://vsogd.pkgs.visualstudio.com/_packaging/CD-Bdd.Core/nuget/v3/index.json" /> | |||
</packageSources> | |||
<packageRestore> | |||
<add key="enabled" value="True" /> | |||
<add key="automatic" value="True" /> | |||
</packageRestore> | |||
<bindingRedirects> | |||
<add key="skip" value="False" /> | |||
</bindingRedirects> | |||
<packageManagement> | |||
<add key="format" value="1" /> | |||
<add key="disabled" value="True" /> | |||
</packageManagement> | |||
</configuration> |
@ -0,0 +1,27 @@ | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// <copyright file="AssemblyInfo.cs" company="Microsoft"> | |||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
// OTHER DEALINGS IN THE SOFTWARE. | |||
// </copyright> | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
using System; | |||
using System.Resources; | |||
//// using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
using NUnit.Framework; | |||
//// using XUnit.Extensibility.Core; | |||
[assembly: Parallelizable(ParallelScope.Fixtures)] // NUnit | |||
//// [assembly: Parallelize(Scope = ExecutionScope.ClassLevel)] // MSTest | |||
//// [assembly: CollectionBehavior(CollectionBehavior.CollectionPerClass)] // XUnit | |||
[assembly: CLSCompliant(false)] | |||
[assembly: NeutralResourcesLanguage("en-US")] |
@ -0,0 +1,90 @@ | |||
//------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by a tool. | |||
// Runtime Version:4.0.30319.42000 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// </auto-generated> | |||
//------------------------------------------------------------------------------ | |||
namespace EShopApplicationWebSolution.Properties { | |||
using System; | |||
/// <summary> | |||
/// A strongly-typed resource class, for looking up localized strings, etc. | |||
/// </summary> | |||
// This class was auto-generated by the StronglyTypedResourceBuilder | |||
// class via a tool like ResGen or Visual Studio. | |||
// To add or remove a member, edit your .ResX file then rerun ResGen | |||
// with the /str option, or rebuild your VS project. | |||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] | |||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | |||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
internal class Resources { | |||
private static global::System.Resources.ResourceManager resourceMan; | |||
private static global::System.Globalization.CultureInfo resourceCulture; | |||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] | |||
internal Resources() { | |||
} | |||
/// <summary> | |||
/// Returns the cached ResourceManager instance used by this class. | |||
/// </summary> | |||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
internal static global::System.Resources.ResourceManager ResourceManager { | |||
get { | |||
if (object.ReferenceEquals(resourceMan, null)) { | |||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EShopApplicationWebSolution.Properties.Resources", typeof(Resources).Assembly); | |||
resourceMan = temp; | |||
} | |||
return resourceMan; | |||
} | |||
} | |||
/// <summary> | |||
/// Overrides the current thread's CurrentUICulture property for all | |||
/// resource lookups using this strongly typed resource class. | |||
/// </summary> | |||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |||
internal static global::System.Globalization.CultureInfo Culture { | |||
get { | |||
return resourceCulture; | |||
} | |||
set { | |||
resourceCulture = value; | |||
} | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to xpath://button[contains(text(),'{0}')]. | |||
/// </summary> | |||
internal static string ButtonByText { | |||
get { | |||
return ResourceManager.GetString("ButtonByText", resourceCulture); | |||
} | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to xpath://div[contains(text(),'{0}')]. | |||
/// </summary> | |||
internal static string DivLinks { | |||
get { | |||
return ResourceManager.GetString("DivLinks", resourceCulture); | |||
} | |||
} | |||
/// <summary> | |||
/// Looks up a localized string similar to xpath://*[@id='{0}']. | |||
/// </summary> | |||
internal static string Id { | |||
get { | |||
return ResourceManager.GetString("Id", resourceCulture); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,129 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<root> | |||
<!-- | |||
Microsoft ResX Schema | |||
Version 2.0 | |||
The primary goals of this format is to allow a simple XML format | |||
that is mostly human readable. The generation and parsing of the | |||
various data types are done through the TypeConverter classes | |||
associated with the data types. | |||
Example: | |||
... ado.net/XML headers & schema ... | |||
<resheader name="resmimetype">text/microsoft-resx</resheader> | |||
<resheader name="version">2.0</resheader> | |||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
<value>[base64 mime encoded serialized .NET Framework object]</value> | |||
</data> | |||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
<comment>This is a comment</comment> | |||
</data> | |||
There are any number of "resheader" rows that contain simple | |||
name/value pairs. | |||
Each data row contains a name, and value. The row also contains a | |||
type or mimetype. Type corresponds to a .NET class that support | |||
text/value conversion through the TypeConverter architecture. | |||
Classes that don't support this are serialized and stored with the | |||
mimetype set. | |||
The mimetype is used for serialized objects, and tells the | |||
ResXResourceReader how to depersist the object. This is currently not | |||
extensible. For a given mimetype the value must be set accordingly: | |||
Note - application/x-microsoft.net.object.binary.base64 is the format | |||
that the ResXResourceWriter will generate, however the reader can | |||
read any of the formats listed below. | |||
mimetype: application/x-microsoft.net.object.binary.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.soap.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
value : The object must be serialized into a byte array | |||
: using a System.ComponentModel.TypeConverter | |||
: and then encoded with base64 encoding. | |||
--> | |||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
<xsd:element name="root" msdata:IsDataSet="true"> | |||
<xsd:complexType> | |||
<xsd:choice maxOccurs="unbounded"> | |||
<xsd:element name="metadata"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" use="required" type="xsd:string" /> | |||
<xsd:attribute name="type" type="xsd:string" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="assembly"> | |||
<xsd:complexType> | |||
<xsd:attribute name="alias" type="xsd:string" /> | |||
<xsd:attribute name="name" type="xsd:string" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="data"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="resheader"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:choice> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:schema> | |||
<resheader name="resmimetype"> | |||
<value>text/microsoft-resx</value> | |||
</resheader> | |||
<resheader name="version"> | |||
<value>2.0</value> | |||
</resheader> | |||
<resheader name="reader"> | |||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
<resheader name="writer"> | |||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
<data name="ButtonByText" xml:space="preserve"> | |||
<value>xpath://button[contains(text(),'{0}')]</value> | |||
</data> | |||
<data name="DivLinks" xml:space="preserve"> | |||
<value>xpath://div[contains(text(),'{0}')]</value> | |||
</data> | |||
<data name="Id" xml:space="preserve"> | |||
<value>xpath://*[@id='{0}']</value> | |||
</data> | |||
</root> |
@ -0,0 +1,21 @@ | |||
// <copyright file="CommonSteps.cs" company="Microsoft"> | |||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
// OTHER DEALINGS IN THE SOFTWARE. | |||
// </copyright> | |||
namespace EShopApplicationWebSolution.StepDefinitions | |||
{ | |||
using global::Bdd.Core.Web.StepDefinitions; | |||
using TechTalk.SpecFlow; | |||
[Binding] | |||
public class CommonSteps : WebStepDefinitionBase | |||
{ | |||
} | |||
} |
@ -0,0 +1,78 @@ | |||
using EShopApplicationWebSolution.Properties; | |||
using System.Threading.Tasks; | |||
using System.Windows.Forms; | |||
namespace EShopApplicationWebSolution.StepDefinitions | |||
{ | |||
using Bdd.Core.Entities; | |||
using Bdd.Core.Utils; | |||
using Bdd.Core.Web.Executors; | |||
using Bdd.Core.Web.StepDefinitions; | |||
using Bdd.Core.Web.Utils; | |||
using NUnit.Framework; | |||
using Ocaramba; | |||
using SmartFormat; | |||
using TechTalk.SpecFlow; | |||
[Binding] | |||
public class Login_EShopApplicationSteps : WebStepDefinitionBase | |||
{ | |||
[When(@"user launches EShop application")] | |||
public void WhenUserLaunchesEShopApplication() | |||
{ | |||
var url = Smart.Format(BaseConfiguration.GetUrlValue); | |||
this.Get<UrlPage>().NavigateToUrl(url); | |||
} | |||
[When(@"user clicks on ""(.*)""")] | |||
public async Task WhenUserClicksOnAsync(string linkText) | |||
{ | |||
this.Get<ElementPage>().GetElement(nameof(Resources.DivLinks), linkText).Click(); | |||
} | |||
[When(@"user clicks on ""(.*)"" option")] | |||
public void WhenUserClicksOnOption(string linkText) | |||
{ | |||
this.Get<ElementPage>().GetElement(nameof(Resources.DivLinks), linkText).Click(); | |||
} | |||
[When(@"user enter Email and Password of ""(.*)""")] | |||
public void WhenIEnterEmailAndPasswordOf(string user) | |||
{ | |||
var userdata = this.ScenarioContext.GetCredential<Credentials>(this.FeatureContext, user, "input=Credentials.xlsx"); | |||
this.Get<ElementPage>().EnterText(nameof(Resources.Id), userdata.User, "Email"); | |||
this.Get<ElementPage>().EnterText(nameof(Resources.Id), userdata.Password, "Password"); | |||
this.ScenarioContext[user] = userdata.User; | |||
} | |||
[When(@"user click on ""(.*)"" button")] | |||
public void WhenIClickOnButton(string buttonText) | |||
{ | |||
this.Get<ElementPage>().GetElement(nameof(Resources.ButtonByText), buttonText).Click(); | |||
} | |||
[Then(@"verify if ""(.*)"" is logged-in")] | |||
public void ThenIVerifyIfIsLogged_In(string user) | |||
{ | |||
var addToCartPresent = this.Get<ElementPage>().CheckIfElementIsPresent(nameof(Resources.ButtonByText), 30, "ADD TO CART"); | |||
var isloggedIn = this.Get<ElementPage>().CheckIfElementIsPresent(nameof(Resources.DivLinks), 30, this.ScenarioContext[user].ToString()); | |||
Assert.IsTrue(addToCartPresent&& isloggedIn, $"Login Falied"); | |||
} | |||
[Given(@"the user is no registered to EShop application")] | |||
public void GivenTheUserIsNoRegisteredToEShopApplication() | |||
{ | |||
ScenarioContext.Current.Pending(); | |||
} | |||
[Then(@"the user should not be able to login to the application")] | |||
public void ThenTheUserShouldNotBeAbleToLoginToTheApplication() | |||
{ | |||
ScenarioContext.Current.Pending(); | |||
} | |||
} | |||
} |
@ -0,0 +1,174 @@ | |||
# ADD STEPS THAT RUN TESTS, CREATE A NUGET PACKAGE, DEPLOY, AND MORE: https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core | |||
# YAML SCHEMA: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema | |||
# PREDEFINED VARIABLES: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=vsts | |||
# HOSTED AGENT SOFTWARES: https://github.com/Microsoft/azure-pipelines-image-generation/blob/master/images/win/Vs2017-Server2016-Readme.md | |||
# UNCOMMENT THE BELOW LINE TO DISABLE CI BUILDS | |||
# trigger: none | |||
# WHEN USING VARIABLE-GROUPS (UNDER ARTIFACTS > LIBRARY), USE THE FOLLOWING FORMAT TO DEFINE THE VARIABLES | |||
#variables: | |||
# - group: CloudCreds # NOTE: Create the Variable-Group under Pipelines > Library > Variable Group | |||
# - name: appName | |||
# value: 'Bdd.Core.Api.Sample' | |||
# - name: appPath | |||
# value: '$(System.DefaultWorkingDirectory)\$(appName)' | |||
# - name: system.debug | |||
# value: 'true' | |||
# - name: solution | |||
# value: '$(appPath)\$(appName).sln' | |||
# - name: buildPlatform | |||
# value: 'Any CPU' | |||
# - name: buildConfiguration | |||
# value: 'Release' | |||
# - name: cloudTestUser | |||
# value: $(CloudUser) | |||
# - name: cloudTestKey | |||
# value: $(CloudKey) | |||
variables: | |||
appName: 'EShopApplicationWebSolution' | |||
appPath: '$(System.DefaultWorkingDirectory)\$(appName)' # NOTE: Change this to appropriate path based on your folder structure | |||
solution: '$(appPath)\$(appName).sln' | |||
buildPlatform: 'Any CPU' | |||
buildConfiguration: 'Release' | |||
binFolder: '$(appPath)\bin\$(buildConfiguration)' | |||
cloudTestUser: '$(CloudUser)' # NOTE: Set this Variable in the UI (Visual Designer > Variables [OR] Pipelines > Library > Variable Group > Variable) | |||
cloudTestKey: '$(CloudKey)' # NOTE: Set this Variable in the UI and 'lock' it (Visual Designer > Variables [OR] Pipelines > Library > Variable Group > Variable > Lock icon) | |||
Env: 'dev' | |||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=vsts&tabs=yaml | |||
jobs: | |||
- job: 'TestSetup' | |||
timeoutInMinutes: 0 | |||
pool: | |||
vmImage: 'windows-latest' # name: 'Hosted VS2017' | |||
steps: | |||
- script: echo 'Sample Test-Setup' | |||
- job: 'RunTests' | |||
dependsOn: 'TestSetup' | |||
timeoutInMinutes: 0 | |||
strategy: # https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#strategies | |||
maxParallel: 3 #6 | |||
matrix: | |||
EdgeWindows: | |||
remotePlatform: 'EdgeWindows' | |||
SafariMac: | |||
remotePlatform: 'SafariMac' | |||
ChromeAndroid: | |||
remotePlatform: 'ChromeAndroid' | |||
# SafariIPhone: | |||
# remotePlatform: 'SafariIPhone' | |||
# SafariIPad: | |||
# remotePlatform: 'SafariIPad' | |||
# IEWindows: | |||
# remotePlatform: 'IEWindows' | |||
pool: | |||
vmImage: 'windows-latest' # name: 'Hosted VS2017' | |||
steps: | |||
- task: NuGetCommand@2 | |||
displayName: 'Authenticate with Azure DevOps NuGet' | |||
inputs: | |||
command: custom | |||
arguments: sources update -Name "CD-Bdd.Core" -Username "vsts" -Password "$(System.AccessToken)" -StorePasswordInClearText -ConfigFile $(appPath)\Nuget.config | |||
- script: dotnet restore $(solution) --configfile "$(appPath)\Nuget.config" # --no-cache | |||
displayName: 'DOTNET RESTORE' | |||
- script: 'for /r $(appPath) %%x in (*.csproj) do ("%userprofile%\.nuget\packages\SpecFlow\3.1.97\tools\specflow.exe" GenerateAll -p %%~x)' | |||
displayName: SPECFLOW GENERATEALL | |||
enabled:false | |||
- script: dotnet build $(solution) --configuration $(buildConfiguration) --no-restore | |||
displayName: 'DOTNET BUILD' | |||
# https://docs.opensource.microsoft.com/tools/cg.html | |||
# TPN: https://opensource.microsoft.com/tpn | |||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 | |||
enabled: true | |||
continueOnError: true | |||
displayName: 'COMPONENT DETECTION' | |||
inputs: | |||
scanType: Register # LogOnly | |||
snapshotForceEnabled: true | |||
# ignoreDirectories: | |||
# sourceScanPath: | |||
# verbosity: Detailed # Normal, Quite | |||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/test/vstest?view=azure-devops | |||
- task: VSTest@2 | |||
displayName: RUN TESTS | |||
continueOnError: true | |||
inputs: | |||
platform: '$(buildPlatform)' | |||
configuration: '$(buildConfiguration)' | |||
testSelector: 'testAssemblies' # Options: testAssemblies, testPlan, testRun | |||
testAssemblyVer2: '$(binFolder)\$(appName).dll' | |||
runSettingsFile: '$(binFolder)\$(appName).$(Env).runsettings' | |||
testFiltercriteria: '(TestCategory=api|TestCategory=ui)&TestCategory!=manual&TestCategory!=bddcore-wrapper' | |||
runOnlyImpactedTests: false | |||
runInParallel: false | |||
pathtoCustomTestAdapters: '$(binFolder)' | |||
diagnosticsEnabled: false # Optional | |||
searchFolder: '$(binFolder)' | |||
uiTests: true | |||
publishRunAttachments: true | |||
overrideTestrunParameters: -appSettings.browser Chrome -database.DbUser $(DbUser) -database.DbPwd $(DbPwd) | |||
# overrideTestrunParameters: -appSettings.browser RemoteWebDriver -appSettings.CrossBrowserEnvironment $(remotePlatform) -DriverCapabilities.browserstack.user $(cloudTestUser) -DriverCapabilities.browserstack.key $(cloudTestKey) -database.DbUser $(DbUser) -database.DbPwd $(DbPwd) | |||
# NOT USED: TO LOCALLY TRIGGER PARALLEL-TESTS ON CLOUD-BASED TESTING-PLATFORMS LIKE BROWSERSTACK/SAUCELABS/TESTINGBOT ETC. | |||
# - script: '$(appPath)\muppet.cmd -config=$(buildConfiguration) -filter="(FullyQualifiedName~$(appName).Features)" -platforms="Edge.Windows;Safari.Mac;Chrome.Android" -user=$(cloudTestUser) -key=$(cloudTestKey)' | |||
# displayName: 'MUPPET TESTS' | |||
- task: CopyFiles@2 | |||
displayName: Copy Output | |||
inputs: | |||
contents: '$(binFolder)\TestOutput\**\*.*' | |||
targetFolder: $(Build.ArtifactStagingDirectory) | |||
overWrite: true | |||
flattenFolders: true | |||
- task: PublishPipelineArtifact@1 | |||
displayName: Publish Output | |||
inputs: | |||
targetPath: $(Build.ArtifactStagingDirectory) # '$(Pipeline.Workspace)' | |||
artifact: 'TestOutput_$(Build.BuildNumber)' | |||
- task: PowerShell@2 | |||
enabled: false | |||
displayName: Compress Output for Release-Pipeline | |||
continueOnError: true | |||
inputs: | |||
targetType: 'inline' # Optional. Options: filePath, inline | |||
script: 'Compress-Archive -Path "$(Build.ArtifactStagingDirectory)" -DestinationPath "$(System.DefaultWorkingDirectory)/TestOutput_$(Build.BuildNumber).zip" -Force' # Required when targetType == Inline | |||
#arguments: # Optional | |||
errorActionPreference: 'continue' # Optional. Options: stop, continue, silentlyContinue | |||
ignoreLASTEXITCODE: true # Optional | |||
#failOnStderr: false # Optional | |||
#pwsh: false # Optional | |||
#workingDirectory: # Optional | |||
- task: PowerShell@2 | |||
enabled: false | |||
displayName: Write Output for Release-Pipeline | |||
continueOnError: true | |||
inputs: | |||
targetType: 'inline' # Optional. Options: filePath, inline | |||
script: 'Write-host "##vso[task.uploadfile]$(System.DefaultWorkingDirectory)/TestOutput_$(Build.BuildNumber).zip"' # Required when targetType == Inline | |||
#arguments: # Optional | |||
errorActionPreference: 'continue' # Optional. Options: stop, continue, silentlyContinue | |||
ignoreLASTEXITCODE: true # Optional | |||
#failOnStderr: false # Optional | |||
#pwsh: false # Optional | |||
#workingDirectory: # Optional | |||
- job: 'TestTeardown' | |||
dependsOn: 'RunTests' | |||
timeoutInMinutes: 0 | |||
pool: | |||
vmImage: 'windows-latest' # name: 'Hosted VS2017' | |||
steps: | |||
- script: echo 'Sample Test-Teardown' |
@ -0,0 +1,101 @@ | |||
@echo off | |||
setlocal disabledelayedexpansion | |||
REM https://stackoverflow.com/a/40104177 | |||
:: MuPPET: Multi Platform Parallel Execution Tests | |||
:: USAGE: muppet.cmd -config=Release -platforms="Safari.Mac;Chrome.Windows" -user=cloud_user -key=cloud_key | |||
set "currentDir=%~dp0" | |||
for %%x in (%currentDir%*.csproj) do if not defined app set "app=%%~nx" | |||
set "filter=(TestCategory!=ignore&TestCategory!=manual&TestCategory!=localization&TestCategory=bvt&TestCategory=ui)" | |||
set "config=Debug" | |||
set "platforms=Edge.Windows;Safari.Mac" | |||
:parseArgs | |||
:: Asks for the -argument and store the value in the variable (Credit: https://stackoverflow.com/a/47169024) | |||
call :getArgWithValue "-app" "app" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgWithValue "-config" "config" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgWithValue "-platforms" "platforms" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgWithValue "-filter" "filter" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgWithValue "-user" "user" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgWithValue "-key" "key" "%~1" "%~2" && shift && shift && goto :parseArgs | |||
call :getArgFlag "-debug" "VSTEST_RUNNER_DEBUG" "%~1" && shift && goto :parseArgs | |||
:: Start | |||
echo app: %app% | |||
echo config: %config% | |||
echo platforms: %platforms% | |||
echo user: %user% | |||
setlocal enabledelayedexpansion | |||
echo filter: !filter! | |||
goto runSettingFiles | |||
:: This function sets a variable from a cli arg with value | |||
:: 1 cli argument name | |||
:: 2 variable name | |||
:: 3 current Argument Name | |||
:: 4 current Argument Value | |||
:getArgWithValue | |||
if "%~3"=="%~1" ( | |||
if "%~4"=="" ( | |||
REM unset the variable if value is not provided | |||
set "%~2=" | |||
exit /B 1 | |||
) | |||
set "%~2=%~4" | |||
exit /B 0 | |||
) | |||
exit /B 1 | |||
goto:end | |||
:: This function sets a variable to value "TRUE" from a cli "flag" argument | |||
:: 1 cli argument name | |||
:: 2 variable name | |||
:: 3 current Argument Name | |||
:getArgFlag | |||
if "%~3"=="%~1" ( | |||
set %~2=1 | |||
exit /B 0 | |||
) | |||
exit /B 1 | |||
goto:end | |||
:runSettingFiles | |||
echo Using runSetting files | |||
for %%i in (%platforms%) do ( | |||
echo %%i | |||
set "int=%%i" | |||
set "int=!int:.= !" | |||
for /f "tokens=1,2 delims= " %%a in ("!int!") do ( | |||
echo CrossBrowserEnvironment=%%a%%b | |||
REM Credit: https://www.dostips.com/forum/viewtopic.php?t=6044 | |||
call %currentDir%jrepl.bat "(name=\qappSettings\.browser\q value=\q)(.*?)(\q)" "$1RemoteWebDriver$3" /x /f "%currentDir%%app%.runsettings" /o "%currentDir%%app%.Remote.%%a.%%b.runsettings" | |||
call %currentDir%jrepl.bat "(name=\qappSettings\.DriverCapabilities\q value=\q)(.*?)(\q)" "$1CloudProvider$3" /x /f "%currentDir%%app%.Remote.%%a.%%b.runsettings" /o - | |||
call %currentDir%jrepl.bat "(name=\qappSettings\.CrossBrowserEnvironment\q value=\q)(.*?)(\q)" "$1%%a%%b$3" /x /f "%currentDir%%app%.Remote.%%a.%%b.runsettings" /o - | |||
call %currentDir%jrepl.bat "(name=\qDriverCapabilities\.browserstack\.user\q value=\q)(.*?)(\q)" "$1%user%$3" /x /f "%currentDir%%app%.Remote.%%a.%%b.runsettings" /o - | |||
call %currentDir%jrepl.bat "(name=\qDriverCapabilities\.browserstack\.key\q value=\q)(.*?)(\q)" "$1%key%$3" /x /f "%currentDir%%app%.Remote.%%a.%%b.runsettings" /o - | |||
echo starting "%%i" dotnet test "%currentDir%%app%.csproj" -f "net471" -c "%config%" -a "%currentDir%bin\%config%" -v "n" --logger "trx" -r ".\TestResults" --filter !filter! --settings "%currentDir%%app%.Remote.%%a.%%b.runsettings" --no-restore --no-build | |||
start "%%i" dotnet test "%currentDir%%app%.csproj" -f "net471" -c "%config%" -a "%currentDir%bin\%config%" -v "n" --logger "trx" -r ".\TestResults" --filter !filter! --settings "%currentDir%%app%.Remote.%%a.%%b.runsettings" --no-restore --no-build | |||
) | |||
) | |||
goto end | |||
REM Not-used / Doesn't work (https://github.com/Microsoft/vstest/issues/862) | |||
:runSettingArgs | |||
echo Using runSetting args | |||
for %%i in (%input%) do ( | |||
echo %%i | |||
set "int=%%i" | |||
set "int=!int:.= !" | |||
for /f "tokens=1,2 delims= " %%a in ("!int!") do ( | |||
echo CrossBrowserEnvironment=$1%%a$3$1%%b$3 | |||
REM /B /NEWWINDOW | |||
start "%%i" /B dotnet test "%currentDir%%app%.csproj" -f "net471" -c "%config%" -a "./" --no-build --logger "trx" -r "./TestResults" --filter !filter! --settings "%currentDir%%app%.runsettings" -- appSettings.browser=RemoteWebDriver appSettings.DriverCapabilities=CloudProvider appSettings.CrossBrowserEnvironment=%%a%%b | |||
) | |||
) | |||
goto end | |||
:end | |||
endlocal |
@ -0,0 +1,28 @@ | |||
BDD.CORE.WEB | |||
------------ | |||
- AzDevOps Sync | |||
- Use [Spex](https://vamsitp.github.io/spexdocs/) | |||
- Code files | |||
- `Core\AppTestBase.cs`: Used for "Hooks" | |||
- Configuration | |||
- `app.config`: Change values under `<spex>` node for Spex (AzDevOps-Sync) | |||
- Make sure the values of DefaultAssignedTo (in .config) / @owner tag (in .feature) are valid. | |||
- e.g.: The alias vamsitp(@microsoft.com) is different than vamsi.tp(@microsoft.com) - though both are valid aliases. AzDevOps only honors that one that was added to the account | |||
- Main classes to use | |||
- `UIStepDefinitionBase`: To add additional functionality, inherit this class and add/override methods | |||
- `ProjectPageBase`: To add additional functionality, inherit this class and add/override methods | |||
- `ElementPage`: To add additional functionality, inherit this class and add/override methods | |||
- `UrlPage`: To add additional functionality, inherit this class and add/override methods | |||
- `WindowPage`: To add additional functionality, inherit this class and add/override methods | |||
- You can add more Pages / PageObjects as you deem fit for your project (see NOTE below) | |||
- Tools | |||
- `muppet.cmd`: Used for Parallel-test-runs (Uses [jrepl.bat](https://www.dostips.com/forum/viewtopic.php?t=6044)) | |||
- Scenario specific Packages | |||
- `Bdd.Core.Web`: For Web Tests | |||
- `Bdd.Core.Api`: For Api Tests |
@ -0,0 +1,24 @@ | |||
{ /*https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md*/ | |||
"settings": { | |||
"indentation": { | |||
}, | |||
"spacingRules": { | |||
}, | |||
"readabilityRules": { | |||
}, | |||
"orderingRules": { | |||
}, | |||
"namingRules": { | |||
"allowedHungarianPrefixes": [ "ui", "db", "js" ] | |||
}, | |||
"maintainabilityRules": { | |||
}, | |||
"layoutRules": { | |||
}, | |||
"documentationRules": { | |||
"companyName": "Microsoft", | |||
"copyrightText": " THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.", | |||
"headerDecoration": "--------------------------------------------------------------------------------------------------------------------" | |||
} | |||
} | |||
} |