From 7cc6bd9192a25158c3cdeb18dce5d178fc0a73f9 Mon Sep 17 00:00:00 2001
From: KarmaKamikaze
Date: Mon, 20 Nov 2023 10:07:55 +0100
Subject: [PATCH 1/6] E2E test CharacterDescription textarea
---
ChatRPGTests/AuthorizedIndexE2ETests.cs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ChatRPGTests/AuthorizedIndexE2ETests.cs b/ChatRPGTests/AuthorizedIndexE2ETests.cs
index 32078d9..7d02cf1 100644
--- a/ChatRPGTests/AuthorizedIndexE2ETests.cs
+++ b/ChatRPGTests/AuthorizedIndexE2ETests.cs
@@ -424,6 +424,21 @@ public void
Assert.True(characterNameAlert.Displayed && campaignTitleAlert.Displayed);
}
+ [Fact]
+ public void AuthorizedIndexPage_CustomCampaign_CharacterDescriptionIsEmptyOnInitialization()
+ {
+ // Arrange
+ string expectedCharacterDescription = string.Empty;
+
+ // Act
+ IWebElement? characterDescription =
+ _wait.Until(webDriver => webDriver.FindElement(By.Id("inputCharacterDescription")));
+ string actualCharacterDescription = characterDescription.Text;
+
+ // Assert
+ Assert.Equal(expectedCharacterDescription, actualCharacterDescription);
+ }
+
public void Dispose()
{
E2ETestUtility.Teardown(_driver);
From ec618402e554da7f422cb8a2efed55a0ead36fd9 Mon Sep 17 00:00:00 2001
From: KarmaKamikaze
Date: Mon, 20 Nov 2023 11:40:32 +0100
Subject: [PATCH 2/6] Fix dynamic scalability problems in UI
---
ChatRPG/wwwroot/css/site.css | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/ChatRPG/wwwroot/css/site.css b/ChatRPG/wwwroot/css/site.css
index 18dbc97..2aeb2cc 100644
--- a/ChatRPG/wwwroot/css/site.css
+++ b/ChatRPG/wwwroot/css/site.css
@@ -2,6 +2,7 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ height: 100%;
}
h1:focus {
@@ -12,6 +13,10 @@ a, .btn-link {
color: #0071c1;
}
+.page {
+ min-height: 100vh;
+}
+
.btn-primary {
background-color: #4eb758;
color: black;
@@ -180,7 +185,7 @@ a, .btn-link {
.dashboard-wrapper {
display: flex;
flex-direction: column;
- height: 100vh;
+ height: 100%;
}
.dashboard-container {
@@ -189,8 +194,7 @@ a, .btn-link {
flex-direction: column;
align-items: center;
justify-content: center;
- overflow-y: auto;
- margin-top: -120px;
+ margin-top: -50px;
}
.title-front {
From a1d3834fd77e2e1a42573274fbeaf47368ad7091 Mon Sep 17 00:00:00 2001
From: KarmaKamikaze
Date: Mon, 20 Nov 2023 13:11:04 +0100
Subject: [PATCH 3/6] Add DeleteAsync method to EfPersisterService
---
ChatRPG/Services/EfPersisterService.cs | 25 +++++++++++++++
ChatRPG/Services/IPersisterService.cs | 6 ++++
ChatRPGTests/CampaignE2ETests.cs | 42 ++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100644 ChatRPGTests/CampaignE2ETests.cs
diff --git a/ChatRPG/Services/EfPersisterService.cs b/ChatRPG/Services/EfPersisterService.cs
index 300c6a7..128719b 100644
--- a/ChatRPG/Services/EfPersisterService.cs
+++ b/ChatRPG/Services/EfPersisterService.cs
@@ -42,6 +42,31 @@ public async Task SaveAsync(Campaign campaign)
}
}
+ public async Task DeleteAsync(Campaign campaign)
+ {
+ if (!(await _dbContext.Campaigns.ContainsAsync(campaign)))
+ {
+ return;
+ }
+
+ await using IDbContextTransaction transaction = await _dbContext.Database.BeginTransactionAsync();
+ try
+ {
+ int campaignId = campaign.Id;
+ _dbContext.Campaigns.Remove(campaign);
+
+ await _dbContext.SaveChangesAsync();
+ await transaction.CommitAsync();
+ _logger.LogInformation("Deleted campaign with id {Id} successfully", campaignId);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An error occurred while deleting");
+ await transaction.RollbackAsync();
+ throw;
+ }
+ }
+
///
public async Task LoadFromCampaignIdAsync(int campaignId)
{
diff --git a/ChatRPG/Services/IPersisterService.cs b/ChatRPG/Services/IPersisterService.cs
index a67540e..dd2e080 100644
--- a/ChatRPG/Services/IPersisterService.cs
+++ b/ChatRPG/Services/IPersisterService.cs
@@ -14,6 +14,12 @@ public interface IPersisterService
/// A task representing the asynchronous operation.
Task SaveAsync(Campaign campaign);
///
+ /// Deletes the given and all its related entities.
+ ///
+ /// The campaign to delete.
+ /// A task representing the asynchronous operation.
+ Task DeleteAsync(Campaign campaign);
+ ///
/// Loads the campaign with the given with all its related entities.
///
/// Id of the campaign to load.
diff --git a/ChatRPGTests/CampaignE2ETests.cs b/ChatRPGTests/CampaignE2ETests.cs
new file mode 100644
index 0000000..8ae78cc
--- /dev/null
+++ b/ChatRPGTests/CampaignE2ETests.cs
@@ -0,0 +1,42 @@
+using OpenQA.Selenium;
+using OpenQA.Selenium.Support.UI;
+
+namespace ChatRPGTests;
+
+[Collection("E2E collection")]
+public class CampaignE2ETests : IDisposable
+{
+ private readonly ChatRPGFixture _fixture;
+ private readonly IWebDriver _driver;
+ private readonly WebDriverWait _wait;
+ private readonly string _testUsername = "test";
+ private readonly string _testPassword = "test";
+
+ public CampaignE2ETests(ChatRPGFixture fixture)
+ {
+ _fixture = fixture;
+ _driver = E2ETestUtility.Setup("/");
+ _wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));
+
+ // Login and prepare to test Campaign page
+ Login(_testUsername, _testPassword);
+ }
+
+ public void Dispose()
+ {
+ E2ETestUtility.Teardown(_driver);
+ _driver.Dispose();
+ }
+
+ private void Login(string username, string password)
+ {
+ Thread.Sleep(1000); // wait for Index title animation to finish
+ _wait.Until(webDriver => webDriver.FindElement(By.Id("login-button"))).Click();
+ IWebElement? usernameForm = _wait.Until(webDriver => webDriver.FindElement(By.Id("username-form")));
+ usernameForm.SendKeys(username);
+ IWebElement? passwordForm = _wait.Until(webDriver => webDriver.FindElement(By.Id("password-form")));
+ passwordForm.SendKeys(password);
+ _wait.Until(webDriver => webDriver.FindElement(By.Id("login-submit"))).Submit();
+ Thread.Sleep(500); // wait for page to load fully
+ }
+}
From 237e5e44197c70de14731b13ea0dc1408321310a Mon Sep 17 00:00:00 2001
From: KarmaKamikaze
Date: Mon, 20 Nov 2023 17:02:45 +0100
Subject: [PATCH 4/6] Add campaign deletion confirmation modal
---
ChatRPG/App.razor | 26 ++++-----
ChatRPG/ChatRPG.csproj | 1 +
ChatRPG/Pages/ConfirmModal.razor | 58 +++++++++++++++++++++
ChatRPG/Pages/UserCampaignOverview.razor | 5 +-
ChatRPG/Pages/UserCampaignOverview.razor.cs | 23 ++++++++
ChatRPG/Pages/_Host.cshtml | 1 +
ChatRPG/Program.cs | 2 +
ChatRPG/Services/EfPersisterService.cs | 1 +
ChatRPG/_Imports.razor | 2 +
ChatRPG/wwwroot/css/site.css | 14 ++++-
10 files changed, 119 insertions(+), 14 deletions(-)
create mode 100644 ChatRPG/Pages/ConfirmModal.razor
diff --git a/ChatRPG/App.razor b/ChatRPG/App.razor
index 47e0fa8..51d9db5 100644
--- a/ChatRPG/App.razor
+++ b/ChatRPG/App.razor
@@ -1,14 +1,16 @@
-
-
-
-
-
-
- Not found
-
- Sorry, there's nothing at this address.
-
-
-
+
+
+
+
+
+
+
+ Not found
+
+ Sorry, there's nothing at this address.
+
+
+
+
diff --git a/ChatRPG/ChatRPG.csproj b/ChatRPG/ChatRPG.csproj
index 40616a6..5e47a2a 100644
--- a/ChatRPG/ChatRPG.csproj
+++ b/ChatRPG/ChatRPG.csproj
@@ -8,6 +8,7 @@
+
diff --git a/ChatRPG/Pages/ConfirmModal.razor b/ChatRPG/Pages/ConfirmModal.razor
new file mode 100644
index 0000000..f6333c2
--- /dev/null
+++ b/ChatRPG/Pages/ConfirmModal.razor
@@ -0,0 +1,58 @@
+@using ChatRPG.Services
+@using ChatRPG.Data.Models
+
+
+
+
+
+
+
+
+
Do you really want to delete the campaign?
+
+ Campaign title: @CampaignToDelete!.Title
+
+
+ Character name: @CampaignToDelete!.Player.Name
+
+
+
+
+
+
+
+@code {
+
+ [CascadingParameter]
+ BlazoredModalInstance Modal { get; set; } = default!;
+
+ [Parameter]
+ [EditorRequired]
+ public Campaign? CampaignToDelete { get; set; }
+
+ [Inject]
+ private IPersisterService? PersistService { get; set; }
+
+ private async Task Confirm()
+ {
+ if (CampaignToDelete is null)
+ {
+ await Modal.CancelAsync();
+ }
+
+ await PersistService!.DeleteAsync(CampaignToDelete!);
+ await Modal.CloseAsync(ModalResult.Ok(true));
+ }
+
+ private async Task Close() => await Modal.CloseAsync(ModalResult.Ok(false));
+ private async Task Cancel() => await Modal.CancelAsync();
+
+}
diff --git a/ChatRPG/Pages/UserCampaignOverview.razor b/ChatRPG/Pages/UserCampaignOverview.razor
index eebee32..8a6ae28 100644
--- a/ChatRPG/Pages/UserCampaignOverview.razor
+++ b/ChatRPG/Pages/UserCampaignOverview.razor
@@ -15,7 +15,7 @@
@foreach (CampaignModel campaign in Campaigns)
{
-
diff --git a/ChatRPG/Pages/UserCampaignOverview.razor.cs b/ChatRPG/Pages/UserCampaignOverview.razor.cs
index 91f4f8f..8447afd 100644
--- a/ChatRPG/Pages/UserCampaignOverview.razor.cs
+++ b/ChatRPG/Pages/UserCampaignOverview.razor.cs
@@ -1,5 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Security.Authentication;
+using Blazored.Modal;
+using Blazored.Modal.Services;
using ChatRPG.Data.Models;
using ChatRPG.Services;
using Microsoft.AspNetCore.Components;
@@ -32,6 +34,8 @@ public partial class UserCampaignOverview : ComponentBase
[Inject] private ICampaignMediatorService? CampaignMediatorService { get; set; }
[Inject] private NavigationManager? NavMan { get; set; }
+ [CascadingParameter] public IModalService? ConfirmDeleteModal { get; set; }
+
protected override async Task OnInitializedAsync()
{
AuthenticationState authState = await AuthProvider!.GetAuthenticationStateAsync();
@@ -79,6 +83,25 @@ private void ApplyStartingScenario(string title, string scenario)
StateHasChanged();
}
+ private async Task ShowCampaignDeleteModal(Campaign campaign)
+ {
+ IModalReference modal = ConfirmDeleteModal!.Show("Delete Campaign",
+ new ModalParameters().Add(nameof(ConfirmModal.CampaignToDelete), campaign));
+
+ ModalResult shouldDelete = await modal.Result;
+ if (shouldDelete.Confirmed)
+ {
+ await ModalClosed();
+ }
+ }
+
+ private async Task ModalClosed()
+ {
+ Campaigns = await PersisterService!.GetCampaignsForUser(User!);
+ Campaigns.Reverse(); // Reverse to display latest campaign first
+ StateHasChanged();
+ }
+
private bool FieldIsEmpty()
{
if (string.IsNullOrWhiteSpace(CampaignTitle) && string.IsNullOrWhiteSpace(CharacterName))
diff --git a/ChatRPG/Pages/_Host.cshtml b/ChatRPG/Pages/_Host.cshtml
index 4f203c7..f9eaa1e 100644
--- a/ChatRPG/Pages/_Host.cshtml
+++ b/ChatRPG/Pages/_Host.cshtml
@@ -10,6 +10,7 @@
+
diff --git a/ChatRPG/Program.cs b/ChatRPG/Program.cs
index a674565..5338a3e 100644
--- a/ChatRPG/Program.cs
+++ b/ChatRPG/Program.cs
@@ -1,3 +1,4 @@
+using Blazored.Modal;
using ChatRPG.API;
using ChatRPG.Areas.Identity;
using ChatRPG.Data;
@@ -22,6 +23,7 @@
.AddEntityFrameworkStores();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
+builder.Services.AddBlazoredModal();
HttpMessageHandlerFactory httpMessageHandlerFactory = new HttpMessageHandlerFactory(configuration);
builder.Services.AddScoped>()
diff --git a/ChatRPG/Services/EfPersisterService.cs b/ChatRPG/Services/EfPersisterService.cs
index 128719b..473c681 100644
--- a/ChatRPG/Services/EfPersisterService.cs
+++ b/ChatRPG/Services/EfPersisterService.cs
@@ -42,6 +42,7 @@ public async Task SaveAsync(Campaign campaign)
}
}
+ ///
public async Task DeleteAsync(Campaign campaign)
{
if (!(await _dbContext.Campaigns.ContainsAsync(campaign)))
diff --git a/ChatRPG/_Imports.razor b/ChatRPG/_Imports.razor
index 81bc3b1..ba7e22f 100644
--- a/ChatRPG/_Imports.razor
+++ b/ChatRPG/_Imports.razor
@@ -6,5 +6,7 @@
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
+@using Blazored.Modal
+@using Blazored.Modal.Services
@using ChatRPG
@using ChatRPG.Shared
diff --git a/ChatRPG/wwwroot/css/site.css b/ChatRPG/wwwroot/css/site.css
index 2aeb2cc..0400cc2 100644
--- a/ChatRPG/wwwroot/css/site.css
+++ b/ChatRPG/wwwroot/css/site.css
@@ -230,7 +230,6 @@ a, .btn-link {
}
.card-dim {
- width: 18rem;
background: #dcdcdc;
}
@@ -358,3 +357,16 @@ a, .btn-link {
.dashboard-title-container {
padding-bottom: 60px;
}
+
+.campaign-button {
+ position: relative;
+}
+
+.delete-campaign-button {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ margin-right: 5px;
+ margin-bottom: 5px;
+ background: #ececec;
+}
From c1ee7543d285d9251d8801e76e707f5502b2cc45 Mon Sep 17 00:00:00 2001
From: KarmaKamikaze
Date: Mon, 20 Nov 2023 20:37:23 +0100
Subject: [PATCH 5/6] E2E tests for campaign deletion modal
---
ChatRPG/Pages/ConfirmModal.razor | 4 +-
ChatRPG/wwwroot/css/site.css | 9 +-
ChatRPGTests/AuthorizedIndexE2ETests.cs | 156 +++++++++++++++++++++---
ChatRPGTests/CampaignE2ETests.cs | 14 +--
ChatRPGTests/E2ETestUtility.cs | 38 ++++++
5 files changed, 189 insertions(+), 32 deletions(-)
diff --git a/ChatRPG/Pages/ConfirmModal.razor b/ChatRPG/Pages/ConfirmModal.razor
index f6333c2..42985c3 100644
--- a/ChatRPG/Pages/ConfirmModal.razor
+++ b/ChatRPG/Pages/ConfirmModal.razor
@@ -22,8 +22,8 @@
diff --git a/ChatRPG/wwwroot/css/site.css b/ChatRPG/wwwroot/css/site.css
index 0400cc2..9884cb2 100644
--- a/ChatRPG/wwwroot/css/site.css
+++ b/ChatRPG/wwwroot/css/site.css
@@ -368,5 +368,12 @@ a, .btn-link {
right: 0;
margin-right: 5px;
margin-bottom: 5px;
- background: #ececec;
+ background: none;
+ overflow: hidden;
+ outline:none;
+ border:solid 1px black;
+}
+
+.delete-campaign-button:hover {
+ background: #eaeaea;
}
diff --git a/ChatRPGTests/AuthorizedIndexE2ETests.cs b/ChatRPGTests/AuthorizedIndexE2ETests.cs
index 7d02cf1..8dbd783 100644
--- a/ChatRPGTests/AuthorizedIndexE2ETests.cs
+++ b/ChatRPGTests/AuthorizedIndexE2ETests.cs
@@ -21,7 +21,7 @@ public AuthorizedIndexE2ETests(ChatRPGFixture fixture)
_wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));
// Login and prepare to test Authorized Index
- Login(_testUsername, _testPassword);
+ E2ETestUtility.Login(_wait, _testUsername, _testPassword);
}
[Fact]
@@ -116,14 +116,14 @@ public void AuthorizedIndexPage_YourCampaigns_ContainsSameAmountOfCampaignsAsDis
// Arranged
IWebElement? campaignsContainer = _wait.Until(webDriver => webDriver.FindElement(By.Id("your-campaigns")));
ReadOnlyCollection? campaigns = campaignsContainer.FindElements(By.ClassName("card"));
- string expectedAmountOfScenarios = campaigns.Count.ToString();
+ string expectedAmountOfCampaigns = campaigns.Count.ToString();
// Act
IWebElement? campaignsCounter = _wait.Until(webDriver => webDriver.FindElement(By.Id("campaigns-count")));
- string actualAmountOfScenarios = Regex.Match(campaignsCounter.Text, @"\d+").Value;
+ string actualAmountOfCampaigns = Regex.Match(campaignsCounter.Text, @"\d+").Value;
// Assert
- Assert.Equal(expectedAmountOfScenarios, actualAmountOfScenarios);
+ Assert.Equal(expectedAmountOfCampaigns, actualAmountOfCampaigns);
}
[Fact]
@@ -439,22 +439,146 @@ public void AuthorizedIndexPage_CustomCampaign_CharacterDescriptionIsEmptyOnInit
Assert.Equal(expectedCharacterDescription, actualCharacterDescription);
}
- public void Dispose()
+ [Fact]
+ public void AuthorizedIndexPage_YourCampaigns_DisplaysRemoveCampaignButtonWhenEarlierCampaignExists()
{
- E2ETestUtility.Teardown(_driver);
- _driver.Dispose();
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+
+ // Act
+ IWebElement? firstRemoveCampaignButton = _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0];
+
+ // Assert
+ Assert.True(firstRemoveCampaignButton.Displayed);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_ModalIsDisplayedAfterRemoveCampaignButtonIsClicked()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+
+ // Act
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+ IWebElement? modal = _wait.Until(webDriver => webDriver.FindElement(By.ClassName("modal")));
+
+ // Assert
+ Assert.True(modal.Displayed);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_ModalCloseButtonIsDisplayedWhenModalIsActivated()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+
+ // Act
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+ IWebElement? modalCloseButton = _wait.Until(webDriver => webDriver.FindElement(By.Id("modal-close")));
+
+ // Assert
+ Assert.True(modalCloseButton.Displayed);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
}
- private void Login(string username, string password)
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_ModalConfirmButtonIsDisplayedWhenModalIsActivated()
{
- Thread.Sleep(1000); // wait for Index title animation to finish
- _wait.Until(webDriver => webDriver.FindElement(By.Id("login-button"))).Click();
- IWebElement? usernameForm = _wait.Until(webDriver => webDriver.FindElement(By.Id("username-form")));
- usernameForm.SendKeys(username);
- IWebElement? passwordForm = _wait.Until(webDriver => webDriver.FindElement(By.Id("password-form")));
- passwordForm.SendKeys(password);
- _wait.Until(webDriver => webDriver.FindElement(By.Id("login-submit"))).Submit();
- Thread.Sleep(500); // wait for page to load fully
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+
+ // Act
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+ IWebElement? modalConfirmButton = _wait.Until(webDriver => webDriver.FindElement(By.Id("modal-confirm")));
+
+ // Assert
+ Assert.True(modalConfirmButton.Displayed);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_ModalBodyContainsCorrectCampaignTitle()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+ string expectedCampaignTitleString = "Campaign title: Test Title";
+
+ // Act
+ IWebElement? modalBody = _wait.Until(webDriver => webDriver.FindElement(By.ClassName("modal-body")));
+
+ // Assert
+ Assert.Contains(expectedCampaignTitleString, modalBody.Text);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_ModalBodyContainsCorrectCharacterName()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+ string expectedCharacterName = "Character name: Test Name";
+
+ // Act
+ IWebElement? modalBody = _wait.Until(webDriver => webDriver.FindElement(By.ClassName("modal-body")));
+
+ // Assert
+ Assert.Contains(expectedCharacterName, modalBody.Text);
+ E2ETestUtility.RemoveTestCampaign(_driver, _wait);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_CampaignIsDeletedAndRemovedFromCampaignListWhenModalIsConfirmed()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+ IWebElement? campaignsCounterBefore = _wait.Until(webDriver => webDriver.FindElement(By.Id("campaigns-count")));
+ int expectedAmountOfCampaigns = int.Parse(Regex.Match(campaignsCounterBefore.Text, @"\d+").Value) - 1;
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+
+ // Act
+ _wait.Until(webDriver => webDriver.FindElement(By.Id("modal-confirm"))).Click();
+ Thread.Sleep(500); // Wait for page to update
+ IWebElement? campaignsCounterAfter = _wait.Until(webDriver => webDriver.FindElement(By.Id("campaigns-count")));
+ int actualAmountOfCampaigns = int.Parse(Regex.Match(campaignsCounterAfter.Text, @"\d+").Value);
+
+ // Assert
+ Assert.Equal(expectedAmountOfCampaigns, actualAmountOfCampaigns);
+ }
+
+ [Fact]
+ public void AuthorizedIndexPage_DeleteCampaignModal_CampaignIsPreservedInCampaignListWhenModalIsClosed()
+ {
+ // Arrange
+ E2ETestUtility.CreateTestCampaign(_driver, _wait);
+ IWebElement? campaignsCounterBefore = _wait.Until(webDriver => webDriver.FindElement(By.Id("campaigns-count")));
+ int expectedAmountOfCampaigns = int.Parse(Regex.Match(campaignsCounterBefore.Text, @"\d+").Value);
+ _wait.Until(webDriver => webDriver.FindElements(By.ClassName("delete-campaign-button")))[0].Click();
+ Thread.Sleep(200); // wait for modal to load
+
+ // Act
+ _wait.Until(webDriver => webDriver.FindElement(By.Id("modal-close"))).Click();
+ Thread.Sleep(500); // Wait for page to update
+ IWebElement? campaignsCounterAfter = _wait.Until(webDriver => webDriver.FindElement(By.Id("campaigns-count")));
+ int actualAmountOfCampaigns = int.Parse(Regex.Match(campaignsCounterAfter.Text, @"\d+").Value);
+
+ // Assert
+ Assert.Equal(expectedAmountOfCampaigns, actualAmountOfCampaigns);
+ }
+
+ public void Dispose()
+ {
+ E2ETestUtility.Teardown(_driver);
+ _driver.Dispose();
}
public static IEnumerable