Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/Autotests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
branches: [ main ]

env:
BROWSER_PARAMS: "--window-size=1920,1080 --allowed-ips"
BROWSER_PARAMS: "--window-size=1920,1080 --allowed-ips --no-sandbox"

jobs:
build:
Expand All @@ -22,8 +22,8 @@ jobs:
- name: Restore dependencies
run: dotnet restore
- name: Build
working-directory: ./Behavioral.Automation.DemoScenarios
working-directory: ./Behavioral.Automation.Selenium/Behavioral.Automation.DemoScenarios
run: dotnet build -c Release --no-restore
- name: Test
working-directory: ./Behavioral.Automation.DemoScenarios
working-directory: ./Behavioral.Automation.Selenium/Behavioral.Automation.DemoScenarios
run: dotnet test -c Release --no-build --verbosity normal
6 changes: 3 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ jobs:
run: dotnet build -c Release --no-restore
- name: Get version
run: |
export VER=$(grep -oP '\d+\.\d+\.\d+(?=</PackageVersion>)' src/Behavioral.Automation/Behavioral.Automation.csproj)
export VER=$(grep -oP '\d+\.\d+\.\d+(?=</PackageVersion>)' Behavioral.Automation.Selenium/Behavioral.Automation/Behavioral.Automation.csproj)
echo "VER=$VER" >> $GITHUB_ENV
echo $VER
- name: Package app
run: |
dotnet pack ./src/Behavioral.Automation/Behavioral.Automation.csproj \
dotnet pack ./Behavioral.Automation.Selenium/Behavioral.Automation/Behavioral.Automation.csproj \
--configuration Release /p:Platform=\"AnyCPU\" \
/p:PackageVersion=${{ env.VER }} --output ./
- name: Create Release
uses: ncipollo/release-action@v1
with:
tag: ${{ env.VER }}
artifacts: "Behavioral.Automation.${{ env.VER }}.nupkg"
bodyFile: "CHANGELOG.md"
bodyFile: "Behavioral.Automation.Selenium/CHANGELOG.md"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish app into nuget.org
env:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Configurations>Debug;Release;Test;Dev;Prod</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Reflection;
using Microsoft.Extensions.Configuration;

namespace Behavioral.Automation.Configs;

public static class ConfigManager
{
private static IConfiguration Configuration { get; }

static ConfigManager()
{
var env = Environment.GetEnvironmentVariable("STAND");

if (string.IsNullOrEmpty(env))
{
var attributes = Assembly.GetExecutingAssembly().GetCustomAttributes();
var configAttribute = attributes.FirstOrDefault(attribute => attribute.TypeId.Equals(typeof(AssemblyConfigurationAttribute)));
var configEnv = (AssemblyConfigurationAttribute) configAttribute!;
env = configEnv.Configuration;
}

Configuration = new ConfigurationBuilder()
.AddJsonFile("AutomationConfig.json", true, true)
.AddJsonFile($"AutomationConfig.{env.ToLower()}.json", true, true)
.AddEnvironmentVariables()
.Build();
}

public static T GetConfig<T>()
{
if (Configuration is null) throw new ArgumentException("Please, init configuration");

var config = Configuration.Get<T>();
return config;
}

public static string GetConfig(string configKey)
{
return Configuration.GetSection(configKey).Value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Behavioral.Automation.Configs.utils;

public static class NormalizePath
{
public static string NormalizePathAccordingOs(this string fullPath)
{
fullPath = fullPath.Replace("/", Path.DirectorySeparatorChar.ToString());
fullPath = fullPath.Replace(@"\", Path.DirectorySeparatorChar.ToString());
return fullPath;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Quantori Inc.</Authors>
<Description>Platform design is based on strong and well-defined borderline between procedural test cases structure and object-oriented code-behind.

We think that test cases implementation approach (inside BDD paradigm) is literaly the same across different applications. That means that we can define and reuse grammar structures across different application domains. On top of this, while talking about single page web applications, we may take into account that atomic controls behavior is also the same across different domains.

The whole automation code is divided into the following parts:
- Feature files
- Bindings
- Wrappers
- Infrastructure bindings
- UI structure descriptive code
- Supportive code
</Description>
<Copyright>Quantori Inc.</Copyright>
<PackageVersion>0.1</PackageVersion>
<RepositoryUrl>https://github.com/quantori/Behavioral.Automation</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BoDi" Version="1.5.0" />
<PackageReference Include="CucumberExpressions.SpecFlow.3-9" Version="1.0.7" />
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.22.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="SpecFlow" Version="3.9.74" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Behavioral.Automation.Configs\Behavioral.Automation.Configs.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Linq;
using System.Threading.Tasks;
using Behavioral.Automation.Playwright.WebElementsWrappers.Interface;
using Microsoft.Playwright;
using TechTalk.SpecFlow;

namespace Behavioral.Automation.Playwright.Bindings;

[Binding]
public class AttributeBinding
{
private readonly ElementTransformations.ElementTransformations _elementTransformations;

public AttributeBinding(ElementTransformations.ElementTransformations elementTransformations)
{
_elementTransformations = elementTransformations;
}


/// <summary>
/// Check if element is disabled or enabled
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <param name="enabled">Element expected status (enabled or disabled)</param>
/// <example>Then "Test" input should be enabled</example>
[Given(@"the ""(.+?)"" is (enabled|disabled)")]
[Then(@"the ""(.+?)"" should be| (enabled|disabled)")]
public async Task CheckElementIsDisabled(IWebElementWrapper element, bool enabled)
{
if (enabled)
{
await Assertions.Expect(element.Locator).Not.ToBeDisabledAsync();
}
else
{
await Assertions.Expect(element.Locator).ToBeDisabledAsync();
}
}

/// <summary>
/// Check that multiple elements are disabled or enabled
/// </summary>
/// <param name="enabled">Elements expected status (enabled or disabled)</param>
/// <param name="table">Specflow table with element names to be tested</param>
/// <example>
/// Then the following controls should be enabled:
/// | control |
/// | Test" input |
/// | Test2 input |
/// </example>
[Given("the following controls are (enabled|disabled):")]
[Then("the following controls should be (enabled|disabled):")]
public async Task CheckControlTypeCollectionShown(bool enabled, Table table)
{
foreach (var row in table.Rows)
{
await CheckElementIsDisabled(_elementTransformations.GetElement(row.Values.First()), enabled);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Threading.Tasks;
using Behavioral.Automation.Playwright.WebElementsWrappers.Interface;
using TechTalk.SpecFlow;

namespace Behavioral.Automation.Playwright.Bindings;

[Binding]
public class ClickBinding
{
/// <summary>
/// Execute click on the element
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <example>When user clicks on "Test" button</example>
[Given(@"user clicked on ""(.+?)""")]
[When(@"user clicks on ""(.+?)""")]
public async Task ClickOnElement(IWebElementWrapper element)
{
await element.Locator.ClickAsync();
}

/// <summary>
/// Execute double click on the element
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <example>When user clicks twice on "Test" button</example>
[Given(@"user clicked twice on ""(.+?)""")]
[When(@"user clicks twice on ""(.+?)""")]
public async Task ClickTwiceOnElement(IWebElementWrapper element)
{
await element.Locator.DblClickAsync();
}

/// <summary>
/// Execute click on the specific element in the collection
/// </summary>
/// <param name="index">Number of the tested element in the collection</param>
/// <param name="element">Tested web element wrapper</param>
/// <example>When user clicks at first element among "Test" buttons (note that numbers from 1 to 10 can be written as words)</e
[Given(@"user clicked at (.+?) element among ""(.+?)""")]
[When(@"user clicks at (.+?) element among ""(.+?)""")]
public async Task ClickByIndex(int index, IWebElementWrapper element)
{
await element.Locator.Nth(index).ClickAsync();
}

/// <summary>
/// Hover mouse over element
/// </summary>
/// <param name="element">Tested web element wrapper</param>
/// <example>When user hovers mouse over "Test" button</example>
[Given(@"user hovered mouse over ""(.+?)""")]
[When(@"user hovers mouse over ""(.+?)""")]
public async Task HoverMouse(IWebElementWrapper element)
{
await element.Locator.HoverAsync();
}
}
Loading