Skip to content

Playwright refactoring + api project #134

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions Behavioral.Automation.API.DemoScenarios/AutomationConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"API_HOST": "https://reqres.in/"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="SpecFlow" Version="3.9.74" />
<PackageReference Include="SpecFlow.NUnit" Version="3.9.69" />
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.9.69" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
</ItemGroup>

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

<ItemGroup>
<None Update="specflow.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="AutomationConfig.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<Content Include="TestData\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions Behavioral.Automation.API.DemoScenarios/Features/Demo.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Feature: reqres test

Scenario: Get all users
When user sends a "GET" request to "api/users" url
Then response json path "$..data[?(@.email == 'george.bluth@reqres.in')].first_name" value should be "["George"]"

Scenario: Get second page
When user sends a "GET" request to "api/users" url with the following parameters:
| Name | Value | Kind |
| page | 2 | Param |
| CustomHeader | test | Header |

Scenario: Complex request
Given user creates a "POST" request to "api/users" url with the json:
"""
{
"name": "morpheus",
"job": "leader"
}
"""
When user adds parameters and send request:
| Name | Value | Kind |
| CustomHeader | test | Header |

Scenario: Request with json file
When user sends a "POST" request to "api/users" url with the json file "TestData\User.json"
4 changes: 4 additions & 0 deletions Behavioral.Automation.API.DemoScenarios/TestData/User.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "morpheus",
"job": "leader"
}
19 changes: 19 additions & 0 deletions Behavioral.Automation.API.DemoScenarios/specflow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"bindingCulture": {
"language": "en-us"
},
"language": {
"feature": "en-us"
},
"runtime": {
"missingOrPendingStepsOutcome": "Error"
},
"stepAssemblies": [
{
"assembly": "Behavioral.Automation.API"
},
{
"assembly": "Behavioral.Automation.Transformations"
}
]
}
25 changes: 25 additions & 0 deletions Behavioral.Automation.API/Behavioral.Automation.API.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" 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" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="SpecFlow" Version="3.9.74" />
</ItemGroup>

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

</Project>
226 changes: 226 additions & 0 deletions Behavioral.Automation.API/Bindings/HttpRequestSteps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
using System.Text;
using System.Web;
using Behavioral.Automation.API.Configs;
using Behavioral.Automation.API.Context;
using Behavioral.Automation.API.Models;
using Behavioral.Automation.API.Services;
using Behavioral.Automation.Configs;
using Behavioral.Automation.Configs.utils;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;

namespace Behavioral.Automation.API.Bindings;

[Binding]
public class HttpRequestSteps
{
private readonly ApiContext _apiContext;
private readonly HttpService _httpService;

public HttpRequestSteps(ApiContext apiContext, HttpService httpService)
{
_apiContext = apiContext;
_httpService = httpService;
}

[When("user sends a \"(.*)\" request to \"(.*)\" url")]
public HttpResponseMessage UserSendsHttpRequest(string httpMethod, string url)
{
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));
_httpService.SendContextRequest();

return _apiContext.Response;
}

[When("user sends a \"(.*)\" request to \"(.*)\" url with the following parameters:")]
public HttpResponseMessage UserSendsHttpRequestWithParameters(string httpMethod, string url, Table tableParameters)
{
UserCreatesHttpRequestWithParameters(httpMethod, url, tableParameters);
_httpService.SendContextRequest();

return _apiContext.Response;
}

[When("user sends a \"(.*)\" request to \"(.*)\" url with the json:")]
public HttpResponseMessage UserSendsHttpRequestWithJson(string httpMethod, string url, string jsonToSend)
{
//TODO: body can be:
// form-data
// raw (Text, JavaScript, JSON, HTML, XML)
// binary
// GraphQL
// Consider adding other types
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));
_apiContext.Request.Content = new StringContent(jsonToSend, Encoding.UTF8, "application/json");

_httpService.SendContextRequest();

return _apiContext.Response;
}

[When("user sends a \"(.*)\" request to \"(.*)\" url with the json file \"(.*)\"")]
public HttpResponseMessage UserSendsHttpRequestWithJsonFile(string httpMethod, string url, string filePath)
{
//TODO: body can be:
// form-data
// raw (Text, JavaScript, JSON, HTML, XML)
// binary
// GraphQL
// Consider adding other types
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));

var fullPath = Path.GetFullPath(Path.Join(Directory.GetCurrentDirectory(), filePath)).NormalizePathAccordingOs();
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("The file does not exist", fullPath);
}

var jsonToSend = File.ReadAllText(filePath);

_apiContext.Request.Content = new StringContent(jsonToSend, Encoding.UTF8, "application/json");

_httpService.SendContextRequest();

return _apiContext.Response;
}


[When("user sends a \"(.*)\" request to \"(.*)\" url with the application/x-www-form-urlencoded:")]
public HttpResponseMessage UserSendsHttpRequestWithFormUrlEncodedContent(string httpMethod, string url, Table parameters)
{
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));

var body = parameters.Rows.Select(row => new KeyValuePair<string, string>(row[0], row[1]));

_apiContext.Request.Content = new FormUrlEncodedContent(body);

_httpService.SendContextRequest();

return _apiContext.Response;
}

[Given("user creates a \"(.*)\" request to \"(.*)\" url with the json:")]
public HttpRequestMessage UserCreatesHttpRequestWithJson(string httpMethod, string url, string jsonToSend)
{
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));
_apiContext.Request.Content = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
return _apiContext.Request;
}

[Given("user creates a \"(.*)\" request to \"(.*)\" url")]
public HttpRequestMessage GivenUserCreatesARequestToUrl(string httpMethod, string url)
{
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));
return _apiContext.Request;
}

[Given("user creates a \"(.*)\" request to \"(.*)\" url with the following parameters:")]
public HttpRequestMessage UserCreatesHttpRequestWithParameters(string httpMethod, string url, Table tableParameters)
{
var method = new HttpMethod(httpMethod.ToUpper());

_apiContext.Request = new HttpRequestMessage(method, GetUri(url));
AddParametersToRequest(_apiContext.Request, tableParameters);
return _apiContext.Request;
}

[When("user adds a JSON body and send the request:")]
public HttpResponseMessage WhenUserAddsJsonBodyAndSendRequest(string jsonToSend)
{
_apiContext.Request.Content = new StringContent(jsonToSend, Encoding.UTF8, "application/json");

_httpService.SendContextRequest();

return _apiContext.Response;
}

[When("user adds parameters and send request:")]
public HttpResponseMessage WhenUserAddsParametersAndSendRequest(Table tableParameters)
{
AddParametersToRequest(_apiContext.Request, tableParameters);
_httpService.SendContextRequest();

return _apiContext.Response;
}

[When("user sends request")]
public HttpResponseMessage WhenUserSendsRequest()
{
_httpService.SendContextRequest();
return _apiContext.Response;
}

[Given("the response status code should be \"(\\d*)\"")]
public void ChangeResponseStatusCode(int statusCode)
{
_apiContext.ExpectedStatusCode = statusCode;
}

private static Uri GetUri(string url)
{
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
url = ConfigManager.GetConfig<Config>().ApiHost + url;
}

return new UriBuilder(url).Uri;
}

private static void AddParametersToRequest(HttpRequestMessage request, Table tableParameters)
{
var uriBuilder = new UriBuilder(request.RequestUri);

var parameters = tableParameters.CreateSet<HttpParameters>();

var headers = new List<KeyValuePair<string, IEnumerable<string>>>();
if (parameters is not null)
{
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
foreach (var parameter in parameters)
{
var parameterKind = Enum.Parse<RequestParameterKind>(parameter.Kind);

if (parameterKind is RequestParameterKind.Param)
{
query.Add(parameter.Name, parameter.Value);
}

if (parameterKind is RequestParameterKind.Header)
{
var headerValue = parameter.Value.Trim().Split(",");
headers.Add(new KeyValuePair<string, IEnumerable<string>>(parameter.Name, headerValue));
}
}

uriBuilder.Query = query.ToString();
}

request.RequestUri = uriBuilder.Uri;

if (headers.Any())
{
foreach (var header in headers)
{
if (header.Key.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase))
{
throw new Exception(
"Remove the Content-Type header, please. The Content-Type header is automatically added with request step bindings.");
}

request.Headers.Add(header.Key, header.Value);
}
}
}
}
Loading