Skip to content

Commit 6cf65e7

Browse files
Allure TestOps: Add Tags (#55)
* Add Tags
1 parent a8db79c commit 6cf65e7

File tree

8 files changed

+96
-15
lines changed

8 files changed

+96
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
[3.16.0] - 2022-09-12
7+
[3.17.0] - 2022-09-21
88

99
### Added
10-
- Allure TestOps: Add scenario
10+
- Allure TestOps: Add tags to a test case

GherkinSyncTool.Synchronizers.AllureTestOps/Client/AllureClientWrapper.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ public void UploadStepAttachments(CreateTestCaseRequestExtended caseRequestExten
215215

216216
ValidateResponse(response);
217217
}
218+
219+
public List<Tag> GetAllTestTags()
220+
{
221+
var response = _allureClient.GetTagsAsync().Result;
222+
ValidateResponse(response);
223+
return response.Content;
224+
}
225+
226+
public Tag AddTestTags(string name)
227+
{
228+
var response = _allureClient.CreateTagAsync(new Tag {Name = name}).Result;
229+
ValidateResponse(response);
230+
return response.Content;
231+
}
218232

219233
private void UpdateTestCaseStepAttachments(CreateTestCaseRequestExtended caseToUpdate, TestCaseOverview testCaseOverview)
220234
{
@@ -236,6 +250,13 @@ private static bool AreTestCasesContentsEqual(TestCaseOverview currentCase, Crea
236250
if (!currentCase.Automated.Equals(caseToUpdate.CreateTestCaseRequest.Automated)) return false;
237251
if (!currentCase.Status.Id.Equals(caseToUpdate.CreateTestCaseRequest.StatusId)) return false;
238252
if (!currentCase.Description.Equals(caseToUpdate.CreateTestCaseRequest.Description)) return false;
253+
254+
var caseToUpdateTagIds = caseToUpdate.CreateTestCaseRequest.Tags.Select(tag => tag.Id).ToList();
255+
var currentCaseTagIds = currentCase.Tags.Select(tag => tag.Id).ToList();
256+
257+
if (currentCaseTagIds.Count != caseToUpdateTagIds.Count) return false;
258+
if (currentCaseTagIds.Except(caseToUpdateTagIds).Any()) return false;
259+
239260
return true;
240261
}
241262

GherkinSyncTool.Synchronizers.AllureTestOps/Content/CaseContentBuilder.cs

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
using NLog;
1313
using Quantori.AllureTestOpsClient.Model;
1414
using Refit;
15-
using Scenario = Gherkin.Ast.Scenario;
16-
using Step = Gherkin.Ast.Step;
1715
using AllureTestCaseStep = Quantori.AllureTestOpsClient.Model.Step;
1816
using AllureScenario = Quantori.AllureTestOpsClient.Model.Scenario;
17+
using Scenario = Gherkin.Ast.Scenario;
18+
using Step = Gherkin.Ast.Step;
19+
using Tag = Quantori.AllureTestOpsClient.Model.Tag;
1920

2021
namespace GherkinSyncTool.Synchronizers.AllureTestOps.Content;
2122

@@ -31,6 +32,7 @@ public class CaseContentBuilder
3132
private List<WorkflowSchema> _workflowSchemas;
3233
private Item _automatedWorkflowId;
3334
private Item _manualWorkflowId;
35+
private List<Tag> _testTags;
3436

3537
public List<WorkflowSchema> WorkflowSchemas =>
3638
_workflowSchemas ??= _allureClientWrapper.GetAllWorkflowSchemas(_allureTestOpsSettings.ProjectId).ToList();
@@ -42,6 +44,7 @@ public class CaseContentBuilder
4244
_automatedWorkflowId ??= WorkflowSchemas.FirstOrDefault(schema => schema.Type.Equals(TestType.Automated))!.Workflow;
4345

4446
public Item ManualWorkflow => _manualWorkflowId ??= WorkflowSchemas.FirstOrDefault(schema => schema.Type.Equals(TestType.Manual))!.Workflow;
47+
public List<Tag> AllureTestTags => _testTags ??= _allureClientWrapper.GetAllTestTags();
4548

4649
public CaseContentBuilder(AllureClientWrapper allureClientWrapper, Context context)
4750
{
@@ -61,14 +64,50 @@ public CreateTestCaseRequestExtended BuildCaseRequest(Scenario scenario, IFeatur
6164
StatusId = AddStatus(scenario, featureFile),
6265
WorkflowId = AddWorkflow(scenario, featureFile),
6366
Description = AddDescription(scenario, featureFile),
64-
Scenario = AddScenario(scenario, featureFile)
67+
Scenario = AddScenario(scenario, featureFile),
68+
Tags = AddTags(scenario, featureFile)
6569
},
6670
StepsAttachments = AddStepAttachments(scenario, featureFile)
6771
};
6872

6973
return createTestCaseRequestExtended;
7074
}
7175

76+
private List<Tag> AddTags(Scenario scenario, IFeatureFile featureFile)
77+
{
78+
var allTags = GherkinHelper.GetAllTags(scenario, featureFile);
79+
//Remove tags that will duplicate existing fields
80+
RemoveTags(allTags, TagsConstants.Reference, TagsConstants.Automated, TagsConstants.Status);
81+
82+
var result = new List<Tag>();
83+
if (allTags.Any())
84+
{
85+
foreach (var tag in allTags)
86+
{
87+
var tagName = tag.Name.Replace("@", "");
88+
var allureTag = AllureTestTags.FirstOrDefault(t => t.Name.Equals(tagName, StringComparison.InvariantCultureIgnoreCase));
89+
if (allureTag is null)
90+
{
91+
var newTag = _allureClientWrapper.AddTestTags(tagName);
92+
AllureTestTags.Add(newTag);
93+
result.Add(newTag);
94+
continue;
95+
}
96+
result.Add(new Tag {Id = allureTag.Id, Name = tagName});
97+
}
98+
}
99+
100+
return result;
101+
}
102+
103+
private void RemoveTags(List<Gherkin.Ast.Tag> allTags, params string[] tagsToRemove)
104+
{
105+
foreach (var tagToRemove in tagsToRemove)
106+
{
107+
allTags.RemoveAll(tag => tag.Name.Contains(tagToRemove, StringComparison.InvariantCultureIgnoreCase));
108+
}
109+
}
110+
72111
private Dictionary<int, ByteArrayPart> AddStepAttachments(Scenario scenario, IFeatureFile featureFile)
73112
{
74113
var attachments = ExtractAttachments(scenario.Steps.ToList());
@@ -78,7 +117,7 @@ private Dictionary<int, ByteArrayPart> AddStepAttachments(Scenario scenario, IFe
78117
{
79118
var backgroundStepCount = background.Steps.Count();
80119
var attachmentsShifted = attachments.ToDictionary(attachment => attachment.Key + backgroundStepCount, attachment => attachment.Value);
81-
120+
82121
var backgroundAttachments = ExtractAttachments(background.Steps.ToList());
83122
return backgroundAttachments.Concat(attachmentsShifted).ToDictionary(pair => pair.Key, pair => pair.Value);
84123
}
@@ -97,13 +136,13 @@ private Dictionary<int, ByteArrayPart> ExtractAttachments(List<Step> steps)
97136
switch (step.Argument)
98137
{
99138
case DocString docString:
100-
139+
101140
var textBytes = Encoding.ASCII.GetBytes(docString.Content);
102141
result.Add(index, new ByteArrayPart(textBytes, "Text", "text/plain"));
103142
break;
104-
143+
105144
case DataTable table:
106-
145+
107146
var csvBytes = Encoding.ASCII.GetBytes(ConvertToCsvTable(table.Rows.ToList()));
108147
result.Add(index, new ByteArrayPart(csvBytes, "Table", "text/csv"));
109148
break;
@@ -171,11 +210,11 @@ private string AddDescription(Scenario scenario, IFeatureFile featureFile)
171210
if (background is not null && (!string.IsNullOrWhiteSpace(background.Name) || !string.IsNullOrWhiteSpace(background.Description)))
172211
{
173212
description.AppendLine($"**{background.Keyword}:** {background.Name}");
174-
if(!string.IsNullOrWhiteSpace(background.Description)) description.AppendLine(background.Description);
213+
if (!string.IsNullOrWhiteSpace(background.Description)) description.AppendLine(background.Description);
175214
}
176215

177216
description.AppendLine($"**Feature file:** {featureFile.RelativePath}");
178-
217+
179218
var examples = scenario.Examples.ToList();
180219

181220
if (examples.Any())
@@ -210,6 +249,7 @@ private string ConvertToMarkdownTable(List<TableRow> tableRows)
210249
{
211250
table.Append($"{cell.Value}|");
212251
}
252+
213253
table.AppendLine();
214254
table.Append("|");
215255
//Header delimiter

GherkinSyncTool.Synchronizers.AllureTestOps/Model/TagsConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ public static class TagsConstants
44
{
55
public const string Automated = "@Automated";
66
public const string Status = "@Status:";
7+
public const string Reference = "@Reference:";
78
}
89
}

GherkinSyncTool/GherkinSyncTool.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<AssemblyVersion>3.16.0</AssemblyVersion>
4+
<AssemblyVersion>3.17.0</AssemblyVersion>
55
<OutputType>Exe</OutputType>
66
<TargetFrameworks>netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
77
<PackAsTool>true</PackAsTool>

Quantori.AllureTestOpsClient/IAllureClient.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ public interface IAllureClient
5757
Task<IApiResponse<GetContentResponse<Status>>> GetStatusAsync(int? workflowId = null, int page = 0, int size = 100, string sort = null);
5858
#endregion
5959

60-
6160
#region Workflow schema controller
6261
/// <summary>
6362
/// Find all workflow schemas for given project
@@ -71,10 +70,10 @@ public interface IAllureClient
7170
#endregion
7271

7372
#region Workflow controller
73+
7474
/// <summary>
7575
/// Find all workflow
7676
/// </summary>
77-
/// <param name="projectId"></param>
7877
/// <param name="page"></param>
7978
/// <param name="size"></param>
8079
/// <param name="sort"></param>
@@ -121,5 +120,23 @@ public interface IAllureClient
121120
Task<IApiResponse<Scenario>> DeleteTestCaseScenarioAsync([AliasAs("id")] long testCaseId);
122121

123122
#endregion
123+
124+
#region Test tag controller
125+
126+
/// <summary>
127+
/// Find all test tags
128+
/// </summary>
129+
/// <returns></returns>
130+
[Get("/api/rs/tag")]
131+
Task<IApiResponse<List<Tag>>> GetTagsAsync();
132+
133+
/// <summary>
134+
/// Create a new test tag
135+
/// </summary>
136+
/// <returns></returns>
137+
[Post("/api/rs/tag")]
138+
Task<IApiResponse<Tag>> CreateTagAsync([Body] Tag tag);
139+
140+
#endregion
124141
}
125142
}

Quantori.AllureTestOpsClient/Model/Tag.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
public class Tag
44
{
5-
public int Id { get; set; }
5+
public long Id { get; set; }
66
public string Name { get; set; }
77
}
88
}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ GherkinSyncTool can be configured in three ways. The priority corresponds to the
7777
| BaseDirectory | Absolute or relative to application folder path that contains *.feature files | Yes |
7878
| TagIdPrefix | A tag prefix that will be used for mark test scenarios as synchronized with a test management system | No |
7979
80+
Allure TestOps note: `TagIdPrefix` should be configured to fill the 'as_id' Allure label correctly. For example, for Specflow TagIdPrefix should be equals `@label:as_id:` It is required to not duplicate manual and automated test cases. The test run result will be attached to the correct Allure test ID.
81+
8082
### Formatting settings
8183
8284
| Parameter | Description | Required |

0 commit comments

Comments
 (0)