Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Selenoid engine #82

Merged
merged 16 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ Testware provides capabilities to automate:
<img src="https://github.com/devicons/devicon/blob/master/icons/chrome/chrome-original-wordmark.svg" title="Chrome" alt="Chrome" width="40" height="40"/>
<img src="https://github.com/devicons/devicon/blob/master/icons/firefox/firefox-original-wordmark.svg" title="Firefox" alt="Firefox" width="40" height="40"/>
<img src="https://github.com/devicons/devicon/blob/master/icons/ie10/ie10-original.svg" title="IE" alt="IE" width="40" height="40"/>
<img src="https://upload.wikimedia.org/wikipedia/commons/9/98/Microsoft_Edge_logo_%282019%29.svg" title="Edge" alt="Edge" width="40" height="40"/>

<img src="https://upload.wikimedia.org/wikipedia/commons/3/32/Microsoft_Edge_Dev_Icon_%282019%29.svg" title="Edge" alt="Edge" width="40" height="40"/>
- **Websites** (using Selenoid)
- Supported Browsers:
<img src="https://github.com/devicons/devicon/blob/master/icons/chrome/chrome-original-wordmark.svg" title="Chrome" alt="Chrome" width="40" height="40"/>
<img src="https://github.com/devicons/devicon/blob/master/icons/firefox/firefox-original-wordmark.svg" title="Firefox" alt="Firefox" width="40" height="40"/>
<img src="https://upload.wikimedia.org/wikipedia/commons/3/32/Microsoft_Edge_Dev_Icon_%282019%29.svg" title="Edge" alt="Edge" width="40" height="40"/>
- **Mobile Applications** (using Appium)
- **Windows Desktop applications** (using WinAppDriver)
- **API Rest** (using Restsharp)
Expand Down Expand Up @@ -155,6 +159,53 @@ Evidence collection:
}
]
},
{
"Tag": "RemoteDriver",
"Capabilities": [
{
"Name": "Chrome",
"Uri": "http://localhost:4444/wd/hub",
"BrowserName": "Chrome",
"BrowserVersion": "111.0",
"Resolution": "1920x1080x24",
"EnableLog": false,
"EnableVnc": true,
"EnableVideo": false,
"CommandTimeOutInMinutes": 5,
"Arguments": [
"--start-maximized"
]
},
{
"Name": "Firefox",
"Uri": "http://localhost:4444/wd/hub",
"BrowserName": "Firefox",
"BrowserVersion": "110.0",
"Resolution": "1920x1080x24",
"EnableLog": false,
"EnableVnc": true,
"EnableVideo": false,
"CommandTimeOutInMinutes": 5,
"Arguments": [
"--start-maximized"
]
},
{
"Name": "Edge",
"Uri": "http://localhost:4444/wd/hub",
"BrowserName": "Edge",
"BrowserVersion": "111.0",
"Resolution": "1920x1080x24",
"EnableLog": false,
"EnableVnc": true,
"EnableVideo": false,
"CommandTimeOutInMinutes": 5,
"Arguments": [
"--start-maximized"
]
}
]
},
{
"Name": "Appiumdriver",
"AppiumUrl": "http://127.0.0.1:4723/wd/hub",
Expand Down
14 changes: 14 additions & 0 deletions TestWare.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.ExtentReport", "sr
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Reporting", "Reporting", "{DCCEF363-0EBE-46EA-B02B-CD59010626F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Engines.Selenoid", "src\Engines\TestWare.Engines.Selenoid\TestWare.Engines.Selenoid.csproj", "{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestWare.Samples.Selenoid.Web", "samples\TestWare.Samples.Selenoid.Web\TestWare.Samples.Selenoid.Web.csproj", "{672C5D48-DD50-4AA3-8974-50B95746EA07}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -84,6 +88,14 @@ Global
{94025C6B-DF0D-4AC4-BBC5-A94A9FA3AB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94025C6B-DF0D-4AC4-BBC5-A94A9FA3AB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94025C6B-DF0D-4AC4-BBC5-A94A9FA3AB0A}.Release|Any CPU.Build.0 = Release|Any CPU
{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}.Release|Any CPU.Build.0 = Release|Any CPU
{672C5D48-DD50-4AA3-8974-50B95746EA07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{672C5D48-DD50-4AA3-8974-50B95746EA07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{672C5D48-DD50-4AA3-8974-50B95746EA07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{672C5D48-DD50-4AA3-8974-50B95746EA07}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -102,6 +114,8 @@ Global
{71120454-DD7A-484C-93F2-699B4C363297} = {58B1446D-98A3-46A2-A668-305F0170B39F}
{94025C6B-DF0D-4AC4-BBC5-A94A9FA3AB0A} = {DCCEF363-0EBE-46EA-B02B-CD59010626F6}
{DCCEF363-0EBE-46EA-B02B-CD59010626F6} = {4678C707-68DB-4E06-9184-A07FB398832C}
{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE} = {A2E4E1F7-CB61-48DC-AA38-A74F7DC74CA2}
{672C5D48-DD50-4AA3-8974-50B95746EA07} = {58B1446D-98A3-46A2-A668-305F0170B39F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4F88CB24-23C8-4E0E-8B83-29023C1642B8}
Expand Down
6 changes: 3 additions & 3 deletions samples/TestWare.Samples.API/TestWare.Samples.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ExtentReports" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="RestSharp" Version="107.1.1" />
<PackageReference Include="SpecFlow.Plus.LivingDocPlugin" Version="3.9.57" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.40" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.74" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="FluentAssertions" Version="6.3.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

<ItemGroup>
<PackageReference Include="Appium.WebDriver" Version="5.0.0-beta01" />
<PackageReference Include="ExtentReports" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="SpecFlow.Plus.LivingDocPlugin" Version="3.9.57" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.40" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.74" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="FluentAssertions" Version="6.3.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
<SpecFlowObsoleteCodeBehindFiles Remove="Support\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ExtentReports" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="SpecFlow.Plus.LivingDocPlugin" Version="3.9.57" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.40" />
<PackageReference Include="FluentAssertions" Version="6.3.0" />
<PackageReference Include="SpecFlow.MsTest" Version="3.9.74" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@RemoteDriver
Feature: Login

Scenario Outline: Login
Given the user enters username '<username>'
And the user enters password '<password>'
When the user clicks submit
Then the user can login

@Chrome
Examples:
| Example Description | username | password |
| standard | standard_user | secret_sauce |
| problem | problem_user | secret_sauce |

@Firefox
Examples:
| Example Description | username | password |
| standard | standard_user | secret_sauce |
| problem | problem_user | secret_sauce |

@Edge
Examples:
| Example Description | username | password |
| standard | standard_user | secret_sauce |
| problem | problem_user | secret_sauce |

@Chrome
Scenario: Logout
Given user 'standard_user' is logged with 'secret_sauce' into SwagLabs
When the user clicks Logout button
Then the user is at Login page
110 changes: 110 additions & 0 deletions samples/TestWare.Samples.Selenoid.Web/Hook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using TestWare.Reporting.ExtentReport;

namespace TestWare.Samples.Selenoid.Web;

[Binding]
public sealed class Hook
{
private readonly TestContext _testContext;
private int _stepCounter;
private static readonly LifeCycle _lifeCycle = new();
private static ExtentReport _testReport;

public Hook(TestContext testContext)
{
_testContext = testContext;
}

[BeforeFeature]
public static void BeforeFeature(FeatureContext featureContext)
{
var name = featureContext.FeatureInfo.Title;
var tags = featureContext.FeatureInfo.Tags;

_lifeCycle.BeginTestSuite(name);
_testReport.CreateFeature(name, tags);
}

[AfterFeature]
public static void AfterFeature(FeatureContext featureContext)
{
_lifeCycle.EndTestSuite();
}

[BeforeScenario]
public void BeforeScenario(FeatureContext featureContext, ScenarioContext scenarioContext)
{
var name = scenarioContext.ScenarioInfo.Arguments.Count > 0
? $"{DateTime.UtcNow.ToString("yyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture)} - {scenarioContext.ScenarioInfo.Title}"
: scenarioContext.ScenarioInfo.Title;

var description = scenarioContext.ScenarioInfo.Description ?? "";
var scenarioTags = scenarioContext.ScenarioInfo.Tags;
_testReport.CreateTestCase(name, description, scenarioTags);

_testContext.WriteLine("----------------------------------------- \r\n");
_testContext.WriteLine($"Feature: {featureContext.FeatureInfo.Title}");
_testContext.WriteLine($" Scenario: {scenarioContext.ScenarioInfo.Title} \r\n");

_stepCounter = 1;
var tags = GetTags(featureContext, scenarioContext);
_lifeCycle.BeginTestCase(name, tags);
}

[AfterScenario]
public void AfterScenario()
{
_testReport.SetTestcaseOutcome(_testContext.CurrentTestOutcome);
_lifeCycle.EndTestCase();
}

[BeforeTestRun]
public static void BeforeTestRun()
{
_lifeCycle.BeginTestExecution();
_testReport = new ExtentReport(_lifeCycle.GetCurrentResultsDirectory());
}

[AfterTestRun]
public static void AfterTestRun()
{
_lifeCycle.EndTestExecution();
_testReport.CreateTestReportFile();
}

[BeforeStep]
public void BeforeStep(ScenarioContext scenarioContext)
{
var name = scenarioContext.CurrentScenarioBlock.ToString();
var description = scenarioContext.StepContext.StepInfo.Text;
_testReport.CreateStep(name, description);

var stepId = $"{_stepCounter:00} {description}";
_stepCounter++;
_lifeCycle.BeginTestStep(stepId);
}

[AfterStep]
public void AfterStep(ScenarioContext scenarioContext)
{
_lifeCycle.EndTestStep();
var evidencesPath = _lifeCycle.GetStepEvidences();

foreach (var evidence in evidencesPath)
{
_testReport.AddScreenshotToStep(evidence);
_testContext.AddResultFile(evidence);
}
}

private static List<string> GetTags(FeatureContext featureContext, ScenarioContext scenarioContext)
{
var tags = featureContext.FeatureInfo.Tags.ToList();
tags.AddRange(scenarioContext.ScenarioInfo.Tags.ToList());
return tags;
}
}
3 changes: 3 additions & 0 deletions samples/TestWare.Samples.Selenoid.Web/ImplicitUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
global using FluentAssertions;
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using TechTalk.SpecFlow;
36 changes: 36 additions & 0 deletions samples/TestWare.Samples.Selenoid.Web/LifeCycle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Reflection;
using TestWare.Core;
using TestWare.Core.Configuration;
using TestWare.Core.Interfaces;
using TestWare.Engines.Selenoid;

namespace TestWare.Samples.Selenoid.Web;

internal class LifeCycle : AutomationLifeCycleBase
{
protected override IEnumerable<Assembly> GetTestWareComponentAssemblies()
{
IEnumerable<Assembly> assemblies = new[]
{
typeof(Hook).Assembly
};

return assemblies;
}

protected override IEnumerable<IEngineManager> GetTestWareEngines()
{
IEnumerable<IEngineManager> engines = new[]
{
new SelenoidManager()
};

return engines;
}

protected override TestConfiguration GetConfiguration()
{
return ConfigurationManager.ReadConfigurationFile("TestConfiguration.Web.json");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using TestWare.Core.Interfaces;

namespace TestWare.Samples.Selenoid.Web.POM.Inventory;

public interface IInventoryPage : ITestWareComponent
{
void CheckUserIsAtInventory();
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using OpenQA.Selenium;
using TestWare.Core.Libraries;
using TestWare.Engines.Selenoid.Factory;
using TestWare.Engines.Selenoid.Pages;

namespace TestWare.Samples.Selenoid.Web.POM.Inventory;

public class InventoryPage : WebPage, IInventoryPage
{
private const string InventoryUrl = "https://www.saucedemo.com/inventory.html";

public InventoryPage(IWebDriver driver) : base(driver)
{
}

/// <inheritdoc cref="IInventoryPage" />
public void CheckUserIsAtInventory()
{
RetryPolicies.ExecuteActionWithRetries(
() =>
{
this.Driver.Url.Should().Be(InventoryUrl);
});
}

}

Loading
Loading