@code {
+ ///
+ /// Id for the input field.
+ ///
+ [Parameter]
+ public string Id { get; set; } = string.Empty;
+
///
/// Label for the input field.
///
@@ -26,8 +32,6 @@
[Parameter]
public EventCallback ValueChanged { get; set; }
- private string _inputId = Guid.NewGuid().ToString();
-
private async Task OnInputChanged(ChangeEventArgs e)
{
Value = e.Value?.ToString() ?? string.Empty;
diff --git a/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor b/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
index c0ced68f6..0a28987cc 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
+++ b/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
@@ -51,10 +51,10 @@ else
Service
-
+
-
+
@@ -72,14 +72,14 @@ else
-
+
-
+
-
+
@@ -94,43 +94,43 @@ else
Identity
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/Tests/AliasVault.E2ETests/AliasTests.cs b/src/Tests/AliasVault.E2ETests/AliasTests.cs
index a911a953c..6c539f968 100644
--- a/src/Tests/AliasVault.E2ETests/AliasTests.cs
+++ b/src/Tests/AliasVault.E2ETests/AliasTests.cs
@@ -16,50 +16,15 @@ public class AliasTests : PlaywrightTest
{
private static readonly Random Random = new();
- ///
- /// Helper method to fill all input fields on a page with random data.
- ///
- /// IPage instance where to fill the input fields for.
- /// Async task.
- public static async Task FillAllInputFields(IPage page)
- {
- // Locate all input fields
- var inputFields = page.Locator("input");
-
- // Get the count of input fields
- var count = await inputFields.CountAsync();
-
- // Iterate through each input field and fill with random data
- for (int i = 0; i < count; i++)
- {
- var input = inputFields.Nth(i);
- var inputType = await input.GetAttributeAsync("type");
-
- // Generate appropriate random data based on input type
- string randomData = inputType switch
- {
- "email" => GenerateRandomEmail(),
- "number" => GenerateRandomNumber(),
- "password" => GenerateRandomPassword(),
- _ => GenerateRandomString(), // Default for all other types
- };
-
- await input.FillAsync(randomData);
- }
- }
-
///
/// Test if the alias listing index page works.
///
/// Async task.
[Test]
- public async Task AliasListingCorrect()
+ public async Task AliasListingTest()
{
await Page.GotoAsync(AppBaseUrl + "aliases");
- await WaitForURLAsync("**/aliases");
-
- // Wait for the content to load.
- await Page.WaitForSelectorAsync("text=AliasVault");
+ await WaitForURLAsync("**/aliases", "AliasVault");
// Check if the expected content is present.
var pageContent = await Page.TextContentAsync("body");
@@ -71,34 +36,115 @@ public class AliasTests : PlaywrightTest
///
/// Async task.
[Test]
- public async Task CreateAlias()
+ public async Task CreateAliasTest()
{
- await Page.GotoAsync(AppBaseUrl + "add-alias");
- await WaitForURLAsync("**/add-alias");
+ // Create a new alias with service name = "Test Service".
+ var serviceName = "Test Service";
+ await CreateAlias(new Dictionary
+ {
+ { "service-name", serviceName },
+ });
- // Wait for the content to load.
- await Page.WaitForSelectorAsync("text=AliasVault");
+ // Check that the service name is present in the content.
+ var pageContent = await Page.TextContentAsync("body");
+ Assert.That(pageContent, Does.Contain(serviceName), "Created alias service name does not appear on alias page.");
+ }
- // Check if a button with text "Generate Random Identity" appears
- var generateButton = Page.Locator("text=Generate Random Identity");
- Assert.That(generateButton, Is.Not.Null, "Generate button not found.");
+ ///
+ /// Test if editing a created alias works.
+ ///
+ /// Async task.
+ [Test]
+ public async Task EditAliasTest()
+ {
+ // Create a new alias with service name = "Alias service before".
+ var serviceNameBefore = "Alias service before";
+ await CreateAlias(new Dictionary
+ {
+ { "service-name", serviceNameBefore },
+ });
- // Fill all input fields with random data
- await FillAllInputFields(Page);
+ // Check that the service name is present in the content.
+ var pageContent = await Page.TextContentAsync("body");
+ Assert.That(pageContent, Does.Contain(serviceNameBefore), "Created alias service name does not appear on alias page.");
+
+ // Click the edit button.
+ var editButton = Page.Locator("text=Edit alias").First;
+ await editButton.ClickAsync();
+ await WaitForURLAsync("**/edit", "Save Alias");
+
+ // Replace the service name with "Alias service after".
+ var serviceNameAfter = "Alias service after";
+ await FillInputFields(
+ page: Page,
+ fieldValues: new Dictionary
+ {
+ { "service-name", serviceNameAfter },
+ });
- // Press submit button with text "Create Alias"
var submitButton = Page.Locator("text=Save Alias").First;
await submitButton.ClickAsync();
- await WaitForURLAsync("**/alias/**");
+ await WaitForURLAsync("**/alias/**", "View alias");
- // Wait for the content to load.
- await Page.WaitForSelectorAsync("text=Login credentials");
+ // Check if the alias was correctly updated.
+ pageContent = await Page.TextContentAsync("body");
+ Assert.That(pageContent, Does.Contain(serviceNameAfter), "Alias not updated correctly.");
+ }
- // Check if the alias was created
- var pageContent = await Page.TextContentAsync("body");
- Assert.That(pageContent, Does.Contain("Login credentials"), "Alias not created.");
+ ///
+ /// Helper method to fill specified input fields on a page with given values.
+ ///
+ /// IPage instance where to fill the input fields for.
+ /// Dictionary with html element ids and values to input as field value.
+ /// Async task.
+ private static async Task FillInputFields(IPage page, Dictionary? fieldValues = null)
+ {
+ var inputFields = page.Locator("input");
+ var count = await inputFields.CountAsync();
+ for (int i = 0; i < count; i++)
+ {
+ var input = inputFields.Nth(i);
+ var inputId = await input.GetAttributeAsync("id");
- // TODO: Implement proper data input and verification if what was created is correct.
+ // If fieldValues dictionary is provided and the inputId is found in it, fill the input with the value.
+ if (inputId is not null && fieldValues is not null && fieldValues.TryGetValue(inputId, out var fieldValue))
+ {
+ await input.FillAsync(fieldValue);
+ }
+ }
+ }
+
+ ///
+ /// Helper method to fill all empty input fields on a page with random data if not provided.
+ ///
+ /// IPage instance where to fill the input fields for.
+ /// Async task.
+ private static async Task FillEmptyInputFieldsWithRandom(IPage page)
+ {
+ var inputFields = page.Locator("input");
+ var count = await inputFields.CountAsync();
+ for (int i = 0; i < count; i++)
+ {
+ var input = inputFields.Nth(i);
+ var inputType = await input.GetAttributeAsync("type");
+
+ // If is not empty, skip.
+ if (!string.IsNullOrEmpty(await input.InputValueAsync()))
+ {
+ continue;
+ }
+
+ // Generate appropriate random data based on input type.
+ string randomData = inputType switch
+ {
+ "email" => GenerateRandomEmail(),
+ "number" => GenerateRandomNumber(),
+ "password" => GenerateRandomPassword(),
+ _ => GenerateRandomString(), // Default for all other types.
+ };
+
+ await input.FillAsync(randomData);
+ }
}
private static string GenerateRandomString(int length = 10)
@@ -124,4 +170,31 @@ public class AliasTests : PlaywrightTest
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[Random.Next(s.Length)]).ToArray());
}
+
+ ///
+ /// Create new alias.
+ ///
+ /// Dictionary with html element ids and values to input as field value.
+ /// Async task.
+ private async Task CreateAlias(Dictionary? formValues = null)
+ {
+ await Page.GotoAsync(AppBaseUrl + "add-alias");
+ await WaitForURLAsync("**/add-alias", "Add alias");
+
+ // Check if a button with text "Generate Random Identity" appears
+ var generateButton = Page.Locator("text=Generate Random Identity");
+ Assert.That(generateButton, Is.Not.Null, "Generate button not found.");
+
+ // Fill all input fields with specified values and remaining empty fields with random data.
+ await FillInputFields(Page, formValues);
+ await FillEmptyInputFieldsWithRandom(Page);
+
+ var submitButton = Page.Locator("text=Save Alias").First;
+ await submitButton.ClickAsync();
+ await WaitForURLAsync("**/alias/**", "Login credentials");
+
+ // Check if the alias was created
+ var pageContent = await Page.TextContentAsync("body");
+ Assert.That(pageContent, Does.Contain("Login credentials"), "Alias not created.");
+ }
}
diff --git a/src/Tests/AliasVault.E2ETests/AuthTests.cs b/src/Tests/AliasVault.E2ETests/AuthTests.cs
index 240d8c3de..752d52939 100644
--- a/src/Tests/AliasVault.E2ETests/AuthTests.cs
+++ b/src/Tests/AliasVault.E2ETests/AuthTests.cs
@@ -5,8 +5,6 @@
//
//-----------------------------------------------------------------------
-using Microsoft.Playwright;
-
namespace AliasVault.E2ETests;
///
@@ -17,7 +15,7 @@ namespace AliasVault.E2ETests;
public class AuthTests : PlaywrightTest
{
///
- /// Test if registering a new account works.
+ /// Test if logging out and logging in works.
///
/// Async task.
[Test]
@@ -25,13 +23,10 @@ public class AuthTests : PlaywrightTest
{
// Logout.
await Page.GotoAsync(AppBaseUrl + "user/logout");
- await Page.WaitForURLAsync("**/user/logout", new PageWaitForURLOptions() { Timeout = 2000 });
-
- // Wait for the content to load.
- await Page.WaitForSelectorAsync("text=AliasVault");
+ await WaitForURLAsync("**/user/logout", "AliasVault");
// Wait and check if we get redirected to /user/login.
- await Page.WaitForURLAsync("**/user/login", new PageWaitForURLOptions() { Timeout = 2000 });
+ await WaitForURLAsync("**/user/login");
await Login();
}
@@ -40,7 +35,7 @@ public class AuthTests : PlaywrightTest
/// Test if logging in works.
///
/// Async task.
- public async Task Login()
+ private async Task Login()
{
await Page.GotoAsync(AppBaseUrl);
diff --git a/src/Tests/AliasVault.E2ETests/Common/PlaywrightTest.cs b/src/Tests/AliasVault.E2ETests/Common/PlaywrightTest.cs
index 6cf0f0481..871e6b7cd 100644
--- a/src/Tests/AliasVault.E2ETests/Common/PlaywrightTest.cs
+++ b/src/Tests/AliasVault.E2ETests/Common/PlaywrightTest.cs
@@ -138,6 +138,21 @@ public class PlaywrightTest
await Page.WaitForURLAsync(url, new PageWaitForURLOptions() { Timeout = timeoutInMs });
}
+ ///
+ /// Wait for the specified URL to be loaded with a custom timeout.
+ ///
+ /// The URL to wait for. This may also contains wildcard such as "**/user/login".
+ /// Wait until a certain text appears on the page.
+ /// This can be useful for content that is loaded via AJAX after navigation.
+ /// Async task.
+ protected async Task WaitForURLAsync(string url, string waitForText)
+ {
+ await Page.WaitForURLAsync(url, new PageWaitForURLOptions() { Timeout = TestDefaults.DefaultTimeout });
+
+ // Wait for actual content to load (web API calls, etc.)
+ await Page.WaitForSelectorAsync("text=" + waitForText, new PageWaitForSelectorOptions() { Timeout = TestDefaults.DefaultTimeout });
+ }
+
///
/// Register a new random account.
///
diff --git a/src/Tests/AliasVault.E2ETests/Infrastructure/BlazorWasmAppManager.cs b/src/Tests/AliasVault.E2ETests/Infrastructure/BlazorWasmAppManager.cs
index 75c213c14..af3a81d11 100644
--- a/src/Tests/AliasVault.E2ETests/Infrastructure/BlazorWasmAppManager.cs
+++ b/src/Tests/AliasVault.E2ETests/Infrastructure/BlazorWasmAppManager.cs
@@ -113,7 +113,6 @@ public class BlazorWasmAppManager
}
Console.WriteLine(e.Message);
- await Task.Delay(500);
}
}
}