Skip to content

Commit 92d034c

Browse files
operator integration test added
1 parent 4ec028f commit 92d034c

3 files changed

Lines changed: 313 additions & 0 deletions

File tree

EstateManagementUI.IntegrationTests/Common/DashboardPageHelper.cs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,158 @@ await _page.Locator("#loginButton").WaitForAsync(new LocatorWaitForOptions
7979
}, nameof(AssertEstateInfoPageVisibleAsync));
8080
}
8181

82+
public async Task OpenOperatorManagementScreenAsync()
83+
{
84+
await RunWithFailureArtifactsAsync(async () =>
85+
{
86+
var operatorLink = _page.Locator("#operatorsLink");
87+
if (await operatorLink.CountAsync() > 0 && await operatorLink.First.IsVisibleAsync())
88+
{
89+
await operatorLink.First.ClickAsync(new LocatorClickOptions { NoWaitAfter = true });
90+
}
91+
else
92+
{
93+
await _page.GotoAsync(ResolveEstateManagementBaseUrl() + "/operators");
94+
}
95+
96+
await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
97+
}, nameof(OpenOperatorManagementScreenAsync));
98+
}
99+
100+
public async Task AssertOperatorManagementHeadingVisibleAsync()
101+
{
102+
await RunWithFailureArtifactsAsync(async () =>
103+
{
104+
await WaitForOperatorManagementAsync();
105+
(await _page.GetByRole(AriaRole.Heading, new() { Name = "Operator Management" }).IsVisibleAsync()).ShouldBeTrue();
106+
}, nameof(AssertOperatorManagementHeadingVisibleAsync));
107+
}
108+
109+
public async Task AssertOperatorListContainsAsync(string operatorName)
110+
{
111+
await RunWithFailureArtifactsAsync(async () =>
112+
{
113+
var operatorRow = GetOperatorRow(operatorName);
114+
await operatorRow.WaitForAsync(new LocatorWaitForOptions
115+
{
116+
State = WaitForSelectorState.Visible,
117+
Timeout = 10000
118+
});
119+
120+
(await operatorRow.IsVisibleAsync()).ShouldBeTrue();
121+
}, nameof(AssertOperatorListContainsAsync));
122+
}
123+
124+
public async Task OpenOperatorViewAsync(string operatorName)
125+
{
126+
await RunWithFailureArtifactsAsync(async () =>
127+
{
128+
var operatorRow = GetOperatorRow(operatorName);
129+
await operatorRow.WaitForAsync(new LocatorWaitForOptions
130+
{
131+
State = WaitForSelectorState.Visible,
132+
Timeout = 10000
133+
});
134+
135+
await operatorRow.ClickAsync();
136+
}, nameof(OpenOperatorViewAsync));
137+
}
138+
139+
public async Task AssertOperatorViewVisibleAsync(string operatorName)
140+
{
141+
await RunWithFailureArtifactsAsync(async () =>
142+
{
143+
var heading = _page.GetByRole(AriaRole.Heading, new() { Name = $"View Operator: {operatorName}" });
144+
await heading.WaitForAsync(new LocatorWaitForOptions
145+
{
146+
State = WaitForSelectorState.Visible,
147+
Timeout = 10000
148+
});
149+
150+
(await heading.IsVisibleAsync()).ShouldBeTrue();
151+
(await _page.GetByRole(AriaRole.Heading, new() { Name = "Operator Details" }).IsVisibleAsync()).ShouldBeTrue();
152+
(await _page.GetByRole(AriaRole.Button, new() { Name = "Back to List" }).IsVisibleAsync()).ShouldBeTrue();
153+
}, nameof(AssertOperatorViewVisibleAsync));
154+
}
155+
156+
public async Task BackToOperatorListFromViewAsync()
157+
{
158+
await RunWithFailureArtifactsAsync(async () =>
159+
{
160+
await _page.GetByRole(AriaRole.Button, new() { Name = "Back to List" }).ClickAsync();
161+
await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
162+
}, nameof(BackToOperatorListFromViewAsync));
163+
}
164+
165+
public async Task OpenOperatorEditAsync(string operatorName)
166+
{
167+
await RunWithFailureArtifactsAsync(async () =>
168+
{
169+
var editButton = GetOperatorRow(operatorName).GetByRole(AriaRole.Button, new() { Name = "Edit" });
170+
await editButton.WaitForAsync(new LocatorWaitForOptions
171+
{
172+
State = WaitForSelectorState.Visible,
173+
Timeout = 10000
174+
});
175+
176+
await editButton.ClickAsync();
177+
}, nameof(OpenOperatorEditAsync));
178+
}
179+
180+
public async Task AssertOperatorEditVisibleAsync(string operatorName)
181+
{
182+
await RunWithFailureArtifactsAsync(async () =>
183+
{
184+
var heading = _page.GetByRole(AriaRole.Heading, new() { Name = $"Edit Operator: {operatorName}" });
185+
await heading.WaitForAsync(new LocatorWaitForOptions
186+
{
187+
State = WaitForSelectorState.Visible,
188+
Timeout = 10000
189+
});
190+
191+
(await heading.IsVisibleAsync()).ShouldBeTrue();
192+
(await _page.Locator("input[placeholder='Enter operator name']").IsVisibleAsync()).ShouldBeTrue();
193+
(await _page.GetByRole(AriaRole.Button, new() { Name = "Update Operator" }).IsVisibleAsync()).ShouldBeTrue();
194+
}, nameof(AssertOperatorEditVisibleAsync));
195+
}
196+
197+
public async Task CancelOperatorEditAsync()
198+
{
199+
await RunWithFailureArtifactsAsync(async () =>
200+
{
201+
await _page.GetByRole(AriaRole.Button, new() { Name = "Cancel" }).ClickAsync();
202+
await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
203+
}, nameof(CancelOperatorEditAsync));
204+
}
205+
206+
public async Task OpenNewOperatorScreenAsync()
207+
{
208+
await RunWithFailureArtifactsAsync(async () =>
209+
{
210+
await _page.Locator("#newOperatorButton").ClickAsync();
211+
await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
212+
}, nameof(OpenNewOperatorScreenAsync));
213+
}
214+
215+
public async Task AssertNewOperatorScreenVisibleAsync()
216+
{
217+
await RunWithFailureArtifactsAsync(async () =>
218+
{
219+
(await _page.GetByRole(AriaRole.Heading, new() { Name = "Create New Operator" }).IsVisibleAsync()).ShouldBeTrue();
220+
(await _page.Locator("input[placeholder='Enter operator name']").IsVisibleAsync()).ShouldBeTrue();
221+
(await _page.Locator("#createOperatorButton").IsVisibleAsync()).ShouldBeTrue();
222+
}, nameof(AssertNewOperatorScreenVisibleAsync));
223+
}
224+
225+
public async Task CreateOperatorAsync(string operatorName)
226+
{
227+
await RunWithFailureArtifactsAsync(async () =>
228+
{
229+
await _page.Locator("input[placeholder='Enter operator name']").FillAsync(operatorName);
230+
await _page.Locator("#createOperatorButton").ClickAsync();
231+
}, nameof(CreateOperatorAsync));
232+
}
233+
82234
public async Task ClickSignInButtonAsync()
83235
{
84236
await RunWithFailureArtifactsAsync(async () =>
@@ -492,12 +644,30 @@ await _page.Locator(".animate-spin").WaitForAsync(new LocatorWaitForOptions
492644
});
493645
}
494646

647+
private async Task WaitForOperatorManagementAsync()
648+
{
649+
var spinner = _page.Locator(".animate-spin");
650+
if (await spinner.CountAsync() > 0)
651+
{
652+
await spinner.First.WaitForAsync(new LocatorWaitForOptions
653+
{
654+
State = WaitForSelectorState.Hidden,
655+
Timeout = 10000
656+
});
657+
}
658+
}
659+
495660
private ILocator GetAssignedOperatorRow(string operatorName)
496661
{
497662
return _page.Locator("div.flex.items-center.justify-between.p-3.bg-gray-50.rounded-lg")
498663
.Filter(new() { HasText = operatorName });
499664
}
500665

666+
private ILocator GetOperatorRow(string operatorName)
667+
{
668+
return _page.Locator("tbody tr").Filter(new() { HasText = operatorName });
669+
}
670+
501671
private async Task<bool> IsAnyVisibleAsync(params string[] selectors)
502672
{
503673
foreach (var selector in selectors)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
@base @background @estate
2+
Feature: Operator Management
3+
As an authenticated estate user
4+
I want to move through the operator management screens
5+
So that I can manage operators from one end-to-end journey
6+
7+
Background:
8+
Given I create the following roles
9+
| Role Name |
10+
| Administrator |
11+
| Estate |
12+
13+
Given I create the following api scopes
14+
| Name | DisplayName | Description |
15+
| transactionProcessor | Transaction Processor REST Scope | Scope for Transaction Processor REST |
16+
| fileProcessor | File Processor REST Scope | Scope for File Processor REST |
17+
| estateReporting | Estate Reporting REST Scope | Scope for Estate Reporting REST |
18+
19+
Given I create the following api resources
20+
| Name | DisplayName | Secret | Scopes | UserClaims |
21+
| transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId,estateId,role |
22+
| fileProcessor | File Processor REST | Secret1 | fileProcessor | merchantId,estateId,role |
23+
| estateReporting | Estate Reporting REST | Secret1 | estateReporting | merchantId,estateId,role |
24+
25+
Given I create the following identity resources
26+
| Name | DisplayName | Description | UserClaims |
27+
| openid | Your user identifier | | sub |
28+
| profile | User profile | Your user profile information (first name, last name, etc.) | name,role,email,given_name,middle_name,family_name,estateId,merchantId |
29+
| email | Email | Email and Email Verified Flags | email_verified,email |
30+
31+
Given I create the following clients
32+
| ClientId | Name | Secret | Scopes | GrantTypes | RedirectUris | PostLogoutRedirectUris | RequireConsent | AllowOfflineAccess | ClientUri |
33+
| serviceClient | Service Client | Secret1 | transactionProcessor,fileProcessor,estateReporting | client_credentials | | | | | |
34+
| estateUIClient | Merchant Client | Secret1 | fileProcessor,transactionProcessor,estateReporting,openid,email,profile | hybrid | https://127.0.0.1:[port]/signin-oidc | https://127.0.0.1:[port]/signout-oidc | false | true | https://127.0.0.1:[port] |
35+
36+
Given I create the following users
37+
| Email Address | Phone Number | Given Name | Middle Name | Family Name | Claims | Roles | Password |
38+
| administrator@admin.co.uk | 123456789 | Test | | User 1 | | Administrator | 123456 |
39+
40+
Given I have a token to access the transaction Processor resource
41+
| ClientId |
42+
| serviceClient |
43+
44+
Given I have created the following estates
45+
| EstateName |
46+
| Test Estate |
47+
48+
And I have created the following operators
49+
| EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
50+
| Test Estate | Test Operator | True | True |
51+
| Test Estate | Spare Operator | False | False |
52+
53+
And I have assigned the following operators to the estates
54+
| EstateName | OperatorName |
55+
| Test Estate | Test Operator |
56+
57+
And I have created the following security users
58+
| EmailAddress | Password | GivenName | FamilyName | EstateName |
59+
| estateuser@testestate1.co.uk | 123456 | TestEstate | User1 | Test Estate |
60+
61+
Given the user navigates to the entry screen
62+
Then I should see the entry screen
63+
When I open the estate information page
64+
Then I should see the estate info page
65+
And I click on the Sign In Button
66+
Then I am presented with a login screen
67+
When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
68+
Then I should see the dashboard heading
69+
70+
Scenario: Estate users can navigate the operator screens and manage operators
71+
When I open the operator management screen
72+
Then I should see the operator management heading
73+
And I should see the operator 'Test Operator' in the operator list
74+
When I open the operator view for 'Test Operator'
75+
Then I should see the operator view page for 'Test Operator'
76+
When I go back to the operator list from the view page
77+
Then I should see the operator management heading
78+
When I open the operator edit page for 'Test Operator'
79+
Then I should see the operator edit page for 'Test Operator'
80+
When I cancel operator editing
81+
Then I should see the operator management heading
82+
When I open the new operator screen
83+
Then I should see the new operator screen
84+
When I create the operator 'Integration Operator'
85+
Then I should see the operator management heading
86+
And I should see the operator 'Integration Operator' in the operator list
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using EstateManagementUI.IntegrationTests.Common;
2+
using Microsoft.Playwright;
3+
using Reqnroll;
4+
5+
namespace EstateManagementUI.IntegrationTests.Steps;
6+
7+
[Binding]
8+
[Scope(Tag = "estate")]
9+
public sealed class OperatorManagementSteps
10+
{
11+
private readonly IPage _page;
12+
private readonly TestingContext _testingContext;
13+
14+
public OperatorManagementSteps(IPage page, TestingContext testingContext)
15+
{
16+
_page = page;
17+
_testingContext = testingContext;
18+
}
19+
20+
[When("I open the operator management screen")]
21+
public Task WhenIOpenTheOperatorManagementScreen() => GetHelper().OpenOperatorManagementScreenAsync();
22+
23+
[Then("I should see the operator management heading")]
24+
public Task ThenIShouldSeeTheOperatorManagementHeading() => GetHelper().AssertOperatorManagementHeadingVisibleAsync();
25+
26+
[Then("I should see the operator {string} in the operator list")]
27+
public Task ThenIShouldSeeTheOperatorInTheOperatorList(string operatorName) => GetHelper().AssertOperatorListContainsAsync(operatorName);
28+
29+
[When("I open the operator view for {string}")]
30+
public Task WhenIOpenTheOperatorViewFor(string operatorName) => GetHelper().OpenOperatorViewAsync(operatorName);
31+
32+
[Then("I should see the operator view page for {string}")]
33+
public Task ThenIShouldSeeTheOperatorViewPageFor(string operatorName) => GetHelper().AssertOperatorViewVisibleAsync(operatorName);
34+
35+
[When("I go back to the operator list from the view page")]
36+
public Task WhenIGoBackToTheOperatorListFromTheViewPage() => GetHelper().BackToOperatorListFromViewAsync();
37+
38+
[When("I open the operator edit page for {string}")]
39+
public Task WhenIOpenTheOperatorEditPageFor(string operatorName) => GetHelper().OpenOperatorEditAsync(operatorName);
40+
41+
[Then("I should see the operator edit page for {string}")]
42+
public Task ThenIShouldSeeTheOperatorEditPageFor(string operatorName) => GetHelper().AssertOperatorEditVisibleAsync(operatorName);
43+
44+
[When("I cancel operator editing")]
45+
public Task WhenICancelOperatorEditing() => GetHelper().CancelOperatorEditAsync();
46+
47+
[When("I open the new operator screen")]
48+
public Task WhenIOpenTheNewOperatorScreen() => GetHelper().OpenNewOperatorScreenAsync();
49+
50+
[Then("I should see the new operator screen")]
51+
public Task ThenIShouldSeeTheNewOperatorScreen() => GetHelper().AssertNewOperatorScreenVisibleAsync();
52+
53+
[When("I create the operator {string}")]
54+
public Task WhenICreateTheOperator(string operatorName) => GetHelper().CreateOperatorAsync(operatorName);
55+
56+
private DashboardPageHelper GetHelper() => new(_page, _testingContext);
57+
}

0 commit comments

Comments
 (0)