From e3c34aaa8db5f4ddbb18e2e41f632f0ee6027c42 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 09:54:50 +0000
Subject: [PATCH 1/7] Initial plan
From ab9b37b6cc741e0a930ada8fa831ca65ef6edb5b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 10:01:55 +0000
Subject: [PATCH 2/7] Add Dashboard integration tests project with Reqnroll,
Playwright, and Shouldly
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
---
EstateManagementUI.DashboardTests/.gitignore | 42 +++
.../Common/DashboardPageHelper.cs | 242 ++++++++++++++++++
.../EstateManagementUI.DashboardTests.csproj | 39 +++
.../Features/Dashboard.feature | 88 +++++++
.../Hooks/BrowserHooks.cs | 144 +++++++++++
EstateManagementUI.DashboardTests/README.md | 138 ++++++++++
.../Steps/DashboardSteps.cs | 187 ++++++++++++++
.../appsettings.json | 23 ++
8 files changed, 903 insertions(+)
create mode 100644 EstateManagementUI.DashboardTests/.gitignore
create mode 100644 EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
create mode 100644 EstateManagementUI.DashboardTests/EstateManagementUI.DashboardTests.csproj
create mode 100644 EstateManagementUI.DashboardTests/Features/Dashboard.feature
create mode 100644 EstateManagementUI.DashboardTests/Hooks/BrowserHooks.cs
create mode 100644 EstateManagementUI.DashboardTests/README.md
create mode 100644 EstateManagementUI.DashboardTests/Steps/DashboardSteps.cs
create mode 100644 EstateManagementUI.DashboardTests/appsettings.json
diff --git a/EstateManagementUI.DashboardTests/.gitignore b/EstateManagementUI.DashboardTests/.gitignore
new file mode 100644
index 00000000..3eb6e160
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/.gitignore
@@ -0,0 +1,42 @@
+## Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+## Test Results
+[Tt]est[Rr]esult*/
+TestResults/
+*.trx
+*.coverage
+
+## Playwright
+.playwright/
+playwright-report/
+playwright/.cache/
+
+## Screenshots
+screenshot-*.png
+
+## Visual Studio cache/options
+.vs/
+.vscode/
+
+## Reqnroll/SpecFlow generated files
+*.feature.cs
+
+## NuGet
+*.nupkg
+*.snupkg
+packages/
+.nuget/
diff --git a/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs b/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
new file mode 100644
index 00000000..dd61ae61
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
@@ -0,0 +1,242 @@
+using Microsoft.Playwright;
+using Shouldly;
+
+namespace EstateManagementUI.DashboardTests.Common;
+
+///
+/// Helper class for interacting with the Dashboard page using Playwright
+///
+public class DashboardPageHelper
+{
+ private readonly IPage _page;
+ private readonly string _baseUrl;
+
+ public DashboardPageHelper(IPage page, string baseUrl)
+ {
+ _page = page;
+ _baseUrl = baseUrl;
+ }
+
+ #region Navigation
+
+ ///
+ /// Navigate to the home/dashboard page
+ ///
+ public async Task NavigateToDashboard()
+ {
+ await _page.GotoAsync(_baseUrl);
+ await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
+ }
+
+ #endregion
+
+ #region Verification Methods
+
+ ///
+ /// Verify the page title is "Dashboard"
+ ///
+ public async Task VerifyDashboardPageTitle()
+ {
+ var title = await _page.TitleAsync();
+ title.ShouldBe("Dashboard");
+ }
+
+ ///
+ /// Verify the Administrator welcome message is displayed
+ ///
+ public async Task VerifyAdministratorWelcomeMessage()
+ {
+ var heading = await _page.Locator("h2:has-text('Welcome, Administrator')").TextContentAsync();
+ heading.ShouldNotBeNull();
+ heading.ShouldContain("Welcome, Administrator");
+
+ var description = await _page.Locator("p:has-text('administrative access')").TextContentAsync();
+ description.ShouldNotBeNull();
+ description.ShouldContain("administrative access to manage system permissions");
+ }
+
+ ///
+ /// Verify that KPI cards are visible on the dashboard
+ ///
+ public async Task VerifyKpiCardsAreVisible()
+ {
+ await _page.Locator("text=Merchants with Sales (Last Hour)").WaitForAsync();
+ await _page.Locator("text=Merchants with No Sales Today").WaitForAsync();
+ await _page.Locator("text=Merchants with No Sales (7 Days)").WaitForAsync();
+ }
+
+ ///
+ /// Verify that KPI cards are NOT visible (Administrator role)
+ ///
+ public async Task VerifyKpiCardsAreNotVisible()
+ {
+ var salesLastHourCount = await _page.Locator("text=Merchants with Sales (Last Hour)").CountAsync();
+ salesLastHourCount.ShouldBe(0, "KPI cards should not be visible for Administrator role");
+ }
+
+ ///
+ /// Verify Merchant KPI values match expected hardcoded test data
+ ///
+ public async Task VerifyMerchantKpiValues(int salesLastHour, int noSalesToday, int noSales7Days)
+ {
+ // Wait for KPI cards to load
+ await _page.Locator("text=Merchants with Sales (Last Hour)").WaitForAsync();
+
+ // Verify Merchants with Sales in Last Hour
+ var salesLastHourCard = _page.Locator(".info-box").Filter(new LocatorFilterOptions
+ {
+ HasText = "Merchants with Sales (Last Hour)"
+ });
+ var salesLastHourValue = await salesLastHourCard.Locator(".info-box-number").TextContentAsync();
+ salesLastHourValue.ShouldNotBeNull();
+ int.Parse(salesLastHourValue.Trim()).ShouldBe(salesLastHour);
+
+ // Verify Merchants with No Sales Today
+ var noSalesTodayCard = _page.Locator(".info-box").Filter(new LocatorFilterOptions
+ {
+ HasText = "Merchants with No Sales Today"
+ });
+ var noSalesTodayValue = await noSalesTodayCard.Locator(".info-box-number").TextContentAsync();
+ noSalesTodayValue.ShouldNotBeNull();
+ int.Parse(noSalesTodayValue.Trim()).ShouldBe(noSalesToday);
+
+ // Verify Merchants with No Sales in Last 7 Days
+ var noSales7DaysCard = _page.Locator(".info-box").Filter(new LocatorFilterOptions
+ {
+ HasText = "Merchants with No Sales (7 Days)"
+ });
+ var noSales7DaysValue = await noSales7DaysCard.Locator(".info-box-number").TextContentAsync();
+ noSales7DaysValue.ShouldNotBeNull();
+ int.Parse(noSales7DaysValue.Trim()).ShouldBe(noSales7Days);
+ }
+
+ ///
+ /// Verify Today's Sales card is displayed
+ ///
+ public async Task VerifyTodaysSalesCardIsDisplayed()
+ {
+ await _page.Locator("h3:has-text('Today\\'s Sales')").WaitForAsync();
+ }
+
+ ///
+ /// Verify Today's Sales values
+ ///
+ public async Task VerifyTodaysSalesValues(int todayCount, decimal todayValue)
+ {
+ var salesCard = _page.Locator(".card").Filter(new LocatorFilterOptions
+ {
+ HasText = "Today's Sales"
+ });
+
+ // Wait for the card to be visible
+ await salesCard.WaitForAsync();
+
+ // Verify today's sales count
+ var todayTransactions = await salesCard.Locator("p:has-text('transactions')").First.TextContentAsync();
+ todayTransactions.ShouldNotBeNull();
+ todayTransactions.ShouldContain($"{todayCount} transactions");
+
+ // Verify today's sales value is displayed (currency format)
+ var todayValueText = await salesCard.Locator(".text-2xl.font-bold").First.TextContentAsync();
+ todayValueText.ShouldNotBeNull();
+ // Just verify value is present and formatted as currency
+ todayValueText.ShouldContain("$");
+ }
+
+ ///
+ /// Verify Failed Sales card is displayed
+ ///
+ public async Task VerifyFailedSalesCardIsDisplayed()
+ {
+ await _page.Locator("h3:has-text('Failed Sales (Low Credit)')").WaitForAsync();
+ }
+
+ ///
+ /// Verify Failed Sales values
+ ///
+ public async Task VerifyFailedSalesValues(int todayCount)
+ {
+ var failedSalesCard = _page.Locator(".card").Filter(new LocatorFilterOptions
+ {
+ HasText = "Failed Sales (Low Credit)"
+ });
+
+ // Wait for the card to be visible
+ await failedSalesCard.WaitForAsync();
+
+ // Verify today's failed sales count
+ var todayTransactions = await failedSalesCard.Locator("p:has-text('transactions')").First.TextContentAsync();
+ todayTransactions.ShouldNotBeNull();
+ todayTransactions.ShouldContain($"{todayCount} transactions");
+ }
+
+ ///
+ /// Verify comparison date selector is visible
+ ///
+ public async Task VerifyComparisonDateSelectorIsVisible()
+ {
+ await _page.Locator("label:has-text('Compare to:')").WaitForAsync();
+ await _page.Locator("#comparisonDateSelector").WaitForAsync();
+ }
+
+ ///
+ /// Verify comparison date selector is NOT visible (Administrator role)
+ ///
+ public async Task VerifyComparisonDateSelectorIsNotVisible()
+ {
+ var selectorCount = await _page.Locator("#comparisonDateSelector").CountAsync();
+ selectorCount.ShouldBe(0, "Comparison date selector should not be visible for Administrator role");
+ }
+
+ ///
+ /// Verify Recently Created Merchants section is visible
+ ///
+ public async Task VerifyRecentlyCreatedMerchantsIsVisible()
+ {
+ await _page.Locator("h3:has-text('Recently Created Merchants')").WaitForAsync();
+ }
+
+ ///
+ /// Verify Recently Created Merchants section is NOT visible (Administrator role)
+ ///
+ public async Task VerifyRecentlyCreatedMerchantsIsNotVisible()
+ {
+ var merchantsCount = await _page.Locator("h3:has-text('Recently Created Merchants')").CountAsync();
+ merchantsCount.ShouldBe(0, "Recently Created Merchants should not be visible for Administrator role");
+ }
+
+ ///
+ /// Verify that at least one merchant is displayed in the Recently Created Merchants section
+ ///
+ public async Task VerifyRecentlyCreatedMerchantsHasData()
+ {
+ var merchantsCard = _page.Locator(".card").Filter(new LocatorFilterOptions
+ {
+ HasText = "Recently Created Merchants"
+ });
+
+ await merchantsCard.WaitForAsync();
+
+ // Check that at least one merchant is displayed
+ var merchantItems = merchantsCard.Locator(".flex.items-center.justify-between");
+ var count = await merchantItems.CountAsync();
+ count.ShouldBeGreaterThan(0, "At least one merchant should be displayed");
+ }
+
+ #endregion
+
+ #region Interaction Methods
+
+ ///
+ /// Select a comparison date from the dropdown
+ ///
+ public async Task SelectComparisonDate(string dateDescription)
+ {
+ await _page.Locator("#comparisonDateSelector").SelectOptionAsync(new[] { new SelectOptionValue { Label = dateDescription } });
+ // Wait for dashboard to reload
+ await Task.Delay(500); // Small delay for state update
+ await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
+ }
+
+ #endregion
+}
diff --git a/EstateManagementUI.DashboardTests/EstateManagementUI.DashboardTests.csproj b/EstateManagementUI.DashboardTests/EstateManagementUI.DashboardTests.csproj
new file mode 100644
index 00000000..96310436
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/EstateManagementUI.DashboardTests.csproj
@@ -0,0 +1,39 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+ Always
+ true
+ PreserveNewest
+
+
+
+
diff --git a/EstateManagementUI.DashboardTests/Features/Dashboard.feature b/EstateManagementUI.DashboardTests/Features/Dashboard.feature
new file mode 100644
index 00000000..d7e0c8a2
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/Features/Dashboard.feature
@@ -0,0 +1,88 @@
+Feature: Dashboard Integration Tests
+ As a user of the Estate Management UI
+ I want to see appropriate dashboard content based on my role
+ So that I can access the information relevant to my permissions
+
+Background:
+ Given the user navigates to the Dashboard
+
+@DashboardTests @AdminRole
+Scenario: Administrator user sees limited dashboard view
+ Given the user is authenticated as an "Administrator" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the Administrator welcome message is displayed
+ And no merchant KPI cards are displayed
+ And no sales data cards are displayed
+
+@DashboardTests @EstateRole
+Scenario: Estate user sees full dashboard with merchant KPIs
+ Given the user is authenticated as an "Estate" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the merchant KPI cards are displayed
+ And the Merchants with Sales in Last Hour shows "45"
+ And the Merchants with No Sales Today shows "12"
+ And the Merchants with No Sales in Last 7 Days shows "5"
+
+@DashboardTests @EstateRole
+Scenario: Estate user sees sales data on dashboard
+ Given the user is authenticated as an "Estate" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the Today's Sales card is displayed
+ And the Today's Sales card shows "523" transactions
+ And the Today's Sales card shows a value greater than $0
+ And the Failed Sales card is displayed
+ And the Failed Sales card shows "18" transactions
+
+@DashboardTests @EstateRole
+Scenario: Estate user sees comparison date selector
+ Given the user is authenticated as an "Estate" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the comparison date selector is displayed
+
+@DashboardTests @EstateRole
+Scenario: Estate user sees recently created merchants
+ Given the user is authenticated as an "Estate" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the Recently Created Merchants section is displayed
+ And at least "1" merchant is shown in Recently Created Merchants
+
+@DashboardTests @ViewerRole
+Scenario: Viewer user sees full dashboard with merchant KPIs
+ Given the user is authenticated as an "Viewer" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the merchant KPI cards are displayed
+ And the Merchants with Sales in Last Hour shows "45"
+ And the Merchants with No Sales Today shows "12"
+ And the Merchants with No Sales in Last 7 Days shows "5"
+
+@DashboardTests @ViewerRole
+Scenario: Viewer user sees sales data on dashboard
+ Given the user is authenticated as an "Viewer" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the Today's Sales card is displayed
+ And the Today's Sales card shows "523" transactions
+ And the Today's Sales card shows a value greater than $0
+ And the Failed Sales card is displayed
+ And the Failed Sales card shows "18" transactions
+
+@DashboardTests @ViewerRole
+Scenario: Viewer user sees comparison date selector
+ Given the user is authenticated as an "Viewer" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the comparison date selector is displayed
+
+@DashboardTests @ViewerRole
+Scenario: Viewer user sees recently created merchants
+ Given the user is authenticated as an "Viewer" user
+ When the user navigates to the Dashboard
+ Then the Dashboard page is displayed
+ And the Recently Created Merchants section is displayed
+ And at least "1" merchant is shown in Recently Created Merchants
diff --git a/EstateManagementUI.DashboardTests/Hooks/BrowserHooks.cs b/EstateManagementUI.DashboardTests/Hooks/BrowserHooks.cs
new file mode 100644
index 00000000..df8ea919
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/Hooks/BrowserHooks.cs
@@ -0,0 +1,144 @@
+using Microsoft.Playwright;
+using Reqnroll;
+
+namespace EstateManagementUI.DashboardTests.Hooks;
+
+///
+/// Hooks for managing browser lifecycle using Playwright
+///
+[Binding]
+public class BrowserHooks
+{
+ private static IPlaywright? _playwright;
+ private static IBrowser? _browser;
+ private readonly ScenarioContext _scenarioContext;
+
+ public BrowserHooks(ScenarioContext scenarioContext)
+ {
+ _scenarioContext = scenarioContext;
+ }
+
+ ///
+ /// Install Playwright browsers and initialize Playwright before running any tests
+ ///
+ [BeforeTestRun]
+ public static async Task BeforeTestRun()
+ {
+ // Install Playwright browsers if needed
+ var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
+ if (exitCode != 0)
+ {
+ throw new Exception($"Playwright installation failed with exit code {exitCode}");
+ }
+
+ // Initialize Playwright
+ _playwright = await Playwright.CreateAsync();
+ }
+
+ ///
+ /// Create a new browser page for each scenario
+ ///
+ [BeforeScenario(Order = 0)]
+ public async Task BeforeScenario()
+ {
+ var page = await CreateBrowserPage();
+
+ // Register the page for this scenario
+ _scenarioContext.ScenarioContainer.RegisterInstanceAs(page);
+ }
+
+ ///
+ /// Cleanup browser page after each scenario and take screenshot on failure
+ ///
+ [AfterScenario(Order = 0)]
+ public async Task AfterScenario()
+ {
+ var page = _scenarioContext.ScenarioContainer.Resolve();
+
+ if (page != null)
+ {
+ // Take screenshot on failure
+ if (_scenarioContext.TestError != null)
+ {
+ var scenarioName = _scenarioContext.ScenarioInfo.Title.Replace(" ", "_");
+ var screenshotPath = $"screenshot-{scenarioName}-{DateTime.Now:yyyyMMddHHmmss}.png";
+ await page.ScreenshotAsync(new PageScreenshotOptions
+ {
+ Path = screenshotPath,
+ FullPage = true
+ });
+ Console.WriteLine($"Screenshot saved to: {screenshotPath}");
+ }
+
+ await page.CloseAsync();
+ }
+ }
+
+ ///
+ /// Cleanup Playwright resources after all tests complete
+ ///
+ [AfterTestRun]
+ public static async Task AfterTestRun()
+ {
+ if (_browser != null)
+ {
+ await _browser.CloseAsync();
+ _browser = null;
+ }
+
+ if (_playwright != null)
+ {
+ _playwright.Dispose();
+ _playwright = null;
+ }
+ }
+
+ ///
+ /// Create a new browser page with appropriate configuration
+ ///
+ private async Task CreateBrowserPage()
+ {
+ var browserType = Environment.GetEnvironmentVariable("Browser") ?? "Chrome";
+ var isCI = string.Equals(
+ Environment.GetEnvironmentVariable("IsCI"),
+ "true",
+ StringComparison.InvariantCultureIgnoreCase);
+
+ if (_browser == null)
+ {
+ _browser = browserType switch
+ {
+ "Firefox" => await _playwright!.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
+ {
+ Headless = isCI,
+ Args = new[] { "--ignore-certificate-errors" }
+ }),
+ "WebKit" => await _playwright!.Webkit.LaunchAsync(new BrowserTypeLaunchOptions
+ {
+ Headless = isCI,
+ Args = new[] { "--ignore-certificate-errors" }
+ }),
+ _ => await _playwright!.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
+ {
+ Headless = isCI,
+ Args = new[]
+ {
+ "--ignore-certificate-errors",
+ "--no-sandbox",
+ "--disable-dev-shm-usage",
+ "--disable-gpu",
+ "--disable-extensions"
+ }
+ })
+ };
+ }
+
+ var context = await _browser.NewContextAsync(new BrowserNewContextOptions
+ {
+ IgnoreHTTPSErrors = true,
+ ViewportSize = new ViewportSize { Width = 1920, Height = 1080 }
+ });
+
+ return await context.NewPageAsync();
+ }
+}
diff --git a/EstateManagementUI.DashboardTests/README.md b/EstateManagementUI.DashboardTests/README.md
new file mode 100644
index 00000000..b2822e19
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/README.md
@@ -0,0 +1,138 @@
+# Estate Management UI - Dashboard Integration Tests
+
+This project contains integration tests for the Dashboard functionality of the Estate Management Blazor Server application, using Reqnroll (SpecFlow successor), Playwright, and Shouldly.
+
+## Project Structure
+
+```
+EstateManagementUI.DashboardTests/
+├── Features/ # Reqnroll feature files (Gherkin scenarios)
+│ └── Dashboard.feature # Dashboard test scenarios for all roles
+├── Steps/ # Step definitions (links features to code)
+│ └── DashboardSteps.cs # Dashboard step implementations
+├── Hooks/ # Test lifecycle hooks
+│ └── BrowserHooks.cs # Playwright browser management
+├── Common/ # Helper classes and utilities
+│ └── DashboardPageHelper.cs # Page object for Dashboard interactions
+└── appsettings.json # Test configuration and hardcoded test data
+```
+
+## Key Components
+
+### 1. Feature File (`Features/Dashboard.feature`)
+- Defines test scenarios in Gherkin syntax (Given/When/Then)
+- Covers three user roles: Administrator, Estate, and Viewer
+- Tests dashboard visibility and data display based on role permissions
+- Uses hardcoded test data values from the application
+
+### 2. Hooks File (`Hooks/BrowserHooks.cs`)
+- Manages Playwright browser lifecycle
+- `BeforeTestRun`: Installs Playwright browsers and initializes Playwright
+- `BeforeScenario`: Creates a new browser page for each test scenario
+- `AfterScenario`: Cleans up and takes screenshots on test failures
+- `AfterTestRun`: Disposes Playwright resources
+
+### 3. Step Definitions (`Steps/DashboardSteps.cs`)
+- Links Gherkin steps from feature files to C# code
+- Uses DashboardPageHelper to interact with the browser
+- Implements Given/When/Then steps for all Dashboard scenarios
+
+### 4. Page Helper (`Common/DashboardPageHelper.cs`)
+- Encapsulates all Dashboard page interactions using Playwright
+- Provides methods for navigation, verification, and interaction
+- Uses Shouldly for assertions
+
+## Test Data
+
+The tests are designed to assert against hardcoded test data in the application's `TestMediatorService.cs`:
+
+### Merchant KPIs
+- Merchants with Sales in Last Hour: **45**
+- Merchants with No Sales Today: **12**
+- Merchants with No Sales in Last 7 Days: **5**
+
+### Today's Sales
+- Transaction Count: **523**
+- Sales Value: **$145,000.00**
+
+### Failed Sales (Low Credit)
+- Transaction Count: **18**
+- Sales Value: **$850.00**
+
+These values are defined in the application's `TestMediatorService` and can be updated when the test data is changed.
+
+## User Roles Tested
+
+### Administrator Role
+- Can only view the Dashboard with a welcome message
+- No access to merchant KPIs, sales data, or reports
+- Limited to permission management functions
+
+### Estate Role
+- Full access to all dashboard features
+- Can view all merchant KPIs
+- Can view sales data and comparisons
+- Can view recently created merchants
+- Has full CRUD permissions across the application
+
+### Viewer Role
+- View-only access to all dashboard features
+- Can view all merchant KPIs
+- Can view sales data and comparisons
+- Can view recently created merchants
+- Cannot create, edit, or delete any data
+
+## Running the Tests
+
+The tests are designed to run against a running instance of the Estate Management UI application. The application startup and configuration will be handled separately.
+
+### Prerequisites
+1. .NET 10 SDK
+2. Playwright browsers (automatically installed by the test hooks)
+
+### Configuration
+Set the following environment variables before running tests:
+- `APP_URL`: Base URL of the application (default: `https://localhost:5001`)
+- `Browser`: Browser to use - Chrome, Firefox, or WebKit (default: Chrome)
+- `IsCI`: Set to "true" to run in headless mode (default: false)
+
+### Execute Tests
+```bash
+dotnet test EstateManagementUI.DashboardTests.csproj
+```
+
+### Filter by Role
+```bash
+# Run only Administrator role tests
+dotnet test --filter "Category=AdminRole"
+
+# Run only Estate role tests
+dotnet test --filter "Category=EstateRole"
+
+# Run only Viewer role tests
+dotnet test --filter "Category=ViewerRole"
+```
+
+## Notes
+
+- **Application Startup**: The tests assume the application is already running. Application startup logic will be implemented separately.
+- **Authentication**: The authentication/role setup is a placeholder. The actual implementation will depend on how the application is configured for testing.
+- **Test Data**: All assertions are based on hardcoded values in the application's `TestMediatorService`. Update the feature file and `appsettings.json` if test data changes.
+- **Screenshots**: On test failure, screenshots are automatically saved to the test output directory with timestamps.
+
+## Dependencies
+
+- **Reqnroll 3.2.1**: BDD framework (SpecFlow successor)
+- **Playwright 1.49.0**: Browser automation
+- **Shouldly 4.3.0**: Assertion library with readable error messages
+- **NUnit 4.4.0**: Test framework
+- **.NET 10**: Target framework
+
+## Future Enhancements
+
+When application startup is implemented:
+1. Add Docker container management for the application
+2. Add test data setup/teardown
+3. Add user authentication simulation
+4. Add role switching capabilities
+5. Add test reporting and metrics
diff --git a/EstateManagementUI.DashboardTests/Steps/DashboardSteps.cs b/EstateManagementUI.DashboardTests/Steps/DashboardSteps.cs
new file mode 100644
index 00000000..fa7b4878
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/Steps/DashboardSteps.cs
@@ -0,0 +1,187 @@
+using Microsoft.Playwright;
+using Reqnroll;
+using EstateManagementUI.DashboardTests.Common;
+
+namespace EstateManagementUI.DashboardTests.Steps;
+
+///
+/// Step definitions for Dashboard integration tests
+/// Links feature file scenarios to browser automation code
+///
+[Binding]
+public class DashboardSteps
+{
+ private readonly IPage _page;
+ private readonly DashboardPageHelper _dashboardHelper;
+ private readonly ScenarioContext _scenarioContext;
+
+ public DashboardSteps(ScenarioContext scenarioContext)
+ {
+ _scenarioContext = scenarioContext;
+ _page = scenarioContext.ScenarioContainer.Resolve();
+
+ // Get base URL from environment variable or use default
+ var baseUrl = Environment.GetEnvironmentVariable("APP_URL") ?? "https://localhost:5001";
+ _dashboardHelper = new DashboardPageHelper(_page, baseUrl);
+ }
+
+ #region Navigation Steps
+
+ [Given(@"the user navigates to the Dashboard")]
+ [When(@"the user navigates to the Dashboard")]
+ public async Task GivenTheUserNavigatesToTheDashboard()
+ {
+ await _dashboardHelper.NavigateToDashboard();
+ }
+
+ #endregion
+
+ #region Authentication/Role Steps
+
+ [Given(@"the user is authenticated as an ""(.*)"" user")]
+ public async Task GivenTheUserIsAuthenticatedAsAUser(string role)
+ {
+ // Store the role in scenario context for reference
+ _scenarioContext["UserRole"] = role;
+
+ // Note: This step assumes the application will be started in test mode
+ // with the appropriate role already configured. The actual authentication
+ // setup will be handled when the application startup is implemented.
+ await Task.CompletedTask;
+ }
+
+ #endregion
+
+ #region Verification Steps - Common
+
+ [Then(@"the Dashboard page is displayed")]
+ public async Task ThenTheDashboardPageIsDisplayed()
+ {
+ await _dashboardHelper.VerifyDashboardPageTitle();
+ }
+
+ #endregion
+
+ #region Verification Steps - Administrator Role
+
+ [Then(@"the Administrator welcome message is displayed")]
+ public async Task ThenTheAdministratorWelcomeMessageIsDisplayed()
+ {
+ await _dashboardHelper.VerifyAdministratorWelcomeMessage();
+ }
+
+ [Then(@"no merchant KPI cards are displayed")]
+ public async Task ThenNoMerchantKpiCardsAreDisplayed()
+ {
+ await _dashboardHelper.VerifyKpiCardsAreNotVisible();
+ }
+
+ [Then(@"no sales data cards are displayed")]
+ public async Task ThenNoSalesDataCardsAreDisplayed()
+ {
+ await _dashboardHelper.VerifyComparisonDateSelectorIsNotVisible();
+ await _dashboardHelper.VerifyRecentlyCreatedMerchantsIsNotVisible();
+ }
+
+ #endregion
+
+ #region Verification Steps - Estate/Viewer Roles
+
+ [Then(@"the merchant KPI cards are displayed")]
+ public async Task ThenTheMerchantKpiCardsAreDisplayed()
+ {
+ await _dashboardHelper.VerifyKpiCardsAreVisible();
+ }
+
+ [Then(@"the Merchants with Sales in Last Hour shows ""(.*)""")]
+ public async Task ThenTheMerchantsWithSalesInLastHourShows(int expectedValue)
+ {
+ // This will be verified as part of the full KPI verification
+ _scenarioContext["ExpectedSalesLastHour"] = expectedValue;
+ }
+
+ [Then(@"the Merchants with No Sales Today shows ""(.*)""")]
+ public async Task ThenTheMerchantsWithNoSalesTodayShows(int expectedValue)
+ {
+ _scenarioContext["ExpectedNoSalesToday"] = expectedValue;
+ }
+
+ [Then(@"the Merchants with No Sales in Last 7 Days shows ""(.*)""")]
+ public async Task ThenTheMerchantsWithNoSalesInLast7DaysShows(int expectedValue)
+ {
+ _scenarioContext["ExpectedNoSales7Days"] = expectedValue;
+
+ // Now verify all KPI values
+ var salesLastHour = (int)_scenarioContext["ExpectedSalesLastHour"];
+ var noSalesToday = (int)_scenarioContext["ExpectedNoSalesToday"];
+ var noSales7Days = expectedValue;
+
+ await _dashboardHelper.VerifyMerchantKpiValues(salesLastHour, noSalesToday, noSales7Days);
+ }
+
+ [Then(@"the Today's Sales card is displayed")]
+ public async Task ThenTheTodaysSalesCardIsDisplayed()
+ {
+ await _dashboardHelper.VerifyTodaysSalesCardIsDisplayed();
+ }
+
+ [Then(@"the Today's Sales card shows ""(.*)"" transactions")]
+ public async Task ThenTheTodaysSalesCardShowsTransactions(int transactionCount)
+ {
+ // Store for later verification
+ _scenarioContext["TodaysSalesCount"] = transactionCount;
+ }
+
+ [Then(@"the Today's Sales card shows a value greater than \$(.*)")]
+ public async Task ThenTheTodaysSalesCardShowsAValueGreaterThan(decimal minimumValue)
+ {
+ // Verify sales values
+ var salesCount = (int)_scenarioContext["TodaysSalesCount"];
+ await _dashboardHelper.VerifyTodaysSalesValues(salesCount, minimumValue);
+ }
+
+ [Then(@"the Failed Sales card is displayed")]
+ public async Task ThenTheFailedSalesCardIsDisplayed()
+ {
+ await _dashboardHelper.VerifyFailedSalesCardIsDisplayed();
+ }
+
+ [Then(@"the Failed Sales card shows ""(.*)"" transactions")]
+ public async Task ThenTheFailedSalesCardShowsTransactions(int transactionCount)
+ {
+ await _dashboardHelper.VerifyFailedSalesValues(transactionCount);
+ }
+
+ [Then(@"the comparison date selector is displayed")]
+ public async Task ThenTheComparisonDateSelectorIsDisplayed()
+ {
+ await _dashboardHelper.VerifyComparisonDateSelectorIsVisible();
+ }
+
+ [Then(@"the Recently Created Merchants section is displayed")]
+ public async Task ThenTheRecentlyCreatedMerchantsSectionIsDisplayed()
+ {
+ await _dashboardHelper.VerifyRecentlyCreatedMerchantsIsVisible();
+ }
+
+ [Then(@"at least ""(.*)"" merchant is shown in Recently Created Merchants")]
+ public async Task ThenAtLeastMerchantIsShownInRecentlyCreatedMerchants(int minCount)
+ {
+ if (minCount > 0)
+ {
+ await _dashboardHelper.VerifyRecentlyCreatedMerchantsHasData();
+ }
+ }
+
+ #endregion
+
+ #region Interaction Steps
+
+ [When(@"the user selects ""(.*)"" from the comparison date selector")]
+ public async Task WhenTheUserSelectsFromTheComparisonDateSelector(string dateOption)
+ {
+ await _dashboardHelper.SelectComparisonDate(dateOption);
+ }
+
+ #endregion
+}
diff --git a/EstateManagementUI.DashboardTests/appsettings.json b/EstateManagementUI.DashboardTests/appsettings.json
new file mode 100644
index 00000000..b8feceb8
--- /dev/null
+++ b/EstateManagementUI.DashboardTests/appsettings.json
@@ -0,0 +1,23 @@
+{
+ "TestSettings": {
+ "BaseUrl": "https://localhost:5001",
+ "Browser": "Chrome",
+ "Headless": false,
+ "DefaultTimeout": 30000
+ },
+ "HardcodedTestData": {
+ "MerchantKpi": {
+ "MerchantsWithSaleInLastHour": 45,
+ "MerchantsWithNoSaleToday": 12,
+ "MerchantsWithNoSaleInLast7Days": 5
+ },
+ "TodaysSales": {
+ "TodaysSalesCount": 523,
+ "TodaysSalesValue": 145000.00
+ },
+ "TodaysFailedSales": {
+ "TodaysSalesCount": 18,
+ "TodaysSalesValue": 850.00
+ }
+ }
+}
From 0a1b76657115f554a506908c4720462c312ac159 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 10:05:27 +0000
Subject: [PATCH 3/7] Fix test data assertions to match actual hardcoded values
(failed sales count: 15)
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
---
.../Common/DashboardPageHelper.cs | 4 ++--
EstateManagementUI.DashboardTests/Features/Dashboard.feature | 4 ++--
EstateManagementUI.DashboardTests/README.md | 2 +-
EstateManagementUI.DashboardTests/appsettings.json | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs b/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
index dd61ae61..e7c830a9 100644
--- a/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
+++ b/EstateManagementUI.DashboardTests/Common/DashboardPageHelper.cs
@@ -115,7 +115,7 @@ public async Task VerifyMerchantKpiValues(int salesLastHour, int noSalesToday, i
///
public async Task VerifyTodaysSalesCardIsDisplayed()
{
- await _page.Locator("h3:has-text('Today\\'s Sales')").WaitForAsync();
+ await _page.Locator("h3:has-text(\"Today's Sales\")").WaitForAsync();
}
///
@@ -232,7 +232,7 @@ public async Task VerifyRecentlyCreatedMerchantsHasData()
///
public async Task SelectComparisonDate(string dateDescription)
{
- await _page.Locator("#comparisonDateSelector").SelectOptionAsync(new[] { new SelectOptionValue { Label = dateDescription } });
+ await _page.Locator("#comparisonDateSelector").SelectOptionAsync(new[] { dateDescription });
// Wait for dashboard to reload
await Task.Delay(500); // Small delay for state update
await _page.WaitForLoadStateAsync(LoadState.NetworkIdle);
diff --git a/EstateManagementUI.DashboardTests/Features/Dashboard.feature b/EstateManagementUI.DashboardTests/Features/Dashboard.feature
index d7e0c8a2..c4ebbbe5 100644
--- a/EstateManagementUI.DashboardTests/Features/Dashboard.feature
+++ b/EstateManagementUI.DashboardTests/Features/Dashboard.feature
@@ -34,7 +34,7 @@ Scenario: Estate user sees sales data on dashboard
And the Today's Sales card shows "523" transactions
And the Today's Sales card shows a value greater than $0
And the Failed Sales card is displayed
- And the Failed Sales card shows "18" transactions
+ And the Failed Sales card shows "15" transactions
@DashboardTests @EstateRole
Scenario: Estate user sees comparison date selector
@@ -70,7 +70,7 @@ Scenario: Viewer user sees sales data on dashboard
And the Today's Sales card shows "523" transactions
And the Today's Sales card shows a value greater than $0
And the Failed Sales card is displayed
- And the Failed Sales card shows "18" transactions
+ And the Failed Sales card shows "15" transactions
@DashboardTests @ViewerRole
Scenario: Viewer user sees comparison date selector
diff --git a/EstateManagementUI.DashboardTests/README.md b/EstateManagementUI.DashboardTests/README.md
index b2822e19..791334de 100644
--- a/EstateManagementUI.DashboardTests/README.md
+++ b/EstateManagementUI.DashboardTests/README.md
@@ -56,7 +56,7 @@ The tests are designed to assert against hardcoded test data in the application'
- Sales Value: **$145,000.00**
### Failed Sales (Low Credit)
-- Transaction Count: **18**
+- Transaction Count: **15**
- Sales Value: **$850.00**
These values are defined in the application's `TestMediatorService` and can be updated when the test data is changed.
diff --git a/EstateManagementUI.DashboardTests/appsettings.json b/EstateManagementUI.DashboardTests/appsettings.json
index b8feceb8..0f5bae89 100644
--- a/EstateManagementUI.DashboardTests/appsettings.json
+++ b/EstateManagementUI.DashboardTests/appsettings.json
@@ -16,7 +16,7 @@
"TodaysSalesValue": 145000.00
},
"TodaysFailedSales": {
- "TodaysSalesCount": 18,
+ "TodaysSalesCount": 15,
"TodaysSalesValue": 850.00
}
}
From 832638ac66f665f49bfd7aabbf36fad526f39660 Mon Sep 17 00:00:00 2001
From: StuartFerguson
Date: Mon, 12 Jan 2026 10:32:21 +0000
Subject: [PATCH 4/7] remove old tests
---
.../Common/BlazorUiHelpers.cs | 651 --------
.../Common/ClientDetails.cs | 28 -
.../Common/DockerHelper.cs | 479 ------
.../Common/GenericSteps.cs | 64 -
.../Common/Hooks.cs | 136 --
.../Common/PlaywrightExtensions.cs | 225 ---
.../Common/Setup.cs | 20 -
.../Common/SharedSteps.cs | 432 -----
.../Common/TestConfiguration.cs | 102 --
.../Common/TestDataHelper.cs | 96 --
.../Common/TestingContext.cs | 97 --
...ManagementUI.BlazorIntegrationTests.csproj | 67 -
.../MIGRATION_GUIDE.md | 397 -----
.../NuGet.Config | 24 -
.../README.md | 160 --
.../SKIP_REMOTE_CALLS.md | 261 ---
.../Steps/BlazorUiSteps.cs | 403 -----
.../Steps/TestDataManagementSteps.cs | 170 --
.../TEST_INFRASTRUCTURE.md | 247 ---
.../Tests/ContractTests.feature | 128 --
.../Tests/ContractTests.feature.cs | 578 -------
.../Tests/EstateTests.feature | 85 -
.../Tests/EstateTests.feature.cs | 387 -----
.../Tests/MerchantTests.feature | 254 ---
.../Tests/MerchantTests.feature.cs | 1046 ------------
.../Tests/OperatorTests.feature | 102 --
.../Tests/OperatorTests.feature.cs | 465 ------
.../appsettings.json | 6 -
.../nlog.config | 31 -
.../ApiClientTests.cs | 817 ----------
...ateManagementUI.BusinessLogic.Tests.csproj | 47 -
.../ExtensionsTests.cs | 33 -
.../MediatorTests.cs | 151 --
.../ModelFactoryTests.cs | 871 ----------
.../PermissionsServiceTests.cs | 253 ---
.../Common/ClientDetails.cs | 28 -
.../Common/DockerHelper.cs | 467 ------
.../Common/EstateManagementUiSteps.cs | 1133 -------------
.../Common/Extensions.cs | 214 ---
.../Common/GenericSteps.cs | 63 -
.../Common/Hooks.cs | 209 ---
.../Common/Setup.cs | 20 -
.../Common/SharedSteps.cs | 331 ----
.../Common/TestingContext.cs | 97 --
...EstateManagementUI.IntegrationTests.csproj | 60 -
.../Steps/Gimp.cs | 632 --------
.../Tests/ContractTests.feature | 128 --
.../Tests/ContractTests.feature.cs | 578 -------
.../Tests/EstateTests.feature | 85 -
.../Tests/EstateTests.feature.cs | 389 -----
.../Tests/MerchantTests.feature | 254 ---
.../Tests/MerchantTests.feature.cs | 1069 -------------
.../Tests/OperatorTests.feature | 102 --
.../Tests/OperatorTests.feature.cs | 465 ------
.../nlog.config | 31 -
.../EstateManagementUI.Testing.csproj | 35 -
EstateManagementUI.Testing/TestData.cs | 1419 -----------------
.../AddContractDialogTests.cs | 97 --
.../AddDeviceDialogTests.cs | 95 --
.../AddOperatorDialogTests.cs | 99 --
.../ChartHelpersTests.cs | 86 -
.../ContractProductTransactionFeeListTests.cs | 164 --
.../ContractProductsListTests.cs | 199 ---
.../ContractsListTests.cs | 161 --
EstateManagementUI.UITests/DashboardTests.cs | 217 ---
.../DataHelperFunctionsTests.cs | 190 ---
.../EditMerchantTests.cs | 153 --
.../EstateManagementUI.UITests.csproj | 40 -
.../FileDetailsTests.cs | 96 --
.../FileImportLogListTests.cs | 139 --
.../FileImportLogTests.cs | 168 --
EstateManagementUI.UITests/HelpersTests.cs | 98 --
.../MerchantDetailsTests.cs | 344 ----
EstateManagementUI.UITests/MerchantTests.cs | 227 ---
.../MerchantsListTests.cs | 246 ---
.../NavigationServiceTests.cs | 133 --
.../OperatorListTests.cs | 44 -
EstateManagementUI.UITests/OperatorTests.cs | 144 --
.../OperatorsListTests.cs | 159 --
.../ProfileDropdownTests.cs | 91 --
.../SettlementAnalysisTests.cs | 132 --
EstateManagementUI.UITests/TestHelpers.cs | 25 -
.../TransactionAnalysisTests.cs | 433 -----
EstateManagementUI.UITests/UsersListTests.cs | 44 -
EstateManagementUI.UITests/ViewEstateTests.cs | 45 -
EstateManagementUI.sln | 28 +-
86 files changed, 14 insertions(+), 21205 deletions(-)
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/BlazorUiHelpers.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/ClientDetails.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/DockerHelper.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/GenericSteps.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/Hooks.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/PlaywrightExtensions.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/Setup.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/SharedSteps.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/TestConfiguration.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/TestDataHelper.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Common/TestingContext.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/MIGRATION_GUIDE.md
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/NuGet.Config
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/README.md
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/SKIP_REMOTE_CALLS.md
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Steps/BlazorUiSteps.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Steps/TestDataManagementSteps.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/TEST_INFRASTRUCTURE.md
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature.cs
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/appsettings.json
delete mode 100644 EstateManagementUI.BlazorIntegrationTests/nlog.config
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/ApiClientTests.cs
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/EstateManagementUI.BusinessLogic.Tests.csproj
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/ExtensionsTests.cs
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/MediatorTests.cs
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/ModelFactoryTests.cs
delete mode 100644 EstateManagementUI.BusinessLogic.Tests/PermissionsServiceTests.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/ClientDetails.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/DockerHelper.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/EstateManagementUiSteps.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/Extensions.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/GenericSteps.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/Hooks.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/Setup.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/SharedSteps.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Common/TestingContext.cs
delete mode 100644 EstateManagementUI.IntegrationTests/EstateManagementUI.IntegrationTests.csproj
delete mode 100644 EstateManagementUI.IntegrationTests/Steps/Gimp.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/ContractTests.feature
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/ContractTests.feature.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/EstateTests.feature
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/EstateTests.feature.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/MerchantTests.feature
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/MerchantTests.feature.cs
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/OperatorTests.feature
delete mode 100644 EstateManagementUI.IntegrationTests/Tests/OperatorTests.feature.cs
delete mode 100644 EstateManagementUI.IntegrationTests/nlog.config
delete mode 100644 EstateManagementUI.Testing/EstateManagementUI.Testing.csproj
delete mode 100644 EstateManagementUI.Testing/TestData.cs
delete mode 100644 EstateManagementUI.UITests/AddContractDialogTests.cs
delete mode 100644 EstateManagementUI.UITests/AddDeviceDialogTests.cs
delete mode 100644 EstateManagementUI.UITests/AddOperatorDialogTests.cs
delete mode 100644 EstateManagementUI.UITests/ChartHelpersTests.cs
delete mode 100644 EstateManagementUI.UITests/ContractProductTransactionFeeListTests.cs
delete mode 100644 EstateManagementUI.UITests/ContractProductsListTests.cs
delete mode 100644 EstateManagementUI.UITests/ContractsListTests.cs
delete mode 100644 EstateManagementUI.UITests/DashboardTests.cs
delete mode 100644 EstateManagementUI.UITests/DataHelperFunctionsTests.cs
delete mode 100644 EstateManagementUI.UITests/EditMerchantTests.cs
delete mode 100644 EstateManagementUI.UITests/EstateManagementUI.UITests.csproj
delete mode 100644 EstateManagementUI.UITests/FileDetailsTests.cs
delete mode 100644 EstateManagementUI.UITests/FileImportLogListTests.cs
delete mode 100644 EstateManagementUI.UITests/FileImportLogTests.cs
delete mode 100644 EstateManagementUI.UITests/HelpersTests.cs
delete mode 100644 EstateManagementUI.UITests/MerchantDetailsTests.cs
delete mode 100644 EstateManagementUI.UITests/MerchantTests.cs
delete mode 100644 EstateManagementUI.UITests/MerchantsListTests.cs
delete mode 100644 EstateManagementUI.UITests/NavigationServiceTests.cs
delete mode 100644 EstateManagementUI.UITests/OperatorListTests.cs
delete mode 100644 EstateManagementUI.UITests/OperatorTests.cs
delete mode 100644 EstateManagementUI.UITests/OperatorsListTests.cs
delete mode 100644 EstateManagementUI.UITests/ProfileDropdownTests.cs
delete mode 100644 EstateManagementUI.UITests/SettlementAnalysisTests.cs
delete mode 100644 EstateManagementUI.UITests/TestHelpers.cs
delete mode 100644 EstateManagementUI.UITests/TransactionAnalysisTests.cs
delete mode 100644 EstateManagementUI.UITests/UsersListTests.cs
delete mode 100644 EstateManagementUI.UITests/ViewEstateTests.cs
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/BlazorUiHelpers.cs b/EstateManagementUI.BlazorIntegrationTests/Common/BlazorUiHelpers.cs
deleted file mode 100644
index f17f2c98..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/BlazorUiHelpers.cs
+++ /dev/null
@@ -1,651 +0,0 @@
-using Microsoft.Playwright;
-using Reqnroll;
-using Shared.IntegrationTesting;
-using Shouldly;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Common;
-
-public class BlazorUiHelpers
-{
- private readonly IPage Page;
- private readonly Int32 EstateManagementUiPort;
-
- public BlazorUiHelpers(IPage page, Int32 estateManagementUiPort)
- {
- this.Page = page;
- this.EstateManagementUiPort = estateManagementUiPort;
- }
-
- private async Task VerifyPageTitle(String expectedTitle)
- {
- await Retry.For(async () =>
- {
- var title = await this.Page.TitleAsync();
- title.ShouldBe($"{expectedTitle}");
- });
- }
-
- public async Task NavigateToHomePage()
- {
- await this.Page.GotoAsync($"https://localhost:{this.EstateManagementUiPort}");
- if (TestConfiguration.IsTestMode == false) {
- await this.VerifyPageTitle("Welcome - Estate Management");
- }
- }
-
- public async Task ClickContractsSidebarOption()
- {
- await this.Page.ClickButtonById("contractsLink");
- }
-
- public async Task ClickMyEstateSidebarOption()
- {
- await this.Page.ClickButtonById("estateDetailsLink");
- }
-
- public async Task ClickMyMerchantsSidebarOption()
- {
- await this.Page.ClickButtonById("merchantsLink");
- }
-
- public async Task ClickMyOperatorsSidebarOption()
- {
- await this.Page.ClickButtonById("operatorsLink");
- }
-
- public async Task ClickOnTheSignInButton()
- {
- await this.Page.ClickButtonById("loginButton");
- }
-
- public async Task VerifyOnTheMakeMerchantDepositScreen()
- {
- await Retry.For(async () =>
- {
- var title = await this.Page.TitleAsync();
- title.ShouldBe("Make Merchant Deposit");
- });
- }
-
- public async Task VerifyOnTheTheMerchantDetailsScreen(String merchantName)
- {
- await Retry.For(async () =>
- {
- var value = await this.Page.GetValueById("MerchantName");
- value.ShouldBe(merchantName);
- });
- }
-
- public async Task VerifyOnTheNewContractScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("New Contract"); });
- }
-
- public async Task VerifyOnTheNewContractProductScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("New Contract Product"); });
- }
-
- public async Task VerifyOnTheNewMerchantScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Create New Merchant"); });
- }
-
- public async Task VerifyOnTheEditMerchantScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Edit Merchant"); });
- }
-
- public async Task VerifyOnTheMakeDepositScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Make Deposit"); });
- }
-
- public async Task VerifyOnTheViewMerchantScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("View Merchant"); });
- }
-
- public async Task VerifyOnTheNewOperatorScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("New Operator"); });
- }
-
- public async Task VerifyOnTheEditOperatorScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Edit Operator"); });
- }
-
- public async Task VerifyOnTheContractsListScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Contract Management"); });
- }
-
- public async Task VerifyOnTheContractProductsListScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("View Contract Products"); });
- }
-
- public async Task VerifyOnTheContractProductsFeesListScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("View Contract Product Fees"); });
- }
-
- public async Task VerifyOnTheNewTransactionFeeScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("New Transaction Fee"); });
- }
-
- public async Task VerifyOnTheLoginScreen()
- {
- await Retry.For(async () =>
- {
- var loginButton = await this.Page.FindButtonByText("Login", TimeSpan.FromMinutes(2));
- loginButton.ShouldNotBeNull();
- });
- }
-
- public async Task ClickOnTheMerchantOperatorsTab()
- {
- await this.ClickTab("nav-operators-tab");
- }
-
- public async Task ClickOnTheMerchantContractsTab()
- {
- await this.ClickTab("nav-contracts-tab");
- }
-
- public async Task ClickOnTheMerchantDevicesTab()
- {
- await this.ClickTab("nav-devices-tab");
- }
-
- private async Task ClickTab(String tabId)
- {
- await Retry.For(async () =>
- {
- var locator = this.Page.Locator($"#{tabId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- await locator.ClickAsync();
- });
- }
-
- public async Task VerifyOnMerchantOperatorsTab()
- {
- await Retry.For(async () =>
- {
- var locator = this.Page.Locator("#merchantOperatorList");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- });
- }
-
- public async Task VerifyOnMerchantContractsTab()
- {
- await Retry.For(async () =>
- {
- var locator = this.Page.Locator("#merchantContractList");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- });
- }
-
- public async Task VerifyOnMerchantDevicesTab()
- {
- await Retry.For(async () =>
- {
- var locator = this.Page.Locator("#merchantDeviceList");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- });
- }
-
- public async Task VerifyOnTheDashboard()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Dashboard"); });
- }
-
- public async Task VerifyOnTheEstateDetailsScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Estate Management"); });
- }
-
- public async Task VerifyOnTheMerchantsListScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Merchant Management"); });
- }
-
- public async Task VerifyOnTheOperatorsListScreen()
- {
- await Retry.For(async () => { await this.VerifyPageTitle("Operator Management"); });
- }
-
- public async Task VerifyTheCorrectEstateDetailsAreDisplayed(String estateName)
- {
- await Retry.For(async () =>
- {
- var estateNameValue = await this.Page.GetValueById("Estate_Name");
- estateNameValue.ShouldBe(estateName);
-
- var estateRefValue = await this.Page.GetValueById("Estate_Reference");
- estateRefValue.ShouldNotBeNull();
- estateRefValue.ShouldNotBeEmpty();
- });
- }
-
- public async Task VerifyTheContractDetailsAreInTheList(List<(String, String, Int32)> contractDescriptions)
- {
- await Retry.For(async () =>
- {
- Int32 foundRowCount = 0;
- var rows = await this.Page.Locator("#contractList tr").AllAsync();
-
- rows.Count.ShouldBe(contractDescriptions.Count + 1);
-
- foreach ((String description, String operatorName, Int32 products) in contractDescriptions)
- {
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- // header row so skip
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- if (cellText == description)
- {
- // Compare other fields
- var operatorText = await cells[1].TextContentAsync();
- var productsText = await cells[2].TextContentAsync();
-
- cellText.ShouldBe(description);
- operatorText.ShouldBe(operatorName);
- productsText.ShouldBe(products.ToString());
-
- foundRowCount++;
- break;
- }
- }
- }
- }
-
- foundRowCount.ShouldBe(contractDescriptions.Count);
- }, TimeSpan.FromSeconds(120));
- }
-
- public async Task ClickTheSaveProductButton()
- {
- await this.Page.ClickButtonById("saveProductButton");
- }
-
- public async Task Login(String username, String password)
- {
- await this.Page.FillIn("Input.Username", username);
- await this.Page.FillIn("Input.Password", password);
- await this.Page.ClickButtonByText("Login");
- }
-
- public async Task ClickTheNewOperatorButton()
- {
- await this.Page.ClickButtonById("newOperatorButton");
- }
-
- public async Task ClickTheNewMerchantButton()
- {
- await this.Page.ClickButtonById("newMerchantButton");
- }
-
- public async Task ClickTheEditOperatorButton(String operatorName)
- {
- await this.ClickElementInTable("operatorList", operatorName, "editOperatorLink");
- }
-
- public async Task ClickTheEditMerchantButton(String merchantName)
- {
- await this.ClickElementInTable("merchantList", merchantName, "editMerchantLink");
- }
-
- public async Task ClickTheMakeDepositButtonFor(String merchantName)
- {
- await this.ClickElementInTable("merchantList", merchantName, "makeDepositLink");
- }
-
- public async Task ClickTheAssignOperatorButton()
- {
- await this.Page.ClickButtonById("assignOperatorButton");
- }
-
- public async Task ClickTheAddDeviceButton()
- {
- await this.Page.ClickButtonById("addDeviceButton");
- }
-
- public async Task ClickAddNewContractButton()
- {
- await Retry.For(async () => { await this.Page.ClickButtonById("newContractButton"); });
- }
-
- public async Task ClickAddNewMerchantButton()
- {
- await Retry.For(async () => { await this.Page.ClickButtonById("newMerchantButton"); });
- }
-
- public async Task ClickAddNewProductButton()
- {
- await Retry.For(async () => { await this.Page.ClickButtonById("newContractProductButton"); });
- }
-
- public async Task ClickAddNewTransactionFeeButton()
- {
- await Retry.For(async () => { await this.Page.ClickButtonById("newContractProductTransactionFeeButton"); });
- }
-
- public async Task ClickTheCreateContractButton()
- {
- await this.Page.ClickButtonById("createContractButton");
- }
-
- public async Task VerifyMerchantDetailsAreInTheList(List merchantDetailsList)
- {
- await Retry.For(async () =>
- {
- Int32 foundRowCount = 0;
- var rows = await this.Page.Locator("#merchantList tr").AllAsync();
-
- rows.Count.ShouldBe(merchantDetailsList.Count + 1);
-
- foreach (var merchantDetails in merchantDetailsList)
- {
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- // The merchant name cell contains an avatar with the first letter and the full name
- // So we check if the cell text contains the merchant name
- if (cellText != null && cellText.Contains(merchantDetails.MerchantName))
- {
- cellText.ShouldContain(merchantDetails.MerchantName);
- var settlementScheduleText = await cells[4].TextContentAsync();
- settlementScheduleText.ShouldBe(merchantDetails.SettlementSchedule);
-
- foundRowCount++;
- break;
- }
- }
- }
- }
-
- foundRowCount.ShouldBe(merchantDetailsList.Count);
- }, TimeSpan.FromSeconds(120));
- }
-
- public async Task VerifyOperatorDetailsAreInTheList(String tableId, List<(String, String, String, String)> operatorDetails)
- {
- await Retry.For(async () =>
- {
- Int32 foundRowCount = 0;
- var rows = await this.Page.Locator($"#{tableId} tr").AllAsync();
-
- rows.Count.ShouldBe(operatorDetails.Count + 1);
-
- foreach ((String name, String merchantNumber, String terminalNumber, String isDeleted) in operatorDetails)
- {
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- if (cellText == name)
- {
- cellText.ShouldBe(name);
- var col1Text = await cells[1].TextContentAsync();
- col1Text.ShouldBe(merchantNumber);
- var col2Text = await cells[2].TextContentAsync();
- col2Text.ShouldBe(terminalNumber);
-
- if (!String.IsNullOrEmpty(isDeleted))
- {
- var col3Text = await cells[3].TextContentAsync();
- col3Text.ShouldBe(isDeleted);
- }
-
- foundRowCount++;
- break;
- }
- }
- }
- }
-
- foundRowCount.ShouldBe(operatorDetails.Count);
- }, TimeSpan.FromSeconds(120));
- }
-
- public async Task VerifyContractDetailsAreInTheList(String tableId, List<(String, String)> contractDetails)
- {
- await Retry.For(async () =>
- {
- Int32 foundRowCount = 0;
- var rows = await this.Page.Locator($"#{tableId} tr").AllAsync();
-
- rows.Count.ShouldBe(contractDetails.Count + 1);
-
- foreach ((String contractName, String isDeleted) in contractDetails)
- {
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- if (cellText == contractName)
- {
- cellText.ShouldBe(contractName);
- var col1Text = await cells[1].TextContentAsync();
- col1Text.ShouldBe(isDeleted);
-
- foundRowCount++;
- break;
- }
- }
- }
- }
-
- foundRowCount.ShouldBe(contractDetails.Count);
- }, TimeSpan.FromSeconds(120));
- }
-
- private async Task ClickElementInTable(String tableId, String textToSearchFor, String elementToClickId)
- {
- await Retry.For(async () =>
- {
- var rows = await this.Page.Locator($"#{tableId} tr").AllAsync();
- rows.ShouldNotBeNull();
- rows.Any().ShouldBeTrue();
-
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- // The merchant name cell contains an avatar with the first letter and the full name
- // So we check if the cell text contains the merchant name
- if (cellText != null && cellText.Contains(textToSearchFor))
- {
-
- var link = row.Locator($"#{elementToClickId}");
- await link.ClickAsync();
- return;
- }
- }
- }
-
- throw new Exception($"Could not find row with text '{textToSearchFor}' in table '{tableId}'");
- });
- }
-
- public async Task FillInNewMerchantForm(String merchantName, String settlementSchedule, String addressLine1,
- String town, String region, String country, String contactName, String emailAddress)
- {
- await this.Page.FillIn("MerchantName", merchantName);
- await this.Page.SelectDropDownItemByText("SettlementSchedule", settlementSchedule);
- await this.Page.FillIn("AddressLine1", addressLine1);
- await this.Page.FillIn("Town", town);
- await this.Page.FillIn("Region", region);
- await this.Page.FillIn("PostCode", "12345"); // Default postcode
- await this.Page.FillIn("Country", country);
- await this.Page.FillIn("ContactName", contactName);
- await this.Page.FillIn("EmailAddress", emailAddress);
- await this.Page.FillIn("PhoneNumber", "1234567890"); // Default phone number
- }
-
- public async Task ClickTheCreateMerchantButton()
- {
- await this.Page.ClickButtonById("createMerchantButton");
- }
-
- public async Task ClickTheUpdateMerchantButton()
- {
- //await this.Page.ClickButtonById("createMerchantButton");
- // Click the save button on the respective tab
- await Retry.For(async () =>
- {
- var saveButton = this.Page.Locator("button:has-text('Save')").First;
- await saveButton.ClickAsync();
- }, TimeSpan.FromSeconds(30));
- }
-
- public async Task UpdateMerchantField(String tab, String field, String value)
- {
- // Click the tab first
- await Retry.For(async () =>
- {
- var tabButton = this.Page.Locator($"button:has-text('{tab}')");
- await tabButton.ClickAsync();
- }, TimeSpan.FromSeconds(30));
-
- // Wait a bit for the tab content to load
- await Task.Delay(500);
-
- // Fill in the field based on the tab
- if (tab.Equals("Merchant Details", StringComparison.OrdinalIgnoreCase))
- {
- await this.Page.FillIn(field, value);
- }
- else if (tab.Equals("Address Details", StringComparison.OrdinalIgnoreCase))
- {
- await this.Page.FillIn(field, value);
- }
- else if (tab.Equals("Contact Details", StringComparison.OrdinalIgnoreCase))
- {
- await this.Page.FillIn(field, value);
- }
- }
-
- public async Task FillInDepositForm(String amount, String date, String reference)
- {
- // Note: Make Deposit functionality might not exist in Blazor Server app yet
- // This is a placeholder implementation
- await this.Page.FillInNumeric("Amount", amount);
-
- if (date.Equals("Today", StringComparison.OrdinalIgnoreCase))
- {
- // Use today's date
- await this.Page.FillIn("Date", DateTime.Now.ToString("yyyy-MM-dd"));
- }
- else
- {
- await this.Page.FillIn("Date", date);
- }
-
- await this.Page.FillIn("Reference", reference);
- }
-
- public async Task ClickTheMakeDepositButton()
- {
- await this.Page.ClickButtonById("makeDepositButton");
- }
-
- public async Task ClickTheViewMerchantButton(String merchantName)
- {
- await Retry.For(async () =>
- {
- var rows = await this.Page.Locator("#merchantList tr").AllAsync();
-
- foreach (var row in rows)
- {
- var headers = await row.Locator("th").AllAsync();
- if (headers.Any())
- {
- continue;
- }
-
- var cells = await row.Locator("td").AllAsync();
- if (cells.Count > 0)
- {
- var cellText = await cells[0].TextContentAsync();
- if (cellText != null && cellText.Contains(merchantName))
- {
- // Find and click the View button in this row
- var viewButton = row.Locator("button[title='View']");
- await viewButton.ClickAsync();
- return;
- }
- }
- }
-
- throw new Exception($"Could not find merchant '{merchantName}' in the list");
- }, TimeSpan.FromSeconds(60));
- }
-}
-
-public record MerchantDetails
-{
- public String MerchantName { get; init; }
- public String SettlementSchedule { get; init; }
- public String ContactName { get; init; }
- public String AddressLine1 { get; init; }
- public String Town { get; init; }
-
- public MerchantDetails(String merchantName, String settlementSchedule, String contactName, String addressLine1, String town)
- {
- this.MerchantName = merchantName;
- this.SettlementSchedule = settlementSchedule;
- this.ContactName = contactName;
- this.AddressLine1 = addressLine1;
- this.Town = town;
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/ClientDetails.cs b/EstateManagementUI.BlazorIntegrationTests/Common/ClientDetails.cs
deleted file mode 100644
index 793b03e5..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/ClientDetails.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- public class ClientDetails
- {
- public String ClientId { get; private set; }
- public String ClientSecret { get; private set; }
- public List GrantTypes { get; private set; }
-
- private ClientDetails(String clientId,
- String clientSecret,
- List grantTypes)
- {
- this.ClientId = clientId;
- this.ClientSecret = clientSecret;
- this.GrantTypes = grantTypes;
- }
-
- public static ClientDetails Create(String clientId,
- String clientSecret,
- List grantTypes)
- {
- return new ClientDetails(clientId, clientSecret, grantTypes);
- }
- }
-}
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/DockerHelper.cs b/EstateManagementUI.BlazorIntegrationTests/Common/DockerHelper.cs
deleted file mode 100644
index ed7ec7df..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/DockerHelper.cs
+++ /dev/null
@@ -1,479 +0,0 @@
-using DotNet.Testcontainers.Builders;
-using DotNet.Testcontainers.Containers;
-using DotNet.Testcontainers.Networks;
-using EstateManagementUI.BlazorIntegrationTests.Common;
-using EstateManagementUI.BusinessLogic.PermissionService;
-using EstateManagementUI.BusinessLogic.PermissionService.Database;
-using EstateManagementUI.BusinessLogic.PermissionService.Database.Entities;
-//using EstateManagementUI.Controllers;
-using EventStore.Client;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Internal;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-using SecurityService.Client;
-using Shared.Exceptions;
-using Shared.IntegrationTesting;
-using Shared.IntegrationTesting.TestContainers;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net.Http;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using TransactionProcessor.Client;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- public class DockerHelper : global::Shared.IntegrationTesting.TestContainers.DockerHelper
- {
- #region Fields
-
- public ITransactionProcessorClient TransactionProcessorClient;
-
- public HttpClient HttpClient;
-
- public ISecurityServiceClient SecurityServiceClient;
-
- public EventStoreProjectionManagementClient ProjectionManagementClient;
-
- public HttpClient TestHostHttpClient;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The logger.
- public DockerHelper()
- {
- this.TestingContext = new TestingContext();
- }
-
- #endregion
-
- #region Methods
-
- public Int32 EstateManagementUiPort;
-
- protected String EstateManagementUiContainerName;
-
- private readonly TestingContext TestingContext;
-
- public override void SetupContainerNames() {
- base.SetupContainerNames();
- this.SecurityServiceContainerName = $"identity-server{this.TestId:N}";
- this.EstateManagementUiContainerName = $"estateadministrationui{this.TestId:N}";
- }
-
- private static void AddEntryToHostsFile(String ipaddress,
- String hostname)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- var hostsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), @"drivers\etc\hosts");
- using (StreamWriter w = File.AppendText(hostsPath))
- {
- w.WriteLine($"{ipaddress} {hostname}");
- }
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- DockerHelper.ExecuteBashCommand($"echo {ipaddress} {hostname} | sudo tee -a /etc/hosts");
- }
- }
-
- ///
- /// Executes the bash command.
- ///
- /// The command.
- ///
- private static void ExecuteBashCommand(String command)
- {
- // according to: https://stackoverflow.com/a/15262019/637142
- // thans to this we will pass everything as one command
- command = command.Replace("\"", "\"\"");
-
- var proc = new Process
- {
- StartInfo = new ProcessStartInfo
- {
- FileName = "/bin/bash",
- Arguments = "-c \"" + command + "\"",
- UseShellExecute = false,
- RedirectStandardOutput = true,
- CreateNoWindow = true
- }
- };
- Console.WriteLine(proc.StartInfo.Arguments);
-
- proc.Start();
- proc.WaitForExit();
- }
-
- public override async Task CreateSubscriptions() {
- if (TestConfiguration.IsUIOnlyTestMode)
- return;
-
- List<(String streamName, String groupName, Int32 maxRetries)> subscriptions = new();
- subscriptions.AddRange(MessagingService.IntegrationTesting.Helpers.SubscriptionsHelper.GetSubscriptions());
- subscriptions.AddRange(TransactionProcessor.IntegrationTesting.Helpers.SubscriptionsHelper.GetSubscriptions());
-
- // TODO: Add File Processor Subscriptions
-
- foreach ((String streamName, String groupName, Int32 maxRetries) subscription in subscriptions)
- {
- var x = subscription;
- x.maxRetries = 2;
- await this.CreatePersistentSubscription(x);
- }
- }
-
- protected override List GetRequiredProjections()
- {
- if (TestConfiguration.IsUIOnlyTestMode)
- return new List();
-
- List requiredProjections = new List();
-
- requiredProjections.Add("EstateAggregator.js");
- requiredProjections.Add("MerchantAggregator.js");
- requiredProjections.Add("MerchantBalanceCalculator.js");
- requiredProjections.Add("MerchantBalanceProjection.js");
-
- return requiredProjections;
- }
-
- public override ContainerBuilder SetupTransactionProcessorContainer()
- {
-
- Dictionary variables = new Dictionary();
- variables.Add($"OperatorConfiguration:PataPawaPrePay:Url",$"http://{this.TestHostContainerName}:{DockerPorts.TestHostPort}/api/patapawaprepay");
-
- this.AdditionalVariables.Add(ContainerType.FileProcessor, variables);
-
- return base.SetupTransactionProcessorContainer();
- }
-
- ///
- /// Starts the containers for scenario run.
- ///
- /// Name of the scenario.
- public override async Task StartContainersForScenarioRun(String scenarioName, DockerServices dockerServices)
- {
- await base.StartContainersForScenarioRun(scenarioName, dockerServices);
-
- await this.StartEstateManagementUiContainer(this.TestNetworks, this.SecurityServicePort, DockerPorts.SecurityServiceDockerPort);
-
- // Setup the base address resolvers
- String TransactionProcessorBaseAddressResolver(String api) => $"http://127.0.0.1:{this.TransactionProcessorPort}";
-
- HttpClientHandler clientHandler = new HttpClientHandler
- {
- ServerCertificateCustomValidationCallback = (message,
- certificate2,
- arg3,
- arg4) =>
- {
- return true;
- }
-
- };
- HttpClient httpClient = new HttpClient(clientHandler);
- this.TransactionProcessorClient = new TransactionProcessorClient(TransactionProcessorBaseAddressResolver, httpClient);
- Func securityServiceBaseAddressResolver = api => $"https://127.0.0.1:{this.SecurityServicePort}";
- this.SecurityServiceClient = new SecurityServiceClient(securityServiceBaseAddressResolver, httpClient);
- this.TestHostHttpClient = new HttpClient(clientHandler);
- this.TestHostHttpClient.BaseAddress = new Uri($"http://127.0.0.1:{this.TestHostServicePort}");
- this.ProjectionManagementClient = new EventStoreProjectionManagementClient(ConfigureEventStoreSettings());
- }
-
- private async Task StartEstateManagementUiContainer(List networkServices,
- Int32 securityServiceContainerPort,
- Int32 securityServiceLocalPort)
- {
- TraceX("About to Start Estate Management UI Container");
-
- var environmentVariables = this.GetCommonEnvironmentVariables();
-
- environmentVariables.Remove("AppSettings:ClientId");
- environmentVariables.Remove("AppSettings:ClientSecret");
-
- // Blazor Server uses Authentication: prefix for OIDC settings
- environmentVariables.Add("Authentication:Authority",$"https://{this.SecurityServiceContainerName}:0"); // The port is set to 0 to stop defaulting to 443
- environmentVariables.Add("Authentication:ClientId","estateUIClient");
- environmentVariables.Add("Authentication:ClientSecret","Secret1");
-
- // Backend API client credentials
- environmentVariables.Add("ApiClient:ClientId", "serviceClient");
- environmentVariables.Add("ApiClient:ClientSecret", "Secret1");
- environmentVariables.Add("ApiClient:Scope", "estateManagement transactionProcessor");
-
- // Other settings
- environmentVariables.Add("AppSettings:SecurityServiceLocalPort",$"{securityServiceLocalPort}");
- environmentVariables.Add("AppSettings:SecurityServicePort",$"{securityServiceContainerPort}");
- environmentVariables.Add("AppSettings:HttpClientIgnoreCertificateErrors",$"true");
- environmentVariables.Add("AppSettings:IsIntegrationTest","true");
- environmentVariables.Add("ASPNETCORE_ENVIRONMENT","Development");
- environmentVariables.Add("urls","https://*:5004");
- environmentVariables.Add($"DataReloadConfig:DefaultInSeconds","1");
- environmentVariables.Add("ConnectionStrings:TransactionProcessorReadModel", this.SetConnectionString( "TransactionProcessorReadModel", this.UseSecureSqlServerDatabase));
-
- TraceX("About to Built Estate Management UI Blazor Container");
- ContainerBuilder containerBuilder = new ContainerBuilder()
- .WithName(this.EstateManagementUiContainerName)
- .WithImage("estatemanagementuiblazorserver")
- .WithEnvironment(environmentVariables)
- .MountHostFolder(this.DockerPlatform, this.HostTraceFolder)
- //.UseNetwork(networkServices.ToArray())
- .WithPortBinding(5004);
- //.MountHostFolder(this.DockerPlatform, this.HostTraceFolder)
- //.SetDockerCredentials(this.DockerCredentials);
- TraceX("About to Call .Start()");
- foreach (INetwork networkService in networkServices) {
- containerBuilder = containerBuilder.WithNetwork(networkService);
- }
-
- IContainer? builtContainer = containerBuilder.Build();
-
- try{
-
-
- await builtContainer.StartAsync();
- //builtContainer.WaitForPort("5004/tcp", 30000);
- this.EstateManagementUiPort = builtContainer.GetMappedPublicPort($"5004");
-
- await Task.Delay(5000);
-
- TraceX("Estate Management UI Started");
-
- /*HttpClientHandler handler = new HttpClientHandler();
- handler.ServerCertificateCustomValidationCallback =
- HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
- // TODO: Refactor this code once it works...
- using (HttpClient client = new HttpClient(handler)) {
- HttpRequestMessage createRolesRequest = new (HttpMethod.Post,
- $"https://localhost:{this.EstateManagementUiPort}/api/Permissions/createRoles");
-
- List roles = ["Administrator"];
-
- createRolesRequest.Content = new StringContent(JsonConvert.SerializeObject(roles), Encoding.UTF8,
- "application/json");
-
- var response = await client.SendAsync(createRolesRequest, CancellationToken.None);
-
- if (response.IsSuccessStatusCode == false) {
- TraceX($"createRolesRequest failed [{response.StatusCode}]");
- }
- TraceX($"Create Role Response is [{response.StatusCode}]");
-
- HttpRequestMessage addUserToRoleRequest = new(HttpMethod.Post,
- $"https://localhost:{this.EstateManagementUiPort}/api/Permissions/addUserToRole");
- List userRolesList = new List {
- new AddUserToRole { UserName = "estateuser@testestate1.co.uk", RoleName = "Administrator" }
- };
-
- addUserToRoleRequest.Content = new StringContent(JsonConvert.SerializeObject(userRolesList), Encoding.UTF8,
- "application/json");
-
- response = await client.SendAsync(addUserToRoleRequest, CancellationToken.None);
- if (response.IsSuccessStatusCode == false)
- {
- TraceX($"addUserToRoleRequest failed [{response.StatusCode}]");
- }
-
- TraceX($"Add User to Role Response is [{response.StatusCode}]");
-
- HttpRequestMessage getRolePermissionsRequest = new(HttpMethod.Get,
- $"https://localhost:{this.EstateManagementUiPort}/api/Permissions/getRolePermissions?roleName=Administrator");
-
- response = await client.SendAsync(getRolePermissionsRequest, CancellationToken.None);
-
- if (response.IsSuccessStatusCode == false)
- {
- TraceX($"getRolePermissionsRequest failed [{response.StatusCode}]");
- }
-
- var x = await response.Content.ReadAsStringAsync(CancellationToken.None);
-
- RolePermissionsObject rolePermissionsObject = JsonConvert.DeserializeObject(x);
-
- List<(int, string, int, string, bool)> Permissions = new();
- foreach (ApplicationSection applicationSection in rolePermissionsObject.ApplicationSections)
- {
- List<(Function, bool)> functionAccess = rolePermissionsObject.PermissionsList.Where(p =>
- p.ApplicationSection.ApplicationSectionId == applicationSection.ApplicationSectionId).Select(x => (x.Function, x.HasAccess)).ToList();
-
- foreach ((Function, bool) function in functionAccess)
- {
- Permissions.Add((applicationSection.ApplicationSectionId, applicationSection.Name, function.Item1.FunctionId, function.Item1.Name, function.Item2));
- }
- }
-
- List<(int, int, bool)> newPermissions = Permissions.Select(p => (p.Item1, p.Item3, true)).ToList();
-
- HttpRequestMessage addRolePermissionsRequest = new(HttpMethod.Post,
- $"https://localhost:{this.EstateManagementUiPort}/api/Permissions/addRolePermissions");
-
- List rolePermissions = new() {
- new RolePermissions { NewPermissions = newPermissions, RoleName = "Administrator" }
- };
-
- addRolePermissionsRequest.Content = new StringContent(JsonConvert.SerializeObject(rolePermissions), Encoding.UTF8,
- "application/json");
-
- response = await client.SendAsync(addRolePermissionsRequest, CancellationToken.None);
- if (response.IsSuccessStatusCode == false)
- {
- TraceX($"addRolePermissionsRequest failed [{response.StatusCode}]");
- }
- }*/
- }
- catch(Exception ex){
- TraceX(ex.GetCombinedExceptionMessages());
-
- }
-
- TraceX("About to attach networkServices");
- //foreach (INetwork networkService in networkServices)
- //{
- // //networkService..Attach(builtContainer, false);
- // builtContainer.
- //}
-
- //Trace("About to get port");
- //// Do a health check here
- //var x = builtContainer.ToHostExposedEndpoint($"5004/tcp");
- //if (x == null){
- // Trace("x is null");
- //}
-
-
-
-
- this.Containers.Add(((DockerServices)1024, builtContainer));
- //await Retry.For(async () =>
- //{
- // String healthCheck =
- // await this.HealthCheckClient.PerformHealthCheck("http", "127.0.0.1", this.EstateManagementUiPort, CancellationToken.None);
-
- // var result = JsonConvert.DeserializeObject(healthCheck);
- // result.Status.ShouldBe(HealthCheckStatus.Healthy.ToString(), $"Details {healthCheck}");
- //});
-
- return builtContainer;
- }
-
- public override ContainerBuilder SetupSecurityServiceContainer()
- {
- this.TraceX("About to Start Security Container");
-
- Retry.For(() => {
- DockerHelper.AddEntryToHostsFile("127.0.0.1", SecurityServiceContainerName);
- return Task.CompletedTask;
- });
-
- Retry.For(() => {
- DockerHelper.AddEntryToHostsFile("localhost", SecurityServiceContainerName);
- return Task.CompletedTask;
- });
-
-
-
- var environmentVariables = this.GetCommonEnvironmentVariables();
- environmentVariables.Add($"ServiceOptions:PublicOrigin",$"https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}");
- environmentVariables.Add($"ServiceOptions:IssuerUrl",$"https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}");
- environmentVariables.Add("ASPNETCORE_ENVIRONMENT",$"IntegrationTest");
- environmentVariables.Add($"urls",$"https://*:{DockerPorts.SecurityServiceDockerPort}");
-
- environmentVariables.Add($"ServiceOptions:PasswordOptions:RequiredLength","6");
- environmentVariables.Add($"ServiceOptions:PasswordOptions:RequireDigit","false");
- environmentVariables.Add($"ServiceOptions:PasswordOptions:RequireUpperCase","false");
- environmentVariables.Add($"ServiceOptions:UserOptions:RequireUniqueEmail","false");
- environmentVariables.Add($"ServiceOptions:SignInOptions:RequireConfirmedEmail","false");
-
- environmentVariables.Add("ConnectionStrings:PersistedGrantDbContext",this.SetConnectionString($"PersistedGrantStore-{this.TestId}", this.UseSecureSqlServerDatabase));
- environmentVariables.Add("ConnectionStrings:ConfigurationDbContext", this.SetConnectionString($"Configuration-{this.TestId}", this.UseSecureSqlServerDatabase));
- environmentVariables.Add("ConnectionStrings:AuthenticationDbContext",this.SetConnectionString($"Authentication-{this.TestId}", this.UseSecureSqlServerDatabase));
-
- environmentVariables.Add("Logging:LogLevel:Microsoft","Information");
- environmentVariables.Add("Logging:LogLevel:Default","Information");
- environmentVariables.Add("Logging:EventLog:LogLevel:Default","None");
-
- var imageDetailsResult = this.GetImageDetails(ContainerType.SecurityService);
-
- ContainerBuilder securityServiceContainer = new ContainerBuilder()
- .WithName(this.SecurityServiceContainerName)
- .WithEnvironment(environmentVariables)
- .WithImage(imageDetailsResult.Data.imageName)
- .MountHostFolder(this.DockerPlatform, this.HostTraceFolder)
- .WithPortBinding(DockerPorts.SecurityServiceDockerPort);
- //.MountHostFolder(this.DockerPlatform, this.HostTraceFolder)
- //.SetDockerCredentials(this.DockerCredentials);
-
-
- // Now build and return the container
- return securityServiceContainer;
- }
-
- ///
- /// Stops the containers for scenario run.
- ///
- public override async Task StopContainersForScenarioRun(DockerServices sharedDockerServices)
- {
- await this.RemoveEstateReadModel().ConfigureAwait(false);
-
- await base.StopContainersForScenarioRun(sharedDockerServices);
- }
-
- private async Task RemoveEstateReadModel()
- {
- //List estateIdList = this.TestingContext.GetAllEstateIds();
-
- //foreach (Guid estateId in estateIdList)
- //{
- // String databaseName = $"EstateReportingReadModel{estateId}";
-
- // // Build the connection string (to master)
- // String connectionString = Setup.GetLocalConnectionString(databaseName);
- // await Retry.For(async () =>
- // {
- // EstateReportingSqlServerContext context = new EstateReportingSqlServerContext(connectionString);
- // await context.Database.EnsureDeletedAsync(CancellationToken.None);
- // },
- // retryFor: TimeSpan.FromMinutes(2),
- // retryInterval: TimeSpan.FromSeconds(30));
- //}
- }
-
- private async Task CreatePermissionsRepository(String dbConnString, CancellationToken cancellationToken) {
- var optionsBuilder = new DbContextOptionsBuilder();
- optionsBuilder.UseSqlite(dbConnString); // Configure for your database provider
-
- var serviceProvider = new ServiceCollection()
- .AddLogging(config => config.AddConsole()) // Add logging if needed
- .BuildServiceProvider();
-
- // Create the DbContextFactory instance
- var contextFactory = new DbContextFactory(serviceProvider, optionsBuilder.Options, new DbContextFactorySource());
-
- //var ctx = await contextFactory.CreateDbContextAsync(cancellationToken);
-
- return new PermissionsRepository(contextFactory);
- }
-
- public void TraceX(String msg) {
- Trace(msg);
- Console.WriteLine(msg);
- }
-
- #endregion
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/GenericSteps.cs b/EstateManagementUI.BlazorIntegrationTests/Common/GenericSteps.cs
deleted file mode 100644
index ed8deb05..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/GenericSteps.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using NLog;
-using Reqnroll;
-using Shared.IntegrationTesting;
-using Shared.Logger;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- [Binding]
- [Scope(Tag = "base")]
- public class GenericSteps
- {
- private readonly ScenarioContext ScenarioContext;
-
- private readonly TestingContext TestingContext;
-
- public GenericSteps(ScenarioContext scenarioContext,
- TestingContext testingContext)
- {
- this.ScenarioContext = scenarioContext;
- this.TestingContext = testingContext;
- }
-
- [BeforeScenario(Order = 1)]
- public async Task StartSystem()
- {
- // Initialise a logger
- String scenarioName = this.ScenarioContext.ScenarioInfo.Title.Replace(" ", "");
- NlogLogger logger = new NlogLogger();
- logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName);
- LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly);
-
- DockerServices dockerServices = DockerServices.CallbackHandler | DockerServices.EventStore |
- DockerServices.FileProcessor | DockerServices.MessagingService | DockerServices.SecurityService |
- DockerServices.TestHost | DockerServices.SqlServer | DockerServices.TransactionProcessor |
- DockerServices.TransactionProcessorAcl;
- dockerServices = DockerServices.None;
-
- this.TestingContext.DockerHelper = new DockerHelper();
- this.TestingContext.DockerHelper.Logger = logger;
- this.TestingContext.Logger = logger;
- this.TestingContext.DockerHelper.RequiredDockerServices = dockerServices;
- this.TestingContext.Logger.LogInformation("About to Start Global Setup");
-
- await Setup.GlobalSetup(this.TestingContext.DockerHelper);
-
- this.TestingContext.DockerHelper.DockerCredentials = Setup.DockerCredentials;
- this.TestingContext.DockerHelper.SqlCredentials = Setup.SqlCredentials;
- this.TestingContext.DockerHelper.SqlServerContainerName = "sharedsqlserver";
-
- this.TestingContext.Logger = logger;
- this.TestingContext.Logger.LogInformation("About to Start Containers for Scenario Run");
- await this.TestingContext.DockerHelper.StartContainersForScenarioRun(scenarioName, dockerServices).ConfigureAwait(false);
- this.TestingContext.Logger.LogInformation("Containers for Scenario Run Started");
- }
-
- [AfterScenario(Order = 1)]
- public async Task StopSystem(){
- DockerServices sharedDockerServices = DockerServices.None;
- await this.TestingContext.DockerHelper.StopContainersForScenarioRun(sharedDockerServices).ConfigureAwait(false);
- }
- }
-}
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/Hooks.cs b/EstateManagementUI.BlazorIntegrationTests/Common/Hooks.cs
deleted file mode 100644
index e14cdf10..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/Hooks.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-using Microsoft.Playwright;
-using Reqnroll;
-using Reqnroll.BoDi;
-using Shared.IntegrationTesting;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Common
-{
- [Binding]
- public class Hooks
- {
- private readonly IObjectContainer ObjectContainer;
- private ScenarioContext ScenarioContext;
- private static IPlaywright? playwright;
- private static IBrowser? browser;
-
- public Hooks(IObjectContainer objectContainer)
- {
- this.ObjectContainer = objectContainer;
- }
-
- [BeforeTestRun]
- public static async Task BeforeTestRun()
- {
- // Install Playwright browsers if needed
- var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
- if (exitCode != 0)
- {
- throw new Exception($"Playwright installation failed with exit code {exitCode}");
- }
-
- // Initialize Playwright
- playwright = await Playwright.CreateAsync();
- }
-
- [BeforeScenario(Order = 0)]
- public async Task BeforeScenario(ScenarioContext scenarioContext)
- {
- this.ScenarioContext = scenarioContext;
- String scenarioName = scenarioContext.ScenarioInfo.Title.Replace(" ", "");
-
- var page = await this.CreateBrowserPage();
-
- // Register the page for this scenario
- scenarioContext.ScenarioContainer.RegisterInstanceAs(page, scenarioName);
- }
-
- [AfterScenario(Order = 0)]
- public async Task AfterScenario()
- {
- String scenarioName = this.ScenarioContext.ScenarioInfo.Title.Replace(" ", "");
- var page = this.ScenarioContext.ScenarioContainer.Resolve(scenarioName);
-
- if (page != null)
- {
- // Take screenshot on failure
- if (this.ScenarioContext.TestError != null)
- {
- var screenshotPath = $"screenshot-{scenarioName}-{DateTime.Now:yyyyMMddHHmmss}.png";
- await page.ScreenshotAsync(new PageScreenshotOptions { Path = screenshotPath, FullPage = true });
- Console.WriteLine($"Screenshot saved to: {screenshotPath}");
- }
-
- await page.CloseAsync();
- }
- }
-
- [AfterTestRun]
- public static async Task AfterTestRun()
- {
- if (browser != null)
- {
- await browser.CloseAsync();
- browser = null;
- }
-
- if (playwright != null)
- {
- playwright.Dispose();
- playwright = null;
- }
- }
-
- private async Task CreateBrowserPage()
- {
- String? browserType = Environment.GetEnvironmentVariable("Browser");
- String? isCi = Environment.GetEnvironmentVariable("IsCI");
-
- if (browser == null)
- {
- switch (browserType)
- {
- case "Firefox":
- browser = await playwright!.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
- {
- Headless = String.Compare(isCi, Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase) == 0,
- Args = new[] { "--ignore-certificate-errors" }
- });
- break;
- case "WebKit":
- browser = await playwright!.Webkit.LaunchAsync(new BrowserTypeLaunchOptions
- {
- Headless = String.Compare(isCi, Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase) == 0,
- Args = new[] { "--ignore-certificate-errors" }
- });
- break;
- case null:
- case "Chrome":
- default:
- browser = await playwright!.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
- {
- Headless = String.Compare(isCi, Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase) == 0,
- Args = new[]
- {
- "--ignore-certificate-errors",
- "--no-sandbox",
- "--disable-dev-shm-usage",
- "--disable-gpu",
- "--disable-extensions"
- }
- });
- break;
- }
- }
-
- var context = await browser.NewContextAsync(new BrowserNewContextOptions
- {
- IgnoreHTTPSErrors = true,
- ViewportSize = new ViewportSize { Width = 1920, Height = 1080 }
- });
-
- var page = await context.NewPageAsync();
-
- return page;
- }
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/PlaywrightExtensions.cs b/EstateManagementUI.BlazorIntegrationTests/Common/PlaywrightExtensions.cs
deleted file mode 100644
index 5de6971a..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/PlaywrightExtensions.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-using Microsoft.Playwright;
-using Shared.IntegrationTesting;
-using Shouldly;
-using System;
-using System.Threading.Tasks;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Common
-{
- public static class PlaywrightExtensions
- {
- public static async Task FillIn(this IPage page,
- String selector,
- String value,
- Boolean clearExistingText = false,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"[name='{selector}']");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
-
- if (clearExistingText)
- {
- await locator.ClearAsync();
- }
-
- if (!String.IsNullOrEmpty(value))
- {
- await locator.FillAsync(value);
- }
- }, timeout);
- }
-
- public static async Task FillInNumeric(this IPage page,
- String selector,
- String value,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"[name='{selector}']");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
-
- await locator.ClickAsync();
- await page.Keyboard.PressAsync("Control+A");
- await page.Keyboard.PressAsync("Delete");
- await locator.FillAsync(value);
- }, timeout);
- }
-
- public static async Task FillInById(this IPage page,
- String elementId,
- String value,
- Boolean clearExistingText = false,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"#{elementId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
-
- if (clearExistingText)
- {
- await locator.ClearAsync();
- }
-
- if (!String.IsNullOrEmpty(value))
- {
- await locator.FillAsync(value);
- }
- }, timeout);
- }
-
- public static async Task FindButtonById(this IPage page,
- String buttonId,
- TimeSpan? timeout = null)
- {
- ILocator locator = null;
- await Retry.For(async () =>
- {
- locator = page.Locator($"#{buttonId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- locator.ShouldNotBeNull();
- }, timeout);
- return locator;
- }
-
- public static async Task FindButtonByText(this IPage page,
- String buttonText,
- TimeSpan? timeout = null)
- {
- ILocator locator = null;
- await Retry.For(async () =>
- {
- locator = page.GetByRole(AriaRole.Button, new() { Name = buttonText });
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- locator.ShouldNotBeNull();
- }, timeout);
- return locator;
- }
-
- public static async Task ClickButtonById(this IPage page, String buttonId)
- {
- var locator = await page.FindButtonById(buttonId);
- await locator.ClickAsync();
- }
-
- public static async Task ClickButtonByText(this IPage page, String buttonText)
- {
- var locator = await page.FindButtonByText(buttonText);
- await locator.ClickAsync();
- }
-
- public static async Task ClickLinkByText(this IPage page, String linkText, TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.GetByRole(AriaRole.Link, new() { Name = linkText });
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- await locator.ClickAsync();
- }, timeout);
- }
-
- public static async Task SelectDropDownByIdAndText(this IPage page,
- String dropDownId,
- String selectionText,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"#{dropDownId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- await locator.SelectOptionAsync(new[] { selectionText });
- }, timeout);
- }
-
- public static async Task SelectDropDownByIdAndValue(this IPage page,
- String dropDownId,
- String selectionValue,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"#{dropDownId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- await locator.SelectOptionAsync(new[] { selectionValue });
- }, timeout);
- }
-
- public static async Task SelectDropDownItemByText(this IPage page,
- String dropDownName,
- String selectionText,
- TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator($"[name='{dropDownName}']");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- await locator.SelectOptionAsync(new SelectOptionValue { Label = selectionText });
- }, timeout);
- }
-
- public static async Task GetDropDownItemText(this IPage page, String dropDownName, TimeSpan? timeout = null)
- {
- String selectedText = null;
- await Retry.For(async () =>
- {
- var locator = page.Locator($"[name='{dropDownName}']");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- var selectedValue = await locator.InputValueAsync();
-
- // Get the text of the selected option
- var selectedOption = locator.Locator($"option[value='{selectedValue}']");
- selectedText = await selectedOption.TextContentAsync();
- }, timeout);
- return selectedText;
- }
-
- public static async Task GetTextById(this IPage page, String elementId, TimeSpan? timeout = null)
- {
- String text = null;
- await Retry.For(async () =>
- {
- var locator = page.Locator($"#{elementId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- text = await locator.TextContentAsync();
- }, timeout);
- return text;
- }
-
- public static async Task GetValueById(this IPage page, String elementId, TimeSpan? timeout = null)
- {
- String value = null;
- await Retry.For(async () =>
- {
- var locator = page.Locator($"#{elementId}");
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- value = await locator.InputValueAsync();
- }, timeout);
- return value;
- }
-
- public static async Task WaitForElement(this IPage page, String selector, TimeSpan? timeout = null)
- {
- await Retry.For(async () =>
- {
- var locator = page.Locator(selector);
- await locator.WaitForAsync(new LocatorWaitForOptions { State = WaitForSelectorState.Visible, Timeout = 30000 });
- }, timeout);
- }
-
- public static async Task IsElementVisible(this IPage page, String selector)
- {
- try
- {
- var locator = page.Locator(selector);
- return await locator.IsVisibleAsync();
- }
- catch
- {
- return false;
- }
- }
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/Setup.cs b/EstateManagementUI.BlazorIntegrationTests/Common/Setup.cs
deleted file mode 100644
index b6899766..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/Setup.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using Ductus.FluentDocker.Services;
-using Ductus.FluentDocker.Services.Extensions;
-using Reqnroll;
-using Shouldly;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- [Binding]
- public class Setup
- {
- public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!");
- public static (String url, String username, String password) DockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland");
-
- public static async Task GlobalSetup(DockerHelper dockerHelper)
- {
- ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(1);
- }
- }
-}
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/SharedSteps.cs b/EstateManagementUI.BlazorIntegrationTests/Common/SharedSteps.cs
deleted file mode 100644
index b83590e9..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/SharedSteps.cs
+++ /dev/null
@@ -1,432 +0,0 @@
-using JasperFx.Core;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
-using Reqnroll;
-using Reqnroll.BoDi;
-using SecurityService.DataTransferObjects;
-using SecurityService.DataTransferObjects.Requests;
-using SecurityService.DataTransferObjects.Responses;
-using SecurityService.IntegrationTesting.Helpers;
-using Shared.IntegrationTesting;
-using Shouldly;
-using SimpleResults;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using EstateManagementUI.BlazorIntegrationTests.Common;
-using TransactionProcessor.Database.Contexts;
-using TransactionProcessor.DataTransferObjects.Requests.Contract;
-using TransactionProcessor.DataTransferObjects.Requests.Estate;
-using TransactionProcessor.DataTransferObjects.Requests.Merchant;
-using TransactionProcessor.DataTransferObjects.Requests.Operator;
-using TransactionProcessor.DataTransferObjects.Responses.Contract;
-using TransactionProcessor.DataTransferObjects.Responses.Estate;
-using TransactionProcessor.DataTransferObjects.Responses.Merchant;
-using TransactionProcessor.IntegrationTesting.Helpers;
-using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
-using AssignOperatorRequest = TransactionProcessor.DataTransferObjects.Requests.Estate.AssignOperatorRequest;
-using ReqnrollTableHelper = Shared.IntegrationTesting.ReqnrollTableHelper;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- [Binding]
- [Scope(Tag = "shared")]
- public class SharedSteps
- {
- #region Fields
-
-
-
- private readonly SecurityServiceSteps SecurityServiceSteps;
-
- private readonly TestingContext TestingContext;
-
- //private readonly IWebDriver WebDriver;
-
- private readonly TransactionProcessorSteps TransactionProcessorSteps;
-
- //private readonly EstateMan EstateAdministrationUiSteps;
-
- #endregion
-
- #region Constructors
-
- public SharedSteps(ScenarioContext scenarioContext, TestingContext testingContext, IObjectContainer container)
- {
- //IWebDriver? webDriver = scenarioContext.ScenarioContainer.Resolve(scenarioContext.ScenarioInfo.Title.Replace(" ", ""));
-
- this.TestingContext = testingContext;
- this.SecurityServiceSteps = new SecurityServiceSteps(this.TestingContext.DockerHelper.SecurityServiceClient);
- this.TransactionProcessorSteps = new TransactionProcessorSteps(this.TestingContext.DockerHelper.TransactionProcessorClient, this.TestingContext.DockerHelper.TestHostHttpClient, this.TestingContext.DockerHelper.ProjectionManagementClient);
- //this.EstateAdministrationUiSteps = new EstateAdministrationUISteps(webDriver, this.TestingContext.DockerHelper.EstateManagementUiPort);
- }
-
- #endregion
-
- #region Methods
-
-
-
- [Given(@"I create the following api resources")]
- public async Task GivenICreateTheFollowingApiResources(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- List requests = table.Rows.ToCreateApiResourceRequests();
- foreach (CreateApiResourceRequest createApiResourceRequest in requests)
- {
- this.TestingContext.ApiResources.Add(createApiResourceRequest.Name);
- }
- return;
- }
-
- List requests2 = table.Rows.ToCreateApiResourceRequests();
- await this.SecurityServiceSteps.GivenTheFollowingApiResourcesExist(requests2);
-
- foreach (CreateApiResourceRequest createApiResourceRequest in requests2)
- {
- this.TestingContext.ApiResources.Add(createApiResourceRequest.Name);
- }
- }
-
- [Given(@"I create the following api scopes")]
- public async Task GivenICreateTheFollowingApiScopes(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- return;
- }
-
- List requests = table.Rows.ToCreateApiScopeRequests();
- await this.SecurityServiceSteps.GivenICreateTheFollowingApiScopes(requests);
- }
-
- [Given(@"I create the following clients")]
- public async Task GivenICreateTheFollowingClients(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- // Just track client details locally
- List requests = table.Rows.ToCreateClientRequests(Guid.Empty, 5004);
- foreach (var request in requests)
- {
- this.TestingContext.AddClientDetails(request.ClientId, "Secret1", request.AllowedGrantTypes);
- }
- return;
- }
-
- List requests2 = table.Rows.ToCreateClientRequests(this.TestingContext.DockerHelper.TestId, this.TestingContext.DockerHelper.EstateManagementUiPort);
- List<(String clientId, String secret, List allowedGrantTypes)> clients = await this.SecurityServiceSteps.GivenTheFollowingClientsExist(requests2);
- foreach ((String clientId, String secret, List allowedGrantTypes) client in clients)
- {
- this.TestingContext.AddClientDetails(client.clientId, client.secret, client.allowedGrantTypes);
- }
- }
-
- [Given(@"I create the following identity resources")]
- public async Task GivenICreateTheFollowingIdentityResources(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- foreach (DataTableRow tableRow in table.Rows)
- {
- String name = ReqnrollTableHelper.GetStringRowValue(tableRow, "Name");
- this.TestingContext.IdentityResources.Add(name);
- }
- return;
- }
-
- foreach (DataTableRow tableRow in table.Rows)
- {
- // Get the scopes
- String userClaims = ReqnrollTableHelper.GetStringRowValue(tableRow, "UserClaims");
-
- CreateIdentityResourceRequest createIdentityResourceRequest = new CreateIdentityResourceRequest
- {
- Name = ReqnrollTableHelper.GetStringRowValue(tableRow, "Name"),
- Claims = String.IsNullOrEmpty(userClaims) ? null : userClaims.Split(",").ToList(),
- Description = ReqnrollTableHelper.GetStringRowValue(tableRow, "Description"),
- DisplayName = ReqnrollTableHelper.GetStringRowValue(tableRow, "DisplayName")
- };
-
- await this.CreateIdentityResource(createIdentityResourceRequest, CancellationToken.None).ConfigureAwait(false);
- }
- }
-
- [Given(@"I create the following roles")]
- public async Task GivenICreateTheFollowingRoles(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- List requests = table.Rows.ToCreateRoleRequests();
- foreach (var request in requests)
- {
- this.TestingContext.Roles.Add(request.RoleName, Guid.NewGuid());
- }
- return;
- }
-
- List requests2 = table.Rows.ToCreateRoleRequests();
- List<(String, Guid)> responses = await this.SecurityServiceSteps.GivenICreateTheFollowingRoles(requests2, CancellationToken.None);
-
- foreach ((String, Guid) response in responses)
- {
- this.TestingContext.Roles.Add(response.Item1, response.Item2);
- }
- }
-
- [Given(@"I create the following users")]
- public async Task GivenICreateTheFollowingUsers(DataTable table)
- {
- List requests = table.Rows.ToCreateUserRequests();
-
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- foreach (CreateUserRequest request in requests)
- {
- this.TestingContext.Users.Add(request.EmailAddress, Guid.NewGuid());
- }
- return;
- }
-
- foreach (CreateUserRequest createUserRequest in requests)
- {
- createUserRequest.EmailAddress = createUserRequest.EmailAddress.Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N"));
- //createUserRequest.Roles.ForEach(r => r.Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N")));
- List newRoles = new List();
- foreach (String role in createUserRequest.Roles)
- {
- newRoles.Add(role.Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N")));
- }
- createUserRequest.Roles = newRoles;
- }
-
- List<(String, Guid)> results = await this.SecurityServiceSteps.GivenICreateTheFollowingUsers(requests, CancellationToken.None);
-
- foreach ((String, Guid) response in results)
- {
- this.TestingContext.Users.Add(response.Item1, response.Item2);
- }
- }
-
- [Given(@"I have a token to access the estate management resource")]
- public async Task GivenIHaveATokenToAccessTheEstateManagementResource(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- // Set a dummy token since authentication is bypassed
- this.TestingContext.AccessToken = "test-mode-token";
- return;
- }
-
- DataTableRow firstRow = table.Rows.First();
- String clientId = ReqnrollTableHelper.GetStringRowValue(firstRow, "ClientId").Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N"));
- ClientDetails clientDetails = this.TestingContext.GetClientDetails(clientId);
-
- this.TestingContext.AccessToken = await this.SecurityServiceSteps.GetClientToken(clientDetails.ClientId, clientDetails.ClientSecret, CancellationToken.None);
- }
-
- [Given(@"I have created the following estates")]
- public async Task GivenIHaveCreatedTheFollowingEstates(DataTable table)
- {
- List requests = table.Rows.ToCreateEstateRequests();
-
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- // Use default estate ID from TestDataStore
- foreach (var request in requests)
- {
- Guid estateId = Guid.Parse("11111111-1111-1111-1111-111111111111");
- this.TestingContext.AddEstateDetails(estateId, request.EstateName, request.EstateName);
- this.TestingContext.Logger.LogInformation($"Estate {request.EstateName} registered with Id {estateId} (UI-only test mode)");
- }
- return;
- }
-
- List verifiedEstates = await this.TransactionProcessorSteps.WhenICreateTheFollowingEstatesX(this.TestingContext.AccessToken, requests);
-
- foreach (EstateResponse verifiedEstate in verifiedEstates)
- {
- this.TestingContext.AddEstateDetails(verifiedEstate.EstateId, verifiedEstate.EstateName, verifiedEstate.EstateReference);
- this.TestingContext.Logger.LogInformation($"Estate {verifiedEstate.EstateName} created with Id {verifiedEstate.EstateId}");
- }
- }
-
- [Given(@"I have created the following operators")]
- public async Task GivenIHaveCreatedTheFollowingOperators(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- // Operators are pre-populated in TestDataStore
- this.TestingContext.Logger.LogInformation("Operators setup skipped (UI-only test mode - using TestDataStore)");
- return;
- }
-
- List<(EstateDetails estate, CreateOperatorRequest request)> requests = table.Rows.ToCreateOperatorRequests(this.TestingContext.Estates);
-
- List<(Guid, EstateOperatorResponse)> results = await this.TransactionProcessorSteps.WhenICreateTheFollowingOperators(this.TestingContext.AccessToken, requests);
-
- foreach ((Guid, EstateOperatorResponse) result in results)
- {
- this.TestingContext.Logger.LogInformation($"Operator {result.Item2.Name} created with Id {result.Item2.OperatorId} for Estate {result.Item1}");
- }
- }
-
- [Given("I have assigned the following operators to the estates")]
- public async Task GivenIHaveAssignedTheFollowingOperatorsToTheEstates(DataTable dataTable)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- this.TestingContext.Logger.LogInformation("Operator assignment skipped (UI-only test mode)");
- return;
- }
-
- List<(EstateDetails estate, AssignOperatorRequest request)> requests = dataTable.Rows.ToAssignOperatorToEstateRequests(this.TestingContext.Estates);
-
- await this.TransactionProcessorSteps.GivenIHaveAssignedTheFollowingOperatorsToTheEstates(this.TestingContext.AccessToken, requests);
-
- // TODO Verify
- }
-
-
-
- [When(@"I add the following devices to the merchant")]
- public async Task WhenIAddTheFollowingDevicesToTheMerchant(DataTable table)
- {
- if (TestConfiguration.IsTestMode)
- return;
- List<(EstateDetails, Guid, AddMerchantDeviceRequest)> requests = table.Rows.ToAddMerchantDeviceRequests(this.TestingContext.Estates);
-
- List<(EstateDetails, MerchantResponse, String)> results = await this.TransactionProcessorSteps.GivenIHaveAssignedTheFollowingDevicesToTheMerchants(this.TestingContext.AccessToken, requests);
- foreach ((EstateDetails, MerchantResponse, String) result in results)
- {
- this.TestingContext.Logger.LogInformation($"Device {result.Item3} assigned to Merchant {result.Item2.MerchantName} Estate {result.Item1.EstateName}");
- }
- }
-
- [When(@"I assign the following operator to the merchants")]
- public async Task WhenIAssignTheFollowingOperatorToTheMerchants(DataTable table)
- {
- if (TestConfiguration.IsTestMode)
- return;
- List<(EstateDetails, Guid, TransactionProcessor.DataTransferObjects.Requests.Merchant.AssignOperatorRequest)> requests = table.Rows.ToAssignOperatorRequests(this.TestingContext.Estates);
-
- List<(EstateDetails, TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantOperatorResponse)> results = await this.TransactionProcessorSteps.WhenIAssignTheFollowingOperatorToTheMerchants(this.TestingContext.AccessToken, requests);
-
- foreach ((EstateDetails, MerchantOperatorResponse) result in results)
- {
- this.TestingContext.Logger.LogInformation($"Operator {result.Item2.Name} assigned to Estate {result.Item1.EstateName}");
- }
- }
-
-
-
- [Given("I create the following merchants")]
- [When(@"I create the following merchants")]
- public async Task WhenICreateTheFollowingMerchants(DataTable table)
- {
- if (TestConfiguration.IsTestMode)
- return;
- List<(EstateDetails estate, CreateMerchantRequest)> requests = table.Rows.ToCreateMerchantRequests(this.TestingContext.Estates);
-
- List verifiedMerchants = await this.TransactionProcessorSteps.WhenICreateTheFollowingMerchants(this.TestingContext.AccessToken, requests);
-
- foreach (MerchantResponse verifiedMerchant in verifiedMerchants)
- {
- EstateDetails estateDetails = this.TestingContext.GetEstateDetails(verifiedMerchant.EstateId);
- estateDetails.AddMerchant(verifiedMerchant);
- this.TestingContext.Logger.LogInformation($"Merchant {verifiedMerchant.MerchantName} created with Id {verifiedMerchant.MerchantId} for Estate {estateDetails.EstateName}");
- }
- }
-
- [When(@"I create the following security users")]
- [Given("I have created the following security users")]
- public async Task WhenICreateTheFollowingSecurityUsers(DataTable table)
- {
- if (TestConfiguration.SkipRemoteCalls)
- {
- // Skip remote API call when running in UI-only test mode
- this.TestingContext.Logger.LogInformation("Security users creation skipped (UI-only test mode)");
- return;
- }
-
- List createUserRequests = table.Rows.ToCreateNewUserRequests(this.TestingContext.Estates);
- await this.TransactionProcessorSteps.WhenICreateTheFollowingSecurityUsers(this.TestingContext.AccessToken, createUserRequests, this.TestingContext.Estates);
- }
-
- [Given(@"I have created the following contracts")]
- public async Task GivenIHaveCreatedTheFollowingContracts(DataTable table)
- {
- List<(EstateDetails, CreateContractRequest)> requests = table.Rows.ToCreateContractRequests(this.TestingContext.Estates);
-
- List responses = await this.TransactionProcessorSteps.GivenICreateAContractWithTheFollowingValues(this.TestingContext.AccessToken, requests);
-
- foreach (ContractResponse contractResponse in responses)
- {
- this.TestingContext.Logger.LogInformation($"Contract {contractResponse.Description} created with Id {contractResponse.ContractId} for Estate {contractResponse.EstateId}");
- EstateDetails estateDetails = this.TestingContext.GetEstateDetails(contractResponse.EstateId);
- estateDetails.AddContract(contractResponse.ContractId, contractResponse.Description, contractResponse.OperatorId);
- }
- }
-
- [Given("I have created the following contract products")]
- public async Task GivenIHaveCreatedTheFollowingContractProducts(DataTable table)
- {
- List<(EstateDetails, Contract, AddProductToContractRequest)> requests = table.Rows.ToAddProductToContractRequest(this.TestingContext.Estates);
- await this.TransactionProcessorSteps.WhenICreateTheFollowingProducts(this.TestingContext.AccessToken, requests);
- }
-
-
- private async Task CreateIdentityResource(CreateIdentityResourceRequest createIdentityResourceRequest,
- CancellationToken cancellationToken)
- {
- CreateIdentityResourceResponse createIdentityResourceResponse = null;
-
- Result> identityResourceList = await this.TestingContext.DockerHelper.SecurityServiceClient.GetIdentityResources(cancellationToken);
- if (identityResourceList.IsFailed)
- {
- // TODO: Handle error properly, e.g., show a message to the user
- }
- if (identityResourceList.Data == null || identityResourceList.Data.Any() == false)
- {
- Result result= await this
- .TestingContext.DockerHelper.SecurityServiceClient
- .CreateIdentityResource(createIdentityResourceRequest, cancellationToken)
- .ConfigureAwait(false);
- result.IsSuccess.ShouldBeTrue();
-
- this.TestingContext.IdentityResources.Add(createIdentityResourceRequest.Name);
- }
- else
- {
- if (identityResourceList.Data.Any(i => i.Name == createIdentityResourceRequest.Name))
- {
- return;
- }
-
- Result result = await this
- .TestingContext.DockerHelper.SecurityServiceClient
- .CreateIdentityResource(createIdentityResourceRequest, cancellationToken)
- .ConfigureAwait(false);
- result.IsSuccess.ShouldBeTrue();
-
- result.IsSuccess.ShouldBeTrue();
-
- this.TestingContext.IdentityResources.Add(createIdentityResourceRequest.Name);
- }
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/TestConfiguration.cs b/EstateManagementUI.BlazorIntegrationTests/Common/TestConfiguration.cs
deleted file mode 100644
index 4627104c..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/TestConfiguration.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System;
-using System.IO;
-using Microsoft.Extensions.Configuration;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Common;
-
-///
-/// Configuration for test execution mode
-/// Controls whether tests make remote calls to backend services or use in-memory test data
-///
-public static class TestConfiguration
-{
- private static IConfiguration? _configuration;
- private static readonly object _lock = new object();
-
- ///
- /// Gets the configuration instance, loading from appsettings.json if not already loaded
- ///
- private static IConfiguration Configuration
- {
- get
- {
- if (_configuration == null)
- {
- lock (_lock)
- {
- if (_configuration == null)
- {
- var builder = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
-
- _configuration = builder.Build();
- }
- }
- }
- return _configuration;
- }
- }
-
- ///
- /// Gets whether the test is running in UI-only mode (skipping remote backend calls)
- /// When true, tests will:
- /// - Skip remote API calls to SecurityService, TransactionProcessor, etc.
- /// - Use in-memory test data via TestDataStore
- /// - Only interact with the UI container
- ///
- /// Configured via appsettings.json: TestSettings:SkipRemoteCalls
- /// Falls back to environment variable: SKIP_REMOTE_CALLS
- ///
- public static bool SkipRemoteCalls
- {
- get
- {
- // First check appsettings.json
- var configValue = Configuration["TestSettings:SkipRemoteCalls"];
- if (!string.IsNullOrEmpty(configValue))
- {
- return configValue.Equals("true", StringComparison.OrdinalIgnoreCase) ||
- configValue.Equals("1", StringComparison.OrdinalIgnoreCase);
- }
-
- // Fall back to environment variable for backward compatibility
- var envValue = Environment.GetEnvironmentVariable("SKIP_REMOTE_CALLS");
- return !string.IsNullOrEmpty(envValue) &&
- (envValue.Equals("true", StringComparison.OrdinalIgnoreCase) ||
- envValue.Equals("1", StringComparison.OrdinalIgnoreCase));
- }
- }
-
- ///
- /// Gets whether the application is running in test mode (with TestDataStore)
- /// This should match the AppSettings:TestMode in the Blazor application
- ///
- /// Configured via appsettings.json: TestSettings:EnableTestMode
- /// Falls back to environment variable: APP_TEST_MODE
- ///
- public static bool IsTestMode
- {
- get
- {
- // First check appsettings.json
- var configValue = Configuration["TestSettings:EnableTestMode"];
- if (!string.IsNullOrEmpty(configValue))
- {
- return configValue.Equals("true", StringComparison.OrdinalIgnoreCase) ||
- configValue.Equals("1", StringComparison.OrdinalIgnoreCase);
- }
-
- // Fall back to environment variable for backward compatibility
- var envValue = Environment.GetEnvironmentVariable("APP_TEST_MODE");
- return !string.IsNullOrEmpty(envValue) &&
- (envValue.Equals("true", StringComparison.OrdinalIgnoreCase) ||
- envValue.Equals("1", StringComparison.OrdinalIgnoreCase));
- }
- }
-
- ///
- /// Gets whether to use UI-only test mode (combination of skip remote calls and test mode)
- ///
- public static bool IsUIOnlyTestMode => SkipRemoteCalls && IsTestMode;
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/TestDataHelper.cs b/EstateManagementUI.BlazorIntegrationTests/Common/TestDataHelper.cs
deleted file mode 100644
index 07d10adb..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/TestDataHelper.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using EstateManagementUI.BlazorServer.Models;
-using EstateManagementUI.BlazorServer.Services;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Common;
-
-///
-/// Helper class for accessing and manipulating test data during integration tests
-/// Provides easy access to the test data store for test setup and verification
-///
-public class TestDataHelper
-{
- private readonly ITestDataStore _testDataStore;
-
- public TestDataHelper(ITestDataStore testDataStore)
- {
- _testDataStore = testDataStore;
- }
-
- // Estate Management
- public EstateModel GetEstate(Guid estateId) => _testDataStore.GetEstate(estateId);
- public void SetEstate(EstateModel estate) => _testDataStore.SetEstate(estate);
-
- // Merchant Management
- public List GetMerchants(Guid estateId) => _testDataStore.GetMerchants(estateId);
- public MerchantModel? GetMerchant(Guid estateId, Guid merchantId) => _testDataStore.GetMerchant(estateId, merchantId);
- public void AddMerchant(Guid estateId, MerchantModel merchant) => _testDataStore.AddMerchant(estateId, merchant);
- public void UpdateMerchant(Guid estateId, MerchantModel merchant) => _testDataStore.UpdateMerchant(estateId, merchant);
- public void RemoveMerchant(Guid estateId, Guid merchantId) => _testDataStore.RemoveMerchant(estateId, merchantId);
-
- // Operator Management
- public List GetOperators(Guid estateId) => _testDataStore.GetOperators(estateId);
- public OperatorModel? GetOperator(Guid estateId, Guid operatorId) => _testDataStore.GetOperator(estateId, operatorId);
- public void AddOperator(Guid estateId, OperatorModel operatorModel) => _testDataStore.AddOperator(estateId, operatorModel);
- public void UpdateOperator(Guid estateId, OperatorModel operatorModel) => _testDataStore.UpdateOperator(estateId, operatorModel);
- public void RemoveOperator(Guid estateId, Guid operatorId) => _testDataStore.RemoveOperator(estateId, operatorId);
-
- // Contract Management
- public List GetContracts(Guid estateId) => _testDataStore.GetContracts(estateId);
- public ContractModel? GetContract(Guid estateId, Guid contractId) => _testDataStore.GetContract(estateId, contractId);
- public void AddContract(Guid estateId, ContractModel contract) => _testDataStore.AddContract(estateId, contract);
- public void UpdateContract(Guid estateId, ContractModel contract) => _testDataStore.UpdateContract(estateId, contract);
- public void RemoveContract(Guid estateId, Guid contractId) => _testDataStore.RemoveContract(estateId, contractId);
-
- // Reset all test data (for test isolation)
- public void Reset() => _testDataStore.Reset();
-
- // Helper methods for common test scenarios
- public Guid DefaultEstateId => Guid.Parse("11111111-1111-1111-1111-111111111111");
-
- public void ResetToDefaultState()
- {
- _testDataStore.Reset();
- }
-
- public MerchantModel CreateTestMerchant(Guid estateId, string name, string reference)
- {
- var merchant = new MerchantModel
- {
- MerchantId = Guid.NewGuid(),
- MerchantName = name,
- MerchantReference = reference,
- Balance = 0,
- AvailableBalance = 0,
- SettlementSchedule = "Immediate"
- };
- AddMerchant(estateId, merchant);
- return merchant;
- }
-
- public OperatorModel CreateTestOperator(Guid estateId, string name, bool requireCustomMerchantNumber = false, bool requireCustomTerminalNumber = false)
- {
- var operatorModel = new OperatorModel
- {
- OperatorId = Guid.NewGuid(),
- Name = name,
- RequireCustomMerchantNumber = requireCustomMerchantNumber,
- RequireCustomTerminalNumber = requireCustomTerminalNumber
- };
- AddOperator(estateId, operatorModel);
- return operatorModel;
- }
-
- public ContractModel CreateTestContract(Guid estateId, string description, Guid operatorId, string operatorName)
- {
- var contract = new ContractModel
- {
- ContractId = Guid.NewGuid(),
- Description = description,
- OperatorId = operatorId,
- OperatorName = operatorName,
- Products = new List()
- };
- AddContract(estateId, contract);
- return contract;
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Common/TestingContext.cs b/EstateManagementUI.BlazorIntegrationTests/Common/TestingContext.cs
deleted file mode 100644
index 74b8f3cb..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Common/TestingContext.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Reqnroll;
-using SecurityService.DataTransferObjects.Responses;
-using Shared.Logger;
-using Shouldly;
-using TransactionProcessor.IntegrationTesting.Helpers;
-using ReqnrollTableHelper = Shared.IntegrationTesting.ReqnrollTableHelper;
-
-namespace EstateManagementUI.IntegrationTests.Common
-{
- public class TestingContext
- {
- public EstateDetails GetEstateDetails(DataTableRow tableRow, Guid? testId = null)
- {
- String estateName = ReqnrollTableHelper.GetStringRowValue(tableRow, "EstateName").Replace("[id]", testId.Value.ToString("N"));
-
- EstateDetails estateDetails = this.Estates.SingleOrDefault(e => e.EstateName == estateName);
-
- estateDetails.ShouldNotBeNull();
-
- return estateDetails;
- }
-
- public List GetAllEstateIds()
- {
- return this.Estates.Select(e => e.EstateId).ToList();
- }
-
- public EstateDetails GetEstateDetails(String estateName)
- {
- EstateDetails estateDetails = this.Estates.SingleOrDefault(e => e.EstateName == estateName);
-
- estateDetails.ShouldNotBeNull();
-
- return estateDetails;
- }
-
- public EstateDetails GetEstateDetails(Guid estateId)
- {
- EstateDetails estateDetails = this.Estates.SingleOrDefault(e => e.EstateId == estateId);
-
- estateDetails.ShouldNotBeNull();
-
- return estateDetails;
- }
-
- public List Estates;
- public void AddEstateDetails(Guid estateId, String estateName, String estateReference)
- {
- this.Estates.Add(EstateDetails.Create(estateId, estateName, estateReference));
- }
-
- public String AccessToken { get; set; }
-
- public DockerHelper DockerHelper { get; set; }
-
- public NlogLogger Logger { get; set; }
-
- public Dictionary Users;
- public Dictionary Roles;
-
- public List Clients;
-
- public List ApiResources;
- public List IdentityResources;
-
- public TokenResponse TokenResponse;
-
- public TestingContext()
- {
- this.Users = new Dictionary();
- this.Roles = new Dictionary();
- this.Clients = new List();
- this.ApiResources = new List();
- this.Estates = new List();
- this.IdentityResources = new List();
- }
-
- public ClientDetails GetClientDetails(String clientId)
- {
- ClientDetails clientDetails = this.Clients.SingleOrDefault(c => c.ClientId == clientId);
-
- clientDetails.ShouldNotBeNull();
-
- return clientDetails;
- }
-
- public void AddClientDetails(String clientId,
- String clientSecret,
- List grantTypes)
- {
- this.Clients.Add(ClientDetails.Create(clientId, clientSecret, grantTypes));
- }
- }
-}
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj b/EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj
deleted file mode 100644
index 90e381ff..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
- net10.0
- enable
- enable
-
- false
- true
-
-
-
-
-
-
-
-
-
- Always
- true
- PreserveNewest
-
-
- Always
- true
- PreserveNewest
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/EstateManagementUI.BlazorIntegrationTests/MIGRATION_GUIDE.md b/EstateManagementUI.BlazorIntegrationTests/MIGRATION_GUIDE.md
deleted file mode 100644
index 3d4c8e80..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/MIGRATION_GUIDE.md
+++ /dev/null
@@ -1,397 +0,0 @@
-# Migration Guide: Selenium to Playwright
-
-This guide helps developers understand the differences between the legacy Selenium-based tests and the new Playwright-based tests for the Blazor UI.
-
-## Overview
-
-| Aspect | Legacy Tests (Selenium) | New Tests (Playwright) |
-|--------|------------------------|------------------------|
-| **Target UI** | EstateManagementUI (ASP.NET Core) | EstateManagementUI.BlazorServer (Blazor Server) |
-| **Test Framework** | Selenium WebDriver | Microsoft Playwright |
-| **Project** | EstateManagementUI.IntegrationTests | EstateManagementUI.BlazorIntegrationTests |
-| **Browser API** | Synchronous (with some async) | Fully Async |
-| **Main Interface** | `IWebDriver` | `IPage` |
-
-## Key Differences
-
-### 1. Browser API Objects
-
-**Selenium:**
-```csharp
-IWebDriver webDriver;
-IWebElement element = webDriver.FindElement(By.Id("myElement"));
-```
-
-**Playwright:**
-```csharp
-IPage page;
-ILocator locator = page.Locator("#myElement");
-```
-
-### 2. Async/Await
-
-Playwright is fully asynchronous, requiring `await` for all interactions.
-
-**Selenium:**
-```csharp
-public void ClickButton()
-{
- var button = webDriver.FindElement(By.Id("submitButton"));
- button.Click();
-}
-```
-
-**Playwright:**
-```csharp
-public async Task ClickButton()
-{
- var button = page.Locator("#submitButton");
- await button.ClickAsync();
-}
-```
-
-### 3. Element Locators
-
-**Selenium:**
-```csharp
-// By ID
-var element = webDriver.FindElement(By.Id("myId"));
-
-// By Name
-var element = webDriver.FindElement(By.Name("myName"));
-
-// By CSS Selector
-var element = webDriver.FindElement(By.CssSelector(".myClass"));
-
-// By XPath
-var element = webDriver.FindElement(By.XPath("//div[@id='myId']"));
-```
-
-**Playwright:**
-```csharp
-// By ID
-var locator = page.Locator("#myId");
-
-// By Name
-var locator = page.Locator("[name='myName']");
-
-// By CSS Selector
-var locator = page.Locator(".myClass");
-
-// By Role (Recommended for accessibility)
-var button = page.GetByRole(AriaRole.Button, new() { Name = "Submit" });
-var link = page.GetByRole(AriaRole.Link, new() { Name = "Home" });
-```
-
-### 4. Form Interactions
-
-**Selenium:**
-```csharp
-// Fill text input
-element.SendKeys("Hello World");
-
-// Clear and fill
-element.Clear();
-element.SendKeys("New Value");
-
-// Select dropdown
-var select = new SelectElement(element);
-select.SelectByText("Option 1");
-```
-
-**Playwright:**
-```csharp
-// Fill text input
-await locator.FillAsync("Hello World");
-
-// Clear and fill (FillAsync clears automatically)
-await locator.FillAsync("New Value");
-
-// Select dropdown
-await locator.SelectOptionAsync(new SelectOptionValue { Label = "Option 1" });
-// or by value:
-await locator.SelectOptionAsync("optionValue");
-```
-
-### 5. Getting Element Properties
-
-**Selenium:**
-```csharp
-String text = element.Text;
-String value = element.GetDomProperty("value");
-Boolean isDisplayed = element.Displayed;
-Boolean isEnabled = element.Enabled;
-```
-
-**Playwright:**
-```csharp
-String text = await locator.TextContentAsync();
-String value = await locator.InputValueAsync();
-Boolean isVisible = await locator.IsVisibleAsync();
-Boolean isEnabled = await locator.IsEnabledAsync();
-```
-
-### 6. Waiting for Elements
-
-**Selenium:**
-```csharp
-WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
-IWebElement element = wait.Until(driver =>
- driver.FindElement(By.Id("myElement"))
-);
-```
-
-**Playwright:**
-```csharp
-// Auto-waiting built-in for most actions
-await page.Locator("#myElement").ClickAsync(); // Waits automatically
-
-// Explicit wait
-await page.Locator("#myElement").WaitForAsync(new LocatorWaitForOptions
-{
- State = WaitForSelectorState.Visible,
- Timeout = 10000
-});
-```
-
-### 7. Navigation
-
-**Selenium:**
-```csharp
-webDriver.Navigate().GoToUrl("https://example.com");
-```
-
-**Playwright:**
-```csharp
-await page.GotoAsync("https://example.com");
-```
-
-### 8. Page Title
-
-**Selenium:**
-```csharp
-String title = webDriver.Title;
-```
-
-**Playwright:**
-```csharp
-String title = await page.TitleAsync();
-```
-
-### 9. Screenshots
-
-**Selenium:**
-```csharp
-var screenshot = ((ITakesScreenshot)webDriver).GetScreenshot();
-screenshot.SaveAsFile("screenshot.png");
-```
-
-**Playwright:**
-```csharp
-await page.ScreenshotAsync(new PageScreenshotOptions
-{
- Path = "screenshot.png",
- FullPage = true
-});
-```
-
-### 10. Browser Setup
-
-**Selenium (Hooks.cs):**
-```csharp
-ChromeOptions options = new();
-options.AddArgument("--headless");
-options.AcceptInsecureCertificates = true;
-webDriver = new ChromeDriver(options);
-```
-
-**Playwright (Hooks.cs):**
-```csharp
-// BeforeTestRun - Install browsers
-playwright = await Playwright.CreateAsync();
-
-// BeforeScenario - Create browser
-browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
-{
- Headless = true,
- Args = new[] { "--ignore-certificate-errors" }
-});
-
-var context = await browser.NewContextAsync(new BrowserNewContextOptions
-{
- IgnoreHTTPSErrors = true,
- ViewportSize = new ViewportSize { Width = 1920, Height = 1080 }
-});
-
-var page = await context.NewPageAsync();
-```
-
-## Extension Methods Comparison
-
-### Legacy (Selenium Extensions)
-
-```csharp
-// EstateManagementUI.IntegrationTests/Common/Extensions.cs
-await webDriver.FillIn("fieldName", "value");
-await webDriver.ClickButtonById("buttonId");
-IWebElement button = await webDriver.FindButtonByText("Login");
-```
-
-### New (Playwright Extensions)
-
-```csharp
-// EstateManagementUI.BlazorIntegrationTests/Common/PlaywrightExtensions.cs
-await page.FillIn("fieldName", "value");
-await page.ClickButtonById("buttonId");
-ILocator button = await page.FindButtonByText("Login");
-```
-
-## UI Helpers Comparison
-
-### Legacy
-
-```csharp
-// EstateManagementUI.IntegrationTests/Common/EstateManagementUiSteps.cs
-public class EstateManagementUiHelpers
-{
- private readonly IWebDriver WebDriver;
-
- public void NavigateToHomePage()
- {
- this.WebDriver.Navigate().GoToUrl($"https://localhost:{port}");
- this.WebDriver.Title.ShouldBe("Welcome - Estate Management");
- }
-}
-```
-
-### New
-
-```csharp
-// EstateManagementUI.BlazorIntegrationTests/Common/BlazorUiHelpers.cs
-public class BlazorUiHelpers
-{
- private readonly IPage Page;
-
- public async Task NavigateToHomePage()
- {
- await this.Page.GotoAsync($"https://localhost:{port}");
- var title = await this.Page.TitleAsync();
- title.ShouldBe("Welcome - Estate Management");
- }
-}
-```
-
-## Step Definitions Comparison
-
-### Legacy
-
-```csharp
-// EstateManagementUI.IntegrationTests/Steps/Gimp.cs
-public EstateManagementUiSteps(ScenarioContext scenarioContext, ...)
-{
- var webDriver = scenarioContext.ScenarioContainer.Resolve(...);
- this.UiHelpers = new EstateManagementUiHelpers(webDriver, ...);
-}
-
-[Given(@"I am on the application home page")]
-public void GivenIAmOnTheApplicationHomePage()
-{
- this.UiHelpers.NavigateToHomePage();
-}
-```
-
-### New
-
-```csharp
-// EstateManagementUI.BlazorIntegrationTests/Steps/BlazorUiSteps.cs
-public BlazorUiSteps(ScenarioContext scenarioContext, ...)
-{
- var page = scenarioContext.ScenarioContainer.Resolve(...);
- this.UiHelpers = new BlazorUiHelpers(page, ...);
-}
-
-[Given(@"I am on the application home page")]
-public async Task GivenIAmOnTheApplicationHomePage()
-{
- await this.UiHelpers.NavigateToHomePage();
-}
-```
-
-## Docker Configuration Differences
-
-The main difference is in environment variable names for authentication:
-
-### Legacy UI (EstateManagementUI)
-```csharp
-environmentVariables.Add("AppSettings:Authority", ...);
-environmentVariables.Add("AppSettings:ClientId", "estateUIClient");
-environmentVariables.Add("AppSettings:ClientSecret", "Secret1");
-```
-
-### Blazor UI (EstateManagementUI.BlazorServer)
-```csharp
-environmentVariables.Add("Authentication:Authority", ...);
-environmentVariables.Add("Authentication:ClientId", "estateUIClient");
-environmentVariables.Add("Authentication:ClientSecret", "Secret1");
-```
-
-## Best Practices with Playwright
-
-1. **Use role-based selectors** when possible for better accessibility and stability:
- ```csharp
- await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();
- ```
-
-2. **Auto-waiting**: Playwright automatically waits for elements to be actionable. No need for explicit waits in most cases.
-
-3. **Locators are lazy**: They don't query the DOM until an action is performed.
-
-4. **Always use await**: All Playwright methods are async and must be awaited.
-
-5. **Screenshots on failure**: Already implemented in `Hooks.AfterScenario`.
-
-6. **Browser context isolation**: Each test gets its own browser context, ensuring test isolation.
-
-## Running Tests
-
-### Legacy Tests
-```bash
-cd EstateManagementUI.IntegrationTests
-dotnet test
-```
-
-### New Tests
-```bash
-cd EstateManagementUI.BlazorIntegrationTests
-# First time only: Install Playwright browsers
-pwsh bin/Debug/net10.0/playwright.ps1 install
-
-dotnet test
-```
-
-## Troubleshooting
-
-### Playwright Installation Issues
-
-If you get errors about missing browsers:
-```bash
-# Install browsers manually
-dotnet tool install --global Microsoft.Playwright.CLI
-playwright install
-```
-
-### Timeout Issues
-
-Playwright has a default timeout of 30 seconds. If you need longer:
-```csharp
-await page.Locator("#slowElement").WaitForAsync(new LocatorWaitForOptions
-{
- Timeout = 60000 // 60 seconds
-});
-```
-
-## Additional Resources
-
-- [Playwright for .NET Documentation](https://playwright.dev/dotnet/docs/intro)
-- [Playwright API Reference](https://playwright.dev/dotnet/docs/api/class-playwright)
-- [Selenium to Playwright Migration Guide](https://playwright.dev/docs/selenium-grid)
diff --git a/EstateManagementUI.BlazorIntegrationTests/NuGet.Config b/EstateManagementUI.BlazorIntegrationTests/NuGet.Config
deleted file mode 100644
index 3086e202..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/NuGet.Config
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/EstateManagementUI.BlazorIntegrationTests/README.md b/EstateManagementUI.BlazorIntegrationTests/README.md
deleted file mode 100644
index d69b74b1..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/README.md
+++ /dev/null
@@ -1,160 +0,0 @@
-# EstateManagementUI.BlazorIntegrationTests
-
-This is a new integration test project that targets the **Blazor Server UI** (`EstateManagementUI.BlazorServer`) using **Playwright** for browser automation.
-
-## Overview
-
-This project replaces the Selenium-based integration tests in `EstateManagementUI.IntegrationTests` with a Playwright-based implementation targeting the new Blazor UI.
-
-### Key Differences from Original Integration Tests
-
-1. **Target Application**: Tests the Blazor Server UI (`EstateManagementUI.BlazorServer`) instead of the old ASP.NET Core UI (`EstateManagementUI`)
-2. **Browser Automation**: Uses **Microsoft Playwright** instead of Selenium WebDriver
-3. **Docker Image**: Targets the `estatemanagementuiblazor` Docker image
-
-## Project Structure
-
-```
-EstateManagementUI.BlazorIntegrationTests/
-├── Common/
-│ ├── BlazorUiHelpers.cs # Playwright-based UI helper methods
-│ ├── PlaywrightExtensions.cs # Extension methods for Playwright IPage
-│ ├── Hooks.cs # Reqnroll hooks for Playwright setup/teardown
-│ ├── DockerHelper.cs # Docker infrastructure (adapted for Blazor)
-│ ├── TestingContext.cs # Shared test context
-│ ├── Setup.cs # Test setup configuration
-│ ├── SharedSteps.cs # Shared step definitions
-│ └── GenericSteps.cs # Generic step definitions
-├── Steps/
-│ └── BlazorUiSteps.cs # Blazor UI-specific step definitions
-├── Tests/
-│ ├── ContractTests.feature # Contract feature tests
-│ ├── EstateTests.feature # Estate feature tests
-│ ├── MerchantTests.feature # Merchant feature tests
-│ └── OperatorTests.feature # Operator feature tests
-└── EstateManagementUI.BlazorIntegrationTests.csproj
-```
-
-## Key Components
-
-### Playwright Extensions (`PlaywrightExtensions.cs`)
-
-Provides extension methods for `IPage` that mirror the Selenium extension patterns but use Playwright APIs:
-- `FillIn()`, `FillInById()`, `FillInNumeric()` - Form field interactions
-- `FindButtonById()`, `FindButtonByText()` - Button locators
-- `ClickButtonById()`, `ClickButtonByText()` - Button click actions
-- `SelectDropDownByIdAndText()`, `SelectDropDownByIdAndValue()` - Dropdown interactions
-- `GetTextById()`, `GetValueById()` - Element value retrieval
-- `WaitForElement()`, `IsElementVisible()` - Element visibility checks
-
-### Blazor UI Helpers (`BlazorUiHelpers.cs`)
-
-High-level test methods for interacting with the Blazor UI:
-- Navigation methods (e.g., `NavigateToHomePage()`, `ClickContractsSidebarOption()`)
-- Screen verification methods (e.g., `VerifyOnTheContractsListScreen()`)
-- Table validation methods (e.g., `VerifyTheContractDetailsAreInTheList()`)
-
-### Hooks (`Hooks.cs`)
-
-Manages Playwright browser lifecycle:
-- **BeforeTestRun**: Installs Playwright browsers
-- **BeforeScenario**: Creates a new browser page for each scenario
-- **AfterScenario**: Takes screenshots on failure and closes the page
-- **AfterTestRun**: Closes browser and cleans up Playwright
-
-### Docker Helper (`DockerHelper.cs`)
-
-Manages Docker containers for integration tests, adapted for Blazor:
-- Starts the Blazor UI container with proper environment variables
-- Uses `Authentication:` prefix for OIDC settings (instead of `AppSettings:`)
-- Configures API client credentials
-- Sets up database connections and other dependencies
-
-## Environment Configuration
-
-The Blazor container is configured with:
-- **Authentication**: OIDC with Security Service
-- **API Client**: Backend service credentials
-- **Database**: Transaction Processor Read Model connection
-- **Development Mode**: Configured for integration testing
-
-## Running Tests
-
-### Prerequisites
-
-1. .NET 10.0 SDK
-2. Docker
-3. Access to private NuGet feed (feedz.io)
-
-### Installation
-
-```bash
-# Install Playwright browsers
-pwsh bin/Debug/net10.0/playwright.ps1 install
-```
-
-### Running Tests
-
-```bash
-cd EstateManagementUI.BlazorIntegrationTests
-dotnet test
-```
-
-### Environment Variables
-
-- `Browser`: Browser type (`Chrome`, `Firefox`, `WebKit`) - defaults to Chrome
-- `IsCI`: Set to `true` for headless mode in CI/CD
-
-## Current Status
-
-### ✅ Completed
-- Project structure created
-- Playwright dependencies added
-- Core Playwright extension methods implemented
-- Basic UI helper methods implemented
-- Docker infrastructure adapted for Blazor
-- Test hooks implemented with Playwright lifecycle management
-- Feature files copied from original tests
-
-### 🚧 In Progress
-- Additional UI helper methods need implementation
-- More step definitions needed to cover all scenarios
-- Build and test execution validation
-
-### 📝 Next Steps
-1. Complete all UI helper methods in `BlazorUiHelpers.cs`
-2. Implement all step definitions in `BlazorUiSteps.cs`
-3. Ensure all feature files are compatible with Blazor UI
-4. Build and run tests to verify functionality
-5. Add CI/CD integration
-
-## Differences from Selenium Tests
-
-### API Changes
-
-| Selenium | Playwright |
-|----------|------------|
-| `IWebDriver` | `IPage` |
-| `FindElement(By.Id("x"))` | `Locator("#x")` |
-| `element.SendKeys(text)` | `locator.FillAsync(text)` |
-| `element.Click()` | `locator.ClickAsync()` |
-| `element.Text` | `await locator.TextContentAsync()` |
-| `element.GetDomProperty("value")` | `await locator.InputValueAsync()` |
-
-### Async/Await
-
-Playwright is fully async, so all methods must use `await` and return `Task`.
-
-### Locators
-
-Playwright uses modern selectors and encourages role-based selection:
-- `page.GetByRole(AriaRole.Button, new() { Name = "Login" })`
-- `page.Locator("#elementId")`
-- `page.Locator("[name='fieldName']")`
-
-## Notes
-
-- The Docker image name for the Blazor UI is assumed to be `estatemanagementuiblazor`
-- Authentication configuration uses the `Authentication:` prefix to match the Blazor app's configuration
-- All tests use the same Docker infrastructure as the original integration tests
-- The project maintains compatibility with Reqnroll (SpecFlow successor) for BDD-style tests
diff --git a/EstateManagementUI.BlazorIntegrationTests/SKIP_REMOTE_CALLS.md b/EstateManagementUI.BlazorIntegrationTests/SKIP_REMOTE_CALLS.md
deleted file mode 100644
index 7e95ec1e..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/SKIP_REMOTE_CALLS.md
+++ /dev/null
@@ -1,261 +0,0 @@
-# Skipping Remote Calls in Tests
-
-## Overview
-
-The test infrastructure now supports a "skip remote calls" mode that allows tests to run without making API calls to backend services (SecurityService, TransactionProcessor, etc.). This enables:
-
-- **UI-Only Testing**: Test the UI without requiring backend Docker containers
-- **Faster Test Execution**: No network latency or backend service setup time
-- **Simplified Setup**: Only the UI container needs to be running
-
-## How It Works
-
-When skip remote calls mode is enabled, the test steps will:
-
-1. **Skip all remote API calls** to SecurityService, TransactionProcessor, etc.
-2. **Use the in-memory TestDataStore** in the Blazor application (when TestMode is enabled)
-3. **Only interact with the UI** via Playwright browser automation
-
-## Configuration
-
-### Option 1: appsettings.json (Recommended)
-
-Configure the test behavior in `appsettings.json`:
-
-```json
-{
- "TestSettings": {
- "SkipRemoteCalls": true,
- "EnableTestMode": true
- }
-}
-```
-
-### Option 2: Environment Variables (Backward Compatible)
-
-You can still use environment variables for configuration:
-
-```bash
-# Skip remote API calls in test steps
-export SKIP_REMOTE_CALLS=true
-
-# Enable test mode in the Blazor application
-export APP_TEST_MODE=true
-```
-
-**Note:** appsettings.json values take precedence over environment variables if both are set.
-
-### Running Tests
-
-```bash
-# Method 1: Using appsettings.json
-# Edit appsettings.json to set SkipRemoteCalls and EnableTestMode to true
-dotnet test EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj
-
-# Method 2: Using environment variables
-export SKIP_REMOTE_CALLS=true
-export APP_TEST_MODE=true
-dotnet test EstateManagementUI.BlazorIntegrationTests/EstateManagementUI.BlazorIntegrationTests.csproj
-```
-
-### Docker Compose
-
-When running tests with Docker, you can use either approach:
-
-**Using appsettings.json:**
-```yaml
-services:
- blazor-ui:
- image: estatemanagementuiblazor:latest
- environment:
- - AppSettings__TestMode=true
- ports:
- - "5004:5004"
-
- tests:
- image: test-runner:latest
- volumes:
- - ./appsettings.json:/app/appsettings.json # Mount custom appsettings
- depends_on:
- - blazor-ui
-```
-
-**Using environment variables:**
-```yaml
-services:
- blazor-ui:
- image: estatemanagementuiblazor:latest
- environment:
- - AppSettings__TestMode=true
- ports:
- - "5004:5004"
-
- tests:
- image: test-runner:latest
- environment:
- - SKIP_REMOTE_CALLS=true
- - APP_TEST_MODE=true
- depends_on:
- - blazor-ui
-```
-
-## What Gets Skipped
-
-When skip remote calls is enabled (via `TestSettings:SkipRemoteCalls` in appsettings.json or `SKIP_REMOTE_CALLS` environment variable), the following steps skip their remote API calls:
-
-### Security Service Steps
-- `Given I create the following api resources`
-- `Given I create the following api scopes`
-- `Given I create the following clients`
-- `Given I create the following identity resources`
-- `Given I create the following roles`
-- `Given I create the following users`
-- `Given I have a token to access the estate management resource`
-
-### Transaction Processor Steps
-- `Given I have created the following estates`
-- `Given I have created the following operators`
-- `Given I have assigned the following operators to the estates`
-- `Given I have created the following security users`
-
-### What Still Runs
-- All UI interaction steps (clicking, typing, verifying)
-- Browser navigation and page interactions
-- Screenshot capture on failures
-
-## Test Data
-
-When running in skip remote calls mode:
-
-1. **Default Test Data**: The TestDataStore initializes with default data:
- - 1 Estate (ID: `11111111-1111-1111-1111-111111111111`)
- - 3 Merchants (MERCH001, MERCH002, MERCH003)
- - 2 Operators (Safaricom, Voucher)
- - 2 Contracts with products
-
-2. **Test Context**: The TestingContext is populated with dummy IDs and references so tests can continue
-
-3. **Authentication**: A dummy token is set instead of requesting a real OAuth token
-
-## Example Scenarios
-
-### Full Integration Test (Default)
-```bash
-# Requires all Docker containers: SecurityService, TransactionProcessor, UI
-export SKIP_REMOTE_CALLS=false
-dotnet test
-```
-
-### UI-Only Test (Fast)
-```bash
-# Requires only UI Docker container
-export SKIP_REMOTE_CALLS=true
-export APP_TEST_MODE=true
-dotnet test
-```
-
-## Configuration Checks
-
-The test infrastructure uses `TestConfiguration.SkipRemoteCalls` to check if remote calls should be skipped. You can verify the configuration:
-
-```csharp
-if (TestConfiguration.SkipRemoteCalls)
-{
- // Skip remote API call
- return;
-}
-
-// Normal remote API call
-await this.SecurityServiceSteps.SomeRemoteCall(...);
-```
-
-## Benefits
-
-### Faster Tests
-- No Docker container startup for backend services (~30-60s saved)
-- No network latency for API calls
-- Immediate test execution
-
-### Simpler Setup
-- Only UI container required
-- No backend service configuration
-- Reduced infrastructure complexity
-
-### Local Development
-- Easier to run tests locally
-- No need for complex Docker setup
-- Quick feedback loop
-
-## Limitations
-
-When running with skip remote calls:
-
-1. **Backend Logic Not Tested**: Only UI behavior is tested, not backend integration
-2. **Default Data Only**: Tests work with pre-configured test data
-3. **Limited Scenarios**: Some complex scenarios may require backend services
-
-## Combining With Test Mode
-
-For full UI-only testing, enable both features:
-
-**Using appsettings.json (Recommended):**
-```json
-{
- "TestSettings": {
- "SkipRemoteCalls": true,
- "EnableTestMode": true
- }
-}
-```
-
-**Using environment variables:**
-```bash
-# In the Blazor application
-export AppSettings__TestMode=true
-
-# In the test project
-export SKIP_REMOTE_CALLS=true
-export APP_TEST_MODE=true
-```
-
-This combination:
-- Skips OIDC authentication (TestAuthenticationHandler)
-- Uses in-memory data (TestDataStore)
-- Skips remote API calls in tests (TestConfiguration.SkipRemoteCalls)
-
-## Troubleshooting
-
-### Tests still making remote calls
-- Check `TestSettings:SkipRemoteCalls` in appsettings.json or `SKIP_REMOTE_CALLS` environment variable is set to `true`
-- Verify that the step definition uses `TestConfiguration.SkipRemoteCalls`
-- Ensure appsettings.json is being copied to the output directory
-
-### Test data not found
-- Ensure `TestSettings:EnableTestMode=true` in appsettings.json or `APP_TEST_MODE=true` environment variable
-- Verify the TestDataStore is initialized with default data in the Blazor application
-- Check that the test estate ID matches the default (`11111111-1111-1111-1111-111111111111`)
-
-### Authentication failures
-- Confirm `AppSettings__TestMode=true` in the Blazor application
-- Verify TestAuthenticationHandler is registered
-- Check that dummy token is set in test context
-
-### Configuration not loading
-- Verify appsettings.json is in the test project root
-- Check that appsettings.json has "Copy to Output Directory" set to "Always"
-- Ensure working directory is set correctly when running tests
-
-## Migration Guide
-
-To convert existing tests to support skip remote calls mode:
-
-1. **No changes needed** - Tests automatically respect the configuration
-2. **Update configuration**: Set `TestSettings:SkipRemoteCalls` to `true` in appsettings.json
-3. **Optional**: Add custom test data setup if default data is insufficient
-4. **Verify**: Run tests to ensure they pass with skip remote calls enabled
-
-## See Also
-
-- [TEST_INFRASTRUCTURE.md](./TEST_INFRASTRUCTURE.md) - Complete test infrastructure guide
-- [IMPLEMENTATION_GUIDE.md](../IMPLEMENTATION_GUIDE.md) - Implementation details
-- [TestConfiguration.cs](./Common/TestConfiguration.cs) - Configuration source code
diff --git a/EstateManagementUI.BlazorIntegrationTests/Steps/BlazorUiSteps.cs b/EstateManagementUI.BlazorIntegrationTests/Steps/BlazorUiSteps.cs
deleted file mode 100644
index 72e5e193..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Steps/BlazorUiSteps.cs
+++ /dev/null
@@ -1,403 +0,0 @@
-using Reqnroll;
-using System;
-using System.Threading.Tasks;
-using Shared.IntegrationTesting;
-using EstateManagementUI.BlazorIntegrationTests.Common;
-using EstateManagementUI.IntegrationTests.Common;
-using Microsoft.Playwright;
-using Reqnroll.BoDi;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Steps
-{
- [Binding]
- [Scope(Tag = "uigeneral")]
- public class BlazorUiSteps
- {
- private readonly TestingContext TestingContext;
- private readonly BlazorUiHelpers UiHelpers;
-
- public BlazorUiSteps(ScenarioContext scenarioContext, TestingContext testingContext, IObjectContainer container)
- {
- var page = scenarioContext.ScenarioContainer.Resolve(scenarioContext.ScenarioInfo.Title.Replace(" ", ""));
-
- this.TestingContext = testingContext;
- this.UiHelpers = new BlazorUiHelpers(page, this.TestingContext.DockerHelper.EstateManagementUiPort);
- }
-
- [Given(@"I am on the application home page")]
- public async Task GivenIAmOnTheApplicationHomePage()
- {
- await this.UiHelpers.NavigateToHomePage();
- }
-
- [Given(@"I click on the My Contracts sidebar option")]
- public async Task GivenIClickOnTheMyContractsSidebarOption()
- {
- await this.UiHelpers.ClickContractsSidebarOption();
- }
-
- [Given(@"I click on the My Estate sidebar option")]
- public async Task GivenIClickOnTheMyEstateSidebarOption()
- {
- await this.UiHelpers.ClickMyEstateSidebarOption();
- }
-
- [Given(@"I click on the My Merchants sidebar option")]
- public async Task GivenIClickOnTheMyMerchantsSidebarOption()
- {
- await this.UiHelpers.ClickMyMerchantsSidebarOption();
- }
-
- [Given(@"I click on the My Operators sidebar option")]
- public async Task GivenIClickOnTheMyOperatorsSidebarOption()
- {
- await this.UiHelpers.ClickMyOperatorsSidebarOption();
- }
-
- [Given(@"I click on the Sign In Button")]
- public async Task GivenIClickOnTheSignInButton()
- {
- if (TestConfiguration.IsTestMode == false) {
- await this.UiHelpers.ClickOnTheSignInButton();
- }
- }
-
- [Then(@"I am presented with a login screen")]
- public async Task ThenIAmPresentedWithALoginScreen()
- {
- if (TestConfiguration.IsTestMode == false) {
- await this.UiHelpers.VerifyOnTheLoginScreen();
- }
- }
-
- [Then(@"I am presented with the Contracts List Screen")]
- public async Task ThenIAmPresentedWithTheContractsListScreen()
- {
- await this.UiHelpers.VerifyOnTheContractsListScreen();
- }
-
- [Then("the Contract Products List Screen is displayed")]
- public async Task ThenTheContractProductsListScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheContractProductsListScreen();
- }
-
- [Then("the Contract Products Transaction Fees List Screen is displayed")]
- public async Task ThenTheContractProductsTransactionFeesListScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheContractProductsFeesListScreen();
- }
-
- [Then(@"I am presented with the Estate Administrator Dashboard")]
- public async Task ThenIAmPresentedWithTheEstateAdministratorDashboard()
- {
- await this.UiHelpers.VerifyOnTheDashboard();
- }
-
- [When("I click the Save Product Button")]
- public async Task WhenIClickTheSaveProductButton()
- {
- await this.UiHelpers.ClickTheSaveProductButton();
- }
-
- [Then(@"I am presented with the View Estate Page")]
- public async Task ThenIamPresentedWithTheViewEstatePage()
- {
- await this.UiHelpers.VerifyOnTheEstateDetailsScreen();
- }
-
- [Then(@"I am presented with the Merchants List Screen")]
- public async Task ThenIAmPresentedWithTheMerchantsListScreen()
- {
- await this.UiHelpers.VerifyOnTheMerchantsListScreen();
- }
-
- [Then(@"I am presented with the Operators List Screen")]
- public async Task ThenIAmPresentedWithTheOperatorsListScreen()
- {
- await this.UiHelpers.VerifyOnTheOperatorsListScreen();
- }
-
- [Then(@"My Estate Details will be shown")]
- public async Task ThenMyEstateDetailsWillBeShown(DataTable table)
- {
- DataTableRow tableRow = table.Rows.Single();
- String estateName = ReqnrollTableHelper.GetStringRowValue(tableRow, "EstateName").Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N"));
- await this.UiHelpers.VerifyTheCorrectEstateDetailsAreDisplayed(estateName);
- }
-
- [Then(@"the following contract details are in the list")]
- public async Task ThenTheFollowingContractDetailsAreInTheList(DataTable table)
- {
- List<(String, String, Int32)> contractDescriptions = new List<(String, String, Int32)>();
- foreach (DataTableRow tableRow in table.Rows)
- {
- contractDescriptions.Add((ReqnrollTableHelper.GetStringRowValue(tableRow, "Description"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "OperatorName"),
- ReqnrollTableHelper.GetIntValue(tableRow, "Products")));
- }
-
- await this.UiHelpers.VerifyTheContractDetailsAreInTheList(contractDescriptions);
- }
-
- [When(@"I login with the username '(.*)' and password '(.*)'")]
- public async Task WhenILoginWithTheUsernameAndPassword(String userName, String password)
- {
- if (TestConfiguration.IsTestMode == false) {
- String username = userName.Replace("[id]", this.TestingContext.DockerHelper.TestId.ToString("N"));
- await this.UiHelpers.Login(username, password);
- }
- }
-
- [When("I click on the New Operator Button")]
- public async Task WhenIClickOnTheNewOperatorButton()
- {
- await this.UiHelpers.ClickTheNewOperatorButton();
- }
-
- [When("I click on the New Merchant Button")]
- public async Task WhenIClickOnTheNewMerchantButton()
- {
- await this.UiHelpers.ClickTheNewMerchantButton();
- }
-
- [Then("the Edit Merchant Screen is displayed")]
- public async Task ThenTheEditMerchantScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheEditMerchantScreen();
- }
-
- [Then("the Make Deposit Screen is displayed")]
- public async Task ThenTheMakeDepositScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheMakeDepositScreen();
- }
-
- [When("I click on the Operators tab")]
- public async Task WhenIClickOnTheOperatorsTab()
- {
- await this.UiHelpers.ClickOnTheMerchantOperatorsTab();
- }
-
- [When("I click on the Contracts tab")]
- public async Task WhenIClickOnTheContractsTab()
- {
- await this.UiHelpers.ClickOnTheMerchantContractsTab();
- }
-
- [When("I click on the Devices tab")]
- public async Task WhenIClickOnTheDevicesTab()
- {
- await this.UiHelpers.ClickOnTheMerchantDevicesTab();
- }
-
- [When("I click on the Add Device Button")]
- public async Task WhenIClickOnTheAddDeviceButton()
- {
- await this.UiHelpers.ClickTheAddDeviceButton();
- }
-
- [Then("I am presented with the Merchants Operator List Screen")]
- public async Task ThenIAmPresentedWithTheMerchantsOperatorListScreen()
- {
- await this.UiHelpers.VerifyOnMerchantOperatorsTab();
- }
-
- [Then("I am presented with the Merchants Contract List Screen")]
- public async Task ThenIAmPresentedWithTheMerchantsContractListScreen()
- {
- await this.UiHelpers.VerifyOnMerchantContractsTab();
- }
-
- [Then("I am presented with the Merchants Device List Screen")]
- public async Task ThenIAmPresentedWithTheMerchantsDeviceListScreen()
- {
- await this.UiHelpers.VerifyOnMerchantDevicesTab();
- }
-
- [Then("the View Merchant Screen is displayed")]
- public async Task ThenTheViewMerchantScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheViewMerchantScreen();
- }
-
- [When("click the Assign Operator button")]
- public async Task WhenClickTheAssignOperatorButton()
- {
- await this.UiHelpers.ClickTheAssignOperatorButton();
- }
-
- [Then("the Add New Merchant Screen is displayed")]
- public async Task ThenTheAddNewMerchantScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheNewMerchantScreen();
- }
-
- [When("I click on the Edit Operator Button for {string}")]
- public async Task WhenIClickOnTheEditOperatorButtonFor(string operatorName)
- {
- await this.UiHelpers.ClickTheEditOperatorButton(operatorName);
- }
-
- [When("I click on the Edit Merchant Button for {string}")]
- public async Task WhenIClickOnTheEditMerchantButtonFor(string merchantName)
- {
- await this.UiHelpers.ClickTheEditMerchantButton(merchantName);
- }
-
- [When("I click on the Make Deposit Button for {string}")]
- public async Task WhenIClickOnTheMakeDepositButtonFor(string merchantName)
- {
- await this.UiHelpers.ClickTheMakeDepositButtonFor(merchantName);
- }
-
- [Then("the Edit Operator Screen is displayed")]
- public async Task ThenTheEditOperatorScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheEditOperatorScreen();
- }
-
- [Then("the New Operator Screen is displayed")]
- public async Task ThenTheNewOperatorScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheNewOperatorScreen();
- }
-
- [Then(@"the following merchants details are in the list")]
- public async Task ThenTheFollowingMerchantsDetailsAreInTheList(DataTable table)
- {
- List merchantDetailsList = new List();
- foreach (DataTableRow tableRow in table.Rows)
- {
- MerchantDetails m = new MerchantDetails(
- tableRow["MerchantName"],
- tableRow["SettlementSchedule"],
- tableRow["ContactName"],
- tableRow["AddressLine1"],
- tableRow["Town"]);
- merchantDetailsList.Add(m);
- }
-
- await this.UiHelpers.VerifyMerchantDetailsAreInTheList(merchantDetailsList);
- }
-
- [Then(@"the following operator details are in the list")]
- public async Task ThenTheFollowingOperatorDetailsAreInTheList(DataTable table)
- {
- List<(String, String, String, String)> operatorsList = new();
- foreach (DataTableRow tableRow in table.Rows)
- {
- operatorsList.Add((ReqnrollTableHelper.GetStringRowValue(tableRow, "OperatorName"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "RequireCustomMerchantNumber"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "RequireCustomTerminalNumber"),
- null));
- }
-
- await this.UiHelpers.VerifyOperatorDetailsAreInTheList("operatorList", operatorsList);
- }
-
- [Then("the following operators are displayed in the list")]
- public async Task ThenTheFollowingOperatorsAreDisplayedInTheList(DataTable table)
- {
- List<(String, String, String, String)> operatorsList = new();
- foreach (DataTableRow tableRow in table.Rows)
- {
- operatorsList.Add((ReqnrollTableHelper.GetStringRowValue(tableRow, "OperatorName"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "MerchantNumber"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "TerminalNumber"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "IsDeleted")));
- }
-
- await this.UiHelpers.VerifyOperatorDetailsAreInTheList("merchantOperatorList", operatorsList);
- }
-
- [Then("the following contracts are displayed in the list")]
- public async Task ThenTheFollowingContractsAreDisplayedInTheList(DataTable dataTable)
- {
- List<(String, String)> contractsList = new();
- foreach (DataTableRow tableRow in dataTable.Rows)
- {
- contractsList.Add((ReqnrollTableHelper.GetStringRowValue(tableRow, "ContractName"),
- ReqnrollTableHelper.GetStringRowValue(tableRow, "IsDeleted")));
- }
-
- await this.UiHelpers.VerifyContractDetailsAreInTheList("merchantContractList", contractsList);
- }
-
- [When("I click on the New Contract Button")]
- public async Task WhenIClickOnTheNewContractButton()
- {
- await this.UiHelpers.ClickAddNewContractButton();
- }
-
- [Then("the New Contract Screen is displayed")]
- public async Task ThenTheNewContractScreenIsDisplayed()
- {
- await this.UiHelpers.VerifyOnTheNewContractScreen();
- }
-
- [When("I enter the following details for the new Merchant")]
- public async Task WhenIEnterTheFollowingDetailsForTheNewMerchant(DataTable dataTable)
- {
- DataTableRow row = dataTable.Rows.Single();
-
- await this.UiHelpers.FillInNewMerchantForm(
- ReqnrollTableHelper.GetStringRowValue(row, "MerchantName"),
- ReqnrollTableHelper.GetStringRowValue(row, "SettlementSchedule"),
- ReqnrollTableHelper.GetStringRowValue(row, "AddressLine1"),
- ReqnrollTableHelper.GetStringRowValue(row, "Town"),
- ReqnrollTableHelper.GetStringRowValue(row, "Region"),
- ReqnrollTableHelper.GetStringRowValue(row, "Country"),
- ReqnrollTableHelper.GetStringRowValue(row, "ContactName"),
- ReqnrollTableHelper.GetStringRowValue(row, "EmailAddress"));
- }
-
- [When("click the Create Merchant button")]
- public async Task WhenClickTheCreateMerchantButton()
- {
- await this.UiHelpers.ClickTheCreateMerchantButton();
- }
-
- [When("click the Update Merchant button")]
- public async Task WhenClickTheUpdateMerchantButton()
- {
- await this.UiHelpers.ClickTheUpdateMerchantButton();
- }
-
- [When("I enter the following details for the updated Merchant")]
- public async Task WhenIEnterTheFollowingDetailsForTheUpdatedMerchant(DataTable dataTable)
- {
- foreach (DataTableRow row in dataTable.Rows)
- {
- String tab = ReqnrollTableHelper.GetStringRowValue(row, "Tab");
- String field = ReqnrollTableHelper.GetStringRowValue(row, "Field");
- String value = ReqnrollTableHelper.GetStringRowValue(row, "Value");
-
- await this.UiHelpers.UpdateMerchantField(tab, field, value);
- }
- }
-
- [When("I enter the following details for the deposit")]
- public async Task WhenIEnterTheFollowingDetailsForTheDeposit(DataTable dataTable)
- {
- DataTableRow row = dataTable.Rows.Single();
-
- await this.UiHelpers.FillInDepositForm(
- ReqnrollTableHelper.GetStringRowValue(row, "Amount"),
- ReqnrollTableHelper.GetStringRowValue(row, "Date"),
- ReqnrollTableHelper.GetStringRowValue(row, "Reference"));
- }
-
- [When("click the Make Deposit button")]
- public async Task WhenClickTheMakeDepositButton()
- {
- await this.UiHelpers.ClickTheMakeDepositButton();
- }
-
- [When("I click on the View Merchant Button for {string}")]
- public async Task WhenIClickOnTheViewMerchantButtonFor(string merchantName)
- {
- await this.UiHelpers.ClickTheViewMerchantButton(merchantName);
- }
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/Steps/TestDataManagementSteps.cs b/EstateManagementUI.BlazorIntegrationTests/Steps/TestDataManagementSteps.cs
deleted file mode 100644
index 6747c4ef..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Steps/TestDataManagementSteps.cs
+++ /dev/null
@@ -1,170 +0,0 @@
-using EstateManagementUI.BlazorServer.Models;
-using EstateManagementUI.BlazorServer.Services;
-using Reqnroll;
-using Shouldly;
-
-namespace EstateManagementUI.BlazorIntegrationTests.Steps;
-
-///
-/// Example step definitions showing how to use the test data store
-/// These examples demonstrate CRUD operations on test data during integration tests
-///
-[Binding]
-public class TestDataManagementSteps
-{
- private readonly ITestDataStore _testDataStore;
- private readonly Guid _defaultEstateId = Guid.Parse("11111111-1111-1111-1111-111111111111");
-
- public TestDataManagementSteps(ITestDataStore testDataStore)
- {
- _testDataStore = testDataStore;
- }
-
- // Example: Adding a merchant dynamically during test
- [Given(@"I have added a merchant with name ""(.*)"" and reference ""(.*)""")]
- public void GivenIHaveAddedMerchant(string merchantName, string merchantReference)
- {
- var merchant = new MerchantModel
- {
- MerchantId = Guid.NewGuid(),
- MerchantName = merchantName,
- MerchantReference = merchantReference,
- Balance = 0,
- AvailableBalance = 0,
- SettlementSchedule = "Immediate"
- };
-
- _testDataStore.AddMerchant(_defaultEstateId, merchant);
- }
-
- // Example: Verifying merchant exists
- [Then(@"the merchant ""(.*)"" should exist in the system")]
- public void ThenMerchantShouldExist(string merchantReference)
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
- var merchant = merchants.FirstOrDefault(m => m.MerchantReference == merchantReference);
-
- merchant.ShouldNotBeNull();
- }
-
- // Example: Updating merchant balance
- [When(@"I update the balance of merchant ""(.*)"" to (.*)")]
- public void WhenIUpdateMerchantBalance(string merchantReference, decimal newBalance)
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
- var merchant = merchants.FirstOrDefault(m => m.MerchantReference == merchantReference);
-
- merchant.ShouldNotBeNull();
- merchant.Balance = newBalance;
-
- _testDataStore.UpdateMerchant(_defaultEstateId, merchant);
- }
-
- // Example: Verifying merchant balance
- [Then(@"the merchant ""(.*)"" should have a balance of (.*)")]
- public void ThenMerchantShouldHaveBalance(string merchantReference, decimal expectedBalance)
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
- var merchant = merchants.FirstOrDefault(m => m.MerchantReference == merchantReference);
-
- merchant.ShouldNotBeNull();
- merchant.Balance.ShouldBe(expectedBalance);
- }
-
- // Example: Removing a merchant
- [When(@"I remove the merchant ""(.*)""")]
- public void WhenIRemoveMerchant(string merchantReference)
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
- var merchant = merchants.FirstOrDefault(m => m.MerchantReference == merchantReference);
-
- merchant.ShouldNotBeNull();
- _testDataStore.RemoveMerchant(_defaultEstateId, merchant.MerchantId);
- }
-
- // Example: Verifying merchant doesn't exist
- [Then(@"the merchant ""(.*)"" should not exist in the system")]
- public void ThenMerchantShouldNotExist(string merchantReference)
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
- var merchant = merchants.FirstOrDefault(m => m.MerchantReference == merchantReference);
-
- merchant.ShouldBeNull();
- }
-
- // Example: Adding an operator
- [Given(@"I have added an operator with name ""(.*)""")]
- public void GivenIHaveAddedOperator(string operatorName)
- {
- var operatorModel = new OperatorModel
- {
- OperatorId = Guid.NewGuid(),
- Name = operatorName,
- RequireCustomMerchantNumber = false,
- RequireCustomTerminalNumber = false
- };
-
- _testDataStore.AddOperator(_defaultEstateId, operatorModel);
- }
-
- // Example: Verifying operator count
- [Then(@"there should be (.*) operators in the system")]
- public void ThenThereShouldBeOperators(int expectedCount)
- {
- var operators = _testDataStore.GetOperators(_defaultEstateId);
- operators.Count.ShouldBe(expectedCount);
- }
-
- // Example: Adding a contract
- [Given(@"I have added a contract with description ""(.*)"" for operator ""(.*)""")]
- public void GivenIHaveAddedContract(string description, string operatorName)
- {
- var operators = _testDataStore.GetOperators(_defaultEstateId);
- var operatorModel = operators.FirstOrDefault(o => o.Name == operatorName);
-
- operatorModel.ShouldNotBeNull();
-
- var contract = new ContractModel
- {
- ContractId = Guid.NewGuid(),
- Description = description,
- OperatorId = operatorModel.OperatorId,
- OperatorName = operatorModel.Name,
- Products = new List()
- };
-
- _testDataStore.AddContract(_defaultEstateId, contract);
- }
-
- // Example: Verifying contract exists
- [Then(@"the contract ""(.*)"" should exist in the system")]
- public void ThenContractShouldExist(string description)
- {
- var contracts = _testDataStore.GetContracts(_defaultEstateId);
- var contract = contracts.FirstOrDefault(c => c.Description == description);
-
- contract.ShouldNotBeNull();
- }
-
- // Example: Resetting test data (useful in BeforeScenario hook)
- [Given(@"the system is reset to default state")]
- public void GivenSystemIsReset()
- {
- _testDataStore.Reset();
- }
-
- // Example: Verifying default merchants exist
- [Then(@"the default test merchants should exist")]
- public void ThenDefaultMerchantsShouldExist()
- {
- var merchants = _testDataStore.GetMerchants(_defaultEstateId);
-
- // Default setup includes 3 merchants
- merchants.Count.ShouldBeGreaterThanOrEqualTo(3);
-
- // Verify specific default merchants
- merchants.ShouldContain(m => m.MerchantReference == "MERCH001");
- merchants.ShouldContain(m => m.MerchantReference == "MERCH002");
- merchants.ShouldContain(m => m.MerchantReference == "MERCH003");
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/TEST_INFRASTRUCTURE.md b/EstateManagementUI.BlazorIntegrationTests/TEST_INFRASTRUCTURE.md
deleted file mode 100644
index e5687625..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/TEST_INFRASTRUCTURE.md
+++ /dev/null
@@ -1,247 +0,0 @@
-# Test Infrastructure Enhancement
-
-## Overview
-
-This document describes the enhanced test infrastructure that enables Blazor integration tests to run without Docker containers for OIDC authentication and provides editable test data management.
-
-## Key Features
-
-### 1. Test Mode Configuration
-
-The application can run in "Test Mode" by setting the `AppSettings:TestMode` configuration to `true`. In test mode:
-
-- **OIDC Authentication is bypassed** using a `TestAuthenticationHandler`
-- **Test data is managed in-memory** using the `TestDataStore`
-- **No external dependencies** are required for authentication or data storage
-
-#### Configuration
-
-In `appsettings.Test.json` or via environment variables:
-
-```json
-{
- "AppSettings": {
- "TestMode": true
- }
-}
-```
-
-### 2. OIDC Authentication Bypass
-
-The `TestAuthenticationHandler` provides automatic authentication for tests without requiring an OIDC server:
-
-- Automatically authenticates all requests
-- Provides test user claims (user ID, name, email, estate ID, role)
-- Eliminates the need for SecurityService Docker containers during testing
-
-**Implementation**: See `EstateManagementUI.BlazorServer/Common/TestAuthenticationHandler.cs`
-
-### 3. Editable In-Memory Test Data
-
-The test infrastructure provides a complete in-memory data store with CRUD operations:
-
-#### ITestDataStore Interface
-
-Provides methods for managing test data:
-
-- **Estate Management**: `GetEstate()`, `SetEstate()`
-- **Merchant Management**: `GetMerchants()`, `GetMerchant()`, `AddMerchant()`, `UpdateMerchant()`, `RemoveMerchant()`
-- **Operator Management**: `GetOperators()`, `GetOperator()`, `AddOperator()`, `UpdateOperator()`, `RemoveOperator()`
-- **Contract Management**: `GetContracts()`, `GetContract()`, `AddContract()`, `UpdateContract()`, `RemoveContract()`
-- **Reset**: `Reset()` - Clears all data and reinitializes with defaults
-
-**Implementation**: See `EstateManagementUI.BlazorServer/Services/ITestDataStore.cs`
-
-#### TestDataStore Implementation
-
-Thread-safe in-memory storage using `ConcurrentDictionary`:
-
-- Stores data organized by Estate ID
-- Provides data isolation between estates
-- Includes default test data on initialization
-- Can be reset between test scenarios
-
-**Implementation**: See `EstateManagementUI.BlazorServer/Services/TestDataStore.cs`
-
-### 4. TestMediatorService
-
-The `TestMediatorService` maintains the mediator pattern while using the in-memory test data store:
-
-- All queries read from the `TestDataStore`
-- All commands execute against the `TestDataStore`
-- CRUD operations are properly reflected in test data
-- Dashboard and file processing queries return mock data
-
-**Implementation**: See `EstateManagementUI.BlazorServer/Services/TestMediatorService.cs`
-
-## Default Test Data
-
-When the `TestDataStore` is initialized (or reset), it contains:
-
-### Estate
-- **Estate ID**: `11111111-1111-1111-1111-111111111111`
-- **Name**: "Test Estate"
-
-### Merchants
-1. **Test Merchant 1** (ID: `22222222-2222-2222-2222-222222222222`)
- - Reference: MERCH001
- - Balance: £10,000.00
- - Settlement: Immediate
-
-2. **Test Merchant 2** (ID: `22222222-2222-2222-2222-222222222223`)
- - Reference: MERCH002
- - Balance: £5,000.00
- - Settlement: Weekly
-
-3. **Test Merchant 3** (ID: `22222222-2222-2222-2222-222222222224`)
- - Reference: MERCH003
- - Balance: £15,000.00
- - Settlement: Monthly
-
-### Operators
-1. **Safaricom** (ID: `33333333-3333-3333-3333-333333333333`)
- - Requires Custom Merchant Number: Yes
- - Requires Custom Terminal Number: No
-
-2. **Voucher** (ID: `33333333-3333-3333-3333-333333333334`)
- - Requires Custom Merchant Number: No
- - Requires Custom Terminal Number: No
-
-### Contracts
-1. **Standard Transaction Contract** (ID: `44444444-4444-4444-4444-444444444444`)
- - Operator: Safaricom
- - Products: Mobile Topup with transaction fees
-
-2. **Voucher Sales Contract** (ID: `44444444-4444-4444-4444-444444444445`)
- - Operator: Voucher
- - Products: Voucher Purchase
-
-## Using Test Data in Integration Tests
-
-### TestDataHelper
-
-The `TestDataHelper` class provides easy access to test data operations:
-
-```csharp
-// Access default estate
-var estateId = testDataHelper.DefaultEstateId;
-
-// Get merchants
-var merchants = testDataHelper.GetMerchants(estateId);
-
-// Add a new merchant
-var newMerchant = testDataHelper.CreateTestMerchant(
- estateId,
- "New Merchant",
- "NEWMERCH001"
-);
-
-// Update a merchant
-var merchant = testDataHelper.GetMerchant(estateId, merchantId);
-merchant.MerchantName = "Updated Name";
-testDataHelper.UpdateMerchant(estateId, merchant);
-
-// Remove a merchant
-testDataHelper.RemoveMerchant(estateId, merchantId);
-
-// Reset all data between tests
-testDataHelper.Reset();
-```
-
-### Test Isolation
-
-To ensure tests don't interfere with each other:
-
-1. **Use `Reset()` before each scenario**: Resets data to default state
-2. **Create unique test data**: Use unique IDs for test-specific entities
-3. **Clean up after tests**: Remove test-specific data if not using `Reset()`
-
-Example in Reqnroll hooks:
-
-```csharp
-[BeforeScenario]
-public void BeforeScenario()
-{
- // Reset test data to default state
- testDataHelper.Reset();
-}
-```
-
-## Running Tests in Test Mode
-
-### Option 1: Environment Variable
-
-Set the environment variable before running tests:
-
-```bash
-export AppSettings__TestMode=true
-dotnet test
-```
-
-### Option 2: Test Configuration File
-
-The application will automatically load `appsettings.Test.json` when running in test environment:
-
-```bash
-ASPNETCORE_ENVIRONMENT=Test dotnet test
-```
-
-### Option 3: Docker Environment Variables
-
-When running the Blazor app in Docker for integration tests:
-
-```yaml
-environment:
- - AppSettings__TestMode=true
-```
-
-## Benefits
-
-1. **Faster Test Execution**: No need to start Docker containers for OIDC
-2. **Simpler Setup**: Reduced infrastructure requirements
-3. **Flexible Data Management**: Easy to create, modify, and verify test data
-4. **Data Isolation**: Each test can have its own data state
-5. **Maintains Architecture**: Continues using the mediator pattern
-
-## Architecture Notes
-
-The test infrastructure maintains the application's architectural patterns:
-
-- **Mediator Pattern**: `TestMediatorService` implements `IMediator`
-- **Dependency Injection**: Test services are registered in the DI container
-- **Configuration-Based**: Test mode is controlled via configuration
-- **Clean Separation**: Test code is isolated in specific classes
-
-## Migration from Docker-Based Tests
-
-Existing tests can be migrated to use test mode:
-
-1. Remove Docker setup for OIDC containers
-2. Set `AppSettings:TestMode=true` in test configuration
-3. Use `TestDataHelper` to set up test data
-4. Remove OIDC-specific test steps
-5. Update test steps to use in-memory data
-
-## Troubleshooting
-
-### Tests can't authenticate
-- Ensure `AppSettings:TestMode` is set to `true`
-- Check that `TestAuthenticationHandler` is registered
-
-### Data not persisting between steps
-- Verify you're not calling `Reset()` between steps in the same scenario
-- Check that you're using the same `TestDataStore` instance (it's registered as singleton)
-
-### Data from previous tests appearing
-- Call `Reset()` in `BeforeScenario` hooks to ensure clean state
-- Verify test isolation is properly configured
-
-## Future Enhancements
-
-Potential improvements to consider:
-
-1. **Custom test user claims**: Allow tests to specify different user contexts
-2. **Test data fixtures**: Pre-defined test data sets for common scenarios
-3. **Data snapshots**: Save and restore test data states
-4. **Query verification**: Track which queries were executed during tests
-5. **Command history**: Record all commands executed for verification
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature b/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature
deleted file mode 100644
index 1d25d48d..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature
+++ /dev/null
@@ -1,128 +0,0 @@
-@base @shared @uigeneral
-Feature: Contract Tests
-
-Background:
-
- Given I create the following roles
- | Role Name |
- | Estate |
-
- Given I create the following api scopes
- | Name | DisplayName | Description |
- | estateManagement | Estate Managememt REST Scope | A scope for Estate Managememt REST |
- | transactionProcessor | Transaction Processor REST Scope | Scope for Transaction Processor REST |
- | fileProcessor | File Processor REST Scope | Scope for File Processor REST |
-
- Given I create the following api resources
- | Name | DisplayName | Secret | Scopes | UserClaims |
- | estateManagement | Estate Managememt REST | Secret1 | estateManagement | merchantId,estateId,role |
- | transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId,estateId,role |
- | fileProcessor | File Processor REST | Secret1 | fileProcessor | merchantId,estateId,role |
-
- Given I create the following identity resources
- | Name | DisplayName | Description | UserClaims |
- | openid | Your user identifier | | sub |
- | profile | User profile | Your user profile information (first name, last name, etc.) | name,role,email,given_name,middle_name,family_name,estateId,merchantId |
- | email | Email | Email and Email Verified Flags | email_verified,email |
-
- Given I create the following clients
- | ClientId | Name | Secret | Scopes | GrantTypes | RedirectUris | PostLogoutRedirectUris | RequireConsent | AllowOfflineAccess | ClientUri |
- | serviceClient | Service Client | Secret1 | estateManagement,transactionProcessor | client_credentials | | | | | |
- | estateUIClient | Merchant Client | Secret1 | estateManagement,fileProcessor,transactionProcessor,openid,email,profile | hybrid | https://localhost:[port]/signin-oidc | https://localhost:[port]/signout-oidc | false | true | https://[url]:[port] |
-
- Given I have a token to access the estate management resource
- | ClientId |
- | serviceClient |
-
- Given I have created the following estates
- | EstateName |
- | Test Estate |
-
- And I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator 1 | True | True |
- | Test Estate | Test Operator 2 | True | False |
- | Test Estate | Test Operator 3 | False | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator 1 |
- | Test Estate | Test Operator 2 |
- | Test Estate | Test Operator 3 |
-
- And I have created the following security users
- | EmailAddress | Password | GivenName | FamilyName | EstateName |
- | estateuser@testestate1.co.uk | 123456 | TestEstate | User1 | Test Estate |
-
- Given I have created the following contracts
- | EstateName | OperatorName | ContractDescription |
- | Test Estate | Test Operator 1 | Operator 1 Contract |
- | Test Estate | Test Operator 2 | Operator 2 Contract |
-
- Given I have created the following contract products
- | EstateName | OperatorName | ContractDescription | ProductName | DisplayText | Value | ProductType |
- | Test Estate | Test Operator 1 | Operator 1 Contract | 100 KES Topup | 100 KES | 100.00 | MobileTopup |
- | Test Estate | Test Operator 1 | Operator 1 Contract | Variable Topup 1 | Custom | | MobileTopup |
- | Test Estate | Test Operator 2 | Operator 2 Contract | 200 KES Topup | 200 KES | 500.00 | MobileTopup |
- | Test Estate | Test Operator 2 | Operator 2 Contract | 500 KES Topup | 500 KES | 500.00 | MobileTopup |
- | Test Estate | Test Operator 2 | Operator 2 Contract | Variable Topup 1 | Custom | | MobileTopup |
-
- Given I am on the application home page
-
- And I click on the Sign In Button
-
- Then I am presented with a login screen
-
- When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
-
- Then I am presented with the Estate Administrator Dashboard
-
-@PRTest
-Scenario: Contract PR Test
-
- Given I click on the My Contracts sidebar option
- Then I am presented with the Contracts List Screen
- And the following contract details are in the list
- | Description | OperatorName | Products |
- | Operator 1 Contract | Test Operator 1 | 2 |
- | Operator 2 Contract | Test Operator 2 | 3 |
- When I click on the New Contract Button
- Then the New Contract Screen is displayed
- When I enter the following details for the new Contract
- | Description | OperatorName |
- | Operator 3 Contract | Test Operator 3 |
- When I click the Save Contract Button
- Then I am presented with the Contracts List Screen
- And the following contract details are in the list
- | Description | OperatorName | Products |
- | Operator 1 Contract | Test Operator 1 | 2 |
- | Operator 2 Contract | Test Operator 2 | 3 |
- | Operator 3 Contract | Test Operator 3 | 0 |
- When I click on the View Products Button for 'Operator 1 Contract'
- Then the Contract Products List Screen is displayed
- And the following contract product details are in the list
- | ProductName | DisplayText | Value | ProductType |
- | 100 KES Topup | 100 KES | 100.00 | MobileTopup |
- | Variable Topup 1 | Custom | Variable | MobileTopup |
- When I click on the New Contract Product Button
- Then the New Product Screen is displayed
- When I enter the following details for the new Product
- | ProductName | DisplayText | Value | ProductType |
- | 200 KES Topup | 200 KES | 200.00 | Mobile Topup |
- When I click the Save Product Button
- Then the Contract Products List Screen is displayed
- And the following contract product details are in the list
- | ProductName | DisplayText | Value | ProductType |
- | 100 KES Topup | 100 KES | 100.00 | MobileTopup |
- | 200 KES Topup | 200 KES | 200.00 | MobileTopup |
- | Variable Topup 1 | Custom | Variable | MobileTopup |
- When I click on the View Fees Button for '100 KES Topup'
- Then the Contract Products Transaction Fees List Screen is displayed
- When I click on the New Contract Product Transaction Button
- Then the New Contract Product Transaction Screen is displayed
- When I enter the following details for the new Transaction Fee
- | Description | CalculationType | FeeType | Value |
- | Test Fixed Fee | Fixed Value | Merchant | 0.25 |
- When I click the Save Transaction Fee Button
- Then the Contract Products Transaction Fees List Screen is displayed
- #And the following contract product transaction fee details are in the list
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature.cs b/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature.cs
deleted file mode 100644
index 634c7850..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/ContractTests.feature.cs
+++ /dev/null
@@ -1,578 +0,0 @@
-// ------------------------------------------------------------------------------
-//
-// This code was generated by Reqnroll (https://reqnroll.net/).
-// Reqnroll Version:3.0.0.0
-// Reqnroll Generator Version:3.0.0.0
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-// ------------------------------------------------------------------------------
-#region Designer generated code
-#pragma warning disable
-using Reqnroll;
-namespace EstateManagementUI.BlazorIntegrationTests.Tests
-{
-
-
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "3.0.0.0")]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::NUnit.Framework.TestFixtureAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Contract Tests")]
- [global::NUnit.Framework.FixtureLifeCycleAttribute(global::NUnit.Framework.LifeCycle.InstancePerTestCase)]
- [global::NUnit.Framework.CategoryAttribute("base")]
- [global::NUnit.Framework.CategoryAttribute("shared")]
- [global::NUnit.Framework.CategoryAttribute("uigeneral")]
- public partial class ContractTestsFeature
- {
-
- private global::Reqnroll.ITestRunner testRunner;
-
- private static string[] featureTags = new string[] {
- "base",
- "shared",
- "uigeneral"};
-
- private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Tests", "Contract Tests", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages());
-
-#line 1 "ContractTests.feature"
-#line hidden
-
- [global::NUnit.Framework.OneTimeSetUpAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureSetupAsync()
- {
- }
-
- [global::NUnit.Framework.OneTimeTearDownAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureTearDownAsync()
- {
- await global::Reqnroll.TestRunnerManager.ReleaseFeatureAsync(featureInfo);
- }
-
- [global::NUnit.Framework.SetUpAttribute()]
- public async global::System.Threading.Tasks.Task TestInitializeAsync()
- {
- testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo);
- try
- {
- if (((testRunner.FeatureContext != null)
- && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false)))
- {
- await testRunner.OnFeatureEndAsync();
- }
- }
- finally
- {
- if (((testRunner.FeatureContext != null)
- && testRunner.FeatureContext.BeforeFeatureHookFailed))
- {
- throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error");
- }
- if ((testRunner.FeatureContext == null))
- {
- await testRunner.OnFeatureStartAsync(featureInfo);
- }
- }
- }
-
- [global::NUnit.Framework.TearDownAttribute()]
- public async global::System.Threading.Tasks.Task TestTearDownAsync()
- {
- if ((testRunner == null))
- {
- return;
- }
- try
- {
- await testRunner.OnScenarioEndAsync();
- }
- finally
- {
- global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner);
- testRunner = null;
- }
- }
-
- public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, global::Reqnroll.RuleInfo ruleInfo)
- {
- testRunner.OnScenarioInitialize(scenarioInfo, ruleInfo);
- testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(global::NUnit.Framework.TestContext.CurrentContext);
- }
-
- public async global::System.Threading.Tasks.Task ScenarioStartAsync()
- {
- await testRunner.OnScenarioStartAsync();
- }
-
- public async global::System.Threading.Tasks.Task ScenarioCleanupAsync()
- {
- await testRunner.CollectScenarioErrorsAsync();
- }
-
- public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync()
- {
-#line 4
-#line hidden
- global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] {
- "Role Name"});
- table1.AddRow(new string[] {
- "Estate"});
-#line 6
- await testRunner.GivenAsync("I create the following roles", ((string)(null)), table1, "Given ");
-#line hidden
- global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description"});
- table2.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST Scope",
- "A scope for Estate Managememt REST"});
- table2.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST Scope",
- "Scope for Transaction Processor REST"});
- table2.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST Scope",
- "Scope for File Processor REST"});
-#line 10
- await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table2, "Given ");
-#line hidden
- global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Secret",
- "Scopes",
- "UserClaims"});
- table3.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST",
- "Secret1",
- "estateManagement",
- "merchantId,estateId,role"});
- table3.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST",
- "Secret1",
- "transactionProcessor",
- "merchantId,estateId,role"});
- table3.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST",
- "Secret1",
- "fileProcessor",
- "merchantId,estateId,role"});
-#line 16
- await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table3, "Given ");
-#line hidden
- global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description",
- "UserClaims"});
- table4.AddRow(new string[] {
- "openid",
- "Your user identifier",
- "",
- "sub"});
- table4.AddRow(new string[] {
- "profile",
- "User profile",
- "Your user profile information (first name, last name, etc.)",
- "name,role,email,given_name,middle_name,family_name,estateId,merchantId"});
- table4.AddRow(new string[] {
- "email",
- "Email",
- "Email and Email Verified Flags",
- "email_verified,email"});
-#line 22
- await testRunner.GivenAsync("I create the following identity resources", ((string)(null)), table4, "Given ");
-#line hidden
- global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] {
- "ClientId",
- "Name",
- "Secret",
- "Scopes",
- "GrantTypes",
- "RedirectUris",
- "PostLogoutRedirectUris",
- "RequireConsent",
- "AllowOfflineAccess",
- "ClientUri"});
- table5.AddRow(new string[] {
- "serviceClient",
- "Service Client",
- "Secret1",
- "estateManagement,transactionProcessor",
- "client_credentials",
- "",
- "",
- "",
- "",
- ""});
- table5.AddRow(new string[] {
- "estateUIClient",
- "Merchant Client",
- "Secret1",
- "estateManagement,fileProcessor,transactionProcessor,openid,email,profile",
- "hybrid",
- "https://localhost:[port]/signin-oidc",
- "https://localhost:[port]/signout-oidc",
- "false",
- "true",
- "https://[url]:[port]"});
-#line 28
- await testRunner.GivenAsync("I create the following clients", ((string)(null)), table5, "Given ");
-#line hidden
- global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] {
- "ClientId"});
- table6.AddRow(new string[] {
- "serviceClient"});
-#line 33
- await testRunner.GivenAsync("I have a token to access the estate management resource", ((string)(null)), table6, "Given ");
-#line hidden
- global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] {
- "EstateName"});
- table7.AddRow(new string[] {
- "Test Estate"});
-#line 37
- await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table7, "Given ");
-#line hidden
- global::Reqnroll.Table table8 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table8.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1",
- "True",
- "True"});
- table8.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "True",
- "False"});
- table8.AddRow(new string[] {
- "Test Estate",
- "Test Operator 3",
- "False",
- "True"});
-#line 41
- await testRunner.AndAsync("I have created the following operators", ((string)(null)), table8, "And ");
-#line hidden
- global::Reqnroll.Table table9 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table9.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1"});
- table9.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2"});
- table9.AddRow(new string[] {
- "Test Estate",
- "Test Operator 3"});
-#line 47
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table9, "And ");
-#line hidden
- global::Reqnroll.Table table10 = new global::Reqnroll.Table(new string[] {
- "EmailAddress",
- "Password",
- "GivenName",
- "FamilyName",
- "EstateName"});
- table10.AddRow(new string[] {
- "estateuser@testestate1.co.uk",
- "123456",
- "TestEstate",
- "User1",
- "Test Estate"});
-#line 53
- await testRunner.AndAsync("I have created the following security users", ((string)(null)), table10, "And ");
-#line hidden
- global::Reqnroll.Table table11 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "ContractDescription"});
- table11.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1",
- "Operator 1 Contract"});
- table11.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "Operator 2 Contract"});
-#line 57
- await testRunner.GivenAsync("I have created the following contracts", ((string)(null)), table11, "Given ");
-#line hidden
- global::Reqnroll.Table table12 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "ContractDescription",
- "ProductName",
- "DisplayText",
- "Value",
- "ProductType"});
- table12.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1",
- "Operator 1 Contract",
- "100 KES Topup",
- "100 KES",
- "100.00",
- "MobileTopup"});
- table12.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1",
- "Operator 1 Contract",
- "Variable Topup 1",
- "Custom",
- "",
- "MobileTopup"});
- table12.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "Operator 2 Contract",
- "200 KES Topup",
- "200 KES",
- "500.00",
- "MobileTopup"});
- table12.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "Operator 2 Contract",
- "500 KES Topup",
- "500 KES",
- "500.00",
- "MobileTopup"});
- table12.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "Operator 2 Contract",
- "Variable Topup 1",
- "Custom",
- "",
- "MobileTopup"});
-#line 62
- await testRunner.GivenAsync("I have created the following contract products", ((string)(null)), table12, "Given ");
-#line hidden
-#line 70
- await testRunner.GivenAsync("I am on the application home page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 72
- await testRunner.AndAsync("I click on the Sign In Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 74
- await testRunner.ThenAsync("I am presented with a login screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 76
- await testRunner.WhenAsync("I login with the username \'estateuser@testestate1.co.uk\' and password \'123456\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 78
- await testRunner.ThenAsync("I am presented with the Estate Administrator Dashboard", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
-
- private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages()
- {
- return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Tests/ContractTests.feature.ndjson", 3);
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Contract PR Test")]
- [global::NUnit.Framework.CategoryAttribute("PRTest")]
- public async global::System.Threading.Tasks.Task ContractPRTest()
- {
- string[] tagsOfScenario = new string[] {
- "PRTest"};
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "0";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Contract PR Test", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 81
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 83
- await testRunner.GivenAsync("I click on the My Contracts sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 84
- await testRunner.ThenAsync("I am presented with the Contracts List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table13 = new global::Reqnroll.Table(new string[] {
- "Description",
- "OperatorName",
- "Products"});
- table13.AddRow(new string[] {
- "Operator 1 Contract",
- "Test Operator 1",
- "2"});
- table13.AddRow(new string[] {
- "Operator 2 Contract",
- "Test Operator 2",
- "3"});
-#line 85
- await testRunner.AndAsync("the following contract details are in the list", ((string)(null)), table13, "And ");
-#line hidden
-#line 89
- await testRunner.WhenAsync("I click on the New Contract Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 90
- await testRunner.ThenAsync("the New Contract Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table14 = new global::Reqnroll.Table(new string[] {
- "Description",
- "OperatorName"});
- table14.AddRow(new string[] {
- "Operator 3 Contract",
- "Test Operator 3"});
-#line 91
- await testRunner.WhenAsync("I enter the following details for the new Contract", ((string)(null)), table14, "When ");
-#line hidden
-#line 94
- await testRunner.WhenAsync("I click the Save Contract Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 95
- await testRunner.ThenAsync("I am presented with the Contracts List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table15 = new global::Reqnroll.Table(new string[] {
- "Description",
- "OperatorName",
- "Products"});
- table15.AddRow(new string[] {
- "Operator 1 Contract",
- "Test Operator 1",
- "2"});
- table15.AddRow(new string[] {
- "Operator 2 Contract",
- "Test Operator 2",
- "3"});
- table15.AddRow(new string[] {
- "Operator 3 Contract",
- "Test Operator 3",
- "0"});
-#line 96
- await testRunner.AndAsync("the following contract details are in the list", ((string)(null)), table15, "And ");
-#line hidden
-#line 101
- await testRunner.WhenAsync("I click on the View Products Button for \'Operator 1 Contract\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 102
- await testRunner.ThenAsync("the Contract Products List Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table16 = new global::Reqnroll.Table(new string[] {
- "ProductName",
- "DisplayText",
- "Value",
- "ProductType"});
- table16.AddRow(new string[] {
- "100 KES Topup",
- "100 KES",
- "100.00",
- "MobileTopup"});
- table16.AddRow(new string[] {
- "Variable Topup 1",
- "Custom",
- "Variable",
- "MobileTopup"});
-#line 103
- await testRunner.AndAsync("the following contract product details are in the list", ((string)(null)), table16, "And ");
-#line hidden
-#line 107
- await testRunner.WhenAsync("I click on the New Contract Product Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 108
- await testRunner.ThenAsync("the New Product Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table17 = new global::Reqnroll.Table(new string[] {
- "ProductName",
- "DisplayText",
- "Value",
- "ProductType"});
- table17.AddRow(new string[] {
- "200 KES Topup",
- "200 KES",
- "200.00",
- "Mobile Topup"});
-#line 109
- await testRunner.WhenAsync("I enter the following details for the new Product", ((string)(null)), table17, "When ");
-#line hidden
-#line 112
- await testRunner.WhenAsync("I click the Save Product Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 113
- await testRunner.ThenAsync("the Contract Products List Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table18 = new global::Reqnroll.Table(new string[] {
- "ProductName",
- "DisplayText",
- "Value",
- "ProductType"});
- table18.AddRow(new string[] {
- "100 KES Topup",
- "100 KES",
- "100.00",
- "MobileTopup"});
- table18.AddRow(new string[] {
- "200 KES Topup",
- "200 KES",
- "200.00",
- "MobileTopup"});
- table18.AddRow(new string[] {
- "Variable Topup 1",
- "Custom",
- "Variable",
- "MobileTopup"});
-#line 114
- await testRunner.AndAsync("the following contract product details are in the list", ((string)(null)), table18, "And ");
-#line hidden
-#line 119
- await testRunner.WhenAsync("I click on the View Fees Button for \'100 KES Topup\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 120
- await testRunner.ThenAsync("the Contract Products Transaction Fees List Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 121
- await testRunner.WhenAsync("I click on the New Contract Product Transaction Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 122
- await testRunner.ThenAsync("the New Contract Product Transaction Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table19 = new global::Reqnroll.Table(new string[] {
- "Description",
- "CalculationType",
- "FeeType",
- "Value"});
- table19.AddRow(new string[] {
- "Test Fixed Fee",
- "Fixed Value",
- "Merchant",
- "0.25"});
-#line 123
- await testRunner.WhenAsync("I enter the following details for the new Transaction Fee", ((string)(null)), table19, "When ");
-#line hidden
-#line 126
- await testRunner.WhenAsync("I click the Save Transaction Fee Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 127
- await testRunner.ThenAsync("the Contract Products Transaction Fees List Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
- }
-}
-#pragma warning restore
-#endregion
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature b/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature
deleted file mode 100644
index 2343d9de..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature
+++ /dev/null
@@ -1,85 +0,0 @@
-@base @shared @uigeneral
-Feature: Estate Tests
-
-Background:
-
- Given I create the following roles
- | Role Name |
- | Estate |
-
- Given I create the following api scopes
- | Name | DisplayName | Description |
- | estateManagement | Estate Managememt REST Scope | A scope for Estate Managememt REST |
- | transactionProcessor | Transaction Processor REST Scope | Scope for Transaction Processor REST |
- | fileProcessor | File Processor REST Scope | Scope for File Processor REST |
-
- Given I create the following api resources
- | Name | DisplayName | Secret | Scopes | UserClaims |
- | estateManagement | Estate Managememt REST | Secret1 | estateManagement | merchantId,estateId,role |
- | transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId,estateId,role |
- | fileProcessor | File Processor REST | Secret1 | fileProcessor | merchantId,estateId,role |
-
- Given I create the following identity resources
- | Name | DisplayName | Description | UserClaims |
- | openid | Your user identifier | | sub |
- | profile | User profile | Your user profile information (first name, last name, etc.) | name,role,email,given_name,middle_name,family_name,estateId,merchantId |
- | email | Email | Email and Email Verified Flags | email_verified,email |
-
- Given I create the following clients
- | ClientId | Name | Secret | Scopes | GrantTypes | RedirectUris | PostLogoutRedirectUris | RequireConsent | AllowOfflineAccess | ClientUri |
- | serviceClient | Service Client | Secret1 | estateManagement,transactionProcessor | client_credentials | | | | | |
- | estateUIClient | Merchant Client | Secret1 | estateManagement,fileProcessor,transactionProcessor,openid,email,profile | hybrid | https://localhost:[port]/signin-oidc | https://localhost:[port]/signout-oidc | false | true | https://[url]:[port] |
-
- Given I have a token to access the estate management resource
- | ClientId |
- | serviceClient |
-
- Given I have created the following estates
- | EstateName |
- | Test Estate |
-
- And I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator | True | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator |
-
- And I have created the following security users
- | EmailAddress | Password | GivenName | FamilyName | EstateName |
- | estateuser@testestate1.co.uk | 123456 | TestEstate | User1 | Test Estate |
-
-
-Scenario: I Can Log Into The Application
-
- Given I am on the application home page
-
- And I click on the Sign In Button
-
- Then I am presented with a login screen
-
- When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
-
- Then I am presented with the Estate Administrator Dashboard
-
-@PRTest
-Scenario: View Estate Details
-
- Given I am on the application home page
-
- And I click on the Sign In Button
-
- Then I am presented with a login screen
-
- When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
-
- Then I am presented with the Estate Administrator Dashboard
-
- Given I click on the My Estate sidebar option
-
- Then I am presented with the View Estate Page
-
- And My Estate Details will be shown
- | EstateName |
- | Test Estate |
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature.cs b/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature.cs
deleted file mode 100644
index 0fd73ed3..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/EstateTests.feature.cs
+++ /dev/null
@@ -1,387 +0,0 @@
-// ------------------------------------------------------------------------------
-//
-// This code was generated by Reqnroll (https://reqnroll.net/).
-// Reqnroll Version:3.0.0.0
-// Reqnroll Generator Version:3.0.0.0
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-// ------------------------------------------------------------------------------
-#region Designer generated code
-#pragma warning disable
-using Reqnroll;
-namespace EstateManagementUI.BlazorIntegrationTests.Tests
-{
-
-
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "3.0.0.0")]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::NUnit.Framework.TestFixtureAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Estate Tests")]
- [global::NUnit.Framework.FixtureLifeCycleAttribute(global::NUnit.Framework.LifeCycle.InstancePerTestCase)]
- [global::NUnit.Framework.CategoryAttribute("base")]
- [global::NUnit.Framework.CategoryAttribute("shared")]
- [global::NUnit.Framework.CategoryAttribute("uigeneral")]
- public partial class EstateTestsFeature
- {
-
- private global::Reqnroll.ITestRunner testRunner;
-
- private static string[] featureTags = new string[] {
- "base",
- "shared",
- "uigeneral"};
-
- private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Tests", "Estate Tests", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages());
-
-#line 1 "EstateTests.feature"
-#line hidden
-
- [global::NUnit.Framework.OneTimeSetUpAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureSetupAsync()
- {
- }
-
- [global::NUnit.Framework.OneTimeTearDownAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureTearDownAsync()
- {
- await global::Reqnroll.TestRunnerManager.ReleaseFeatureAsync(featureInfo);
- }
-
- [global::NUnit.Framework.SetUpAttribute()]
- public async global::System.Threading.Tasks.Task TestInitializeAsync()
- {
- testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo);
- try
- {
- if (((testRunner.FeatureContext != null)
- && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false)))
- {
- await testRunner.OnFeatureEndAsync();
- }
- }
- finally
- {
- if (((testRunner.FeatureContext != null)
- && testRunner.FeatureContext.BeforeFeatureHookFailed))
- {
- throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error");
- }
- if ((testRunner.FeatureContext == null))
- {
- await testRunner.OnFeatureStartAsync(featureInfo);
- }
- }
- }
-
- [global::NUnit.Framework.TearDownAttribute()]
- public async global::System.Threading.Tasks.Task TestTearDownAsync()
- {
- if ((testRunner == null))
- {
- return;
- }
- try
- {
- await testRunner.OnScenarioEndAsync();
- }
- finally
- {
- global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner);
- testRunner = null;
- }
- }
-
- public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, global::Reqnroll.RuleInfo ruleInfo)
- {
- testRunner.OnScenarioInitialize(scenarioInfo, ruleInfo);
- testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(global::NUnit.Framework.TestContext.CurrentContext);
- }
-
- public async global::System.Threading.Tasks.Task ScenarioStartAsync()
- {
- await testRunner.OnScenarioStartAsync();
- }
-
- public async global::System.Threading.Tasks.Task ScenarioCleanupAsync()
- {
- await testRunner.CollectScenarioErrorsAsync();
- }
-
- public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync()
- {
-#line 4
-#line hidden
- global::Reqnroll.Table table20 = new global::Reqnroll.Table(new string[] {
- "Role Name"});
- table20.AddRow(new string[] {
- "Estate"});
-#line 6
- await testRunner.GivenAsync("I create the following roles", ((string)(null)), table20, "Given ");
-#line hidden
- global::Reqnroll.Table table21 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description"});
- table21.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST Scope",
- "A scope for Estate Managememt REST"});
- table21.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST Scope",
- "Scope for Transaction Processor REST"});
- table21.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST Scope",
- "Scope for File Processor REST"});
-#line 10
- await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table21, "Given ");
-#line hidden
- global::Reqnroll.Table table22 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Secret",
- "Scopes",
- "UserClaims"});
- table22.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST",
- "Secret1",
- "estateManagement",
- "merchantId,estateId,role"});
- table22.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST",
- "Secret1",
- "transactionProcessor",
- "merchantId,estateId,role"});
- table22.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST",
- "Secret1",
- "fileProcessor",
- "merchantId,estateId,role"});
-#line 16
- await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table22, "Given ");
-#line hidden
- global::Reqnroll.Table table23 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description",
- "UserClaims"});
- table23.AddRow(new string[] {
- "openid",
- "Your user identifier",
- "",
- "sub"});
- table23.AddRow(new string[] {
- "profile",
- "User profile",
- "Your user profile information (first name, last name, etc.)",
- "name,role,email,given_name,middle_name,family_name,estateId,merchantId"});
- table23.AddRow(new string[] {
- "email",
- "Email",
- "Email and Email Verified Flags",
- "email_verified,email"});
-#line 22
- await testRunner.GivenAsync("I create the following identity resources", ((string)(null)), table23, "Given ");
-#line hidden
- global::Reqnroll.Table table24 = new global::Reqnroll.Table(new string[] {
- "ClientId",
- "Name",
- "Secret",
- "Scopes",
- "GrantTypes",
- "RedirectUris",
- "PostLogoutRedirectUris",
- "RequireConsent",
- "AllowOfflineAccess",
- "ClientUri"});
- table24.AddRow(new string[] {
- "serviceClient",
- "Service Client",
- "Secret1",
- "estateManagement,transactionProcessor",
- "client_credentials",
- "",
- "",
- "",
- "",
- ""});
- table24.AddRow(new string[] {
- "estateUIClient",
- "Merchant Client",
- "Secret1",
- "estateManagement,fileProcessor,transactionProcessor,openid,email,profile",
- "hybrid",
- "https://localhost:[port]/signin-oidc",
- "https://localhost:[port]/signout-oidc",
- "false",
- "true",
- "https://[url]:[port]"});
-#line 28
- await testRunner.GivenAsync("I create the following clients", ((string)(null)), table24, "Given ");
-#line hidden
- global::Reqnroll.Table table25 = new global::Reqnroll.Table(new string[] {
- "ClientId"});
- table25.AddRow(new string[] {
- "serviceClient"});
-#line 33
- await testRunner.GivenAsync("I have a token to access the estate management resource", ((string)(null)), table25, "Given ");
-#line hidden
- global::Reqnroll.Table table26 = new global::Reqnroll.Table(new string[] {
- "EstateName"});
- table26.AddRow(new string[] {
- "Test Estate"});
-#line 37
- await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table26, "Given ");
-#line hidden
- global::Reqnroll.Table table27 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table27.AddRow(new string[] {
- "Test Estate",
- "Test Operator",
- "True",
- "True"});
-#line 41
- await testRunner.AndAsync("I have created the following operators", ((string)(null)), table27, "And ");
-#line hidden
- global::Reqnroll.Table table28 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table28.AddRow(new string[] {
- "Test Estate",
- "Test Operator"});
-#line 45
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table28, "And ");
-#line hidden
- global::Reqnroll.Table table29 = new global::Reqnroll.Table(new string[] {
- "EmailAddress",
- "Password",
- "GivenName",
- "FamilyName",
- "EstateName"});
- table29.AddRow(new string[] {
- "estateuser@testestate1.co.uk",
- "123456",
- "TestEstate",
- "User1",
- "Test Estate"});
-#line 49
- await testRunner.AndAsync("I have created the following security users", ((string)(null)), table29, "And ");
-#line hidden
- }
-
- private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages()
- {
- return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Tests/EstateTests.feature.ndjson", 4);
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("I Can Log Into The Application")]
- public async global::System.Threading.Tasks.Task ICanLogIntoTheApplication()
- {
- string[] tagsOfScenario = ((string[])(null));
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "0";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("I Can Log Into The Application", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 54
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 56
- await testRunner.GivenAsync("I am on the application home page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 58
- await testRunner.AndAsync("I click on the Sign In Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 60
- await testRunner.ThenAsync("I am presented with a login screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 62
- await testRunner.WhenAsync("I login with the username \'estateuser@testestate1.co.uk\' and password \'123456\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 64
- await testRunner.ThenAsync("I am presented with the Estate Administrator Dashboard", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("View Estate Details")]
- [global::NUnit.Framework.CategoryAttribute("PRTest")]
- public async global::System.Threading.Tasks.Task ViewEstateDetails()
- {
- string[] tagsOfScenario = new string[] {
- "PRTest"};
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "1";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("View Estate Details", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 67
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 69
- await testRunner.GivenAsync("I am on the application home page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 71
- await testRunner.AndAsync("I click on the Sign In Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 73
- await testRunner.ThenAsync("I am presented with a login screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 75
- await testRunner.WhenAsync("I login with the username \'estateuser@testestate1.co.uk\' and password \'123456\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 77
- await testRunner.ThenAsync("I am presented with the Estate Administrator Dashboard", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 79
- await testRunner.GivenAsync("I click on the My Estate sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 81
- await testRunner.ThenAsync("I am presented with the View Estate Page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table30 = new global::Reqnroll.Table(new string[] {
- "EstateName"});
- table30.AddRow(new string[] {
- "Test Estate"});
-#line 83
- await testRunner.AndAsync("My Estate Details will be shown", ((string)(null)), table30, "And ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
- }
-}
-#pragma warning restore
-#endregion
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature b/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature
deleted file mode 100644
index cf80f96f..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature
+++ /dev/null
@@ -1,254 +0,0 @@
-@base @shared @uigeneral
-Feature: Merchant Tests
-
-Background:
-
- Given I create the following roles
- | Role Name |
- | Estate |
- | Merchant |
-
- Given I create the following api scopes
- | Name | DisplayName | Description |
- | estateManagement | Estate Managememt REST Scope | A scope for Estate Managememt REST |
- | transactionProcessor | Transaction Processor REST Scope | Scope for Transaction Processor REST |
- | fileProcessor | File Processor REST Scope | Scope for File Processor REST |
-
- Given I create the following api resources
- | Name | DisplayName | Secret | Scopes | UserClaims |
- | estateManagement | Estate Managememt REST | Secret1 | estateManagement | merchantId,estateId,role |
- | transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId,estateId,role |
- | fileProcessor | File Processor REST | Secret1 | fileProcessor | merchantId,estateId,role |
-
- Given I create the following identity resources
- | Name | DisplayName | Description | UserClaims |
- | openid | Your user identifier | | sub |
- | profile | User profile | Your user profile information (first name, last name, etc.) | name,role,email,given_name,middle_name,family_name,estateId,merchantId |
- | email | Email | Email and Email Verified Flags | email_verified,email |
-
- Given I create the following clients
- | ClientId | Name | Secret | Scopes | GrantTypes | RedirectUris | PostLogoutRedirectUris | RequireConsent | AllowOfflineAccess | ClientUri |
- | serviceClient | Service Client | Secret1 | estateManagement,transactionProcessor | client_credentials | | | | | |
- | estateUIClient | Merchant Client | Secret1 | estateManagement,fileProcessor,transactionProcessor,openid,email,profile | hybrid | https://localhost:[port]/signin-oidc | https://localhost:[port]/signout-oidc | false | true | https://[url]:[port] |
-
- Given I have a token to access the estate management resource
- | ClientId |
- | serviceClient |
-
- Given I have created the following estates
- | EstateName |
- | Test Estate |
-
- And I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator | True | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator |
-
- And I have created the following security users
- | EmailAddress | Password | GivenName | FamilyName | EstateName |
- | estateuser@testestate1.co.uk | 123456 | TestEstate | User1 | Test Estate |
-
- Given I create the following merchants
- | MerchantName | SettlementSchedule | AddressLine1 | Town | Region | Country | ContactName | EmailAddress | EstateName |
- | Test Merchant 1 | Immediate | Address Line 1 | TestTown | Test Region | United Kingdom | Test Contact 1 | testcontact1@merchant1.co.uk | Test Estate |
- | Test Merchant 2 | Weekly | Address Line 1 | TestTown | Test Region | United Kingdom | Test Contact 1 | testcontact1@merchant2.co.uk | Test Estate |
- | Test Merchant 3 | Monthly | Address Line 1 | TestTown | Test Region | United Kingdom | Test Contact 1 | testcontact1@merchant3.co.uk | Test Estate |
-
- When I assign the following operator to the merchants
- | OperatorName | MerchantName | MerchantNumber | TerminalNumber | EstateName |
- | Test Operator | Test Merchant 1 | 00000001 | 10000001 | Test Estate |
- | Test Operator | Test Merchant 2 | 00000001 | 10000001 | Test Estate |
- | Test Operator | Test Merchant 3 | 00000001 | 10000001 | Test Estate |
-
- When I create the following security users
- | EmailAddress | Password | GivenName | FamilyName | MerchantName | EstateName |
- | merchantuser1@testmerchant1.co.uk | 123456 | TestMerchant | User1 | Test Merchant 1 | Test Estate |
- | merchantuser1@testmerchant2.co.uk | 123456 | TestMerchant | User1 | Test Merchant 2 | Test Estate |
- | merchantuser1@testmerchant3.co.uk | 123456 | TestMerchant | User1 | Test Merchant 3 | Test Estate |
-
- When I add the following devices to the merchant
- | DeviceIdentifier | MerchantName | EstateName |
- | TestDevice1 | Test Merchant 1 | Test Estate |
- | TestDevice2 | Test Merchant 2 | Test Estate |
-
- Given I am on the application home page
-
- And I click on the Sign In Button
-
- Then I am presented with a login screen
-
- When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
-
- Then I am presented with the Estate Administrator Dashboard
-
-@PRTest
-Scenario: Merchant PR Test
-
- Given I click on the My Merchants sidebar option
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule |ContactName | AddressLine1 | Town |
- | Test Merchant 1 | Immediate |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 2 | Weekly |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly |Test Contact 1 | Address Line 1 | TestTown |
- When I click on the New Merchant Button
- Then the Add New Merchant Screen is displayed
- When I enter the following details for the new Merchant
- | MerchantName | SettlementSchedule | AddressLine1 | Town | Region | Country | ContactName | EmailAddress |
- | Test Merchant 4 | Immediate | Address Line 1 | TestTown | Region | Country | Test Contact 4 | 1@2.com |
- And click the Create Merchant button
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule | ContactName | AddressLine1 | Town |
- | Test Merchant 1 | Immediate | Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 2 | Weekly | Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly | Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 4 | Immediate | Test Contact 4 | Address Line 1 | TestTown |
- When I click on the Edit Merchant Button for 'Test Merchant 1'
- Then the Edit Merchant Screen is displayed
- When I enter the following details for the updated Merchant
- | Tab | Field | Value |
- | Merchant Details | MerchantName | Test Merchant 1 Update |
- | Address Details | AddressLine1 | Address Line 1 Update |
- | Contact Details | ContactName | Test Contact 1 Update |
- And click the Update Merchant button
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule | ContactName | AddressLine1 | Town |
- | Test Merchant 1 Update | Immediate | Test Contact 1 Update | Address Line 1 Update | TestTown |
- | Test Merchant 2 | Weekly | Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly | Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 4 | Immediate | Test Contact 4 | Address Line 1 | TestTown |
- #When I click on the Make Deposit Button for 'Test Merchant 1 Update'
- #Then the Make Deposit Screen is displayed
- #When I enter the following details for the deposit
- #| Amount | Date | Reference |
- #| 1000.00 | Today | Test Deposit 1 |
- #And click the Make Deposit button
- #Then I am presented with the Merchants List Screen
- When I click on the View Merchant Button for 'Test Merchant 1 Update'
- Then the View Merchant Screen is displayed
-
-
-Scenario: Merchant Operator Management
- Given I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator1 | True | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator1 |
-
- Given I click on the My Merchants sidebar option
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule |ContactName | AddressLine1 | Town |
- | Test Merchant 1 | Immediate |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 2 | Weekly |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly |Test Contact 1 | Address Line 1 | TestTown |
-
- When I click on the Edit Merchant Button for 'Test Merchant 1'
- Then the Edit Merchant Screen is displayed
-
- When I click on the Operators tab
- Then I am presented with the Merchants Operator List Screen
- And the following operators are displayed in the list
- | OperatorName | MerchantNumber | TerminalNumber |
- | Test Operator | 00000001 | 10000001 |
- When I click on the Add Operator Button
- Then the Assign Operator Dialog will be displayed
- When I enter the following details for the Operator
- | OperatorName | MerchantNumber | TerminalNumber |
- | Test Operator1 | 00000111 | 10000111 |
- And click the Assign Operator button
- Then I am presented with the Merchants Operator List Screen
- And the following operators are displayed in the list
- | OperatorName | MerchantNumber | TerminalNumber | IsDeleted |
- | Test Operator | 00000001 | 10000001 | False |
- | Test Operator1 | 00000111 | 10000111 | False |
- When I click on the Remove Operator for 'Test Operator1'
- Then I am presented with the Merchants Operator List Screen
- And the following operators are displayed in the list
- | OperatorName | MerchantNumber | TerminalNumber | IsDeleted |
- | Test Operator | 00000001 | 10000001 | False |
- | Test Operator1 | 00000111 | 10000111 | True |
-
-Scenario: Merchant Contract Management
- Given I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator1 | True | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator1 |
-
- # Does this assignt the contract to the estate automatically ??
- Given I have created the following contracts
- | EstateName | OperatorName | ContractDescription |
- | Test Estate | Test Operator1 | Operator 1 Contract |
-
- Given I click on the My Merchants sidebar option
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule |ContactName | AddressLine1 | Town |
- | Test Merchant 1 | Immediate |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 2 | Weekly |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly |Test Contact 1 | Address Line 1 | TestTown |
-
- When I click on the Edit Merchant Button for 'Test Merchant 1'
- Then the Edit Merchant Screen is displayed
-
- When I click on the Contracts tab
- Then I am presented with the Merchants Contract List Screen
- And the following contracts are displayed in the list
- | ContractName | IsDeleted |
-
- When I click on the Add Contract Button
- Then the Assign Contract Dialog will be displayed
- When I enter the following details for the Contract
- | ContractName |
- | Operator 1 Contract |
- And click the Assign Contract button
- Then I am presented with the Merchants Contract List Screen
- And the following contracts are displayed in the list
- | ContractName | IsDeleted |
- | Operator 1 Contract | False |
-
- When I click on the Remove Contract for 'Operator 1 Contract'
- Then I am presented with the Merchants Contract List Screen
- And the following contracts are displayed in the list
- | ContractName | IsDeleted |
- | Operator 1 Contract | True |
-
-
-Scenario: Merchant Device Management
-
- Given I click on the My Merchants sidebar option
- Then I am presented with the Merchants List Screen
- And the following merchants details are in the list
- | MerchantName | SettlementSchedule |ContactName | AddressLine1 | Town |
- | Test Merchant 1 | Immediate |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 2 | Weekly |Test Contact 1 | Address Line 1 | TestTown |
- | Test Merchant 3 | Monthly |Test Contact 1 | Address Line 1 | TestTown |
-
- When I click on the Edit Merchant Button for 'Test Merchant 3'
- Then the Edit Merchant Screen is displayed
-
- When I click on the Devices tab
- Then I am presented with the Merchants Device List Screen
- And the following devices are displayed in the list
- | DeviceIdentifier |
-
- When I click on the Add Device Button
- Then the Add Device Dialog will be displayed
- When I enter the following details for the Device
- | MerchantDevice |
- | 123456ABCDEF |
- And click the Add Device button
- Then I am presented with the Merchants Device List Screen
- And the following devices are displayed in the list
- | DeviceIdentifier |
- | 123456ABCDEF |
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature.cs b/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature.cs
deleted file mode 100644
index f1fb2fcb..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/MerchantTests.feature.cs
+++ /dev/null
@@ -1,1046 +0,0 @@
-// ------------------------------------------------------------------------------
-//
-// This code was generated by Reqnroll (https://reqnroll.net/).
-// Reqnroll Version:3.0.0.0
-// Reqnroll Generator Version:3.0.0.0
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-// ------------------------------------------------------------------------------
-#region Designer generated code
-#pragma warning disable
-using Reqnroll;
-namespace EstateManagementUI.BlazorIntegrationTests.Tests
-{
-
-
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "3.0.0.0")]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::NUnit.Framework.TestFixtureAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Merchant Tests")]
- [global::NUnit.Framework.FixtureLifeCycleAttribute(global::NUnit.Framework.LifeCycle.InstancePerTestCase)]
- [global::NUnit.Framework.CategoryAttribute("base")]
- [global::NUnit.Framework.CategoryAttribute("shared")]
- [global::NUnit.Framework.CategoryAttribute("uigeneral")]
- public partial class MerchantTestsFeature
- {
-
- private global::Reqnroll.ITestRunner testRunner;
-
- private static string[] featureTags = new string[] {
- "base",
- "shared",
- "uigeneral"};
-
- private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Tests", "Merchant Tests", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages());
-
-#line 1 "MerchantTests.feature"
-#line hidden
-
- [global::NUnit.Framework.OneTimeSetUpAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureSetupAsync()
- {
- }
-
- [global::NUnit.Framework.OneTimeTearDownAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureTearDownAsync()
- {
- await global::Reqnroll.TestRunnerManager.ReleaseFeatureAsync(featureInfo);
- }
-
- [global::NUnit.Framework.SetUpAttribute()]
- public async global::System.Threading.Tasks.Task TestInitializeAsync()
- {
- testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo);
- try
- {
- if (((testRunner.FeatureContext != null)
- && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false)))
- {
- await testRunner.OnFeatureEndAsync();
- }
- }
- finally
- {
- if (((testRunner.FeatureContext != null)
- && testRunner.FeatureContext.BeforeFeatureHookFailed))
- {
- throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error");
- }
- if ((testRunner.FeatureContext == null))
- {
- await testRunner.OnFeatureStartAsync(featureInfo);
- }
- }
- }
-
- [global::NUnit.Framework.TearDownAttribute()]
- public async global::System.Threading.Tasks.Task TestTearDownAsync()
- {
- if ((testRunner == null))
- {
- return;
- }
- try
- {
- await testRunner.OnScenarioEndAsync();
- }
- finally
- {
- global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner);
- testRunner = null;
- }
- }
-
- public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, global::Reqnroll.RuleInfo ruleInfo)
- {
- testRunner.OnScenarioInitialize(scenarioInfo, ruleInfo);
- testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(global::NUnit.Framework.TestContext.CurrentContext);
- }
-
- public async global::System.Threading.Tasks.Task ScenarioStartAsync()
- {
- await testRunner.OnScenarioStartAsync();
- }
-
- public async global::System.Threading.Tasks.Task ScenarioCleanupAsync()
- {
- await testRunner.CollectScenarioErrorsAsync();
- }
-
- public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync()
- {
-#line 4
-#line hidden
- global::Reqnroll.Table table31 = new global::Reqnroll.Table(new string[] {
- "Role Name"});
- table31.AddRow(new string[] {
- "Estate"});
- table31.AddRow(new string[] {
- "Merchant"});
-#line 6
- await testRunner.GivenAsync("I create the following roles", ((string)(null)), table31, "Given ");
-#line hidden
- global::Reqnroll.Table table32 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description"});
- table32.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST Scope",
- "A scope for Estate Managememt REST"});
- table32.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST Scope",
- "Scope for Transaction Processor REST"});
- table32.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST Scope",
- "Scope for File Processor REST"});
-#line 11
- await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table32, "Given ");
-#line hidden
- global::Reqnroll.Table table33 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Secret",
- "Scopes",
- "UserClaims"});
- table33.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST",
- "Secret1",
- "estateManagement",
- "merchantId,estateId,role"});
- table33.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST",
- "Secret1",
- "transactionProcessor",
- "merchantId,estateId,role"});
- table33.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST",
- "Secret1",
- "fileProcessor",
- "merchantId,estateId,role"});
-#line 17
- await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table33, "Given ");
-#line hidden
- global::Reqnroll.Table table34 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description",
- "UserClaims"});
- table34.AddRow(new string[] {
- "openid",
- "Your user identifier",
- "",
- "sub"});
- table34.AddRow(new string[] {
- "profile",
- "User profile",
- "Your user profile information (first name, last name, etc.)",
- "name,role,email,given_name,middle_name,family_name,estateId,merchantId"});
- table34.AddRow(new string[] {
- "email",
- "Email",
- "Email and Email Verified Flags",
- "email_verified,email"});
-#line 23
- await testRunner.GivenAsync("I create the following identity resources", ((string)(null)), table34, "Given ");
-#line hidden
- global::Reqnroll.Table table35 = new global::Reqnroll.Table(new string[] {
- "ClientId",
- "Name",
- "Secret",
- "Scopes",
- "GrantTypes",
- "RedirectUris",
- "PostLogoutRedirectUris",
- "RequireConsent",
- "AllowOfflineAccess",
- "ClientUri"});
- table35.AddRow(new string[] {
- "serviceClient",
- "Service Client",
- "Secret1",
- "estateManagement,transactionProcessor",
- "client_credentials",
- "",
- "",
- "",
- "",
- ""});
- table35.AddRow(new string[] {
- "estateUIClient",
- "Merchant Client",
- "Secret1",
- "estateManagement,fileProcessor,transactionProcessor,openid,email,profile",
- "hybrid",
- "https://localhost:[port]/signin-oidc",
- "https://localhost:[port]/signout-oidc",
- "false",
- "true",
- "https://[url]:[port]"});
-#line 29
- await testRunner.GivenAsync("I create the following clients", ((string)(null)), table35, "Given ");
-#line hidden
- global::Reqnroll.Table table36 = new global::Reqnroll.Table(new string[] {
- "ClientId"});
- table36.AddRow(new string[] {
- "serviceClient"});
-#line 34
- await testRunner.GivenAsync("I have a token to access the estate management resource", ((string)(null)), table36, "Given ");
-#line hidden
- global::Reqnroll.Table table37 = new global::Reqnroll.Table(new string[] {
- "EstateName"});
- table37.AddRow(new string[] {
- "Test Estate"});
-#line 38
- await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table37, "Given ");
-#line hidden
- global::Reqnroll.Table table38 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table38.AddRow(new string[] {
- "Test Estate",
- "Test Operator",
- "True",
- "True"});
-#line 42
- await testRunner.AndAsync("I have created the following operators", ((string)(null)), table38, "And ");
-#line hidden
- global::Reqnroll.Table table39 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table39.AddRow(new string[] {
- "Test Estate",
- "Test Operator"});
-#line 46
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table39, "And ");
-#line hidden
- global::Reqnroll.Table table40 = new global::Reqnroll.Table(new string[] {
- "EmailAddress",
- "Password",
- "GivenName",
- "FamilyName",
- "EstateName"});
- table40.AddRow(new string[] {
- "estateuser@testestate1.co.uk",
- "123456",
- "TestEstate",
- "User1",
- "Test Estate"});
-#line 50
- await testRunner.AndAsync("I have created the following security users", ((string)(null)), table40, "And ");
-#line hidden
- global::Reqnroll.Table table41 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "AddressLine1",
- "Town",
- "Region",
- "Country",
- "ContactName",
- "EmailAddress",
- "EstateName"});
- table41.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Address Line 1",
- "TestTown",
- "Test Region",
- "United Kingdom",
- "Test Contact 1",
- "testcontact1@merchant1.co.uk",
- "Test Estate"});
- table41.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Address Line 1",
- "TestTown",
- "Test Region",
- "United Kingdom",
- "Test Contact 1",
- "testcontact1@merchant2.co.uk",
- "Test Estate"});
- table41.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Address Line 1",
- "TestTown",
- "Test Region",
- "United Kingdom",
- "Test Contact 1",
- "testcontact1@merchant3.co.uk",
- "Test Estate"});
-#line 54
- await testRunner.GivenAsync("I create the following merchants", ((string)(null)), table41, "Given ");
-#line hidden
- global::Reqnroll.Table table42 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "MerchantName",
- "MerchantNumber",
- "TerminalNumber",
- "EstateName"});
- table42.AddRow(new string[] {
- "Test Operator",
- "Test Merchant 1",
- "00000001",
- "10000001",
- "Test Estate"});
- table42.AddRow(new string[] {
- "Test Operator",
- "Test Merchant 2",
- "00000001",
- "10000001",
- "Test Estate"});
- table42.AddRow(new string[] {
- "Test Operator",
- "Test Merchant 3",
- "00000001",
- "10000001",
- "Test Estate"});
-#line 60
- await testRunner.WhenAsync("I assign the following operator to the merchants", ((string)(null)), table42, "When ");
-#line hidden
- global::Reqnroll.Table table43 = new global::Reqnroll.Table(new string[] {
- "EmailAddress",
- "Password",
- "GivenName",
- "FamilyName",
- "MerchantName",
- "EstateName"});
- table43.AddRow(new string[] {
- "merchantuser1@testmerchant1.co.uk",
- "123456",
- "TestMerchant",
- "User1",
- "Test Merchant 1",
- "Test Estate"});
- table43.AddRow(new string[] {
- "merchantuser1@testmerchant2.co.uk",
- "123456",
- "TestMerchant",
- "User1",
- "Test Merchant 2",
- "Test Estate"});
- table43.AddRow(new string[] {
- "merchantuser1@testmerchant3.co.uk",
- "123456",
- "TestMerchant",
- "User1",
- "Test Merchant 3",
- "Test Estate"});
-#line 66
- await testRunner.WhenAsync("I create the following security users", ((string)(null)), table43, "When ");
-#line hidden
- global::Reqnroll.Table table44 = new global::Reqnroll.Table(new string[] {
- "DeviceIdentifier",
- "MerchantName",
- "EstateName"});
- table44.AddRow(new string[] {
- "TestDevice1",
- "Test Merchant 1",
- "Test Estate"});
- table44.AddRow(new string[] {
- "TestDevice2",
- "Test Merchant 2",
- "Test Estate"});
-#line 72
- await testRunner.WhenAsync("I add the following devices to the merchant", ((string)(null)), table44, "When ");
-#line hidden
-#line 77
- await testRunner.GivenAsync("I am on the application home page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 79
- await testRunner.AndAsync("I click on the Sign In Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 81
- await testRunner.ThenAsync("I am presented with a login screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 83
- await testRunner.WhenAsync("I login with the username \'estateuser@testestate1.co.uk\' and password \'123456\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 85
- await testRunner.ThenAsync("I am presented with the Estate Administrator Dashboard", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
-
- private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages()
- {
- return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Tests/MerchantTests.feature.ndjson", 6);
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Merchant PR Test")]
- [global::NUnit.Framework.CategoryAttribute("PRTest")]
- public async global::System.Threading.Tasks.Task MerchantPRTest()
- {
- string[] tagsOfScenario = new string[] {
- "PRTest"};
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "0";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Merchant PR Test", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 88
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 90
- await testRunner.GivenAsync("I click on the My Merchants sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 91
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table45 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table45.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table45.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table45.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
-#line 92
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table45, "And ");
-#line hidden
-#line 97
- await testRunner.WhenAsync("I click on the New Merchant Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 98
- await testRunner.ThenAsync("the Add New Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table46 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "AddressLine1",
- "Town",
- "Region",
- "Country",
- "ContactName",
- "EmailAddress"});
- table46.AddRow(new string[] {
- "Test Merchant 4",
- "Immediate",
- "Address Line 1",
- "TestTown",
- "Region",
- "Country",
- "Test Contact 4",
- "1@2.com"});
-#line 99
- await testRunner.WhenAsync("I enter the following details for the new Merchant", ((string)(null)), table46, "When ");
-#line hidden
-#line 102
- await testRunner.AndAsync("click the Create Merchant button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 103
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table47 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table47.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table47.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table47.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table47.AddRow(new string[] {
- "Test Merchant 4",
- "Immediate",
- "Test Contact 4",
- "Address Line 1",
- "TestTown"});
-#line 104
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table47, "And ");
-#line hidden
-#line 110
- await testRunner.WhenAsync("I click on the Edit Merchant Button for \'Test Merchant 1\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 111
- await testRunner.ThenAsync("the Edit Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table48 = new global::Reqnroll.Table(new string[] {
- "Tab",
- "Field",
- "Value"});
- table48.AddRow(new string[] {
- "Merchant Details",
- "MerchantName",
- "Test Merchant 1 Update"});
- table48.AddRow(new string[] {
- "Address Details",
- "AddressLine1",
- "Address Line 1 Update"});
- table48.AddRow(new string[] {
- "Contact Details",
- "ContactName",
- "Test Contact 1 Update"});
-#line 112
- await testRunner.WhenAsync("I enter the following details for the updated Merchant", ((string)(null)), table48, "When ");
-#line hidden
-#line 117
- await testRunner.AndAsync("click the Update Merchant button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 118
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table49 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table49.AddRow(new string[] {
- "Test Merchant 1 Update",
- "Immediate",
- "Test Contact 1 Update",
- "Address Line 1 Update",
- "TestTown"});
- table49.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table49.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table49.AddRow(new string[] {
- "Test Merchant 4",
- "Immediate",
- "Test Contact 4",
- "Address Line 1",
- "TestTown"});
-#line 119
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table49, "And ");
-#line hidden
-#line 132
- await testRunner.WhenAsync("I click on the View Merchant Button for \'Test Merchant 1 Update\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 133
- await testRunner.ThenAsync("the View Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Merchant Operator Management")]
- public async global::System.Threading.Tasks.Task MerchantOperatorManagement()
- {
- string[] tagsOfScenario = ((string[])(null));
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "1";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Merchant Operator Management", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 136
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
- global::Reqnroll.Table table50 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table50.AddRow(new string[] {
- "Test Estate",
- "Test Operator1",
- "True",
- "True"});
-#line 137
- await testRunner.GivenAsync("I have created the following operators", ((string)(null)), table50, "Given ");
-#line hidden
- global::Reqnroll.Table table51 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table51.AddRow(new string[] {
- "Test Estate",
- "Test Operator1"});
-#line 141
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table51, "And ");
-#line hidden
-#line 145
- await testRunner.GivenAsync("I click on the My Merchants sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 146
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table52 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table52.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table52.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table52.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
-#line 147
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table52, "And ");
-#line hidden
-#line 153
- await testRunner.WhenAsync("I click on the Edit Merchant Button for \'Test Merchant 1\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 154
- await testRunner.ThenAsync("the Edit Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 156
- await testRunner.WhenAsync("I click on the Operators tab", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 157
- await testRunner.ThenAsync("I am presented with the Merchants Operator List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table53 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "MerchantNumber",
- "TerminalNumber"});
- table53.AddRow(new string[] {
- "Test Operator",
- "00000001",
- "10000001"});
-#line 158
- await testRunner.AndAsync("the following operators are displayed in the list", ((string)(null)), table53, "And ");
-#line hidden
-#line 161
- await testRunner.WhenAsync("I click on the Add Operator Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 162
- await testRunner.ThenAsync("the Assign Operator Dialog will be displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table54 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "MerchantNumber",
- "TerminalNumber"});
- table54.AddRow(new string[] {
- "Test Operator1",
- "00000111",
- "10000111"});
-#line 163
- await testRunner.WhenAsync("I enter the following details for the Operator", ((string)(null)), table54, "When ");
-#line hidden
-#line 166
- await testRunner.AndAsync("click the Assign Operator button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 167
- await testRunner.ThenAsync("I am presented with the Merchants Operator List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table55 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "MerchantNumber",
- "TerminalNumber",
- "IsDeleted"});
- table55.AddRow(new string[] {
- "Test Operator",
- "00000001",
- "10000001",
- "False"});
- table55.AddRow(new string[] {
- "Test Operator1",
- "00000111",
- "10000111",
- "False"});
-#line 168
- await testRunner.AndAsync("the following operators are displayed in the list", ((string)(null)), table55, "And ");
-#line hidden
-#line 172
- await testRunner.WhenAsync("I click on the Remove Operator for \'Test Operator1\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 173
- await testRunner.ThenAsync("I am presented with the Merchants Operator List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table56 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "MerchantNumber",
- "TerminalNumber",
- "IsDeleted"});
- table56.AddRow(new string[] {
- "Test Operator",
- "00000001",
- "10000001",
- "False"});
- table56.AddRow(new string[] {
- "Test Operator1",
- "00000111",
- "10000111",
- "True"});
-#line 174
- await testRunner.AndAsync("the following operators are displayed in the list", ((string)(null)), table56, "And ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Merchant Contract Management")]
- public async global::System.Threading.Tasks.Task MerchantContractManagement()
- {
- string[] tagsOfScenario = ((string[])(null));
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "2";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Merchant Contract Management", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 179
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
- global::Reqnroll.Table table57 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table57.AddRow(new string[] {
- "Test Estate",
- "Test Operator1",
- "True",
- "True"});
-#line 180
- await testRunner.GivenAsync("I have created the following operators", ((string)(null)), table57, "Given ");
-#line hidden
- global::Reqnroll.Table table58 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table58.AddRow(new string[] {
- "Test Estate",
- "Test Operator1"});
-#line 184
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table58, "And ");
-#line hidden
- global::Reqnroll.Table table59 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "ContractDescription"});
- table59.AddRow(new string[] {
- "Test Estate",
- "Test Operator1",
- "Operator 1 Contract"});
-#line 189
- await testRunner.GivenAsync("I have created the following contracts", ((string)(null)), table59, "Given ");
-#line hidden
-#line 193
- await testRunner.GivenAsync("I click on the My Merchants sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 194
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table60 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table60.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table60.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table60.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
-#line 195
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table60, "And ");
-#line hidden
-#line 201
- await testRunner.WhenAsync("I click on the Edit Merchant Button for \'Test Merchant 1\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 202
- await testRunner.ThenAsync("the Edit Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 204
- await testRunner.WhenAsync("I click on the Contracts tab", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 205
- await testRunner.ThenAsync("I am presented with the Merchants Contract List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table61 = new global::Reqnroll.Table(new string[] {
- "ContractName",
- "IsDeleted"});
-#line 206
- await testRunner.AndAsync("the following contracts are displayed in the list", ((string)(null)), table61, "And ");
-#line hidden
-#line 209
- await testRunner.WhenAsync("I click on the Add Contract Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 210
- await testRunner.ThenAsync("the Assign Contract Dialog will be displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table62 = new global::Reqnroll.Table(new string[] {
- "ContractName"});
- table62.AddRow(new string[] {
- "Operator 1 Contract"});
-#line 211
- await testRunner.WhenAsync("I enter the following details for the Contract", ((string)(null)), table62, "When ");
-#line hidden
-#line 214
- await testRunner.AndAsync("click the Assign Contract button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 215
- await testRunner.ThenAsync("I am presented with the Merchants Contract List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table63 = new global::Reqnroll.Table(new string[] {
- "ContractName",
- "IsDeleted"});
- table63.AddRow(new string[] {
- "Operator 1 Contract",
- "False"});
-#line 216
- await testRunner.AndAsync("the following contracts are displayed in the list", ((string)(null)), table63, "And ");
-#line hidden
-#line 220
- await testRunner.WhenAsync("I click on the Remove Contract for \'Operator 1 Contract\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 221
- await testRunner.ThenAsync("I am presented with the Merchants Contract List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table64 = new global::Reqnroll.Table(new string[] {
- "ContractName",
- "IsDeleted"});
- table64.AddRow(new string[] {
- "Operator 1 Contract",
- "True"});
-#line 222
- await testRunner.AndAsync("the following contracts are displayed in the list", ((string)(null)), table64, "And ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Merchant Device Management")]
- public async global::System.Threading.Tasks.Task MerchantDeviceManagement()
- {
- string[] tagsOfScenario = ((string[])(null));
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "3";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Merchant Device Management", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 227
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 229
- await testRunner.GivenAsync("I click on the My Merchants sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 230
- await testRunner.ThenAsync("I am presented with the Merchants List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table65 = new global::Reqnroll.Table(new string[] {
- "MerchantName",
- "SettlementSchedule",
- "ContactName",
- "AddressLine1",
- "Town"});
- table65.AddRow(new string[] {
- "Test Merchant 1",
- "Immediate",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table65.AddRow(new string[] {
- "Test Merchant 2",
- "Weekly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
- table65.AddRow(new string[] {
- "Test Merchant 3",
- "Monthly",
- "Test Contact 1",
- "Address Line 1",
- "TestTown"});
-#line 231
- await testRunner.AndAsync("the following merchants details are in the list", ((string)(null)), table65, "And ");
-#line hidden
-#line 237
- await testRunner.WhenAsync("I click on the Edit Merchant Button for \'Test Merchant 3\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 238
- await testRunner.ThenAsync("the Edit Merchant Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 240
- await testRunner.WhenAsync("I click on the Devices tab", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 241
- await testRunner.ThenAsync("I am presented with the Merchants Device List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table66 = new global::Reqnroll.Table(new string[] {
- "DeviceIdentifier"});
-#line 242
- await testRunner.AndAsync("the following devices are displayed in the list", ((string)(null)), table66, "And ");
-#line hidden
-#line 245
- await testRunner.WhenAsync("I click on the Add Device Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 246
- await testRunner.ThenAsync("the Add Device Dialog will be displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table67 = new global::Reqnroll.Table(new string[] {
- "MerchantDevice"});
- table67.AddRow(new string[] {
- "123456ABCDEF"});
-#line 247
- await testRunner.WhenAsync("I enter the following details for the Device", ((string)(null)), table67, "When ");
-#line hidden
-#line 250
- await testRunner.AndAsync("click the Add Device button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 251
- await testRunner.ThenAsync("I am presented with the Merchants Device List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table68 = new global::Reqnroll.Table(new string[] {
- "DeviceIdentifier"});
- table68.AddRow(new string[] {
- "123456ABCDEF"});
-#line 252
- await testRunner.AndAsync("the following devices are displayed in the list", ((string)(null)), table68, "And ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
- }
-}
-#pragma warning restore
-#endregion
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature b/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature
deleted file mode 100644
index 4fbc56a9..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature
+++ /dev/null
@@ -1,102 +0,0 @@
-@base @shared @uigeneral
-Feature: Operator Tests
-
-Background:
-
- Given I create the following roles
- | Role Name |
- | Estate |
-
- Given I create the following api scopes
- | Name | DisplayName | Description |
- | estateManagement | Estate Managememt REST Scope | A scope for Estate Managememt REST |
- | transactionProcessor | Transaction Processor REST Scope | Scope for Transaction Processor REST |
- | fileProcessor | File Processor REST Scope | Scope for File Processor REST |
-
- Given I create the following api resources
- | Name | DisplayName | Secret | Scopes | UserClaims |
- | estateManagement | Estate Managememt REST | Secret1 | estateManagement | merchantId,estateId,role |
- | transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId,estateId,role |
- | fileProcessor | File Processor REST | Secret1 | fileProcessor | merchantId,estateId,role |
-
- Given I create the following identity resources
- | Name | DisplayName | Description | UserClaims |
- | openid | Your user identifier | | sub |
- | profile | User profile | Your user profile information (first name, last name, etc.) | name,role,email,given_name,middle_name,family_name,estateId,merchantId |
- | email | Email | Email and Email Verified Flags | email_verified,email |
-
- Given I create the following clients
- | ClientId | Name | Secret | Scopes | GrantTypes | RedirectUris | PostLogoutRedirectUris | RequireConsent | AllowOfflineAccess | ClientUri |
- | serviceClient | Service Client | Secret1 | estateManagement,transactionProcessor | client_credentials | | | | | |
- | estateUIClient | Merchant Client | Secret1 | estateManagement,fileProcessor,transactionProcessor,openid,email,profile | hybrid | https://localhost:[port]/signin-oidc | https://localhost:[port]/signout-oidc | false | true | https://[url]:[port] |
-
- Given I have a token to access the estate management resource
- | ClientId |
- | serviceClient |
-
- Given I have created the following estates
- | EstateName |
- | Test Estate |
-
- And I have created the following operators
- | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Estate | Test Operator 1 | True | True |
- | Test Estate | Test Operator 2 | True | False |
- | Test Estate | Test Operator 3 | False | True |
-
- And I have assigned the following operators to the estates
- | EstateName | OperatorName |
- | Test Estate | Test Operator 1 |
- | Test Estate | Test Operator 2 |
- | Test Estate | Test Operator 3 |
-
- And I have created the following security users
- | EmailAddress | Password | GivenName | FamilyName | EstateName |
- | estateuser@testestate1.co.uk | 123456 | TestEstate | User1 | Test Estate |
-
- Given I am on the application home page
-
- And I click on the Sign In Button
-
- Then I am presented with a login screen
-
- When I login with the username 'estateuser@testestate1.co.uk' and password '123456'
-
- Then I am presented with the Estate Administrator Dashboard
-
-@PRTest
-Scenario: Operator PR Test
-
- Given I click on the My Operators sidebar option
- Then I am presented with the Operators List Screen
- And the following operator details are in the list
- | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Operator 1 | Yes | Yes |
- | Test Operator 2 | Yes | No |
- | Test Operator 3 | No | Yes |
- When I click on the New Operator Button
- Then the Add New Operator Screen is displayed
- When I enter the following details for the new Operator
- | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Operator 4 | Yes | Yes |
- And click the Save Operator button
- Then I am presented with the Operators List Screen
- And the following operator details are in the list
- | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Operator 1 | Yes | Yes |
- | Test Operator 2 | Yes | No |
- | Test Operator 3 | No | Yes |
- | Test Operator 4 | Yes | Yes |
- When I click on the Edit Operator Button for 'Test Operator 1'
- Then the Edit Operator Screen is displayed
- When I enter the following new details for the Operator
- | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Operator 1 update | No | No |
- And click the Save Operator button
- Then I am presented with the Operators List Screen
- And the following operator details are in the list
- | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber |
- | Test Operator 1 update | No | No |
- | Test Operator 2 | Yes | No |
- | Test Operator 3 | No | Yes |
- | Test Operator 4 | Yes | Yes |
\ No newline at end of file
diff --git a/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature.cs b/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature.cs
deleted file mode 100644
index b1b13694..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/Tests/OperatorTests.feature.cs
+++ /dev/null
@@ -1,465 +0,0 @@
-// ------------------------------------------------------------------------------
-//
-// This code was generated by Reqnroll (https://reqnroll.net/).
-// Reqnroll Version:3.0.0.0
-// Reqnroll Generator Version:3.0.0.0
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-// ------------------------------------------------------------------------------
-#region Designer generated code
-#pragma warning disable
-using Reqnroll;
-namespace EstateManagementUI.BlazorIntegrationTests.Tests
-{
-
-
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "3.0.0.0")]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::NUnit.Framework.TestFixtureAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Operator Tests")]
- [global::NUnit.Framework.FixtureLifeCycleAttribute(global::NUnit.Framework.LifeCycle.InstancePerTestCase)]
- [global::NUnit.Framework.CategoryAttribute("base")]
- [global::NUnit.Framework.CategoryAttribute("shared")]
- [global::NUnit.Framework.CategoryAttribute("uigeneral")]
- public partial class OperatorTestsFeature
- {
-
- private global::Reqnroll.ITestRunner testRunner;
-
- private static string[] featureTags = new string[] {
- "base",
- "shared",
- "uigeneral"};
-
- private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Tests", "Operator Tests", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages());
-
-#line 1 "OperatorTests.feature"
-#line hidden
-
- [global::NUnit.Framework.OneTimeSetUpAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureSetupAsync()
- {
- }
-
- [global::NUnit.Framework.OneTimeTearDownAttribute()]
- public static async global::System.Threading.Tasks.Task FeatureTearDownAsync()
- {
- await global::Reqnroll.TestRunnerManager.ReleaseFeatureAsync(featureInfo);
- }
-
- [global::NUnit.Framework.SetUpAttribute()]
- public async global::System.Threading.Tasks.Task TestInitializeAsync()
- {
- testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo);
- try
- {
- if (((testRunner.FeatureContext != null)
- && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false)))
- {
- await testRunner.OnFeatureEndAsync();
- }
- }
- finally
- {
- if (((testRunner.FeatureContext != null)
- && testRunner.FeatureContext.BeforeFeatureHookFailed))
- {
- throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error");
- }
- if ((testRunner.FeatureContext == null))
- {
- await testRunner.OnFeatureStartAsync(featureInfo);
- }
- }
- }
-
- [global::NUnit.Framework.TearDownAttribute()]
- public async global::System.Threading.Tasks.Task TestTearDownAsync()
- {
- if ((testRunner == null))
- {
- return;
- }
- try
- {
- await testRunner.OnScenarioEndAsync();
- }
- finally
- {
- global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner);
- testRunner = null;
- }
- }
-
- public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, global::Reqnroll.RuleInfo ruleInfo)
- {
- testRunner.OnScenarioInitialize(scenarioInfo, ruleInfo);
- testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(global::NUnit.Framework.TestContext.CurrentContext);
- }
-
- public async global::System.Threading.Tasks.Task ScenarioStartAsync()
- {
- await testRunner.OnScenarioStartAsync();
- }
-
- public async global::System.Threading.Tasks.Task ScenarioCleanupAsync()
- {
- await testRunner.CollectScenarioErrorsAsync();
- }
-
- public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync()
- {
-#line 4
-#line hidden
- global::Reqnroll.Table table69 = new global::Reqnroll.Table(new string[] {
- "Role Name"});
- table69.AddRow(new string[] {
- "Estate"});
-#line 6
- await testRunner.GivenAsync("I create the following roles", ((string)(null)), table69, "Given ");
-#line hidden
- global::Reqnroll.Table table70 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description"});
- table70.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST Scope",
- "A scope for Estate Managememt REST"});
- table70.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST Scope",
- "Scope for Transaction Processor REST"});
- table70.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST Scope",
- "Scope for File Processor REST"});
-#line 10
- await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table70, "Given ");
-#line hidden
- global::Reqnroll.Table table71 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Secret",
- "Scopes",
- "UserClaims"});
- table71.AddRow(new string[] {
- "estateManagement",
- "Estate Managememt REST",
- "Secret1",
- "estateManagement",
- "merchantId,estateId,role"});
- table71.AddRow(new string[] {
- "transactionProcessor",
- "Transaction Processor REST",
- "Secret1",
- "transactionProcessor",
- "merchantId,estateId,role"});
- table71.AddRow(new string[] {
- "fileProcessor",
- "File Processor REST",
- "Secret1",
- "fileProcessor",
- "merchantId,estateId,role"});
-#line 16
- await testRunner.GivenAsync("I create the following api resources", ((string)(null)), table71, "Given ");
-#line hidden
- global::Reqnroll.Table table72 = new global::Reqnroll.Table(new string[] {
- "Name",
- "DisplayName",
- "Description",
- "UserClaims"});
- table72.AddRow(new string[] {
- "openid",
- "Your user identifier",
- "",
- "sub"});
- table72.AddRow(new string[] {
- "profile",
- "User profile",
- "Your user profile information (first name, last name, etc.)",
- "name,role,email,given_name,middle_name,family_name,estateId,merchantId"});
- table72.AddRow(new string[] {
- "email",
- "Email",
- "Email and Email Verified Flags",
- "email_verified,email"});
-#line 22
- await testRunner.GivenAsync("I create the following identity resources", ((string)(null)), table72, "Given ");
-#line hidden
- global::Reqnroll.Table table73 = new global::Reqnroll.Table(new string[] {
- "ClientId",
- "Name",
- "Secret",
- "Scopes",
- "GrantTypes",
- "RedirectUris",
- "PostLogoutRedirectUris",
- "RequireConsent",
- "AllowOfflineAccess",
- "ClientUri"});
- table73.AddRow(new string[] {
- "serviceClient",
- "Service Client",
- "Secret1",
- "estateManagement,transactionProcessor",
- "client_credentials",
- "",
- "",
- "",
- "",
- ""});
- table73.AddRow(new string[] {
- "estateUIClient",
- "Merchant Client",
- "Secret1",
- "estateManagement,fileProcessor,transactionProcessor,openid,email,profile",
- "hybrid",
- "https://localhost:[port]/signin-oidc",
- "https://localhost:[port]/signout-oidc",
- "false",
- "true",
- "https://[url]:[port]"});
-#line 28
- await testRunner.GivenAsync("I create the following clients", ((string)(null)), table73, "Given ");
-#line hidden
- global::Reqnroll.Table table74 = new global::Reqnroll.Table(new string[] {
- "ClientId"});
- table74.AddRow(new string[] {
- "serviceClient"});
-#line 33
- await testRunner.GivenAsync("I have a token to access the estate management resource", ((string)(null)), table74, "Given ");
-#line hidden
- global::Reqnroll.Table table75 = new global::Reqnroll.Table(new string[] {
- "EstateName"});
- table75.AddRow(new string[] {
- "Test Estate"});
-#line 37
- await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table75, "Given ");
-#line hidden
- global::Reqnroll.Table table76 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table76.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1",
- "True",
- "True"});
- table76.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2",
- "True",
- "False"});
- table76.AddRow(new string[] {
- "Test Estate",
- "Test Operator 3",
- "False",
- "True"});
-#line 41
- await testRunner.AndAsync("I have created the following operators", ((string)(null)), table76, "And ");
-#line hidden
- global::Reqnroll.Table table77 = new global::Reqnroll.Table(new string[] {
- "EstateName",
- "OperatorName"});
- table77.AddRow(new string[] {
- "Test Estate",
- "Test Operator 1"});
- table77.AddRow(new string[] {
- "Test Estate",
- "Test Operator 2"});
- table77.AddRow(new string[] {
- "Test Estate",
- "Test Operator 3"});
-#line 47
- await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table77, "And ");
-#line hidden
- global::Reqnroll.Table table78 = new global::Reqnroll.Table(new string[] {
- "EmailAddress",
- "Password",
- "GivenName",
- "FamilyName",
- "EstateName"});
- table78.AddRow(new string[] {
- "estateuser@testestate1.co.uk",
- "123456",
- "TestEstate",
- "User1",
- "Test Estate"});
-#line 53
- await testRunner.AndAsync("I have created the following security users", ((string)(null)), table78, "And ");
-#line hidden
-#line 57
- await testRunner.GivenAsync("I am on the application home page", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 59
- await testRunner.AndAsync("I click on the Sign In Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 61
- await testRunner.ThenAsync("I am presented with a login screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
-#line 63
- await testRunner.WhenAsync("I login with the username \'estateuser@testestate1.co.uk\' and password \'123456\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 65
- await testRunner.ThenAsync("I am presented with the Estate Administrator Dashboard", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- }
-
- private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages()
- {
- return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Tests/OperatorTests.feature.ndjson", 3);
- }
-
- [global::NUnit.Framework.TestAttribute()]
- [global::NUnit.Framework.DescriptionAttribute("Operator PR Test")]
- [global::NUnit.Framework.CategoryAttribute("PRTest")]
- public async global::System.Threading.Tasks.Task OperatorPRTest()
- {
- string[] tagsOfScenario = new string[] {
- "PRTest"};
- global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary();
- string pickleIndex = "0";
- global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Operator PR Test", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex);
- string[] tagsOfRule = ((string[])(null));
- global::Reqnroll.RuleInfo ruleInfo = null;
-#line 68
-this.ScenarioInitialize(scenarioInfo, ruleInfo);
-#line hidden
- if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags)))
- {
- await testRunner.SkipScenarioAsync();
- }
- else
- {
- await this.ScenarioStartAsync();
-#line 4
-await this.FeatureBackgroundAsync();
-#line hidden
-#line 70
- await testRunner.GivenAsync("I click on the My Operators sidebar option", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given ");
-#line hidden
-#line 71
- await testRunner.ThenAsync("I am presented with the Operators List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table79 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table79.AddRow(new string[] {
- "Test Operator 1",
- "Yes",
- "Yes"});
- table79.AddRow(new string[] {
- "Test Operator 2",
- "Yes",
- "No"});
- table79.AddRow(new string[] {
- "Test Operator 3",
- "No",
- "Yes"});
-#line 72
- await testRunner.AndAsync("the following operator details are in the list", ((string)(null)), table79, "And ");
-#line hidden
-#line 77
- await testRunner.WhenAsync("I click on the New Operator Button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 78
- await testRunner.ThenAsync("the Add New Operator Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table80 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table80.AddRow(new string[] {
- "Test Operator 4",
- "Yes",
- "Yes"});
-#line 79
- await testRunner.WhenAsync("I enter the following details for the new Operator", ((string)(null)), table80, "When ");
-#line hidden
-#line 82
- await testRunner.AndAsync("click the Save Operator button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 83
- await testRunner.ThenAsync("I am presented with the Operators List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table81 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table81.AddRow(new string[] {
- "Test Operator 1",
- "Yes",
- "Yes"});
- table81.AddRow(new string[] {
- "Test Operator 2",
- "Yes",
- "No"});
- table81.AddRow(new string[] {
- "Test Operator 3",
- "No",
- "Yes"});
- table81.AddRow(new string[] {
- "Test Operator 4",
- "Yes",
- "Yes"});
-#line 84
- await testRunner.AndAsync("the following operator details are in the list", ((string)(null)), table81, "And ");
-#line hidden
-#line 90
- await testRunner.WhenAsync("I click on the Edit Operator Button for \'Test Operator 1\'", ((string)(null)), ((global::Reqnroll.Table)(null)), "When ");
-#line hidden
-#line 91
- await testRunner.ThenAsync("the Edit Operator Screen is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table82 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table82.AddRow(new string[] {
- "Test Operator 1 update",
- "No",
- "No"});
-#line 92
- await testRunner.WhenAsync("I enter the following new details for the Operator", ((string)(null)), table82, "When ");
-#line hidden
-#line 95
- await testRunner.AndAsync("click the Save Operator button", ((string)(null)), ((global::Reqnroll.Table)(null)), "And ");
-#line hidden
-#line 96
- await testRunner.ThenAsync("I am presented with the Operators List Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then ");
-#line hidden
- global::Reqnroll.Table table83 = new global::Reqnroll.Table(new string[] {
- "OperatorName",
- "RequireCustomMerchantNumber",
- "RequireCustomTerminalNumber"});
- table83.AddRow(new string[] {
- "Test Operator 1 update",
- "No",
- "No"});
- table83.AddRow(new string[] {
- "Test Operator 2",
- "Yes",
- "No"});
- table83.AddRow(new string[] {
- "Test Operator 3",
- "No",
- "Yes"});
- table83.AddRow(new string[] {
- "Test Operator 4",
- "Yes",
- "Yes"});
-#line 97
- await testRunner.AndAsync("the following operator details are in the list", ((string)(null)), table83, "And ");
-#line hidden
- }
- await this.ScenarioCleanupAsync();
- }
- }
-}
-#pragma warning restore
-#endregion
diff --git a/EstateManagementUI.BlazorIntegrationTests/appsettings.json b/EstateManagementUI.BlazorIntegrationTests/appsettings.json
deleted file mode 100644
index e4fcd302..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/appsettings.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "TestSettings": {
- "SkipRemoteCalls": true,
- "EnableTestMode": true
- }
-}
diff --git a/EstateManagementUI.BlazorIntegrationTests/nlog.config b/EstateManagementUI.BlazorIntegrationTests/nlog.config
deleted file mode 100644
index b2c330e9..00000000
--- a/EstateManagementUI.BlazorIntegrationTests/nlog.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/EstateManagementUI.BusinessLogic.Tests/ApiClientTests.cs b/EstateManagementUI.BusinessLogic.Tests/ApiClientTests.cs
deleted file mode 100644
index bb1533f2..00000000
--- a/EstateManagementUI.BusinessLogic.Tests/ApiClientTests.cs
+++ /dev/null
@@ -1,817 +0,0 @@
-using EstateManagementUI.BusinessLogic.Clients;
-using EstateManagementUI.BusinessLogic.Models;
-using EstateManagementUI.Pages.Merchant;
-using EstateManagementUI.Testing;
-using EstateReportingAPI.Client;
-using EstateReportingAPI.DataTransferObjects;
-using FileProcessor.Client;
-using Microsoft.Extensions.Configuration;
-using Moq;
-using SecurityService.Client;
-using SecurityService.DataTransferObjects.Responses;
-using Shared.General;
-using Shared.Logger;
-using Shouldly;
-using SimpleResults;
-using TransactionProcessor.Client;
-using TransactionProcessor.DataTransferObjects.Requests.Contract;
-using TransactionProcessor.DataTransferObjects.Requests.Merchant;
-using TransactionProcessor.DataTransferObjects.Requests.Operator;
-using TransactionProcessor.DataTransferObjects.Responses.Contract;
-using TransactionProcessor.DataTransferObjects.Responses.Merchant;
-using TransactionProcessor.DataTransferObjects.Responses.Operator;
-using CreateMerchantModel = EstateManagementUI.BusinessLogic.Models.CreateMerchantModel;
-using SettlementSchedule = EstateManagementUI.BusinessLogic.Models.SettlementSchedule;
-
-namespace EstateManagementUI.BusinessLogic.Tests;
-
-public class ApiClientTests {
- private readonly IApiClient ApiClient;
- private readonly Mock TransactionProcessorClient;
- private readonly Mock FileProcessorClient;
- private readonly Mock EstateReportingApiClient;
- private readonly Mock SecurityServiceClient;
-
- public ApiClientTests() {
- Logger.Initialise(NullLogger.Instance);
-
- this.TransactionProcessorClient = new Mock();
- this.FileProcessorClient = new Mock();
- this.EstateReportingApiClient = new Mock();
- this.SecurityServiceClient = new Mock();
- IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
- ConfigurationReader.Initialise(configurationRoot);
- this.ApiClient = new ApiClient(this.TransactionProcessorClient.Object, this.FileProcessorClient.Object, this.EstateReportingApiClient.Object,
- this.SecurityServiceClient.Object);
- }
-
-
- [Fact]
- public async Task ApiClient_GetEstate_EstateReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetEstate(It.IsAny(), It.IsAny(), It.IsAny()))
- .ReturnsAsync(Result.Success(TestData.EstateResponse));
-
- var result= await this.ApiClient.GetEstate(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- result.Data.EstateName.ShouldBe(TestData.EstateName);
- }
-
- [Fact]
- public async Task ApiClient_GetEstate_ClientCallFailed_ResultFailed()
- {
- this.TransactionProcessorClient.Setup(e => e.GetEstate(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- var result = await this.ApiClient.GetEstate(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetEstate_ClientCallThrewException_ResultFailed()
- {
- this.TransactionProcessorClient.Setup(e => e.GetEstate(It.IsAny(), It.IsAny(), It.IsAny())).ThrowsAsync(new Exception());
-
- var result = await this.ApiClient.GetEstate(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetMerchants_MerchantsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetMerchants(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.MerchantResponses));
-
- var result = await this.ApiClient.GetMerchants(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- result.Data.ShouldNotBeEmpty();
- result.Data.Count.ShouldBe(3);
-
- foreach (MerchantResponse merchantResponse in TestData.MerchantResponses) {
- MerchantModel? merchant = result.Data.SingleOrDefault(m => m.MerchantId == merchantResponse.MerchantId);
- merchant.ShouldNotBeNull();
- }
- }
-
- [Fact]
- public async Task ApiClient_GetMerchants_ClientCallFailed_ResultFailed()
- {
- this.TransactionProcessorClient.Setup(e => e.GetMerchants(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- Result> result = await this.ApiClient.GetMerchants(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetMerchant_ClientCallFailed_ResultFailed() {
- this.TransactionProcessorClient.Setup(e => e.GetMerchant(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- Result result = await this.ApiClient.GetMerchant(TestData.AccessToken, Guid.NewGuid(), Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetMerchant_MerchantReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetMerchant(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.MerchantResponse));
-
- var result= await this.ApiClient.GetMerchant(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Merchant1Id, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- }
-
- [Fact]
- public async Task ApiClient_GetOperators_OperatorsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetOperators(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.OperatorResponses));
-
- var result = await this.ApiClient.GetOperators(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- result.Data.ShouldNotBeEmpty();
- result.Data.Count.ShouldBe(2);
-
- foreach (OperatorResponse operatorResponse in TestData.OperatorResponses) {
- OperatorModel? @operatorModel = result.Data.SingleOrDefault(m => m.OperatorId == operatorResponse.OperatorId);
- operatorModel.ShouldNotBeNull();
- }
- }
-
- [Fact]
- public async Task ApiClient_GetOperators_ClientCallFailed_ResultFailed() {
- this.TransactionProcessorClient.Setup(e => e.GetOperators(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
-
- Result> result = await this.ApiClient.GetOperators(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetOperator_OperatorIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.OperatorResponse));
-
- Result @operator = await this.ApiClient.GetOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Operator1Id, CancellationToken.None);
- @operator.IsSuccess.ShouldBeTrue();
- @operator.ShouldNotBeNull();
- }
-
- [Fact]
- public async Task ApiClient_GetOperator_ClientCallFailed_ResultFailed() {
- this.TransactionProcessorClient.Setup(e => e.GetOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- Result result = await this.ApiClient.GetOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Operator1Id, CancellationToken.None);
-
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetContracts_ContractsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetContracts(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractResponses));
-
-
- var result = await this.ApiClient.GetContracts(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
-
- result.Data.ShouldNotBeNull();
- result.Data.ShouldNotBeEmpty();
- result.Data.Count.ShouldBe(1);
-
- foreach (ContractResponse contractResponse in TestData.ContractResponses) {
- ContractModel? contractModel = result.Data.SingleOrDefault(m => m.ContractId == contractResponse.ContractId);
- contractModel.ShouldNotBeNull();
- }
- }
-
- [Fact]
- public async Task ApiClient_GetContracts_ClientCallFailed_ResultFailed()
- {
- this.TransactionProcessorClient.Setup(e => e.GetContracts(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- var result = await this.ApiClient.GetContracts(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetContract_ContractIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.GetContract(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractResponse1));
-
- var result = await this.ApiClient.GetContract(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Contract1Id, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- result.Data.ContractId.ShouldBe(TestData.ContractResponse1.ContractId);
- result.Data.Description.ShouldBe(TestData.ContractResponse1.Description);
- result.Data.OperatorName.ShouldBe(TestData.ContractResponse1.OperatorName);
- result.Data.NumberOfProducts.ShouldBe(TestData.ContractResponse1.Products.Count);
- foreach (ContractProduct contractResponse1Product in TestData.ContractResponse1.Products) {
- ContractProductModel? modelProduct = result.Data.ContractProducts.SingleOrDefault(cp => cp.ContractProductId == contractResponse1Product.ProductId);
- modelProduct.ShouldNotBeNull();
- }
- }
-
- [Fact]
- public async Task ApiClient_GetContract_ClientCallFailed_ResultFailed()
- {
- this.TransactionProcessorClient.Setup(e => e.GetContract(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
-
- var result= await this.ApiClient.GetContract(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Contract1Id, CancellationToken.None);
-
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_CreateOperator_OperatorIsCreated() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.CreateOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success);
-
- CreateOperatorModel createOperatorModel = new() { RequireCustomMerchantNumber = TestData.RequireCustomMerchantNumber, RequireCustomTerminalNumber = TestData.RequireCustomTerminalNumber, OperatorName = TestData.Operator1Name, OperatorId = TestData.Operator1Id };
-
- Result result = await this.ApiClient.CreateOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, createOperatorModel, CancellationToken.None);
-
- result.IsSuccess.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_CreateOperator_ErrorAtServer_OperatorIsNotCreated() {
- Logger.Initialise(NullLogger.Instance);
- this.TransactionProcessorClient.Setup(e => e.CreateOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure);
-
- CreateOperatorModel createOperatorModel = new() { RequireCustomMerchantNumber = TestData.RequireCustomMerchantNumber, RequireCustomTerminalNumber = TestData.RequireCustomTerminalNumber, OperatorName = TestData.Operator1Name, OperatorId = TestData.Operator1Id };
-
- Result result = await this.ApiClient.CreateOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, createOperatorModel, CancellationToken.None);
-
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_UpdateOperator_OperatorIsUpdated() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.TransactionProcessorClient.Setup(e => e.UpdateOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success());
-
- UpdateOperatorModel updateOperatorModel = new() { RequireCustomMerchantNumber = TestData.RequireCustomMerchantNumber, RequireCustomTerminalNumber = TestData.RequireCustomTerminalNumber, OperatorName = TestData.Operator1Name, OperatorId = TestData.Operator1Id };
-
- Result result = await this.ApiClient.UpdateOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, updateOperatorModel, CancellationToken.None);
-
- result.IsSuccess.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_UpdateOperator_ErrorAtServer_OperatorIsNotUpdated() {
- this.TransactionProcessorClient.Setup(e => e.UpdateOperator(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure);
-
- UpdateOperatorModel updateOperatorModel = new() { RequireCustomMerchantNumber = TestData.RequireCustomMerchantNumber, RequireCustomTerminalNumber = TestData.RequireCustomTerminalNumber, OperatorName = TestData.Operator1Name, OperatorId = TestData.Operator1Id };
-
- Result result = await this.ApiClient.UpdateOperator(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, updateOperatorModel, CancellationToken.None);
-
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetFileImportLogList_DataIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.FileProcessorClient.Setup(e => e.GetFileImportLogs(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync( Result.Success(TestData.FileImportLogList));
-
- Result> result = await this.ApiClient.GetFileImportLogList(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Merchant1Id, TestData.FileImportLogQueryStartDate, TestData.FileImportLogQueryEndDate, CancellationToken.None);
-
- result.IsSuccess.ShouldBeTrue();
- result.Data.ShouldNotBeNull();
- result.Data.ShouldNotBeEmpty();
- result.Data.Count.ShouldBe(TestData.FileImportLogList.FileImportLogs.Count);
- }
-
- [Fact]
- public async Task ApiClient_GetFileImportLogList_ErrorAtServer_NoDataIsReturned() {
- this.FileProcessorClient.Setup(e => e.GetFileImportLogs(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
- Result> result = await this.ApiClient.GetFileImportLogList(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Merchant1Id, TestData.FileImportLogQueryStartDate, TestData.FileImportLogQueryEndDate, CancellationToken.None);
-
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetFileImportLog_DataIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.FileProcessorClient.Setup(e => e.GetFileImportLog(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync( Result.Success(TestData.FileImportLog1));
-
- Result result = await this.ApiClient.GetFileImportLog(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Merchant1Id, TestData.FileImportLogId, CancellationToken.None);
-
- result.IsSuccess.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetFileImportLog_ErrorAtServer_NoDataIsReturned() {
- this.FileProcessorClient.Setup(e => e.GetFileImportLog(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- Result result = await this.ApiClient.GetFileImportLog(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.Merchant1Id, TestData.FileImportLogId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetFileDetails_DataIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.FileProcessorClient.Setup(e => e.GetFile(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.FileDetails1));
-
- Result result = await this.ApiClient.GetFileDetails(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.FileId1, CancellationToken.None);
-
- result.IsSuccess.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetFileDetails_ErrorAtServer_NoDataIsReturned() {
- this.FileProcessorClient.Setup(e => e.GetFile(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure());
-
- Result result = await this.ApiClient.GetFileDetails(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, TestData.FileId1, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
-
- [Fact]
- public async Task ApiClient_GetComparisonDates_DataIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.EstateReportingApiClient.Setup(e => e.GetComparisonDates(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ComparisonDates));
-
- Result> result = await this.ApiClient.GetComparisonDates(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsSuccess.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetComparisonDates_ErrorAtServer_NoDataIsReturned() {
- this.EstateReportingApiClient.Setup(e => e.GetComparisonDates(It.IsAny(), It.IsAny(), It.IsAny())).ThrowsAsync(new Exception());
-
- Result> result = await this.ApiClient.GetComparisonDates(TestData.AccessToken, Guid.NewGuid(), TestData.EstateId, CancellationToken.None);
- result.IsFailed.ShouldBeTrue();
- }
-
- [Fact]
- public async Task ApiClient_GetTodaysSales_DataIsReturned() {
- this.SecurityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TokenResponse.Create(TestData.AccessToken, TestData.AccessToken, 1000)));
- this.EstateReportingApiClient.Setup(e => e.GetTodaysSales(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny