Skip to content

Commit df90a59

Browse files
authored
Merge pull request #116 from quantori/bap-126-playwright-basic-structure
Separated selenium and playwright versions of the framework. Added Playwright MVP
2 parents d9f501f + 8b27f2e commit df90a59

File tree

176 files changed

+1468
-132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+1468
-132
lines changed

.github/workflows/Autotests.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
branches: [ main ]
77

88
env:
9-
BROWSER_PARAMS: "--window-size=1920,1080 --allowed-ips"
9+
BROWSER_PARAMS: "--window-size=1920,1080 --allowed-ips --no-sandbox"
1010

1111
jobs:
1212
build:
@@ -22,8 +22,8 @@ jobs:
2222
- name: Restore dependencies
2323
run: dotnet restore
2424
- name: Build
25-
working-directory: ./Behavioral.Automation.DemoScenarios
25+
working-directory: ./Behavioral.Automation.Selenium/Behavioral.Automation.DemoScenarios
2626
run: dotnet build -c Release --no-restore
2727
- name: Test
28-
working-directory: ./Behavioral.Automation.DemoScenarios
28+
working-directory: ./Behavioral.Automation.Selenium/Behavioral.Automation.DemoScenarios
2929
run: dotnet test -c Release --no-build --verbosity normal

.github/workflows/main.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ jobs:
2828
run: dotnet build -c Release --no-restore
2929
- name: Get version
3030
run: |
31-
export VER=$(grep -oP '\d+\.\d+\.\d+(?=</PackageVersion>)' src/Behavioral.Automation/Behavioral.Automation.csproj)
31+
export VER=$(grep -oP '\d+\.\d+\.\d+(?=</PackageVersion>)' Behavioral.Automation.Selenium/Behavioral.Automation/Behavioral.Automation.csproj)
3232
echo "VER=$VER" >> $GITHUB_ENV
3333
echo $VER
3434
- name: Package app
3535
run: |
36-
dotnet pack ./src/Behavioral.Automation/Behavioral.Automation.csproj \
36+
dotnet pack ./Behavioral.Automation.Selenium/Behavioral.Automation/Behavioral.Automation.csproj \
3737
--configuration Release /p:Platform=\"AnyCPU\" \
3838
/p:PackageVersion=${{ env.VER }} --output ./
3939
- name: Create Release
4040
uses: ncipollo/release-action@v1
4141
with:
4242
tag: ${{ env.VER }}
4343
artifacts: "Behavioral.Automation.${{ env.VER }}.nupkg"
44-
bodyFile: "CHANGELOG.md"
44+
bodyFile: "Behavioral.Automation.Selenium/CHANGELOG.md"
4545
token: ${{ secrets.GITHUB_TOKEN }}
4646
- name: Publish app into nuget.org
4747
env:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<Configurations>Debug;Release;Test;Dev;Prod</Configurations>
8+
<Platforms>AnyCPU</Platforms>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
13+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
15+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
16+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
17+
</ItemGroup>
18+
19+
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System.Reflection;
2+
using Microsoft.Extensions.Configuration;
3+
4+
namespace Behavioral.Automation.Configs;
5+
6+
public static class ConfigManager
7+
{
8+
private static IConfiguration Configuration { get; }
9+
10+
static ConfigManager()
11+
{
12+
var env = Environment.GetEnvironmentVariable("STAND");
13+
14+
if (string.IsNullOrEmpty(env))
15+
{
16+
var attributes = Assembly.GetExecutingAssembly().GetCustomAttributes();
17+
var configAttribute = attributes.FirstOrDefault(attribute => attribute.TypeId.Equals(typeof(AssemblyConfigurationAttribute)));
18+
var configEnv = (AssemblyConfigurationAttribute) configAttribute!;
19+
env = configEnv.Configuration;
20+
}
21+
22+
Configuration = new ConfigurationBuilder()
23+
.AddJsonFile("AutomationConfig.json", true, true)
24+
.AddJsonFile($"AutomationConfig.{env.ToLower()}.json", true, true)
25+
.AddEnvironmentVariables()
26+
.Build();
27+
}
28+
29+
public static T GetConfig<T>()
30+
{
31+
if (Configuration is null) throw new ArgumentException("Please, init configuration");
32+
33+
var config = Configuration.Get<T>();
34+
return config;
35+
}
36+
37+
public static string GetConfig(string configKey)
38+
{
39+
return Configuration.GetSection(configKey).Value;
40+
}
41+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Behavioral.Automation.Configs.utils;
2+
3+
public static class NormalizePath
4+
{
5+
public static string NormalizePathAccordingOs(this string fullPath)
6+
{
7+
fullPath = fullPath.Replace("/", Path.DirectorySeparatorChar.ToString());
8+
fullPath = fullPath.Replace(@"\", Path.DirectorySeparatorChar.ToString());
9+
return fullPath;
10+
}
11+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
5+
<Authors>Quantori Inc.</Authors>
6+
<Description>Platform design is based on strong and well-defined borderline between procedural test cases structure and object-oriented code-behind.
7+
8+
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.
9+
10+
The whole automation code is divided into the following parts:
11+
- Feature files
12+
- Bindings
13+
- Wrappers
14+
- Infrastructure bindings
15+
- UI structure descriptive code
16+
- Supportive code
17+
</Description>
18+
<Copyright>Quantori Inc.</Copyright>
19+
<PackageVersion>0.1</PackageVersion>
20+
<RepositoryUrl>https://github.com/quantori/Behavioral.Automation</RepositoryUrl>
21+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
22+
<IncludeSymbols>true</IncludeSymbols>
23+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
24+
25+
<TargetFramework>net6.0</TargetFramework>
26+
<Nullable>enable</Nullable>
27+
28+
<IsPackable>false</IsPackable>
29+
</PropertyGroup>
30+
31+
<ItemGroup>
32+
<PackageReference Include="BoDi" Version="1.5.0" />
33+
<PackageReference Include="CucumberExpressions.SpecFlow.3-9" Version="1.0.7" />
34+
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" />
35+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
36+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
37+
<PackageReference Include="Microsoft.Playwright" Version="1.22.0" />
38+
<PackageReference Include="NUnit" Version="3.13.2" />
39+
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
40+
<PackageReference Include="coverlet.collector" Version="3.1.0" />
41+
<PackageReference Include="SpecFlow" Version="3.9.74" />
42+
</ItemGroup>
43+
44+
<ItemGroup>
45+
<ProjectReference Include="..\Behavioral.Automation.Configs\Behavioral.Automation.Configs.csproj" />
46+
</ItemGroup>
47+
48+
</Project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Linq;
2+
using System.Threading.Tasks;
3+
using Behavioral.Automation.Playwright.WebElementsWrappers.Interface;
4+
using Microsoft.Playwright;
5+
using TechTalk.SpecFlow;
6+
7+
namespace Behavioral.Automation.Playwright.Bindings;
8+
9+
[Binding]
10+
public class AttributeBinding
11+
{
12+
private readonly ElementTransformations.ElementTransformations _elementTransformations;
13+
14+
public AttributeBinding(ElementTransformations.ElementTransformations elementTransformations)
15+
{
16+
_elementTransformations = elementTransformations;
17+
}
18+
19+
20+
/// <summary>
21+
/// Check if element is disabled or enabled
22+
/// </summary>
23+
/// <param name="element">Tested web element wrapper</param>
24+
/// <param name="enabled">Element expected status (enabled or disabled)</param>
25+
/// <example>Then "Test" input should be enabled</example>
26+
[Given(@"the ""(.+?)"" is (enabled|disabled)")]
27+
[Then(@"the ""(.+?)"" should be| (enabled|disabled)")]
28+
public async Task CheckElementIsDisabled(IWebElementWrapper element, bool enabled)
29+
{
30+
if (enabled)
31+
{
32+
await Assertions.Expect(element.Locator).Not.ToBeDisabledAsync();
33+
}
34+
else
35+
{
36+
await Assertions.Expect(element.Locator).ToBeDisabledAsync();
37+
}
38+
}
39+
40+
/// <summary>
41+
/// Check that multiple elements are disabled or enabled
42+
/// </summary>
43+
/// <param name="enabled">Elements expected status (enabled or disabled)</param>
44+
/// <param name="table">Specflow table with element names to be tested</param>
45+
/// <example>
46+
/// Then the following controls should be enabled:
47+
/// | control |
48+
/// | Test" input |
49+
/// | Test2 input |
50+
/// </example>
51+
[Given("the following controls are (enabled|disabled):")]
52+
[Then("the following controls should be (enabled|disabled):")]
53+
public async Task CheckControlTypeCollectionShown(bool enabled, Table table)
54+
{
55+
foreach (var row in table.Rows)
56+
{
57+
await CheckElementIsDisabled(_elementTransformations.GetElement(row.Values.First()), enabled);
58+
}
59+
}
60+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Threading.Tasks;
2+
using Behavioral.Automation.Playwright.WebElementsWrappers.Interface;
3+
using TechTalk.SpecFlow;
4+
5+
namespace Behavioral.Automation.Playwright.Bindings;
6+
7+
[Binding]
8+
public class ClickBinding
9+
{
10+
/// <summary>
11+
/// Execute click on the element
12+
/// </summary>
13+
/// <param name="element">Tested web element wrapper</param>
14+
/// <example>When user clicks on "Test" button</example>
15+
[Given(@"user clicked on ""(.+?)""")]
16+
[When(@"user clicks on ""(.+?)""")]
17+
public async Task ClickOnElement(IWebElementWrapper element)
18+
{
19+
await element.Locator.ClickAsync();
20+
}
21+
22+
/// <summary>
23+
/// Execute double click on the element
24+
/// </summary>
25+
/// <param name="element">Tested web element wrapper</param>
26+
/// <example>When user clicks twice on "Test" button</example>
27+
[Given(@"user clicked twice on ""(.+?)""")]
28+
[When(@"user clicks twice on ""(.+?)""")]
29+
public async Task ClickTwiceOnElement(IWebElementWrapper element)
30+
{
31+
await element.Locator.DblClickAsync();
32+
}
33+
34+
/// <summary>
35+
/// Execute click on the specific element in the collection
36+
/// </summary>
37+
/// <param name="index">Number of the tested element in the collection</param>
38+
/// <param name="element">Tested web element wrapper</param>
39+
/// <example>When user clicks at first element among "Test" buttons (note that numbers from 1 to 10 can be written as words)</e
40+
[Given(@"user clicked at (.+?) element among ""(.+?)""")]
41+
[When(@"user clicks at (.+?) element among ""(.+?)""")]
42+
public async Task ClickByIndex(int index, IWebElementWrapper element)
43+
{
44+
await element.Locator.Nth(index).ClickAsync();
45+
}
46+
47+
/// <summary>
48+
/// Hover mouse over element
49+
/// </summary>
50+
/// <param name="element">Tested web element wrapper</param>
51+
/// <example>When user hovers mouse over "Test" button</example>
52+
[Given(@"user hovered mouse over ""(.+?)""")]
53+
[When(@"user hovers mouse over ""(.+?)""")]
54+
public async Task HoverMouse(IWebElementWrapper element)
55+
{
56+
await element.Locator.HoverAsync();
57+
}
58+
}

0 commit comments

Comments
 (0)