From 757f78a6af8ff752a4c47e2626a6056958cce910 Mon Sep 17 00:00:00 2001 From: Quaylyn Rimer Date: Tue, 22 Jul 2025 12:43:02 -0600 Subject: [PATCH] feat: Add Vue.js page object generation support - Implement VuePageObjectGenerator class with HTML parsing using HtmlAgilityPack - Add WebPageObject.template for generating C# page object classes - Support id, data-testid, v-test-id, and class attribute locators - Map HTML elements to appropriate Legerity web element types - Update Program.cs to enable Web platform with Vue generator - Add HtmlAgilityPack dependency to project file Resolves #200 --- .../Generators/Web/VuePageObjectGenerator.cs | 303 ++++++++++++++++++ .../Legerity.PageObjectGenerator.csproj | 5 + tools/Legerity.PageObjectGenerator/Program.cs | 3 +- .../Templates/WebPageObject.template | 36 +++ 4 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 tools/Legerity.PageObjectGenerator/Features/Generators/Web/VuePageObjectGenerator.cs create mode 100644 tools/Legerity.PageObjectGenerator/Templates/WebPageObject.template diff --git a/tools/Legerity.PageObjectGenerator/Features/Generators/Web/VuePageObjectGenerator.cs b/tools/Legerity.PageObjectGenerator/Features/Generators/Web/VuePageObjectGenerator.cs new file mode 100644 index 00000000..f5e1967a --- /dev/null +++ b/tools/Legerity.PageObjectGenerator/Features/Generators/Web/VuePageObjectGenerator.cs @@ -0,0 +1,303 @@ +namespace Legerity.Features.Generators.Web; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HtmlAgilityPack; +using Infrastructure.IO; +using Legerity.Features.Generators; +using Legerity.Features.Generators.Models; +using Legerity.Infrastructure.Extensions; +using MADE.Collections.Compare; +using MADE.Data.Validation.Extensions; +using Scriban; +using Serilog; + +internal class VuePageObjectGenerator : IPageObjectGenerator +{ + private const string BaseElementType = "WebElement"; + + private static readonly GenericEqualityComparer SimpleStringComparer = new(s => s.ToLower()); + + public static IEnumerable SupportedCoreWebElements => new List + { + "Button", + "CheckBox", + "Select", + "TextInput", + "FileInput", + "Image", + "List", + "Table", + "TableRow", + "Form", + "Option", + "TextArea", + "RadioButton", + "RangeInput", + "NumberInput", + "DateInput" + }; + + public async Task GenerateAsync(string ns, string inputPath, string outputPath) + { + IEnumerable? filePaths = GetVueFilePaths(inputPath)?.ToList(); + + if (filePaths == null || !filePaths.Any()) + { + Log.Warning("No Vue files found in {InputPath}", inputPath); + return; + } + + foreach (string filePath in filePaths) + { + Log.Information($"Processing {filePath}..."); + + try + { + string vueContent = await File.ReadAllTextAsync(filePath); + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(vueContent); + + var templateNode = htmlDoc.DocumentNode.SelectSingleNode("//template"); + if (templateNode == null) + { + Log.Warning($"Skipping {filePath} as no