diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorFactoryTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorFactoryTests.cs new file mode 100644 index 0000000..ac93abf --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorFactoryTests.cs @@ -0,0 +1,79 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorFactoryTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorFactory codeGeneratorFactory; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = new ObjectRepositoryPage(); + page.Name = "RegistrationPage"; + page.Title = "Registration"; + page.Model = true; + page.Controls.Add(new ObjectRepositoryControl() { Name = "FirstName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "firstname", Value = "Hugoline" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "LastName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "lastname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Country", Type = ControlTypes.ComboBox.ToString(), How = ControlHows.Name.ToString(), Using = "country", Value = "Denmark" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Male", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_0", Value = "False" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Female", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_1", Value = "True" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "IAgreeToTheTermsOfUse", Type = ControlTypes.CheckBox.ToString(), How = ControlHows.Name.ToString(), Using = "agreement" }); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorFactory = new CodeGeneratorFactory(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorFactoryJavaPlaywright_GenerateSourceCode() + { + var listOfLines = codeGeneratorFactory.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(21), "CodeGeneratorFactoryJavaPlaywright GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorFactoryJavaPlaywright_GeneratePackage() + { + var listOfLines = codeGeneratorFactory.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorFactoryJavaPlaywright GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.factories;"), "CodeGeneratorFactoryJavaPlaywright GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorFactoryJavaPlaywright_GenerateClass() + { + var listOfLines = codeGeneratorFactory.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorFactoryJavaPlaywright GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class RegistrationPageModelFactory"), "CodeGeneratorFactoryJavaPlaywright GenerateClass validation"); + } + + [Test] + public void CodeGeneratorFactoryJavaPlaywright_GenerateDefaultMethod() + { + var listOfLines = codeGeneratorFactory.GenerateDefaultMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(14), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + Assert.That(listOfLines[0], Is.EqualTo("public static RegistrationPageModel getDefault() {"), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + Assert.That(listOfLines[1], Is.EqualTo("RegistrationPageModel model = new RegistrationPageModel();"), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + Assert.That(listOfLines[5], Is.EqualTo("model.setFirstName(\"Hugoline\");"), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + Assert.That(listOfLines[8], Is.EqualTo("model.setMale(false);"), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + Assert.That(listOfLines[9], Is.EqualTo("model.setFemale(true);"), "CodeGeneratorFactoryJavaPlaywright GenerateDefaultMethod validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorModelTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorModelTests.cs new file mode 100644 index 0000000..fe6553d --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorModelTests.cs @@ -0,0 +1,90 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorModelTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorModel codeGeneratorModel; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = new ObjectRepositoryPage(); + page.Name = "RegistrationPage"; + page.Title = "Registration"; + page.Model = true; + page.Controls.Add(new ObjectRepositoryControl() { Name = "FirstName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "firstname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "LastName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "lastname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Country", Type = ControlTypes.ComboBox.ToString(), How = ControlHows.Name.ToString(), Using = "country", Value = "Denmark" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Male", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_0", Value = "False" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Female", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_1", Value = "True" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "IAgreeToTheTermsOfUse", Type = ControlTypes.CheckBox.ToString(), How = ControlHows.Name.ToString(), Using = "agreement" }); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorModel = new CodeGeneratorModel(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorModelJavaPlaywright_GenerateSourceCode() + { + var listOfLines = codeGeneratorModel.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(63), "CodeGeneratorModelJavaPlaywright GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorModelJavaPlaywright_GeneratePackage() + { + var listOfLines = codeGeneratorModel.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorModelJavaPlaywright GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.models;"), "CodeGeneratorModelJavaPlaywright GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorModelJavaPlaywright_GenerateClass() + { + var listOfLines = codeGeneratorModel.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorModelJavaPlaywright GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class RegistrationPageModel"), "CodeGeneratorModelJavaPlaywright GenerateClass validation"); + } + + [Test] + public void CodeGeneratorModelJavaPlaywright_GenerateFields() + { + var listOfLines = codeGeneratorModel.GenerateFields(page); + + Assert.That(listOfLines.Count, Is.EqualTo(6), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[0], Is.EqualTo("private String firstName;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[1], Is.EqualTo("private String lastName;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[2], Is.EqualTo("private String country;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[3], Is.EqualTo("private boolean male;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[4], Is.EqualTo("private boolean female;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + Assert.That(listOfLines[5], Is.EqualTo("private boolean iAgreeToTheTermsOfUse;"), "CodeGeneratorModelJavaPlaywright GenerateFields validation"); + } + + [Test] + public void CodeGeneratorModelJavaPlaywright_GenerateAccessors() + { + var listOfLines = codeGeneratorModel.GenerateAccessors(page); + + Assert.That(listOfLines.Count, Is.EqualTo(48), "CodeGeneratorModelJavaPlaywright GenerateAccessors validation"); + Assert.That(listOfLines[0], Is.EqualTo("public String getFirstName() {"), "CodeGeneratorModelJavaPlaywright GenerateAccessors validation"); + Assert.That(listOfLines[4], Is.EqualTo("public void setFirstName(String value) {"), "CodeGeneratorModelJavaPlaywright GenerateAccessors validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorObjectTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorObjectTests.cs new file mode 100644 index 0000000..dd65584 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorObjectTests.cs @@ -0,0 +1,164 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorObjectTests + { + [Test] + public void Configuration_GetPackage() + { + var configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + var codeGeneratorObject = new CodeGeneratorObject(configuration, null); + var result = codeGeneratorObject.GetPackage(); + var expected = "expressium.coffeeshop.web.api"; + + Assert.That(result, Is.EqualTo(expected), "Configuration GetPackage validate generated output"); + } + + [Test] + public void Configuration_GetPackagePath() + { + var configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + var codeGeneratorObject = new CodeGeneratorObject(configuration, null); + var result = codeGeneratorObject.GetPackagePath(); + var expected = "expressium/coffeeshop/web/api"; + + Assert.That(result, Is.EqualTo(expected), "Configuration GetPackagePath validate generated output"); + } + + [Test] + public void CodeGeneratorObject_GetSourceCodeAsFormatted() + { + var input = new List + { + "public class AssetsBar extends BasePage", + "{", + "public boolean assetsBar(boolean value)", + "{", + "if (value)", + "return true;", + "else if (!value)", + "return false;", + "else", + "return false;", + "", + "if (x)", + "if (y)", + "return true;", + "", + "while (a==b)", + "continue;", + "", + "for (int i=0; i + { + "public class AssetsBar extends BasePage", + "{", + " public boolean assetsBar(boolean value)", + " {", + " if (value)", + " return true;", + " else if (!value)", + " return false;", + " else", + " return false;", + "", + " if (x)", + " if (y)", + " return true;", + "", + " while (a==b)", + " continue;", + "", + " for (int i=0; i + { + "", + "", + "" + }; + + var expected = "\r\n\r\n"; + + var result = CodeGeneratorObject.GetSourceCodeAsString(input); + Assert.That(result, Is.EqualTo(expected), "CodeGeneratorObject GetSourceCodeAsString validation"); + } + + [Test] + public void ConfigurationObject_GenerateSourceCodeExtensionMethods() + { + var listOfLines = CodeGeneratorObject.GenerateSourceCodeExtensionMethods(null, "// region Extensions", "// endregion"); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + } + + [Test] + public void ConfigurationObject_GenerateSourceCodeExtensionMethods_With_File() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "SnippetJavaPlaywright.txt"); + File.Delete(filePath); + File.WriteAllText(filePath, "// region Extensions\n\n// This is my life...\n\n// endregion\n"); + + var listOfLines = CodeGeneratorObject.GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("// region Extensions"), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("// This is my life..."), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[4], Is.EqualTo("// endregion"), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + } + + [Test] + public void CodeGeneratorObject_IsSourceCodeModified_With_Comment() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "ExportPageJavaPlaywright.txt"); + + File.Delete(filePath); + File.WriteAllText(filePath, "// TODO - Implement..."); + + Assert.That(CodeGeneratorObject.IsSourceCodeModified(filePath), Is.False, "CodeGeneratorObject IsSourceCodeModified validation"); + } + + [Test] + public void CodeGeneratorObject_IsSourceCodeModified_Without_Comment() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "ImportPageJavaPlaywright.txt"); + + File.Delete(filePath); + File.WriteAllText(filePath, "// TODO - Updated..."); + + Assert.That(CodeGeneratorObject.IsSourceCodeModified(filePath), Is.True, "CodeGeneratorObject IsSourceCodeModified validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorPageTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorPageTests.cs new file mode 100644 index 0000000..f1de7b7 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorPageTests.cs @@ -0,0 +1,169 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorPageTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorPage codeGeneratorPage; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = CreateLoginPage(); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorPage = new CodeGeneratorPage(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateSourceCode() + { + var listOfLines = codeGeneratorPage.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(39), "CodeGeneratorPageJavaPlaywright GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GeneratePackage() + { + var listOfLines = codeGeneratorPage.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorPageJavaPlaywright GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.pages;"), "CodeGeneratorPageJavaPlaywright GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateImports() + { + var listOfLines = codeGeneratorPage.GenerateImports(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorPageJavaPlaywright GenerateImports validation"); + Assert.That(listOfLines[2], Is.EqualTo("import expressium.coffeeshop.web.api.models.*;"), "CodeGeneratorPageJavaPlaywright GenerateImports validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateClass() + { + var listOfLines = codeGeneratorPage.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorPageJavaPlaywright GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class LoginPage extends FramePage"), "CodeGeneratorPageJavaPlaywright GenerateClass validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateMembers() + { + var listOfLines = codeGeneratorPage.GenerateMembers(page); + + Assert.That(listOfLines.Count, Is.EqualTo(2), "CodeGeneratorPageJavaPlaywright GenerateMembers validation"); + Assert.That(listOfLines[0], Is.EqualTo("public MainMenuBar menu;"), "CodeGeneratorPageJavaPlaywright GenerateMembers validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateMembers_With_Table() + { + var tablePage = page.Copy(); + tablePage.AddControl(new ObjectRepositoryControl() { Name = "Grid", Type = "Table", How = "Id", Using = "products" }); + + var listOfLines = codeGeneratorPage.GenerateMembers(tablePage); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorPageJavaPlaywright GenerateMembers validation"); + Assert.That(listOfLines[0], Is.EqualTo("public MainMenuBar menu;"), "CodeGeneratorPageJavaPlaywright GenerateMembers validation"); + Assert.That(listOfLines[1], Is.EqualTo("public BaseTable grid;"), "CodeGeneratorPageJavaPlaywright GenerateMembers validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateLocators() + { + var listOfLines = codeGeneratorPage.GenerateLocators(page); + + Assert.That(listOfLines.Count, Is.EqualTo(2), "CodeGeneratorPageJavaPlaywright GenerateLocators validation"); + Assert.That(listOfLines[0], Is.EqualTo("private WebTextBox username;"), "CodeGeneratorPageJavaPlaywright GenerateLocators validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateConstructor() + { + var listOfLines = codeGeneratorPage.GenerateContructor(page); + + Assert.That(listOfLines.Count, Is.EqualTo(8), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[0], Is.EqualTo("public LoginPage(Logger logger, Page page) {"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[2], Is.EqualTo("this.menu = new MainMenuBar(logger, page);"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[5], Is.EqualTo("waitForPageTitleEquals(\"Home\");"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateConstructor_With_Table() + { + var tablePage = page.Copy(); + tablePage.AddControl(new ObjectRepositoryControl() { Name = "Grid", Type = "Table", How = "Id", Using = "products" }); + + var listOfLines = codeGeneratorPage.GenerateContructor(tablePage); + + Assert.That(listOfLines.Count, Is.EqualTo(9), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[0], Is.EqualTo("public LoginPage(Logger logger, Page page) {"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[2], Is.EqualTo("this.menu = new MainMenuBar(logger, page);"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[3], Is.EqualTo("this.grid = new BaseTable(logger, page, page.locator(\"[id='products']\"));"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + Assert.That(listOfLines[6], Is.EqualTo("waitForPageTitleEquals(\"Home\");"), "CodeGeneratorPageJavaPlaywright GenerateConstructor validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateActionMethods() + { + var listOfLines = codeGeneratorPage.GenerateActionMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(10), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("public void setUsername(String value) {"), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("logger.info(\"setUsername(\" + value + \")\");"), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("username.setText(value);"), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + Assert.That(listOfLines[5], Is.EqualTo("public String getUsername() {"), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + Assert.That(listOfLines[7], Is.EqualTo("return username.getText();"), "CodeGeneratorPageJavaPlaywright GenerateActionMethods validation"); + } + + [Test] + public void CodeGeneratorPageJavaPlaywright_GenerateFillFormMethod() + { + var listOfLines = codeGeneratorPage.GenerateFillFormMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorPageJavaPlaywright GenerateFillFormMethod validation"); + Assert.That(listOfLines[0], Is.EqualTo("public void fillForm(LoginPageModel model) {"), "CodeGeneratorPageJavaPlaywright GenerateFillFormMethod validation"); + Assert.That(listOfLines[1], Is.EqualTo("setUsername(model.getUsername());"), "CodeGeneratorPageJavaPlaywright GenerateFillFormMethod validation"); + } + + private static ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + page.Base = "FramePage"; + page.Model = true; + + var synchronizer = new ObjectRepositorySynchronizer() { How = "WaitForPageTitleEquals", Using = "Home" }; + page.AddSynchronizer(synchronizer); + + var member = new ObjectRepositoryMember() { Name = "Menu", Page = "MainMenuBar" }; + page.AddMember(member); + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + page.AddControl(username); + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorSolutionTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorSolutionTests.cs new file mode 100644 index 0000000..4b94cc0 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorSolutionTests.cs @@ -0,0 +1,80 @@ +using Expressium.Configurations; +using NUnit.Framework; +using System; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorSolutionTests + { + private Configuration configuration; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Microsoft"; + configuration.Project = "Foodshop"; + configuration.ApplicationUrl = "http://www.dr.dk"; + configuration.SolutionPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "CodeGeneratorSolutionJavaPlaywright"); + configuration.CodeGenerator.CodingLanguage = CodingLanguages.Java.ToString(); + configuration.CodeGenerator.CodingFlavour = CodingFlavours.Playwright.ToString(); + + if (Directory.Exists(configuration.SolutionPath)) + Directory.Delete(configuration.SolutionPath, true); + + Directory.CreateDirectory(configuration.SolutionPath); + + var codeGeneratorSolution = new CodeGeneratorSolution(configuration); + codeGeneratorSolution.GenerateAll(); + } + + [Test] + public void CodeGeneratorSolutionJavaPlaywright_GenerateAll_Expressium_Files() + { + Assert.That(File.Exists(configuration.ConfigurationPath), Is.True, "CodeGeneratorSolution solution generation completed..."); + Assert.That(File.Exists(configuration.RepositoryPath), Is.True, "CodeGeneratorSolution solution generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJavaPlaywright_GenerateAll_Configuration_File() + { + var testResourcesPath = Path.Combine(configuration.SolutionPath, "src", "test", "resources"); + var configFile = File.ReadAllText(Path.Combine(testResourcesPath, "configuration.json")); + + Assert.That(configFile, Does.Contain(configuration.Company), "CodeGeneratorSolution solution configuration contains Company..."); + Assert.That(configFile, Does.Contain(configuration.Project), "CodeGeneratorSolution solution configuration contains Project..."); + Assert.That(configFile, Does.Contain(configuration.ApplicationUrl), "CodeGeneratorSolution solution configuration contains URL..."); + } + + [Test] + public void CodeGeneratorSolutionJavaPlaywright_GenerateAll_PomXml() + { + var pomFile = Path.Combine(configuration.SolutionPath, "pom.xml"); + + Assert.That(File.Exists(pomFile), Is.True, "CodeGeneratorSolution pom.xml generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJavaPlaywright_GenerateAll_BasePage() + { + var packagePath = "microsoft/foodshop/web/api"; + var mainSourcePath = Path.Combine(configuration.SolutionPath, "src", "main", "java", packagePath); + var basePageFile = Path.Combine(mainSourcePath, "BasePage.java"); + + Assert.That(File.Exists(basePageFile), Is.True, "CodeGeneratorSolution BasePage.java generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJavaPlaywright_GenerateAll_WebControls() + { + var packagePath = "microsoft/foodshop/web/api"; + var controlsPath = Path.Combine(configuration.SolutionPath, "src", "main", "java", packagePath, "controls"); + + Assert.That(File.Exists(Path.Combine(controlsPath, "WebControl.java")), Is.True, "CodeGeneratorSolution WebControl.java generation completed..."); + Assert.That(File.Exists(Path.Combine(controlsPath, "WebButton.java")), Is.True, "CodeGeneratorSolution WebButton.java generation completed..."); + Assert.That(File.Exists(Path.Combine(controlsPath, "WebTextBox.java")), Is.True, "CodeGeneratorSolution WebTextBox.java generation completed..."); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTestTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTestTests.cs new file mode 100644 index 0000000..25fc0c3 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTestTests.cs @@ -0,0 +1,226 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorTestTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorTest codeGeneratorTest; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = CreateLoginPage(); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorTest = new CodeGeneratorTest(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateSourceCode() + { + var listOfLines = codeGeneratorTest.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(36), "CodeGeneratorTestJavaPlaywright GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GeneratePackage() + { + var listOfLines = codeGeneratorTest.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorTestJavaPlaywright GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.uitests;"), "CodeGeneratorTestJavaPlaywright GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateImports() + { + var listOfLines = codeGeneratorTest.GenerateImports(page); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorTestJavaPlaywright GenerateImports validation"); + Assert.That(listOfLines[2], Is.EqualTo("import expressium.coffeeshop.web.api.models.*;"), "CodeGeneratorTestJavaPlaywright GenerateImports validation"); + Assert.That(listOfLines[3], Is.EqualTo("import expressium.coffeeshop.web.api.pages.*;"), "CodeGeneratorTestJavaPlaywright GenerateImports validation"); + Assert.That(listOfLines[4], Is.EqualTo("import expressium.coffeeshop.web.api.factories.*;"), "CodeGeneratorTestJavaPlaywright GenerateImports validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateTagProperties() + { + var listOfLines = codeGeneratorTest.GenerateTagProperties(page); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJavaPlaywright GenerateTagProperties validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateClass() + { + var listOfLines = codeGeneratorTest.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorTestJavaPlaywright GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class LoginPageTests extends BaseTest"), "CodeGeneratorTestJavaPlaywright GenerateClass validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GeneratedDataVariables() + { + var listOfLines = codeGeneratorTest.GeneratedDataVariables(page); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + Assert.That(listOfLines[0], Is.EqualTo("private LoginPage loginPage;"), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + Assert.That(listOfLines[1], Is.EqualTo("private LoginPageModel loginPageModel = LoginPageModelFactory.getDefault();"), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GeneratedDataVariables_As_Variables() + { + page.Model = false; + var listOfLines = codeGeneratorTest.GeneratedDataVariables(page); + page.Model = true; + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + Assert.That(listOfLines[0], Is.EqualTo("private LoginPage loginPage;"), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + Assert.That(listOfLines[2], Is.EqualTo("private String username = \"Andersen\";"), "CodeGeneratorTestJavaPlaywright GeneratedDataVariables validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateSetUpMethod() + { + var listOfLines = codeGeneratorTest.GenerateSetUpMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(10), "CodeGeneratorTestJavaPlaywright GenerateSetUpMethod validation"); + Assert.That(listOfLines[2], Is.EqualTo("initializeBrowser();"), "CodeGeneratorTestJavaPlaywright GenerateSetUpMethod validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateTitleTestMethod() + { + var listOfLines = codeGeneratorTest.GenerateTitleTestMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorTestJavaPlaywright GenerateTitleTestMethod validation"); + Assert.That(listOfLines[2], Is.EqualTo("asserts.equalTo(loginPage.getTitle(), \"Login\", \"Validating the LoginPage Title...\");"), "CodeGeneratorTestJavaPlaywright GenerateTitleTestMethod validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateFillFormTestMethods() + { + var listOfLines = codeGeneratorTest.GenerateFillFormTestMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorTestJavaPlaywright GenerateFillFormTestMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("public void validate_Page_Property_Username() {"), "CodeGeneratorTestJavaPlaywright GenerateFillFormTestMethods validation"); + Assert.That(listOfLines[3].Contains("equalTo(loginPage.getUsername(), loginPageModel.getUsername()"), Is.True, "CodeGeneratorTestJavaPlaywright GenerateFillFormTestMethods validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GenerateTableTestMethods() + { + var listOfLines = codeGeneratorTest.GenerateTableTestMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(0), "CodeGeneratorTestJavaPlaywright GenerateTableTestMethods validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_Recursive_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.Title = "Login"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Login", Target = loginPage.Name }); + objectRepository.AddPage(loginPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, loginPage.Name); + + Assert.That(listOfLines, Is.Null, "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_Deep_Recursive_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Registration", Target = "RegistrationPage" }); + objectRepository.AddPage(loginPage); + + var registrationPage = new ObjectRepositoryPage(); + registrationPage.Name = "RegistrationPage"; + registrationPage.AddControl(new ObjectRepositoryControl() { Name = "Login", Target = "LoginPage" }); + objectRepository.AddPage(registrationPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, loginPage.Name); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("var registrationPage = new RegistrationPage(logger, page);"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("registrationPage.clickLogin();"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + } + + [Test] + public void CodeGeneratorTestJavaPlaywright_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.Title = "Login"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Registration", Target = "RegistrationPage" }); + objectRepository.AddPage(loginPage); + + var registrationPage = new ObjectRepositoryPage(); + registrationPage.Name = "RegistrationPage"; + registrationPage.AddControl(new ObjectRepositoryControl() { Name = "Settings", Target = "SettingsPage" }); + objectRepository.AddPage(registrationPage); + + var settingsPage = new ObjectRepositoryPage(); + settingsPage.Name = "SettingsPage"; + objectRepository.AddPage(settingsPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, settingsPage.Name); + + Assert.That(listOfLines.Count, Is.EqualTo(6), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("var loginPage = new LoginPage(logger, page);"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("loginPage.clickRegistration();"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[3], Is.EqualTo("var registrationPage = new RegistrationPage(logger, page);"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + Assert.That(listOfLines[4], Is.EqualTo("registrationPage.clickSettings();"), "CodeGeneratorTestJavaPlaywright GetNavigationMethods validation"); + } + + private static ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + page.Base = "FramePage"; + page.Title = "Login"; + page.Model = true; + + var synchronizer = new ObjectRepositorySynchronizer() { How = "WaitForPageTitleEquals", Using = "Home" }; + page.AddSynchronizer(synchronizer); + + var member = new ObjectRepositoryMember() { Name = "Menu", Page = "MainMenuBar" }; + page.AddMember(member); + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + username.Value = "Andersen"; + page.AddControl(username); + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTests.cs b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTests.cs new file mode 100644 index 0000000..9771fb6 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/CodeGeneratorTests.cs @@ -0,0 +1,187 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; +using System; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright.UnitTests +{ + [TestFixture] + public class CodeGeneratorTests + { + string directory = null; + + Configuration configuration; + + [OneTimeSetUp] + public void Setup() + { + directory = Environment.GetEnvironmentVariable("TEMP"); + + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + configuration.ApplicationUrl = "http://www.google.com"; + configuration.SolutionPath = directory; + configuration.CodeGenerator.CodingLanguage = CodingLanguages.Java.ToString(); + configuration.CodeGenerator.CodingFlavour = CodingFlavours.Playwright.ToString(); + } + + [Test] + public void CodeGenerator_GenerateAll() + { + if (File.Exists(configuration.RepositoryPath)) + File.Delete(configuration.RepositoryPath); + + var packagePath = "expressium/coffeeshop/web/api"; + var mainSourcePath = Path.Combine(directory, "src", "main", "java", packagePath); + var testSourcePath = Path.Combine(directory, "src", "test", "java", packagePath); + + var loginPageFile = Path.Combine(mainSourcePath, "pages", "LoginPage.java"); + if (File.Exists(loginPageFile)) + File.Delete(loginPageFile); + + var loginModelFile = Path.Combine(mainSourcePath, "models", "LoginPageModel.java"); + if (File.Exists(loginModelFile)) + File.Delete(loginModelFile); + + var loginTestFile = Path.Combine(testSourcePath, "uitests", "LoginPageTests.java"); + if (File.Exists(loginTestFile)) + File.Delete(loginTestFile); + + var loginFactoryFile = Path.Combine(testSourcePath, "factories", "LoginPageModelFactory.java"); + if (File.Exists(loginFactoryFile)) + File.Delete(loginFactoryFile); + + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, objectRepository); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + codeGenerator.GenerateAll(); + + Assert.That(File.Exists(loginPageFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginModelFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginTestFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginFactoryFile), Is.True, "CodeGenerator GenerateAll validation"); + } + + [Test] + public void CodeGenerator_GeneratePage() + { + if (File.Exists(configuration.RepositoryPath)) + File.Delete(configuration.RepositoryPath); + + var packagePath = "expressium/coffeeshop/web/api"; + var mainSourcePath = Path.Combine(directory, "src", "main", "java", packagePath); + var testSourcePath = Path.Combine(directory, "src", "test", "java", packagePath); + + var loginPageFile = Path.Combine(mainSourcePath, "pages", "LoginPage.java"); + if (File.Exists(loginPageFile)) + File.Delete(loginPageFile); + + var loginPageModelFile = Path.Combine(mainSourcePath, "models", "LoginPageModel.java"); + if (File.Exists(loginPageModelFile)) + File.Delete(loginPageModelFile); + + var loginTestFile = Path.Combine(testSourcePath, "uitests", "LoginPageTests.java"); + if (File.Exists(loginTestFile)) + File.Delete(loginTestFile); + + var loginFactoryFile = Path.Combine(testSourcePath, "factories", "LoginPageModelFactory.java"); + if (File.Exists(loginFactoryFile)) + File.Delete(loginFactoryFile); + + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, objectRepository); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + codeGenerator.GeneratePage("LoginPage"); + + Assert.That(File.Exists(loginPageFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginPageModelFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginTestFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginFactoryFile), Is.True, "CodeGenerator GeneratePage validation"); + } + + [Test] + public void CodeGenerator_GeneratePagePreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GeneratePagePreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPage"), "CodeGenerator GeneratePagePreview validation"); + } + + [Test] + public void CodeGenerator_GenerateModelPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateModelPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModel"), "CodeGenerator GenerateModelPreview validation"); + } + + [Test] + public void CodeGenerator_GenerateTestPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateTestPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModel"), "CodeGenerator GenerateTestPreview validation"); + } + + [Test] + public void CodeGenerator_GenerateFactoryPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateFactoryPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModelFactory"), "CodeGenerator GenerateFactoryPreview validation"); + } + + private ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + page.AddControl(username); + + var password = new ObjectRepositoryControl(); + password.Name = "Password"; + password.Type = "TextBox"; + password.How = "Name"; + password.Using = "password"; + page.AddControl(password); + + var submit = new ObjectRepositoryControl(); + submit.Name = "LogIn"; + submit.Type = "Button"; + submit.How = "XPath"; + submit.Using = "//button[text()='LogIn']"; + page.AddControl(submit); + + page.Model = true; + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright.UnitTests/Expressium.CodeGenerators.Java.Playwright.UnitTests.csproj b/Expressium.CodeGenerators.Java.Playwright.UnitTests/Expressium.CodeGenerators.Java.Playwright.UnitTests.csproj new file mode 100644 index 0000000..5a722c8 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright.UnitTests/Expressium.CodeGenerators.Java.Playwright.UnitTests.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + false + true + + + + + + + + + + + + + diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGenerator.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGenerator.cs new file mode 100644 index 0000000..1602f51 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGenerator.cs @@ -0,0 +1,129 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System; +using System.Collections.Generic; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + public class CodeGenerator : ICodeGenerator + { + private readonly Configuration configuration; + private readonly ObjectRepository objectRepository; + + private readonly CodeGeneratorPage codeGeneratorPage; + private readonly CodeGeneratorModel codeGeneratorModel; + private readonly CodeGeneratorTest codeGeneratorTest; + private readonly CodeGeneratorFactory codeGeneratorFactory; + private readonly CodeGeneratorSolution codeGeneratorSolution; + + public CodeGenerator() + { + } + + public CodeGenerator(Configuration configuration, ObjectRepository objectRepository) + { + configuration.Validate(); + objectRepository.Validate(); + + this.configuration = configuration; + this.objectRepository = objectRepository; + + codeGeneratorPage = new CodeGeneratorPage(configuration, objectRepository); + codeGeneratorModel = new CodeGeneratorModel(configuration, objectRepository); + codeGeneratorTest = new CodeGeneratorTest(configuration, objectRepository); + codeGeneratorFactory = new CodeGeneratorFactory(configuration, objectRepository); + codeGeneratorSolution = new CodeGeneratorSolution(configuration); + } + + public void GenerateAll() + { + foreach (var page in objectRepository.Pages) + { + codeGeneratorPage.Generate(page); + if (page.Model) + codeGeneratorModel.Generate(page); + + codeGeneratorTest.Generate(page); + if (page.Model) + codeGeneratorFactory.Generate(page); + } + } + + public void GeneratePage(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + + codeGeneratorPage.Generate(page); + if (page.Model) + codeGeneratorModel.Generate(page); + + codeGeneratorTest.Generate(page); + if (page.Model) + codeGeneratorFactory.Generate(page); + } + } + + public string GeneratePagePreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + return codeGeneratorPage.GeneratePreview(page); + } + + return null; + } + + public string GenerateModelPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + if (page.Model) + return codeGeneratorModel.GeneratePreview(page); + } + + return null; + } + + public string GenerateTestPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + return codeGeneratorTest.GeneratePreview(page); + } + + return null; + } + + public string GenerateFactoryPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + if (page.Model) + return codeGeneratorFactory.GeneratePreview(page); + } + + return null; + } + + public void GenerateSolution() + { + codeGeneratorSolution.GenerateAll(); + } + + public List GetCodingLanguages() + { + return new List(Enum.GetNames(typeof(CodingLanguages))); + } + + public List GetCodingFlavours() + { + return new List(Enum.GetNames(typeof(CodingFlavours))); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorEnumerations.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorEnumerations.cs new file mode 100644 index 0000000..dffb10e --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorEnumerations.cs @@ -0,0 +1,27 @@ +using System; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal enum CodeFolders + { + models, + pages, + controls + } + + internal enum TestFolders + { + factories, + uitests + } + + internal enum CodingLanguages + { + Java + } + + internal enum CodingFlavours + { + Playwright + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorFactory.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorFactory.cs new file mode 100644 index 0000000..1d46ce7 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorFactory.cs @@ -0,0 +1,122 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorFactory : CodeGeneratorObject + { + internal CodeGeneratorFactory(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + + if (IsSourceCodeModified(filePath)) + return; + + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetTestSourcePath(), TestFolders.factories.ToString(), page.Name + "ModelFactory.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateDefaultMethod(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{TestFolders.factories};" + }; + } + + internal List GenerateImports() + { + return new List + { + $"import {GetPackage()}.{CodeFolders.models}.*;" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}ModelFactory" + }; + } + + internal List GenerateDefaultMethod(ObjectRepositoryPage page) + { + var listOfLines = new List + { + $"public static {page.Name}Model getDefault() {{", + $"{page.Name}Model model = new {page.Name}Model();", + $"", + $"// TODO - Implement potential missing factory property...", + $"" + }; + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + string value = control.Value; + if (string.IsNullOrWhiteSpace(value)) + value = CodeGeneratorUtilities.GenerateRandomString(6); + + listOfLines.Add($"model.set{control.Name}(\"{value}\");"); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + if (control.Value != null && control.Value.ToLower() == "true") + listOfLines.Add($"model.set{control.Name}(true);"); + else + listOfLines.Add($"model.set{control.Name}(false);"); + } + } + + listOfLines.Add($""); + listOfLines.Add($"return model;"); + listOfLines.Add($"}}"); + + return listOfLines; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorModel.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorModel.cs new file mode 100644 index 0000000..70c4268 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorModel.cs @@ -0,0 +1,128 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorModel : CodeGeneratorObject + { + internal CodeGeneratorModel(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetMainSourcePath(), CodeFolders.models.ToString(), page.Name + "Model.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateFields(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateAccessors(page)); + listOfLines.AddRange(GenerateExtensionMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{CodeFolders.models};" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}Model" + }; + } + + internal List GenerateFields(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + listOfLines.Add($"private String {control.Name.CamelCase()};"); + else if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"private boolean {control.Name.CamelCase()};"); + } + + return listOfLines; + } + + internal List GenerateAccessors(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + listOfLines.Add($"public String get{control.Name}() {{"); + listOfLines.Add($"return {control.Name.CamelCase()};"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + listOfLines.Add($"public void set{control.Name}(String value) {{"); + listOfLines.Add($"this.{control.Name.CamelCase()} = value;"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + listOfLines.Add($"public boolean is{control.Name}() {{"); + listOfLines.Add($"return {control.Name.CamelCase()};"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + listOfLines.Add($"public void set{control.Name}(boolean value) {{"); + listOfLines.Add($"this.{control.Name.CamelCase()} = value;"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + } + } + + return listOfLines; + } + + internal List GenerateExtensionMethods(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + return GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorObject.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorObject.cs new file mode 100644 index 0000000..b48a72e --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorObject.cs @@ -0,0 +1,108 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System; +using System.Linq; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorObject + { + protected Configuration configuration; + protected ObjectRepository objectRepository; + + internal CodeGeneratorObject(Configuration configuration, ObjectRepository objectRepository) + { + this.configuration = configuration; + this.objectRepository = objectRepository; + } + + internal static bool IsSourceCodeModified(string filePath) + { + if (File.Exists(filePath) && !File.ReadAllText(filePath).Contains("// TODO - Implement")) + return true; + + return false; + } + + internal static void SaveSourceCode(string filePath, List listOfCodeLines) + { + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + File.WriteAllLines(filePath, listOfCodeLines); + + Console.WriteLine(filePath); + } + + internal static string GetSourceCodeAsString(List listOfCodeLines) + { + return string.Join(Environment.NewLine, listOfCodeLines); + } + + internal static List GetSourceCodeAsFormatted(List listOfCodeLines) + { + return CodeGeneratorUtilities.FormatSourceCode(listOfCodeLines); + } + + internal static List GenerateSourceCodeExtensionMethods(string filePath, string startLine, string endLine) + { + var listOfLines = new List(); + + listOfLines.Add(startLine); + + var listOfCodeLines = GetSourceCodeSnippetInFile(filePath, startLine, endLine); + if (listOfCodeLines != null && listOfCodeLines.Count > 0) + listOfLines.AddRange(listOfCodeLines); + else + listOfLines.Add(""); + + listOfLines.Add(endLine); + + return listOfLines; + } + + internal static List GetSourceCodeSnippetInFile(string filePath, string startLine, string endLine) + { + var listOfLines = new List(); + + if (File.Exists(filePath)) + { + var reading = false; + + foreach (var line in File.ReadAllLines(filePath)) + { + if (reading && line.Trim() == endLine) + reading = false; + + if (reading) + listOfLines.Add(line.Trim()); + + if (line.Trim() == startLine) + reading = true; + } + } + + return listOfLines; + } + + internal string GetPackage() + { + return $"{configuration.Company}.{configuration.Project}.web.api".ToLower(); + } + + internal string GetPackagePath() + { + return GetPackage().Replace(".", "/"); + } + + internal string GetMainSourcePath() + { + return Path.Combine(configuration.SolutionPath, "src", "main", "java", GetPackagePath()); + } + + internal string GetTestSourcePath() + { + return Path.Combine(configuration.SolutionPath, "src", "test", "java", GetPackagePath()); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorPage.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorPage.cs new file mode 100644 index 0000000..f63db02 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorPage.cs @@ -0,0 +1,386 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorPage : CodeGeneratorObject + { + internal CodeGeneratorPage(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetMainSourcePath(), CodeFolders.pages.ToString(), page.Name + ".java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateMembers(page)); + listOfLines.AddRange(GenerateLocators(page)); + listOfLines.AddRange(GenerateContructor(page)); + listOfLines.AddRange(GenerateActionMethods(page)); + listOfLines.AddRange(GenerateFillFormMethod(page)); + listOfLines.AddRange(GenerateExtensionMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{CodeFolders.pages};" + }; + } + + internal List GenerateImports(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add("import com.microsoft.playwright.*;"); + listOfLines.Add($"import {GetPackage()}.{CodeFolders.controls}.*;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.models}.*;"); + + listOfLines.Add("import org.slf4j.Logger;"); + + return listOfLines; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + var basePage = "BasePage"; + if (!string.IsNullOrWhiteSpace(page.Base)) + basePage = page.Base; + + return new List + { + $"public class {page.Name} extends {basePage}" + }; + } + + internal List GenerateMembers(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var member in page.Members) + listOfLines.Add($"public {member.Page} {member.Name.CamelCase()};"); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + listOfLines.Add($"public BaseTable {control.Name.CamelCase()};"); + } + + if (page.Members.Count > 0 || page.Controls.Any(c => c.IsTable())) + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateLocators(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (!control.IsTable()) + listOfLines.AddRange(GenerateLocator(control)); + } + + if (listOfLines.Count > 0) + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateLocator(ObjectRepositoryControl control) + { + var type = control.Type; + if (type == ControlTypes.Element.ToString()) + type = "Control"; + + return new List + { + $"private Web{type} {control.Name.CamelCase()};" + }; + } + + internal List GenerateContructor(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"public {page.Name}(Logger logger, Page page) {{"); + listOfLines.Add($"super(logger, page);"); + + foreach (var member in page.Members) + listOfLines.Add($"this.{member.Name.CamelCase()} = new {member.Page}(logger, page);"); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + listOfLines.Add($"this.{control.Name.CamelCase()} = new BaseTable(logger, page, {GetPlaywrightLocator(control)});"); + } + + foreach (var control in page.Controls) + { + if (!control.IsTable()) + { + var type = control.Type; + if (type == ControlTypes.Element.ToString()) + type = "Control"; + listOfLines.Add($"this.{control.Name.CamelCase()} = new Web{type}(page, {GetPlaywrightLocator(control)});"); + } + } + + if (page.Synchronizers.Count > 0 && (page.Members.Count > 0 || page.Controls.Count > 0)) + listOfLines.Add(""); + + foreach (var synchronizer in page.Synchronizers) + { + if (synchronizer.How == SynchronizerTypes.WaitForPageElementIsVisible.ToString() || + synchronizer.How == SynchronizerTypes.WaitForPageElementIsEnabled.ToString()) + { + listOfLines.Add($"{synchronizer.How.CamelCase()}({synchronizer.Using});"); + } + else + { + listOfLines.Add($"{synchronizer.How.CamelCase()}(\"{synchronizer.Using}\");"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add($""); + + return listOfLines; + } + + internal string GetPlaywrightLocator(ObjectRepositoryControl control) + { + switch (control.How) + { + case "Id": return $"page.locator(\"[id='{control.Using}']\")"; + case "Name": return $"page.locator(\"[name='{control.Using}']\")"; + case "ClassName": return $"page.locator(\".{control.Using}\")"; + case "CssSelector": return $"page.locator(\"{control.Using.EscapeDoubleQuotes()}\")"; + case "XPath": return $"page.locator(\"{control.Using.EscapeDoubleQuotes()}\")"; + case "Label": + var role = GetAriaRole(control.Type); + return $"page.getByRole(AriaRole.{role}, new Page.GetByRoleOptions().setName(\"{control.Using.EscapeDoubleQuotes()}\").setExact(true))"; + default: return $"page.locator(\"{control.Using.EscapeDoubleQuotes()}\")"; + } + } + + internal string GetAriaRole(string controlType) + { + switch (controlType) + { + case "Button": return "BUTTON"; + case "Link": return "LINK"; + case "CheckBox": return "CHECKBOX"; + case "RadioButton": return "RADIO"; + case "ComboBox": return "COMBOBOX"; + case "TextBox": return "TEXTBOX"; + default: return "GENERIC"; + } + } + + internal List GenerateActionMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + listOfLines.AddRange(GenerateActionMethod(control)); + + return listOfLines; + } + + internal List GenerateFillFormMethod(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + if (page.Model) + { + listOfLines.Add($"public void fillForm({page.Name}Model model) {{"); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"set{control.Name}(model.is{control.Name}());"); + else + listOfLines.Add($"set{control.Name}(model.get{control.Name}());"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add(""); + } + + return listOfLines; + } + + internal List GenerateExtensionMethods(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + return GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + } + + internal List GenerateActionMethod(ObjectRepositoryControl control) + { + var listOfLines = new List(); + + if (control.IsTextBox()) + listOfLines.AddRange(GenerateActionMethodTextBox(control)); + else if (control.IsComboBox() || control.IsListBox()) + listOfLines.AddRange(GenerateActionMethodComboBox(control)); + else if (control.IsCheckBox()) + listOfLines.AddRange(GenerateActionMethodCheckBox(control)); + else if (control.IsRadioButton()) + listOfLines.AddRange(GenerateActionMethodRadioBox(control)); + else if (control.IsLink() || control.IsButton()) + listOfLines.AddRange(GenerateActionMethodButton(control)); + else if (control.IsText()) + listOfLines.AddRange(GenerateActionMethodText(control)); + + return listOfLines; + } + + internal List GenerateActionMethodTextBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(String value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setText(value);", + $"}}", + "", + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getText();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodComboBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(String value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setText(value);", + $"}}", + "", + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getSelected();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodCheckBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(boolean value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setChecked(value);", + $"}}", + "", + $"public boolean is{control.Name}() {{", + $"logger.info(\"is{control.Name}()\");", + $"return {control.Name.CamelCase()}.getChecked();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodRadioBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(boolean value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setSelected(value);", + $"}}", + "", + $"public boolean is{control.Name}() {{", + $"logger.info(\"is{control.Name}()\");", + $"return {control.Name.CamelCase()}.getSelected();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodButton(ObjectRepositoryControl control) + { + var listOfLines = new List(); + + listOfLines.Add($"public void click{control.Name}() {{"); + + if (!string.IsNullOrEmpty(control.Source)) + { + listOfLines.Add($"click{control.Source}();"); + listOfLines.Add(""); + } + + listOfLines.Add($"logger.info(\"click{control.Name}()\");"); + listOfLines.Add($"{control.Name.CamelCase()}.click();"); + listOfLines.Add($"}}"); + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateActionMethodText(ObjectRepositoryControl control) + { + return new List + { + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getText();", + $"}}", + "" + }; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorSolution.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorSolution.cs new file mode 100644 index 0000000..2b38ce2 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorSolution.cs @@ -0,0 +1,97 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using Expressium.CodeGenerators.Java.Playwright.Properties; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorSolution : CodeGeneratorObject + { + internal CodeGeneratorSolution(Configuration configuration) : base(configuration, null) + { + } + + internal void GenerateAll() + { + var directory = configuration.SolutionPath; + + // Setup Solution Mapping Properties... + var mapOfProperties = new Dictionary + { + { "$Company$", configuration.Company }, + { "$Project$", configuration.Project }, + { "$Package$", GetPackage() }, + { "$PackagePath$", GetPackagePath() }, + { "$Url$", configuration.ApplicationUrl }, + { "$BrowserType$", configuration.Enroller.BrowserType } + }; + + // Generate Root Files... + WriteToFile(Path.Combine(directory, ".gitignore"), Resources.GitIgnore, mapOfProperties); + WriteToFile(Path.Combine(directory, "pom.xml"), Resources.PomXml, mapOfProperties); + + // Generate Main Source Files... + var mainSourcePath = GetMainSourcePath(); + + Directory.CreateDirectory(Path.Combine(mainSourcePath, CodeFolders.models.ToString())); + Directory.CreateDirectory(Path.Combine(mainSourcePath, CodeFolders.pages.ToString())); + + WriteToFile(Path.Combine(mainSourcePath, "BasePage.java"), Resources.BasePage, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "BaseTable.java"), Resources.BaseTable, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "Logger.java"), Resources.Logger, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "Randomizer.java"), Resources.Randomizer, mapOfProperties); + + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebControl.java"), Resources.WebControl, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebButton.java"), Resources.WebButton, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebCheckBox.java"), Resources.WebCheckBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebComboBox.java"), Resources.WebComboBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebLink.java"), Resources.WebLink, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebListBox.java"), Resources.WebListBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebRadioButton.java"), Resources.WebRadioButton, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebText.java"), Resources.WebText, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebTextBox.java"), Resources.WebTextBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebTable.java"), Resources.WebTable, mapOfProperties); + + // Generate Test Source Files... + var testSourcePath = GetTestSourcePath(); + + Directory.CreateDirectory(Path.Combine(testSourcePath, TestFolders.factories.ToString())); + Directory.CreateDirectory(Path.Combine(testSourcePath, TestFolders.uitests.ToString())); + + WriteToFile(Path.Combine(testSourcePath, "BaseTest.java"), Resources.BaseTest, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BaseTestFixture.java"), Resources.BaseTestFixture, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BrowserFactory.java"), Resources.BrowserFactory, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BrowserManager.java"), Resources.BrowserManager, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "Asserts.java"), Resources.Asserts, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "Configuration.java"), Resources.Configuration, mapOfProperties); + + // Generate Test Resources... + var testResourcesPath = Path.Combine(directory, "src", "test", "resources"); + WriteToFile(Path.Combine(testResourcesPath, "configuration.json"), Resources.ConfigurationJson, mapOfProperties); + + // Save Configuration & Object Repository Files... + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, new ObjectRepository()); + ConfigurationUtilities.SerializeAsJson(configuration.ConfigurationPath, configuration); + } + + protected static void WriteToFile(string destinationFile, string text, Dictionary mapOfProperties) + { + foreach (var property in mapOfProperties) + text = text.Replace(property.Key, property.Value); + + var directory = Path.GetDirectoryName(destinationFile); + if (!Directory.Exists(directory)) + Directory.CreateDirectory(directory); + + using (var fileStream = File.Create(destinationFile)) + { + using (var streamWriter = new StreamWriter(fileStream)) + streamWriter.WriteLine(text); + } + + Console.WriteLine(destinationFile); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorTest.cs b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorTest.cs new file mode 100644 index 0000000..cf8d92a --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/CodeGeneratorTest.cs @@ -0,0 +1,338 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Playwright +{ + internal class CodeGeneratorTest : CodeGeneratorObject + { + internal CodeGeneratorTest(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + + if (IsSourceCodeModified(filePath)) + return; + + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetTestSourcePath(), TestFolders.uitests.ToString(), page.Name + "Tests.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateTagProperties(page)); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GeneratedDataVariables(page)); + listOfLines.AddRange(GenerateSetUpMethod(page)); + listOfLines.AddRange(GenerateTitleTestMethod(page)); + listOfLines.AddRange(GenerateFillFormTestMethods(page)); + listOfLines.AddRange(GenerateTableTestMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{TestFolders.uitests};" + }; + } + + internal List GenerateImports(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add("import org.junit.jupiter.api.*;"); + listOfLines.Add("import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.models}.*;"); + + if (objectRepository.Pages.Count > 0) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.pages}.*;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.factories.*;"); + + return listOfLines; + } + + internal List GenerateTagProperties(ObjectRepositoryPage page) + { + return new List + { + $"@TestInstance(PER_CLASS)", + $"@Tag(\"{TestFolders.uitests}\")", + $"@DisplayName(\"Validate Navigation & Content of {page.Name}\")" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}Tests extends BaseTest" + }; + } + + internal List GeneratedDataVariables(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"private {page.Name} {page.Name.CamelCase()};"); + + if (page.Model) + { + listOfLines.Add($"private {page.Name}Model {page.Name.CamelCase()}Model = {page.Name}ModelFactory.getDefault();"); + } + else + { + if (page.HasFillFormControls()) + { + listOfLines.Add($""); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + if (string.IsNullOrWhiteSpace(control.Value)) + listOfLines.Add($"private String {control.Name.CamelCase()} = \"{CodeGeneratorUtilities.GenerateRandomString(6)}\";"); + else + listOfLines.Add($"private String {control.Name.CamelCase()} = \"{control.Value}\";"); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + if (string.IsNullOrWhiteSpace(control.Value)) + listOfLines.Add($"private boolean {control.Name.CamelCase()} = true;"); + else + { + if (control.Value.ToLower() == "true") + listOfLines.Add($"private boolean {control.Name.CamelCase()} = true;"); + else + listOfLines.Add($"private boolean {control.Name.CamelCase()} = false;"); + } + } + } + } + } + } + + listOfLines.Add($""); + + return listOfLines; + } + + internal List GenerateSetUpMethod(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"@BeforeAll"); + listOfLines.Add($"public void setUp() {{"); + + if (!string.IsNullOrWhiteSpace(configuration.CodeGenerator.InitialLoginPage) && !configuration.CodeGenerator.InitialLoginPage.Contains(page.Name)) + listOfLines.Add($"initializeBrowserWithLogin();"); + else + listOfLines.Add($"initializeBrowser();"); + listOfLines.Add($""); + + listOfLines.Add($"// TODO - Implement potential missing page navigations..."); + listOfLines.Add($""); + + var listOfNavigationLines = GetNavigationMethods(objectRepository, page.Name); + if (listOfNavigationLines != null) + listOfLines.AddRange(listOfNavigationLines); + + listOfLines.Add($"{page.Name.CamelCase()} = new {page.Name}(logger, page);"); + + if (page.Model) + { + listOfLines.Add($"{page.Name.CamelCase()}.fillForm({page.Name.CamelCase()}Model);"); + } + else + { + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + listOfLines.Add($"{page.Name.CamelCase()}.set{control.Name}({control.Name.CamelCase()});"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add($""); + + return listOfLines; + } + + internal List GetNavigationMethods(ObjectRepository objectRepository, string name) + { + return GetNavigationMethods(objectRepository, name, name); + } + + internal List GetNavigationMethods(ObjectRepository objectRepository, string origin, string name) + { + foreach (var page in objectRepository.Pages) + { + if (page.Name == origin) + continue; + + if (page.Name == name) + continue; + + foreach (var control in page.Controls) + { + if (control.Target == name) + { + var listOfLines = new List(); + + var listOfParentLines = GetNavigationMethods(objectRepository, origin, page.Name); + if (listOfParentLines != null) + listOfLines.AddRange(listOfParentLines); + + listOfLines.Add($"var {page.Name.CamelCase()} = new {page.Name}(logger, page);"); + listOfLines.Add($"{page.Name.CamelCase()}.click{control.Name}();"); + listOfLines.Add($""); + + return listOfLines; + } + } + } + + return null; + } + + internal List GenerateTitleTestMethod(ObjectRepositoryPage page) + { + return new List + { + $"@Test", + $"public void validate_Page_Title() {{", + $"asserts.equalTo({page.Name.CamelCase()}.getTitle(), \"{page.Title}\", \"Validating the {page.Name} Title...\");", + $"}}" + }; + } + + internal List GenerateFillFormTestMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_Property_{control.Name}() {{"); + + if (page.Model) + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.is{control.Name}(), {page.Name.CamelCase()}Model.is{control.Name}(), \"Validating the {page.Name} property {control.Name}...\");"); + else + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.get{control.Name}(), {page.Name.CamelCase()}Model.get{control.Name}(), \"Validating the {page.Name} property {control.Name}...\");"); + } + else + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.is{control.Name}(), {control.Name.CamelCase()}, \"Validating the {page.Name} property {control.Name}...\");"); + else + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.get{control.Name}(), {control.Name.CamelCase()}, \"Validating the {page.Name} property {control.Name}...\");"); + } + + listOfLines.Add($"}}"); + } + } + + return listOfLines; + } + + internal List GenerateTableTestMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Number_Of_Rows() {{"); + listOfLines.Add($"asserts.greaterThan({page.Name.CamelCase()}.{control.Name.CamelCase()}.getNumberOfRows(), -1, \"Validating the {page.Name} {control.Name} number of rows...\");"); + listOfLines.Add($"}}"); + + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Number_Of_Columns() {{"); + listOfLines.Add($"asserts.greaterThan({page.Name.CamelCase()}.{control.Name.CamelCase()}.getNumberOfColumns(), -1, \"Validating the {page.Name} {control.Name} number of columns...\");"); + listOfLines.Add($"}}"); + + var numberOfHeaders = 0; + if (!string.IsNullOrWhiteSpace(control.Value)) + numberOfHeaders = control.Value.Split(';').Length; + + if (numberOfHeaders > 1) + { + var listOfHeaders = control.Value.Split(';'); + foreach (var header in listOfHeaders) + { + var name = header.Trim(); + + if (CodeGeneratorUtilities.IsValidClassName(name)) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Cell_Text_{name}() {{"); + listOfLines.Add($"asserts.isNotNull({page.Name.CamelCase()}.{control.Name.CamelCase()}.getCellText(1, \"{name}\"), \"Validating the {page.Name} {control.Name} table cell Text {name}...\");"); + listOfLines.Add($"}}"); + } + } + } + else + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Cell_Text() {{"); + listOfLines.Add($"asserts.isNotNull({page.Name.CamelCase()}.{control.Name.CamelCase()}.getCellText(1, 2), \"Validating the {page.Name} {control.Name} table cell Text...\");"); + listOfLines.Add($"}}"); + } + } + } + + return listOfLines; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Expressium.CodeGenerators.Java.Playwright.csproj b/Expressium.CodeGenerators.Java.Playwright/Expressium.CodeGenerators.Java.Playwright.csproj new file mode 100644 index 0000000..ebd36e5 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Expressium.CodeGenerators.Java.Playwright.csproj @@ -0,0 +1,35 @@ + + + + net8.0 + + + + + <_Parameter1>Expressium.CodeGenerators.Java.Playwright.UnitTests + + + + + + + + + + + + Resources.resx + True + True + + + + + + Designer + Resources.Designer.cs + ResXFileCodeGenerator + + + + diff --git a/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.Designer.cs b/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.Designer.cs new file mode 100644 index 0000000..30a19b2 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.Designer.cs @@ -0,0 +1,270 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Expressium.CodeGenerators.Java.Playwright.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Expressium.CodeGenerators.Java.Playwright.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Asserts. + /// + internal static string Asserts { + get { + return ResourceManager.GetString("Asserts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BasePage. + /// + internal static string BasePage { + get { + return ResourceManager.GetString("BasePage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTable. + /// + internal static string BaseTable { + get { + return ResourceManager.GetString("BaseTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTest. + /// + internal static string BaseTest { + get { + return ResourceManager.GetString("BaseTest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTestFixture. + /// + internal static string BaseTestFixture { + get { + return ResourceManager.GetString("BaseTestFixture", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BrowserFactory. + /// + internal static string BrowserFactory { + get { + return ResourceManager.GetString("BrowserFactory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BrowserManager. + /// + internal static string BrowserManager { + get { + return ResourceManager.GetString("BrowserManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Configuration. + /// + internal static string Configuration { + get { + return ResourceManager.GetString("Configuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ConfigurationJson. + /// + internal static string ConfigurationJson { + get { + return ResourceManager.GetString("ConfigurationJson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to GitIgnore. + /// + internal static string GitIgnore { + get { + return ResourceManager.GetString("GitIgnore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logger. + /// + internal static string Logger { + get { + return ResourceManager.GetString("Logger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PomXml. + /// + internal static string PomXml { + get { + return ResourceManager.GetString("PomXml", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Randomizer. + /// + internal static string Randomizer { + get { + return ResourceManager.GetString("Randomizer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebButton. + /// + internal static string WebButton { + get { + return ResourceManager.GetString("WebButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebCheckBox. + /// + internal static string WebCheckBox { + get { + return ResourceManager.GetString("WebCheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebComboBox. + /// + internal static string WebComboBox { + get { + return ResourceManager.GetString("WebComboBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebControl. + /// + internal static string WebControl { + get { + return ResourceManager.GetString("WebControl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebLink. + /// + internal static string WebLink { + get { + return ResourceManager.GetString("WebLink", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebListBox. + /// + internal static string WebListBox { + get { + return ResourceManager.GetString("WebListBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebRadioButton. + /// + internal static string WebRadioButton { + get { + return ResourceManager.GetString("WebRadioButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebTable. + /// + internal static string WebTable { + get { + return ResourceManager.GetString("WebTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebText. + /// + internal static string WebText { + get { + return ResourceManager.GetString("WebText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebTextBox. + /// + internal static string WebTextBox { + get { + return ResourceManager.GetString("WebTextBox", resourceCulture); + } + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.resx b/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.resx new file mode 100644 index 0000000..2f29601 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Properties/Resources.resx @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Asserts.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BasePage.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTest.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTestFixture.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BrowserFactory.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BrowserManager.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Configuration.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\ConfigurationJson.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\GitIgnore.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Logger.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\PomXml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Randomizer.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebButton.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebCheckBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebComboBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebControl.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebLink.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebListBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebRadioButton.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebText.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebTextBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/Asserts.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/Asserts.txt new file mode 100644 index 0000000..53a79b5 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/Asserts.txt @@ -0,0 +1,112 @@ +package $Package$; + +import org.junit.jupiter.api.Assertions; +import org.slf4j.Logger; + +public class Asserts { + private final Logger logger; + + public Asserts(Logger logger) { + this.logger = logger; + } + + public void equalTo(Object actual, Object expected, String message) { + try { + Assertions.assertEquals(expected, actual, message); + logger.info(message); + logger.info("Expected to be equal [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void isTrue(boolean actual, String message) { + try { + Assertions.assertTrue(actual, message); + logger.info(message); + logger.info("Expected to be equal [true] and was [true] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [true] but was [false] - FAILED"); + } + } + + public void isFalse(boolean actual, String message) { + try { + Assertions.assertFalse(actual, message); + logger.info(message); + logger.info("Expected to be equal [false] and was [false] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [false] but was [true] - FAILED"); + } + } + + public void isNull(Object actual, String message) { + try { + Assertions.assertNull(actual, message); + logger.info(message); + logger.info("Expected to be equal [null] and was [null] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [null] but was [" + actual + "] - FAILED"); + } + } + + public void isNotNull(String actual, String message) { + try { + Assertions.assertNotNull(actual, message); + logger.info(message); + logger.info("Expected to be different from [null] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be different from [null] but was [null] - FAILED"); + } + } + + public void isNotEmpty(String actual, String message) { + try { + Assertions.assertFalse(actual == null || actual.isEmpty(), message); + logger.info(message); + logger.info("Expected to be different from [empty] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be different from [empty] but was [empty] - FAILED"); + } + } + + public void greaterThan(int actual, int expected, String message) { + try { + Assertions.assertTrue(actual > expected, message); + logger.info(message); + logger.info("Expected to be greater than [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be greater than [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void lessThan(int actual, int expected, String message) { + try { + Assertions.assertTrue(actual < expected, message); + logger.info(message); + logger.info("Expected to be less than [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be less than [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void doesContain(String actual, String expected, String message) { + try { + Assertions.assertTrue(actual != null && actual.contains(expected), message); + logger.info(message); + logger.info("Expected to contain [" + expected + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to contain [" + expected + "] - FAILED"); + } + } + + public void doesNotContain(String actual, String expected, String message) { + try { + Assertions.assertFalse(actual != null && actual.contains(expected), message); + logger.info(message); + logger.info("Expected to not contain [" + expected + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to not contain [" + expected + "] - FAILED"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BasePage.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BasePage.txt new file mode 100644 index 0000000..06fa577 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BasePage.txt @@ -0,0 +1,95 @@ +package $Package$; + +import com.microsoft.playwright.*; +import $Package$.controls.WebControl; +import org.slf4j.Logger; + +public class BasePage { + protected final Logger logger; + protected final Page page; + + public static int pageTimeOut = 10000; + + public BasePage(Logger logger, Page page) { + this.logger = logger; + this.page = page; + page.waitForLoadState(LoadState.DOMCONTENTLOADED); + } + + public String getTitle() { + logger.info("getTitle()"); + return page.title(); + } + + public String getURL() { + logger.info("getURL()"); + return page.url(); + } + + protected void waitForPageTitleEquals(String title) { + try { + page.waitForCondition(() -> page.title().equals(title), + new Page.WaitForConditionOptions().setTimeout(pageTimeOut)); + } catch (Exception e) { + throw new RuntimeException("Page title was expected to be equal to '" + title + "' but was '" + page.title() + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageTitleContains(String title) { + try { + page.waitForCondition(() -> page.title().contains(title), + new Page.WaitForConditionOptions().setTimeout(pageTimeOut)); + } catch (Exception e) { + throw new RuntimeException("Page title was expected to contain '" + title + "' but was '" + page.title() + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageUrlEquals(String url) { + try { + page.waitForURL(url, new Page.WaitForURLOptions().setTimeout(pageTimeOut)); + } catch (Exception e) { + throw new RuntimeException("Page URL was expected to be equal to '" + url + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageUrlContains(String url) { + try { + page.waitForURL("**" + url + "**", new Page.WaitForURLOptions().setTimeout(pageTimeOut)); + } catch (Exception e) { + throw new RuntimeException("Page URL was expected to contain '" + url + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageElementIsVisible(WebControl control) { + control.waitForElementIsVisible(); + } + + protected void waitForPageElementIsEnabled(WebControl control) { + control.waitForElementIsEnabled(); + } + + public void navigateBack() { + logger.info("navigateBack()"); + page.goBack(); + } + + public void navigateForward() { + logger.info("navigateForward()"); + page.goForward(); + } + + public void navigateRefresh() { + logger.info("navigateRefresh()"); + page.reload(); + } + + public void scrollToTop() { + logger.info("scrollToTop()"); + page.evaluate("window.scrollTo(0, 0);"); + } + + public void scrollToBottom() { + logger.info("scrollToBottom()"); + page.evaluate("window.scrollTo(0, document.body.scrollHeight);"); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTable.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTable.txt new file mode 100644 index 0000000..cc77692 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTable.txt @@ -0,0 +1,34 @@ +package $Package$; + +import $Package$.controls.WebTable; +import com.microsoft.playwright.*; +import org.slf4j.Logger; + +public class BaseTable extends BasePage { + protected final WebTable baseControl; + + public BaseTable(Logger logger, Page page, Locator baseLocator) { + super(logger, page); + baseControl = new WebTable(page, baseLocator); + } + + public int getNumberOfRows() { + logger.info("getNumberOfRows()"); + return baseControl.getNumberOfRows(); + } + + public int getNumberOfColumns() { + logger.info("getNumberOfColumns()"); + return baseControl.getNumberOfColumns(); + } + + public String getCellText(Object rowId, Object columnId) { + logger.info("getCellText(" + rowId + ", " + columnId + ")"); + return baseControl.getCellText(rowId, columnId); + } + + public String getCellText(String cellText) { + logger.info("getCellText(" + cellText + ")"); + return baseControl.getCellText(cellText); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTest.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTest.txt new file mode 100644 index 0000000..76fe332 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTest.txt @@ -0,0 +1,22 @@ +package $Package$; + +import com.microsoft.playwright.*; + +public class BaseTest extends BaseTestFixture { + public void initializeBrowser() { + page = browserManager.getPage(); + } + + public void initializeBrowserWithLogin() { + initializeBrowser(); + + throw new RuntimeException("Implementation of initializeBrowserWithLogin is missing..."); + + // TODO - Implement potential missing login sequence... + + // LoginPage loginPage = new LoginPage(logger, page); + // loginPage.setUsername(configuration.username); + // loginPage.setPassword(configuration.password); + // loginPage.clickLogin(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTestFixture.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTestFixture.txt new file mode 100644 index 0000000..9fbdc30 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BaseTestFixture.txt @@ -0,0 +1,58 @@ +package $Package$; + +import com.microsoft.playwright.*; +import org.junit.jupiter.api.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.nio.file.Paths; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class BaseTestFixture { + protected final Configuration configuration; + protected final BrowserManager browserManager; + + protected Logger logger; + protected Asserts asserts; + + protected Page page; + + public BaseTestFixture() { + configuration = Configuration.getCurrentConfiguration(); + browserManager = new BrowserManager(configuration); + } + + @BeforeAll + protected void initializeFixture() { + logger = LoggerFactory.getLogger(getClass().getSimpleName()); + asserts = new Asserts(logger); + page = browserManager.getPage(); + + logger.info(""); + logger.info("// Initialize Test Fixture"); + logger.info("Company: " + configuration.company); + logger.info("Project: " + configuration.project); + logger.info("Environment: " + configuration.environment); + logger.info("Url: " + configuration.url); + } + + @AfterAll + protected void finalizeFixture() { + logger.info(""); + logger.info("// Finalize Test Fixture"); + + if (browserManager.isInitialized()) { + if (configuration.screenshots) { + String filePath = Paths.get("Screenshots", getClass().getSimpleName() + ".png").toString(); + browserManager.saveScreenshot(filePath); + } + + browserManager.quit(); + } + } + + @BeforeEach + protected void initializeTest(TestInfo testInfo) { + logger.info(""); + logger.info("// " + testInfo.getDisplayName()); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserFactory.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserFactory.txt new file mode 100644 index 0000000..2394d03 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserFactory.txt @@ -0,0 +1,39 @@ +package $Package$; + +import com.microsoft.playwright.*; + +public class BrowserFactory { + public enum BrowserTypes { + Chrome, Firefox, Edge + } + + public static Browser initialize(Playwright playwright, Configuration configuration) { + if (BrowserTypes.Chrome.name().equals(configuration.browserType)) + return initializeChromeBrowser(playwright, configuration); + else if (BrowserTypes.Firefox.name().equals(configuration.browserType)) + return initializeFirefoxBrowser(playwright, configuration); + else if (BrowserTypes.Edge.name().equals(configuration.browserType)) + return initializeEdgeBrowser(playwright, configuration); + else + throw new IllegalArgumentException("Specified browser type '" + configuration.browserType + "' is unknown..."); + } + + private static Browser initializeChromeBrowser(Playwright playwright, Configuration configuration) { + BrowserType.LaunchOptions options = new BrowserType.LaunchOptions(); + options.setHeadless(configuration.headless); + return playwright.chromium().launch(options); + } + + private static Browser initializeFirefoxBrowser(Playwright playwright, Configuration configuration) { + BrowserType.LaunchOptions options = new BrowserType.LaunchOptions(); + options.setHeadless(configuration.headless); + return playwright.firefox().launch(options); + } + + private static Browser initializeEdgeBrowser(Playwright playwright, Configuration configuration) { + BrowserType.LaunchOptions options = new BrowserType.LaunchOptions(); + options.setChannel("msedge"); + options.setHeadless(configuration.headless); + return playwright.chromium().launch(options); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserManager.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserManager.txt new file mode 100644 index 0000000..7fff406 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/BrowserManager.txt @@ -0,0 +1,57 @@ +package $Package$; + +import com.microsoft.playwright.*; +import java.nio.file.Paths; + +public class BrowserManager { + private final Configuration configuration; + private Playwright playwright; + private Browser browser; + private Page page; + + public BrowserManager(Configuration configuration) { + this.configuration = configuration; + } + + public Page getPage() { + if (page == null) { + playwright = Playwright.create(); + browser = BrowserFactory.initialize(playwright, configuration); + page = browser.newPage(); + + if (configuration.maximize) + page.setViewportSize(1920, 1080); + else if (configuration.windowSize) + page.setViewportSize(configuration.windowWidth, configuration.windowHeight); + + if (configuration.url != null) + page.navigate(configuration.url); + } + return page; + } + + public boolean isInitialized() { + return page != null; + } + + public void saveScreenshot(String filePath) { + if (page != null) { + try { + page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get(filePath))); + } catch (Exception e) { + // ignore + } + } + } + + public void quit() { + if (page != null) { + page.close(); + browser.close(); + playwright.close(); + page = null; + browser = null; + playwright = null; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/Configuration.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/Configuration.txt new file mode 100644 index 0000000..9cc171a --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/Configuration.txt @@ -0,0 +1,55 @@ +package $Package$; + +import $Package$.controls.WebControl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; + +public class Configuration { + public String company; + public String project; + public String environment; + public boolean loggings; + public boolean screenshots; + public String url; + public String username; + public String password; + public String browserType; + public boolean maximize; + public boolean headless; + public boolean windowSize; + public int windowWidth; + public int windowHeight; + public boolean highlight; + public int highlightTimeOut; + + public static Configuration getCurrentConfiguration() { + String profile = System.getenv("PROFILE"); + if (profile == null || profile.isEmpty()) profile = "Development"; + + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode root = mapper.readTree(new File("src/test/resources/configuration.json")); + JsonNode profileNode = root.path("Profiles").path(profile); + + Configuration config = mapper.treeToValue(profileNode, Configuration.class); + + if (config == null) + throw new RuntimeException("Configuration profile '" + profile + "' is unknown..."); + + if (config.username == null || config.username.isEmpty()) + config.username = System.getenv("USERNAME"); + + if (config.password == null || config.password.isEmpty()) + config.password = System.getenv("PASSWORD"); + + WebControl.highlight = config.highlight; + WebControl.highlightTimeOut = config.highlightTimeOut; + + return config; + } catch (IOException e) { + throw new RuntimeException("Failed to load configuration: " + e.getMessage()); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/ConfigurationJson.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/ConfigurationJson.txt new file mode 100644 index 0000000..c1eb0e6 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/ConfigurationJson.txt @@ -0,0 +1,22 @@ +{ + "Profiles": { + "Development": { + "company": "$Company$", + "project": "$Project$", + "environment": "Development", + "loggings": true, + "screenshots": true, + "url": "$Url$", + "username": "john.doe@microsoft.com", + "password": "1234567890", + "browserType": "$BrowserType$", + "maximize": true, + "headless": false, + "windowSize": false, + "windowWidth": 1920, + "windowHeight": 1080, + "highlight": true, + "highlightTimeOut": 150 + } + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/GitIgnore.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/GitIgnore.txt new file mode 100644 index 0000000..b092dd9 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/GitIgnore.txt @@ -0,0 +1,27 @@ +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# IDE +.idea/ +*.iml +.classpath +.project +.settings/ +*.class + +# Logs +*.log +Loggings/ +Screenshots/ + +# OS +.DS_Store +Thumbs.db diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/Logger.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/Logger.txt new file mode 100644 index 0000000..cb7a36f --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/Logger.txt @@ -0,0 +1,10 @@ +package $Package$; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoggerUtility { + public static Logger initialize(String name) { + return LoggerFactory.getLogger(name); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/PomXml.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/PomXml.txt new file mode 100644 index 0000000..ef29c45 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/PomXml.txt @@ -0,0 +1,71 @@ + + + 4.0.0 + + $Package$ + $Company$-$Project$-web-api + 1.0.0 + jar + + + 11 + 11 + UTF-8 + + + + + + com.microsoft.playwright + playwright + 1.49.0 + + + + + org.junit.jupiter + junit-jupiter + 5.11.3 + test + + + + + org.slf4j + slf4j-api + 2.0.16 + + + + + org.apache.logging.log4j + log4j-slf4j2-impl + 2.24.1 + + + + org.apache.logging.log4j + log4j-core + 2.24.1 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.18.1 + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.1 + + + + diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/Randomizer.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/Randomizer.txt new file mode 100644 index 0000000..79bc4b0 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/Randomizer.txt @@ -0,0 +1,30 @@ +package $Package$; + +import java.security.SecureRandom; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Randomizer { + private static final SecureRandom random = new SecureRandom(); + private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + public static String getRandomString(int length) { + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + sb.append(CHARS.charAt(random.nextInt(CHARS.length()))); + } + return sb.toString(); + } + + public static int getRandomInteger(int minValue, int maxValue) { + return random.nextInt(maxValue - minValue) + minValue; + } + + public static String getUniqueId() { + return "ID" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssnn")); + } + + public static String getDateTimeId() { + return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebButton.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebButton.txt new file mode 100644 index 0000000..6d57153 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebButton.txt @@ -0,0 +1,16 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebButton extends WebControl { + public WebButton(Page page, Locator locator) { + super(page, locator); + } + + public void click() { + waitForElementIsEnabled(); + highlightElementAsAction(); + highlightElementClear(); + clickElement(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebCheckBox.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebCheckBox.txt new file mode 100644 index 0000000..553f89f --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebCheckBox.txt @@ -0,0 +1,24 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebCheckBox extends WebControl { + public WebCheckBox(Page page, Locator locator) { + super(page, locator); + } + + public void setChecked(boolean value) { + waitForElementIsEnabled(); + if ((!isChecked() && value) || (isChecked() && !value)) { + highlightElementAsAction(); + clickElement(); + highlightElementClear(); + } + } + + public boolean getChecked() { + waitForElementIsVisible(); + highlightElementAsValidation(); + return isChecked(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebComboBox.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebComboBox.txt new file mode 100644 index 0000000..78e0e1a --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebComboBox.txt @@ -0,0 +1,45 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; +import com.microsoft.playwright.options.SelectOption; +import java.util.List; + +public class WebComboBox extends WebControl { + public WebComboBox(Page page, Locator locator) { + super(page, locator); + } + + public void setText(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + locator.selectOption(new SelectOption().setLabel(value)); + highlightElementClear(); + } + + public void selectByIndex(int value) { + waitForElementIsEnabled(); + highlightElementAsAction(); + locator.selectOption(new SelectOption().setIndex(value)); + highlightElementClear(); + } + + public void selectByValue(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + locator.selectOption(value); + highlightElementClear(); + } + + public String getSelected() { + waitForElementIsVisible(); + highlightElementAsValidation(); + Object result = locator.evaluate("el => el.options[el.selectedIndex] ? el.options[el.selectedIndex].text : ''"); + return result != null ? result.toString().trim() : null; + } + + public List getOptions() { + return locator.locator("option").allTextContents(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebControl.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebControl.txt new file mode 100644 index 0000000..a7728dc --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebControl.txt @@ -0,0 +1,72 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebControl { + protected Page page; + protected Locator locator; + + public static boolean highlight = false; + public static int highlightTimeOut = 150; + + public WebControl(Page page, Locator locator) { + this.page = page; + this.locator = locator; + } + + public String getAttribute(String name) { + return locator.getAttribute(name); + } + + public boolean isVisible() { + return locator.isVisible(); + } + + public boolean isEnabled() { + return locator.isEnabled(); + } + + public boolean isChecked() { + return locator.isChecked(); + } + + public void waitForElementIsVisible() { + locator.waitFor(new Locator.WaitForOptions().setState(WaitForSelectorState.VISIBLE)); + } + + public void waitForElementIsEnabled() { + locator.waitFor(new Locator.WaitForOptions().setState(WaitForSelectorState.VISIBLE)); + } + + public void highlightElementAsAction() { + if (highlight) { + try { + page.evaluate("el => { el.style.border='3px solid blue'; }", locator.elementHandle()); + Thread.sleep(highlightTimeOut); + page.evaluate("el => { el.style.border=''; }", locator.elementHandle()); + } catch (Exception ignored) {} + } + } + + public void highlightElementAsValidation() { + if (highlight) { + try { + page.evaluate("el => { el.style.border='3px solid green'; }", locator.elementHandle()); + Thread.sleep(highlightTimeOut); + page.evaluate("el => { el.style.border=''; }", locator.elementHandle()); + } catch (Exception ignored) {} + } + } + + public void highlightElementClear() { + if (highlight) { + try { + page.evaluate("el => { el.style.border=''; }", locator.elementHandle()); + } catch (Exception ignored) {} + } + } + + public void clickElement() { + locator.click(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebLink.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebLink.txt new file mode 100644 index 0000000..e51b924 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebLink.txt @@ -0,0 +1,9 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebLink extends WebButton { + public WebLink(Page page, Locator locator) { + super(page, locator); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebListBox.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebListBox.txt new file mode 100644 index 0000000..c9f39e1 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebListBox.txt @@ -0,0 +1,9 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebListBox extends WebComboBox { + public WebListBox(Page page, Locator locator) { + super(page, locator); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebRadioButton.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebRadioButton.txt new file mode 100644 index 0000000..ba7bf0a --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebRadioButton.txt @@ -0,0 +1,24 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebRadioButton extends WebControl { + public WebRadioButton(Page page, Locator locator) { + super(page, locator); + } + + public void setSelected(boolean value) { + waitForElementIsEnabled(); + if (!isChecked() && value) { + highlightElementAsAction(); + clickElement(); + highlightElementClear(); + } + } + + public boolean getSelected() { + waitForElementIsVisible(); + highlightElementAsValidation(); + return isChecked(); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebTable.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebTable.txt new file mode 100644 index 0000000..6d1b6d3 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebTable.txt @@ -0,0 +1,54 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; +import java.util.List; + +public class WebTable extends WebControl { + public WebTable(Page page, Locator locator) { + super(page, locator); + } + + public int getNumberOfRows() { + return locator.locator("xpath=./tbody/tr").count(); + } + + public int getNumberOfColumns() { + return locator.locator("xpath=./thead/tr/th").count(); + } + + public String getCellText(Object rowId, Object columnId) { + Locator cellLocator = getCellLocator(rowId, columnId); + String val = cellLocator.textContent(); + return val != null ? val.trim() : ""; + } + + public String getCellText(String cellText) { + Locator cellLocator = locator.locator("xpath=./tbody/tr/td[contains(normalize-space(),'" + cellText + "')]"); + String val = cellLocator.textContent(); + return val != null ? val.trim() : ""; + } + + protected Locator getCellLocator(Object rowId, Object columnId) { + if (rowId instanceof Integer && columnId instanceof Integer) { + return locator.locator("xpath=./tbody/tr[" + rowId + "]/td[" + columnId + "]"); + } else if (rowId instanceof Integer && columnId instanceof String) { + return getCellLocator(rowId, getColumnIndex((String) columnId)); + } else if (rowId instanceof String && columnId instanceof Integer) { + return locator.locator("xpath=./tbody/tr[td[contains(normalize-space(),'" + rowId + "')]]/td[" + columnId + "]"); + } else if (rowId instanceof String && columnId instanceof String) { + return getCellLocator(rowId, getColumnIndex((String) columnId)); + } else { + throw new IllegalArgumentException("Invalid argument types for getCellLocator..."); + } + } + + protected int getColumnIndex(String columnName) { + List texts = locator.locator("xpath=./thead/tr/th").allTextContents(); + for (int i = 0; i < texts.size(); i++) { + if (texts.get(i).equals(columnName)) { + return i + 1; + } + } + throw new RuntimeException("The column name '" + columnName + "' was not found..."); + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebText.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebText.txt new file mode 100644 index 0000000..0c082ca --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebText.txt @@ -0,0 +1,16 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebText extends WebControl { + public WebText(Page page, Locator locator) { + super(page, locator); + } + + public String getText() { + waitForElementIsVisible(); + highlightElementAsValidation(); + String val = locator.textContent(); + return val != null ? val.trim() : ""; + } +} diff --git a/Expressium.CodeGenerators.Java.Playwright/Resources/WebTextBox.txt b/Expressium.CodeGenerators.Java.Playwright/Resources/WebTextBox.txt new file mode 100644 index 0000000..66f73f7 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Playwright/Resources/WebTextBox.txt @@ -0,0 +1,25 @@ +package $Package$.controls; + +import com.microsoft.playwright.*; + +public class WebTextBox extends WebControl { + public WebTextBox(Page page, Locator locator) { + super(page, locator); + } + + public void setText(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + locator.clear(); + locator.fill(value); + highlightElementClear(); + } + + public String getText() { + waitForElementIsVisible(); + highlightElementAsValidation(); + String val = locator.inputValue(); + return val != null ? val.trim() : ""; + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorFactoryTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorFactoryTests.cs new file mode 100644 index 0000000..c6a7031 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorFactoryTests.cs @@ -0,0 +1,79 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorFactoryTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorFactory codeGeneratorFactory; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = new ObjectRepositoryPage(); + page.Name = "RegistrationPage"; + page.Title = "Registration"; + page.Model = true; + page.Controls.Add(new ObjectRepositoryControl() { Name = "FirstName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "firstname", Value = "Hugoline" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "LastName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "lastname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Country", Type = ControlTypes.ComboBox.ToString(), How = ControlHows.Name.ToString(), Using = "country", Value = "Denmark" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Male", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_0", Value = "False" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Female", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_1", Value = "True" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "IAgreeToTheTermsOfUse", Type = ControlTypes.CheckBox.ToString(), How = ControlHows.Name.ToString(), Using = "agreement" }); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorFactory = new CodeGeneratorFactory(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorFactoryJava_GenerateSourceCode() + { + var listOfLines = codeGeneratorFactory.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(21), "CodeGeneratorFactoryJava GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorFactoryJava_GeneratePackage() + { + var listOfLines = codeGeneratorFactory.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorFactoryJava GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.factories;"), "CodeGeneratorFactoryJava GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorFactoryJava_GenerateClass() + { + var listOfLines = codeGeneratorFactory.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorFactoryJava GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class RegistrationPageModelFactory"), "CodeGeneratorFactoryJava GenerateClass validation"); + } + + [Test] + public void CodeGeneratorFactoryJava_GenerateDefaultMethod() + { + var listOfLines = codeGeneratorFactory.GenerateDefaultMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(14), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + Assert.That(listOfLines[0], Is.EqualTo("public static RegistrationPageModel getDefault() {"), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + Assert.That(listOfLines[1], Is.EqualTo("RegistrationPageModel model = new RegistrationPageModel();"), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + Assert.That(listOfLines[5], Is.EqualTo("model.setFirstName(\"Hugoline\");"), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + Assert.That(listOfLines[8], Is.EqualTo("model.setMale(false);"), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + Assert.That(listOfLines[9], Is.EqualTo("model.setFemale(true);"), "CodeGeneratorFactoryJava GenerateDefaultMethod validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorModelTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorModelTests.cs new file mode 100644 index 0000000..8495280 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorModelTests.cs @@ -0,0 +1,90 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorModelTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorModel codeGeneratorModel; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = new ObjectRepositoryPage(); + page.Name = "RegistrationPage"; + page.Title = "Registration"; + page.Model = true; + page.Controls.Add(new ObjectRepositoryControl() { Name = "FirstName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "firstname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "LastName", Type = ControlTypes.TextBox.ToString(), How = ControlHows.Name.ToString(), Using = "lastname" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Country", Type = ControlTypes.ComboBox.ToString(), How = ControlHows.Name.ToString(), Using = "country", Value = "Denmark" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Male", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_0", Value = "False" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "Female", Type = ControlTypes.RadioButton.ToString(), How = ControlHows.Id.ToString(), Using = "gender_1", Value = "True" }); + page.Controls.Add(new ObjectRepositoryControl() { Name = "IAgreeToTheTermsOfUse", Type = ControlTypes.CheckBox.ToString(), How = ControlHows.Name.ToString(), Using = "agreement" }); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorModel = new CodeGeneratorModel(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorModelJava_GenerateSourceCode() + { + var listOfLines = codeGeneratorModel.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(63), "CodeGeneratorModelJava GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorModelJava_GeneratePackage() + { + var listOfLines = codeGeneratorModel.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorModelJava GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.models;"), "CodeGeneratorModelJava GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorModelJava_GenerateClass() + { + var listOfLines = codeGeneratorModel.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorModelJava GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class RegistrationPageModel"), "CodeGeneratorModelJava GenerateClass validation"); + } + + [Test] + public void CodeGeneratorModelJava_GenerateFields() + { + var listOfLines = codeGeneratorModel.GenerateFields(page); + + Assert.That(listOfLines.Count, Is.EqualTo(6), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[0], Is.EqualTo("private String firstName;"), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[1], Is.EqualTo("private String lastName;"), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[2], Is.EqualTo("private String country;"), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[3], Is.EqualTo("private boolean male;"), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[4], Is.EqualTo("private boolean female;"), "CodeGeneratorModelJava GenerateFields validation"); + Assert.That(listOfLines[5], Is.EqualTo("private boolean iAgreeToTheTermsOfUse;"), "CodeGeneratorModelJava GenerateFields validation"); + } + + [Test] + public void CodeGeneratorModelJava_GenerateAccessors() + { + var listOfLines = codeGeneratorModel.GenerateAccessors(page); + + Assert.That(listOfLines.Count, Is.EqualTo(48), "CodeGeneratorModelJava GenerateAccessors validation"); + Assert.That(listOfLines[0], Is.EqualTo("public String getFirstName() {"), "CodeGeneratorModelJava GenerateAccessors validation"); + Assert.That(listOfLines[4], Is.EqualTo("public void setFirstName(String value) {"), "CodeGeneratorModelJava GenerateAccessors validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorObjectTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorObjectTests.cs new file mode 100644 index 0000000..643111c --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorObjectTests.cs @@ -0,0 +1,164 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorObjectTests + { + [Test] + public void Configuration_GetPackage() + { + var configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + var codeGeneratorObject = new CodeGeneratorObject(configuration, null); + var result = codeGeneratorObject.GetPackage(); + var expected = "expressium.coffeeshop.web.api"; + + Assert.That(result, Is.EqualTo(expected), "Configuration GetPackage validate generated output"); + } + + [Test] + public void Configuration_GetPackagePath() + { + var configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + var codeGeneratorObject = new CodeGeneratorObject(configuration, null); + var result = codeGeneratorObject.GetPackagePath(); + var expected = "expressium/coffeeshop/web/api"; + + Assert.That(result, Is.EqualTo(expected), "Configuration GetPackagePath validate generated output"); + } + + [Test] + public void CodeGeneratorObject_GetSourceCodeAsFormatted() + { + var input = new List + { + "public class AssetsBar extends BasePage", + "{", + "public boolean assetsBar(boolean value)", + "{", + "if (value)", + "return true;", + "else if (!value)", + "return false;", + "else", + "return false;", + "", + "if (x)", + "if (y)", + "return true;", + "", + "while (a==b)", + "continue;", + "", + "for (int i=0; i + { + "public class AssetsBar extends BasePage", + "{", + " public boolean assetsBar(boolean value)", + " {", + " if (value)", + " return true;", + " else if (!value)", + " return false;", + " else", + " return false;", + "", + " if (x)", + " if (y)", + " return true;", + "", + " while (a==b)", + " continue;", + "", + " for (int i=0; i + { + "", + "", + "" + }; + + var expected = "\r\n\r\n"; + + var result = CodeGeneratorObject.GetSourceCodeAsString(input); + Assert.That(result, Is.EqualTo(expected), "CodeGeneratorObject GetSourceCodeAsString validation"); + } + + [Test] + public void ConfigurationObject_GenerateSourceCodeExtensionMethods() + { + var listOfLines = CodeGeneratorObject.GenerateSourceCodeExtensionMethods(null, "// region Extensions", "// endregion"); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + } + + [Test] + public void ConfigurationObject_GenerateSourceCodeExtensionMethods_With_File() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "SnippetJava.txt"); + File.Delete(filePath); + File.WriteAllText(filePath, "// region Extensions\n\n// This is my life...\n\n// endregion\n"); + + var listOfLines = CodeGeneratorObject.GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("// region Extensions"), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("// This is my life..."), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + Assert.That(listOfLines[4], Is.EqualTo("// endregion"), "CodeGeneratorObject GenerateSourceCodeExtensionMethods validation"); + } + + [Test] + public void CodeGeneratorObject_IsSourceCodeModified_With_Comment() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "ExportPageJava.txt"); + + File.Delete(filePath); + File.WriteAllText(filePath, "// TODO - Implement..."); + + Assert.That(CodeGeneratorObject.IsSourceCodeModified(filePath), Is.False, "CodeGeneratorObject IsSourceCodeModified validation"); + } + + [Test] + public void CodeGeneratorObject_IsSourceCodeModified_Without_Comment() + { + var directory = Environment.GetEnvironmentVariable("TEMP"); + var filePath = Path.Combine(directory, "ImportPageJava.txt"); + + File.Delete(filePath); + File.WriteAllText(filePath, "// TODO - Updated..."); + + Assert.That(CodeGeneratorObject.IsSourceCodeModified(filePath), Is.True, "CodeGeneratorObject IsSourceCodeModified validation"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorPageTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorPageTests.cs new file mode 100644 index 0000000..ee0eab4 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorPageTests.cs @@ -0,0 +1,169 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorPageTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorPage codeGeneratorPage; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = CreateLoginPage(); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorPage = new CodeGeneratorPage(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorPageJava_GenerateSourceCode() + { + var listOfLines = codeGeneratorPage.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(39), "CodeGeneratorPageJava GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorPageJava_GeneratePackage() + { + var listOfLines = codeGeneratorPage.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorPageJava GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.pages;"), "CodeGeneratorPageJava GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateImports() + { + var listOfLines = codeGeneratorPage.GenerateImports(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorPageJava GenerateImports validation"); + Assert.That(listOfLines[2], Is.EqualTo("import expressium.coffeeshop.web.api.models.*;"), "CodeGeneratorPageJava GenerateImports validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateClass() + { + var listOfLines = codeGeneratorPage.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorPageJava GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class LoginPage extends FramePage"), "CodeGeneratorPageJava GenerateClass validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateMembers() + { + var listOfLines = codeGeneratorPage.GenerateMembers(page); + + Assert.That(listOfLines.Count, Is.EqualTo(2), "CodeGeneratorPageJava GenerateMembers validation"); + Assert.That(listOfLines[0], Is.EqualTo("public MainMenuBar menu;"), "CodeGeneratorPageJava GenerateMembers validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateMembers_With_Table() + { + var tablePage = page.Copy(); + tablePage.AddControl(new ObjectRepositoryControl() { Name = "Grid", Type = "Table", How = "Id", Using = "products" }); + + var listOfLines = codeGeneratorPage.GenerateMembers(tablePage); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorPageJava GenerateMembers validation"); + Assert.That(listOfLines[0], Is.EqualTo("public MainMenuBar menu;"), "CodeGeneratorPageJava GenerateMembers validation"); + Assert.That(listOfLines[1], Is.EqualTo("public BaseTable grid;"), "CodeGeneratorPageJava GenerateMembers validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateLocators() + { + var listOfLines = codeGeneratorPage.GenerateLocators(page); + + Assert.That(listOfLines.Count, Is.EqualTo(2), "CodeGeneratorPageJava GenerateLocators validation"); + Assert.That(listOfLines[0], Is.EqualTo("private WebTextBox username;"), "CodeGeneratorPageJava GenerateLocators validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateConstructor() + { + var listOfLines = codeGeneratorPage.GenerateContructor(page); + + Assert.That(listOfLines.Count, Is.EqualTo(8), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[0], Is.EqualTo("public LoginPage(Logger logger, WebDriver driver) {"), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[2], Is.EqualTo("this.menu = new MainMenuBar(logger, driver);"), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[5], Is.EqualTo("waitForPageTitleEquals(\"Home\");"), "CodeGeneratorPageJava GenerateConstructor validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateConstructor_With_Table() + { + var tablePage = page.Copy(); + tablePage.AddControl(new ObjectRepositoryControl() { Name = "Grid", Type = "Table", How = "Id", Using = "products" }); + + var listOfLines = codeGeneratorPage.GenerateContructor(tablePage); + + Assert.That(listOfLines.Count, Is.EqualTo(9), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[0], Is.EqualTo("public LoginPage(Logger logger, WebDriver driver) {"), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[2], Is.EqualTo("this.menu = new MainMenuBar(logger, driver);"), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[3], Is.EqualTo("this.grid = new BaseTable(logger, driver, By.id(\"products\"));"), "CodeGeneratorPageJava GenerateConstructor validation"); + Assert.That(listOfLines[6], Is.EqualTo("waitForPageTitleEquals(\"Home\");"), "CodeGeneratorPageJava GenerateConstructor validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateActionMethods() + { + var listOfLines = codeGeneratorPage.GenerateActionMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(10), "CodeGeneratorPageJava GenerateActionMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("public void setUsername(String value) {"), "CodeGeneratorPageJava GenerateActionMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("logger.info(\"setUsername(\" + value + \")\");"), "CodeGeneratorPageJava GenerateActionMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("username.setText(value);"), "CodeGeneratorPageJava GenerateActionMethods validation"); + Assert.That(listOfLines[5], Is.EqualTo("public String getUsername() {"), "CodeGeneratorPageJava GenerateActionMethods validation"); + Assert.That(listOfLines[7], Is.EqualTo("return username.getText();"), "CodeGeneratorPageJava GenerateActionMethods validation"); + } + + [Test] + public void CodeGeneratorPageJava_GenerateFillFormMethod() + { + var listOfLines = codeGeneratorPage.GenerateFillFormMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorPageJava GenerateFillFormMethod validation"); + Assert.That(listOfLines[0], Is.EqualTo("public void fillForm(LoginPageModel model) {"), "CodeGeneratorPageJava GenerateFillFormMethod validation"); + Assert.That(listOfLines[1], Is.EqualTo("setUsername(model.getUsername());"), "CodeGeneratorPageJava GenerateFillFormMethod validation"); + } + + private static ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + page.Base = "FramePage"; + page.Model = true; + + var synchronizer = new ObjectRepositorySynchronizer() { How = "WaitForPageTitleEquals", Using = "Home" }; + page.AddSynchronizer(synchronizer); + + var member = new ObjectRepositoryMember() { Name = "Menu", Page = "MainMenuBar" }; + page.AddMember(member); + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + page.AddControl(username); + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorSolutionTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorSolutionTests.cs new file mode 100644 index 0000000..ab9c939 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorSolutionTests.cs @@ -0,0 +1,80 @@ +using Expressium.Configurations; +using NUnit.Framework; +using System; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorSolutionTests + { + private Configuration configuration; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Microsoft"; + configuration.Project = "Foodshop"; + configuration.ApplicationUrl = "http://www.dr.dk"; + configuration.SolutionPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "CodeGeneratorSolutionJava"); + configuration.CodeGenerator.CodingLanguage = CodingLanguages.Java.ToString(); + configuration.CodeGenerator.CodingFlavour = CodingFlavours.Selenium.ToString(); + + if (Directory.Exists(configuration.SolutionPath)) + Directory.Delete(configuration.SolutionPath, true); + + Directory.CreateDirectory(configuration.SolutionPath); + + var codeGeneratorSolution = new CodeGeneratorSolution(configuration); + codeGeneratorSolution.GenerateAll(); + } + + [Test] + public void CodeGeneratorSolutionJava_GenerateAll_Expressium_Files() + { + Assert.That(File.Exists(configuration.ConfigurationPath), Is.True, "CodeGeneratorSolution solution generation completed..."); + Assert.That(File.Exists(configuration.RepositoryPath), Is.True, "CodeGeneratorSolution solution generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJava_GenerateAll_Configuration_File() + { + var testResourcesPath = Path.Combine(configuration.SolutionPath, "src", "test", "resources"); + var configFile = File.ReadAllText(Path.Combine(testResourcesPath, "configuration.json")); + + Assert.That(configFile, Does.Contain(configuration.Company), "CodeGeneratorSolution solution configuration contains Company..."); + Assert.That(configFile, Does.Contain(configuration.Project), "CodeGeneratorSolution solution configuration contains Project..."); + Assert.That(configFile, Does.Contain(configuration.ApplicationUrl), "CodeGeneratorSolution solution configuration contains URL..."); + } + + [Test] + public void CodeGeneratorSolutionJava_GenerateAll_PomXml() + { + var pomFile = Path.Combine(configuration.SolutionPath, "pom.xml"); + + Assert.That(File.Exists(pomFile), Is.True, "CodeGeneratorSolution pom.xml generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJava_GenerateAll_BasePage() + { + var packagePath = "microsoft/foodshop/web/api"; + var mainSourcePath = Path.Combine(configuration.SolutionPath, "src", "main", "java", packagePath); + var basePageFile = Path.Combine(mainSourcePath, "BasePage.java"); + + Assert.That(File.Exists(basePageFile), Is.True, "CodeGeneratorSolution BasePage.java generation completed..."); + } + + [Test] + public void CodeGeneratorSolutionJava_GenerateAll_WebControls() + { + var packagePath = "microsoft/foodshop/web/api"; + var controlsPath = Path.Combine(configuration.SolutionPath, "src", "main", "java", packagePath, "controls"); + + Assert.That(File.Exists(Path.Combine(controlsPath, "WebControl.java")), Is.True, "CodeGeneratorSolution WebControl.java generation completed..."); + Assert.That(File.Exists(Path.Combine(controlsPath, "WebButton.java")), Is.True, "CodeGeneratorSolution WebButton.java generation completed..."); + Assert.That(File.Exists(Path.Combine(controlsPath, "WebTextBox.java")), Is.True, "CodeGeneratorSolution WebTextBox.java generation completed..."); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTestTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTestTests.cs new file mode 100644 index 0000000..4a654c5 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTestTests.cs @@ -0,0 +1,226 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorTestTests + { + private Configuration configuration; + private ObjectRepository objectRepository; + private ObjectRepositoryPage page; + + private CodeGeneratorTest codeGeneratorTest; + + [OneTimeSetUp] + public void Setup() + { + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + + page = CreateLoginPage(); + + objectRepository = new ObjectRepository(); + objectRepository.AddPage(page); + + codeGeneratorTest = new CodeGeneratorTest(configuration, objectRepository); + } + + [Test] + public void CodeGeneratorTestJava_GenerateSourceCode() + { + var listOfLines = codeGeneratorTest.GenerateSourceCode(page); + + Assert.That(listOfLines.Count, Is.EqualTo(36), "CodeGeneratorTestJava GenerateSourceCode validation"); + } + + [Test] + public void CodeGeneratorTestJava_GeneratePackage() + { + var listOfLines = codeGeneratorTest.GeneratePackage(); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorTestJava GeneratePackage validation"); + Assert.That(listOfLines[0], Is.EqualTo("package expressium.coffeeshop.web.api.uitests;"), "CodeGeneratorTestJava GeneratePackage validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateImports() + { + var listOfLines = codeGeneratorTest.GenerateImports(page); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorTestJava GenerateImports validation"); + Assert.That(listOfLines[2], Is.EqualTo("import expressium.coffeeshop.web.api.models.*;"), "CodeGeneratorTestJava GenerateImports validation"); + Assert.That(listOfLines[3], Is.EqualTo("import expressium.coffeeshop.web.api.pages.*;"), "CodeGeneratorTestJava GenerateImports validation"); + Assert.That(listOfLines[4], Is.EqualTo("import expressium.coffeeshop.web.api.factories.*;"), "CodeGeneratorTestJava GenerateImports validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateTagProperties() + { + var listOfLines = codeGeneratorTest.GenerateTagProperties(page); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJava GenerateTagProperties validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateClass() + { + var listOfLines = codeGeneratorTest.GenerateClass(page); + + Assert.That(listOfLines.Count, Is.EqualTo(1), "CodeGeneratorTestJava GenerateClass validation"); + Assert.That(listOfLines[0], Is.EqualTo("public class LoginPageTests extends BaseTest"), "CodeGeneratorTestJava GenerateClass validation"); + } + + [Test] + public void CodeGeneratorTestJava_GeneratedDataVariables() + { + var listOfLines = codeGeneratorTest.GeneratedDataVariables(page); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJava GeneratedDataVariables validation"); + Assert.That(listOfLines[0], Is.EqualTo("private LoginPage loginPage;"), "CodeGeneratorTestJava GeneratedDataVariables validation"); + Assert.That(listOfLines[1], Is.EqualTo("private LoginPageModel loginPageModel = LoginPageModelFactory.getDefault();"), "CodeGeneratorTestJava GeneratedDataVariables validation"); + } + + [Test] + public void CodeGeneratorTestJava_GeneratedDataVariables_As_Variables() + { + page.Model = false; + var listOfLines = codeGeneratorTest.GeneratedDataVariables(page); + page.Model = true; + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorTestJava GeneratedDataVariables validation"); + Assert.That(listOfLines[0], Is.EqualTo("private LoginPage loginPage;"), "CodeGeneratorTestJava GeneratedDataVariables validation"); + Assert.That(listOfLines[2], Is.EqualTo("private String username = \"Andersen\";"), "CodeGeneratorTestJava GeneratedDataVariables validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateSetUpMethod() + { + var listOfLines = codeGeneratorTest.GenerateSetUpMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(10), "CodeGeneratorTestJava GenerateSetUpMethod validation"); + Assert.That(listOfLines[2], Is.EqualTo("initializeBrowser();"), "CodeGeneratorTestJava GenerateSetUpMethod validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateTitleTestMethod() + { + var listOfLines = codeGeneratorTest.GenerateTitleTestMethod(page); + + Assert.That(listOfLines.Count, Is.EqualTo(4), "CodeGeneratorTestJava GenerateTitleTestMethod validation"); + Assert.That(listOfLines[2], Is.EqualTo("asserts.equalTo(loginPage.getTitle(), \"Login\", \"Validating the LoginPage Title...\");"), "CodeGeneratorTestJava GenerateTitleTestMethod validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateFillFormTestMethods() + { + var listOfLines = codeGeneratorTest.GenerateFillFormTestMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(5), "CodeGeneratorTestJava GenerateFillFormTestMethods validation"); + Assert.That(listOfLines[2], Is.EqualTo("public void validate_Page_Property_Username() {"), "CodeGeneratorTestJava GenerateFillFormTestMethods validation"); + Assert.That(listOfLines[3].Contains("equalTo(loginPage.getUsername(), loginPageModel.getUsername()"), Is.True, "CodeGeneratorTestJava GenerateFillFormTestMethods validation"); + } + + [Test] + public void CodeGeneratorTestJava_GenerateTableTestMethods() + { + var listOfLines = codeGeneratorTest.GenerateTableTestMethods(page); + + Assert.That(listOfLines.Count, Is.EqualTo(0), "CodeGeneratorTestJava GenerateTableTestMethods validation"); + } + + [Test] + public void CodeGeneratorTestJava_Recursive_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.Title = "Login"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Login", Target = loginPage.Name }); + objectRepository.AddPage(loginPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, loginPage.Name); + + Assert.That(listOfLines, Is.Null, "CodeGeneratorTestJava GetNavigationMethods validation"); + } + + [Test] + public void CodeGeneratorTestJava_Deep_Recursive_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Registration", Target = "RegistrationPage" }); + objectRepository.AddPage(loginPage); + + var registrationPage = new ObjectRepositoryPage(); + registrationPage.Name = "RegistrationPage"; + registrationPage.AddControl(new ObjectRepositoryControl() { Name = "Login", Target = "LoginPage" }); + objectRepository.AddPage(registrationPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, loginPage.Name); + + Assert.That(listOfLines.Count, Is.EqualTo(3), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("var registrationPage = new RegistrationPage(logger, driver);"), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("registrationPage.clickLogin();"), "CodeGeneratorTestJava GetNavigationMethods validation"); + } + + [Test] + public void CodeGeneratorTestJava_GetNavigationMethods() + { + var objectRepository = new ObjectRepository(); + + var loginPage = new ObjectRepositoryPage(); + loginPage.Name = "LoginPage"; + loginPage.Title = "Login"; + loginPage.AddControl(new ObjectRepositoryControl() { Name = "Registration", Target = "RegistrationPage" }); + objectRepository.AddPage(loginPage); + + var registrationPage = new ObjectRepositoryPage(); + registrationPage.Name = "RegistrationPage"; + registrationPage.AddControl(new ObjectRepositoryControl() { Name = "Settings", Target = "SettingsPage" }); + objectRepository.AddPage(registrationPage); + + var settingsPage = new ObjectRepositoryPage(); + settingsPage.Name = "SettingsPage"; + objectRepository.AddPage(settingsPage); + + var listOfLines = codeGeneratorTest.GetNavigationMethods(objectRepository, settingsPage.Name); + + Assert.That(listOfLines.Count, Is.EqualTo(6), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[0], Is.EqualTo("var loginPage = new LoginPage(logger, driver);"), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[1], Is.EqualTo("loginPage.clickRegistration();"), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[3], Is.EqualTo("var registrationPage = new RegistrationPage(logger, driver);"), "CodeGeneratorTestJava GetNavigationMethods validation"); + Assert.That(listOfLines[4], Is.EqualTo("registrationPage.clickSettings();"), "CodeGeneratorTestJava GetNavigationMethods validation"); + } + + private static ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + page.Base = "FramePage"; + page.Title = "Login"; + page.Model = true; + + var synchronizer = new ObjectRepositorySynchronizer() { How = "WaitForPageTitleEquals", Using = "Home" }; + page.AddSynchronizer(synchronizer); + + var member = new ObjectRepositoryMember() { Name = "Menu", Page = "MainMenuBar" }; + page.AddMember(member); + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + username.Value = "Andersen"; + page.AddControl(username); + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTests.cs b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTests.cs new file mode 100644 index 0000000..f226a45 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/CodeGeneratorTests.cs @@ -0,0 +1,187 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using NUnit.Framework; +using System; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium.UnitTests +{ + [TestFixture] + public class CodeGeneratorTests + { + string directory = null; + + Configuration configuration; + + [OneTimeSetUp] + public void Setup() + { + directory = Environment.GetEnvironmentVariable("TEMP"); + + configuration = new Configuration(); + configuration.Company = "Expressium"; + configuration.Project = "Coffeeshop"; + configuration.ApplicationUrl = "http://www.google.com"; + configuration.SolutionPath = directory; + configuration.CodeGenerator.CodingLanguage = CodingLanguages.Java.ToString(); + configuration.CodeGenerator.CodingFlavour = CodingFlavours.Selenium.ToString(); + } + + [Test] + public void CodeGenerator_GenerateAll() + { + if (File.Exists(configuration.RepositoryPath)) + File.Delete(configuration.RepositoryPath); + + var packagePath = "expressium/coffeeshop/web/api"; + var mainSourcePath = Path.Combine(directory, "src", "main", "java", packagePath); + var testSourcePath = Path.Combine(directory, "src", "test", "java", packagePath); + + var loginPageFile = Path.Combine(mainSourcePath, "pages", "LoginPage.java"); + if (File.Exists(loginPageFile)) + File.Delete(loginPageFile); + + var loginModelFile = Path.Combine(mainSourcePath, "models", "LoginPageModel.java"); + if (File.Exists(loginModelFile)) + File.Delete(loginModelFile); + + var loginTestFile = Path.Combine(testSourcePath, "uitests", "LoginPageTests.java"); + if (File.Exists(loginTestFile)) + File.Delete(loginTestFile); + + var loginFactoryFile = Path.Combine(testSourcePath, "factories", "LoginPageModelFactory.java"); + if (File.Exists(loginFactoryFile)) + File.Delete(loginFactoryFile); + + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, objectRepository); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + codeGenerator.GenerateAll(); + + Assert.That(File.Exists(loginPageFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginModelFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginTestFile), Is.True, "CodeGenerator GenerateAll validation"); + Assert.That(File.Exists(loginFactoryFile), Is.True, "CodeGenerator GenerateAll validation"); + } + + [Test] + public void CodeGenerator_GeneratePage() + { + if (File.Exists(configuration.RepositoryPath)) + File.Delete(configuration.RepositoryPath); + + var packagePath = "expressium/coffeeshop/web/api"; + var mainSourcePath = Path.Combine(directory, "src", "main", "java", packagePath); + var testSourcePath = Path.Combine(directory, "src", "test", "java", packagePath); + + var loginPageFile = Path.Combine(mainSourcePath, "pages", "LoginPage.java"); + if (File.Exists(loginPageFile)) + File.Delete(loginPageFile); + + var loginPageModelFile = Path.Combine(mainSourcePath, "models", "LoginPageModel.java"); + if (File.Exists(loginPageModelFile)) + File.Delete(loginPageModelFile); + + var loginTestFile = Path.Combine(testSourcePath, "uitests", "LoginPageTests.java"); + if (File.Exists(loginTestFile)) + File.Delete(loginTestFile); + + var loginFactoryFile = Path.Combine(testSourcePath, "factories", "LoginPageModelFactory.java"); + if (File.Exists(loginFactoryFile)) + File.Delete(loginFactoryFile); + + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, objectRepository); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + codeGenerator.GeneratePage("LoginPage"); + + Assert.That(File.Exists(loginPageFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginPageModelFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginTestFile), Is.True, "CodeGenerator GeneratePage validation"); + Assert.That(File.Exists(loginFactoryFile), Is.True, "CodeGenerator GeneratePage validation"); + } + + [Test] + public void CodeGenerator_GeneratePagePreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GeneratePagePreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPage"), "CodeGenerator GeneratePagePreview validation"); + } + + [Test] + public void CodeGenerator_GenerateModelPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateModelPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModel"), "CodeGenerator GenerateModelPreview validation"); + } + + [Test] + public void CodeGenerator_GenerateTestPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateTestPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModel"), "CodeGenerator GenerateTestPreview validation"); + } + + [Test] + public void CodeGenerator_GenerateFactoryPreview() + { + var objectRepository = new ObjectRepository(); + objectRepository.AddPage(CreateLoginPage()); + + var codeGenerator = new CodeGenerator(configuration, objectRepository); + var result = codeGenerator.GenerateFactoryPreview("LoginPage"); + + Assert.That(result, Does.Contain("LoginPageModelFactory"), "CodeGenerator GenerateFactoryPreview validation"); + } + + private ObjectRepositoryPage CreateLoginPage() + { + var page = new ObjectRepositoryPage(); + page.Name = "LoginPage"; + + var username = new ObjectRepositoryControl(); + username.Name = "Username"; + username.Type = "TextBox"; + username.How = "Id"; + username.Using = "username"; + page.AddControl(username); + + var password = new ObjectRepositoryControl(); + password.Name = "Password"; + password.Type = "TextBox"; + password.How = "Name"; + password.Using = "password"; + page.AddControl(password); + + var submit = new ObjectRepositoryControl(); + submit.Name = "LogIn"; + submit.Type = "Button"; + submit.How = "XPath"; + submit.Using = "//button[text()='LogIn']"; + page.AddControl(submit); + + page.Model = true; + + return page; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium.UnitTests/Expressium.CodeGenerators.Java.Selenium.UnitTests.csproj b/Expressium.CodeGenerators.Java.Selenium.UnitTests/Expressium.CodeGenerators.Java.Selenium.UnitTests.csproj new file mode 100644 index 0000000..90f4da3 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium.UnitTests/Expressium.CodeGenerators.Java.Selenium.UnitTests.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + false + true + + + + + + + + + + + + + diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGenerator.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGenerator.cs new file mode 100644 index 0000000..51372a2 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGenerator.cs @@ -0,0 +1,129 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System; +using System.Collections.Generic; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + public class CodeGenerator : ICodeGenerator + { + private readonly Configuration configuration; + private readonly ObjectRepository objectRepository; + + private readonly CodeGeneratorPage codeGeneratorPage; + private readonly CodeGeneratorModel codeGeneratorModel; + private readonly CodeGeneratorTest codeGeneratorTest; + private readonly CodeGeneratorFactory codeGeneratorFactory; + private readonly CodeGeneratorSolution codeGeneratorSolution; + + public CodeGenerator() + { + } + + public CodeGenerator(Configuration configuration, ObjectRepository objectRepository) + { + configuration.Validate(); + objectRepository.Validate(); + + this.configuration = configuration; + this.objectRepository = objectRepository; + + codeGeneratorPage = new CodeGeneratorPage(configuration, objectRepository); + codeGeneratorModel = new CodeGeneratorModel(configuration, objectRepository); + codeGeneratorTest = new CodeGeneratorTest(configuration, objectRepository); + codeGeneratorFactory = new CodeGeneratorFactory(configuration, objectRepository); + codeGeneratorSolution = new CodeGeneratorSolution(configuration); + } + + public void GenerateAll() + { + foreach (var page in objectRepository.Pages) + { + codeGeneratorPage.Generate(page); + if (page.Model) + codeGeneratorModel.Generate(page); + + codeGeneratorTest.Generate(page); + if (page.Model) + codeGeneratorFactory.Generate(page); + } + } + + public void GeneratePage(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + + codeGeneratorPage.Generate(page); + if (page.Model) + codeGeneratorModel.Generate(page); + + codeGeneratorTest.Generate(page); + if (page.Model) + codeGeneratorFactory.Generate(page); + } + } + + public string GeneratePagePreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + return codeGeneratorPage.GeneratePreview(page); + } + + return null; + } + + public string GenerateModelPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + if (page.Model) + return codeGeneratorModel.GeneratePreview(page); + } + + return null; + } + + public string GenerateTestPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + return codeGeneratorTest.GeneratePreview(page); + } + + return null; + } + + public string GenerateFactoryPreview(string name) + { + if (objectRepository.IsPageAdded(name)) + { + var page = objectRepository.GetPage(name); + if (page.Model) + return codeGeneratorFactory.GeneratePreview(page); + } + + return null; + } + + public void GenerateSolution() + { + codeGeneratorSolution.GenerateAll(); + } + + public List GetCodingLanguages() + { + return new List(Enum.GetNames(typeof(CodingLanguages))); + } + + public List GetCodingFlavours() + { + return new List(Enum.GetNames(typeof(CodingFlavours))); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorEnumerations.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorEnumerations.cs new file mode 100644 index 0000000..c1d9975 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorEnumerations.cs @@ -0,0 +1,27 @@ +using System; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal enum CodeFolders + { + models, + pages, + controls + } + + internal enum TestFolders + { + factories, + uitests + } + + internal enum CodingLanguages + { + Java + } + + internal enum CodingFlavours + { + Selenium + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorFactory.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorFactory.cs new file mode 100644 index 0000000..687ecb1 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorFactory.cs @@ -0,0 +1,122 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorFactory : CodeGeneratorObject + { + internal CodeGeneratorFactory(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + + if (IsSourceCodeModified(filePath)) + return; + + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetTestSourcePath(), TestFolders.factories.ToString(), page.Name + "ModelFactory.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateDefaultMethod(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{TestFolders.factories};" + }; + } + + internal List GenerateImports() + { + return new List + { + $"import {GetPackage()}.{CodeFolders.models}.*;" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}ModelFactory" + }; + } + + internal List GenerateDefaultMethod(ObjectRepositoryPage page) + { + var listOfLines = new List + { + $"public static {page.Name}Model getDefault() {{", + $"{page.Name}Model model = new {page.Name}Model();", + $"", + $"// TODO - Implement potential missing factory property...", + $"" + }; + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + string value = control.Value; + if (string.IsNullOrWhiteSpace(value)) + value = CodeGeneratorUtilities.GenerateRandomString(6); + + listOfLines.Add($"model.set{control.Name}(\"{value}\");"); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + if (control.Value != null && control.Value.ToLower() == "true") + listOfLines.Add($"model.set{control.Name}(true);"); + else + listOfLines.Add($"model.set{control.Name}(false);"); + } + } + + listOfLines.Add($""); + listOfLines.Add($"return model;"); + listOfLines.Add($"}}"); + + return listOfLines; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorModel.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorModel.cs new file mode 100644 index 0000000..c2dc09e --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorModel.cs @@ -0,0 +1,128 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorModel : CodeGeneratorObject + { + internal CodeGeneratorModel(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetMainSourcePath(), CodeFolders.models.ToString(), page.Name + "Model.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateFields(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateAccessors(page)); + listOfLines.AddRange(GenerateExtensionMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{CodeFolders.models};" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}Model" + }; + } + + internal List GenerateFields(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + listOfLines.Add($"private String {control.Name.CamelCase()};"); + else if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"private boolean {control.Name.CamelCase()};"); + } + + return listOfLines; + } + + internal List GenerateAccessors(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + listOfLines.Add($"public String get{control.Name}() {{"); + listOfLines.Add($"return {control.Name.CamelCase()};"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + listOfLines.Add($"public void set{control.Name}(String value) {{"); + listOfLines.Add($"this.{control.Name.CamelCase()} = value;"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + listOfLines.Add($"public boolean is{control.Name}() {{"); + listOfLines.Add($"return {control.Name.CamelCase()};"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + listOfLines.Add($"public void set{control.Name}(boolean value) {{"); + listOfLines.Add($"this.{control.Name.CamelCase()} = value;"); + listOfLines.Add($"}}"); + listOfLines.Add($""); + } + } + + return listOfLines; + } + + internal List GenerateExtensionMethods(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + return GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorObject.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorObject.cs new file mode 100644 index 0000000..e4eba31 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorObject.cs @@ -0,0 +1,108 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System; +using System.Linq; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorObject + { + protected Configuration configuration; + protected ObjectRepository objectRepository; + + internal CodeGeneratorObject(Configuration configuration, ObjectRepository objectRepository) + { + this.configuration = configuration; + this.objectRepository = objectRepository; + } + + internal static bool IsSourceCodeModified(string filePath) + { + if (File.Exists(filePath) && !File.ReadAllText(filePath).Contains("// TODO - Implement")) + return true; + + return false; + } + + internal static void SaveSourceCode(string filePath, List listOfCodeLines) + { + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + File.WriteAllLines(filePath, listOfCodeLines); + + Console.WriteLine(filePath); + } + + internal static string GetSourceCodeAsString(List listOfCodeLines) + { + return string.Join(Environment.NewLine, listOfCodeLines); + } + + internal static List GetSourceCodeAsFormatted(List listOfCodeLines) + { + return CodeGeneratorUtilities.FormatSourceCode(listOfCodeLines); + } + + internal static List GenerateSourceCodeExtensionMethods(string filePath, string startLine, string endLine) + { + var listOfLines = new List(); + + listOfLines.Add(startLine); + + var listOfCodeLines = GetSourceCodeSnippetInFile(filePath, startLine, endLine); + if (listOfCodeLines != null && listOfCodeLines.Count > 0) + listOfLines.AddRange(listOfCodeLines); + else + listOfLines.Add(""); + + listOfLines.Add(endLine); + + return listOfLines; + } + + internal static List GetSourceCodeSnippetInFile(string filePath, string startLine, string endLine) + { + var listOfLines = new List(); + + if (File.Exists(filePath)) + { + var reading = false; + + foreach (var line in File.ReadAllLines(filePath)) + { + if (reading && line.Trim() == endLine) + reading = false; + + if (reading) + listOfLines.Add(line.Trim()); + + if (line.Trim() == startLine) + reading = true; + } + } + + return listOfLines; + } + + internal string GetPackage() + { + return $"{configuration.Company}.{configuration.Project}.web.api".ToLower(); + } + + internal string GetPackagePath() + { + return GetPackage().Replace(".", "/"); + } + + internal string GetMainSourcePath() + { + return Path.Combine(configuration.SolutionPath, "src", "main", "java", GetPackagePath()); + } + + internal string GetTestSourcePath() + { + return Path.Combine(configuration.SolutionPath, "src", "test", "java", GetPackagePath()); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorPage.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorPage.cs new file mode 100644 index 0000000..51d505f --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorPage.cs @@ -0,0 +1,372 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorPage : CodeGeneratorObject + { + internal CodeGeneratorPage(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetMainSourcePath(), CodeFolders.pages.ToString(), page.Name + ".java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GenerateMembers(page)); + listOfLines.AddRange(GenerateLocators(page)); + listOfLines.AddRange(GenerateContructor(page)); + listOfLines.AddRange(GenerateActionMethods(page)); + listOfLines.AddRange(GenerateFillFormMethod(page)); + listOfLines.AddRange(GenerateExtensionMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{CodeFolders.pages};" + }; + } + + internal List GenerateImports(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add("import org.openqa.selenium.*;"); + listOfLines.Add($"import {GetPackage()}.{CodeFolders.controls}.*;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.models}.*;"); + + listOfLines.Add("import org.slf4j.Logger;"); + + return listOfLines; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + var basePage = "BasePage"; + if (!string.IsNullOrWhiteSpace(page.Base)) + basePage = page.Base; + + return new List + { + $"public class {page.Name} extends {basePage}" + }; + } + + internal List GenerateMembers(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var member in page.Members) + listOfLines.Add($"public {member.Page} {member.Name.CamelCase()};"); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + listOfLines.Add($"public BaseTable {control.Name.CamelCase()};"); + } + + if (page.Members.Count > 0 || page.Controls.Any(c => c.IsTable())) + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateLocators(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (!control.IsTable()) + listOfLines.AddRange(GenerateLocator(control)); + } + + if (listOfLines.Count > 0) + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateLocator(ObjectRepositoryControl control) + { + var type = control.Type; + if (type == ControlTypes.Element.ToString()) + type = "Control"; + + return new List + { + $"private Web{type} {control.Name.CamelCase()};" + }; + } + + internal List GenerateContructor(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"public {page.Name}(Logger logger, WebDriver driver) {{"); + listOfLines.Add($"super(logger, driver);"); + + foreach (var member in page.Members) + listOfLines.Add($"this.{member.Name.CamelCase()} = new {member.Page}(logger, driver);"); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + listOfLines.Add($"this.{control.Name.CamelCase()} = new BaseTable(logger, driver, By.{GetJavaByMethod(control.How)}(\"{control.Using}\"));"); + } + + foreach (var control in page.Controls) + { + if (!control.IsTable()) + { + var type = control.Type; + if (type == ControlTypes.Element.ToString()) + type = "Control"; + listOfLines.Add($"this.{control.Name.CamelCase()} = new Web{type}(driver, By.{GetJavaByMethod(control.How)}(\"{control.Using.EscapeDoubleQuotes()}\"));"); + } + } + + if (page.Synchronizers.Count > 0 && (page.Members.Count > 0 || page.Controls.Count > 0)) + listOfLines.Add(""); + + foreach (var synchronizer in page.Synchronizers) + { + if (synchronizer.How == SynchronizerTypes.WaitForPageElementIsVisible.ToString() || + synchronizer.How == SynchronizerTypes.WaitForPageElementIsEnabled.ToString()) + { + listOfLines.Add($"{synchronizer.How.CamelCase()}({synchronizer.Using});"); + } + else + { + listOfLines.Add($"{synchronizer.How.CamelCase()}(\"{synchronizer.Using}\");"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add($""); + + return listOfLines; + } + + internal string GetJavaByMethod(string how) + { + switch (how) + { + case "Id": return "id"; + case "Name": return "name"; + case "XPath": return "xpath"; + case "CssSelector": return "cssSelector"; + case "ClassName": return "className"; + case "TagName": return "tagName"; + case "LinkText": return "linkText"; + case "PartialLinkText": return "partialLinkText"; + default: return how.ToLower(); + } + } + + internal List GenerateActionMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + listOfLines.AddRange(GenerateActionMethod(control)); + + return listOfLines; + } + + internal List GenerateFillFormMethod(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + if (page.Model) + { + listOfLines.Add($"public void fillForm({page.Name}Model model) {{"); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"set{control.Name}(model.is{control.Name}());"); + else + listOfLines.Add($"set{control.Name}(model.get{control.Name}());"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add(""); + } + + return listOfLines; + } + + internal List GenerateExtensionMethods(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + return GenerateSourceCodeExtensionMethods(filePath, "// region Extensions", "// endregion"); + } + + internal List GenerateActionMethod(ObjectRepositoryControl control) + { + var listOfLines = new List(); + + if (control.IsTextBox()) + listOfLines.AddRange(GenerateActionMethodTextBox(control)); + else if (control.IsComboBox() || control.IsListBox()) + listOfLines.AddRange(GenerateActionMethodComboBox(control)); + else if (control.IsCheckBox()) + listOfLines.AddRange(GenerateActionMethodCheckBox(control)); + else if (control.IsRadioButton()) + listOfLines.AddRange(GenerateActionMethodRadioBox(control)); + else if (control.IsLink() || control.IsButton()) + listOfLines.AddRange(GenerateActionMethodButton(control)); + else if (control.IsText()) + listOfLines.AddRange(GenerateActionMethodText(control)); + + return listOfLines; + } + + internal List GenerateActionMethodTextBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(String value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setText(value);", + $"}}", + "", + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getText();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodComboBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(String value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setText(value);", + $"}}", + "", + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getSelected();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodCheckBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(boolean value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setChecked(value);", + $"}}", + "", + $"public boolean is{control.Name}() {{", + $"logger.info(\"is{control.Name}()\");", + $"return {control.Name.CamelCase()}.getChecked();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodRadioBox(ObjectRepositoryControl control) + { + return new List + { + $"public void set{control.Name}(boolean value) {{", + $"logger.info(\"set{control.Name}(\" + value + \")\");", + $"{control.Name.CamelCase()}.setSelected(value);", + $"}}", + "", + $"public boolean is{control.Name}() {{", + $"logger.info(\"is{control.Name}()\");", + $"return {control.Name.CamelCase()}.getSelected();", + $"}}", + "" + }; + } + + internal List GenerateActionMethodButton(ObjectRepositoryControl control) + { + var listOfLines = new List(); + + listOfLines.Add($"public void click{control.Name}() {{"); + + if (!string.IsNullOrEmpty(control.Source)) + { + listOfLines.Add($"click{control.Source}();"); + listOfLines.Add(""); + } + + listOfLines.Add($"logger.info(\"click{control.Name}()\");"); + listOfLines.Add($"{control.Name.CamelCase()}.click();"); + listOfLines.Add($"}}"); + listOfLines.Add(""); + + return listOfLines; + } + + internal List GenerateActionMethodText(ObjectRepositoryControl control) + { + return new List + { + $"public String get{control.Name}() {{", + $"logger.info(\"get{control.Name}()\");", + $"return {control.Name.CamelCase()}.getText();", + $"}}", + "" + }; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorSolution.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorSolution.cs new file mode 100644 index 0000000..25d7058 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorSolution.cs @@ -0,0 +1,97 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using Expressium.CodeGenerators.Java.Selenium.Properties; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorSolution : CodeGeneratorObject + { + internal CodeGeneratorSolution(Configuration configuration) : base(configuration, null) + { + } + + internal void GenerateAll() + { + var directory = configuration.SolutionPath; + + // Setup Solution Mapping Properties... + var mapOfProperties = new Dictionary + { + { "$Company$", configuration.Company }, + { "$Project$", configuration.Project }, + { "$Package$", GetPackage() }, + { "$PackagePath$", GetPackagePath() }, + { "$Url$", configuration.ApplicationUrl }, + { "$BrowserType$", configuration.Enroller.BrowserType } + }; + + // Generate Root Files... + WriteToFile(Path.Combine(directory, ".gitignore"), Resources.GitIgnore, mapOfProperties); + WriteToFile(Path.Combine(directory, "pom.xml"), Resources.PomXml, mapOfProperties); + + // Generate Main Source Files... + var mainSourcePath = GetMainSourcePath(); + + Directory.CreateDirectory(Path.Combine(mainSourcePath, CodeFolders.models.ToString())); + Directory.CreateDirectory(Path.Combine(mainSourcePath, CodeFolders.pages.ToString())); + + WriteToFile(Path.Combine(mainSourcePath, "BasePage.java"), Resources.BasePage, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "BaseTable.java"), Resources.BaseTable, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "Logger.java"), Resources.Logger, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, "Randomizer.java"), Resources.Randomizer, mapOfProperties); + + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebControl.java"), Resources.WebControl, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebButton.java"), Resources.WebButton, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebCheckBox.java"), Resources.WebCheckBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebComboBox.java"), Resources.WebComboBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebLink.java"), Resources.WebLink, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebListBox.java"), Resources.WebListBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebRadioButton.java"), Resources.WebRadioButton, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebText.java"), Resources.WebText, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebTextBox.java"), Resources.WebTextBox, mapOfProperties); + WriteToFile(Path.Combine(mainSourcePath, CodeFolders.controls.ToString(), "WebTable.java"), Resources.WebTable, mapOfProperties); + + // Generate Test Source Files... + var testSourcePath = GetTestSourcePath(); + + Directory.CreateDirectory(Path.Combine(testSourcePath, TestFolders.factories.ToString())); + Directory.CreateDirectory(Path.Combine(testSourcePath, TestFolders.uitests.ToString())); + + WriteToFile(Path.Combine(testSourcePath, "BaseTest.java"), Resources.BaseTest, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BaseTestFixture.java"), Resources.BaseTestFixture, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BrowserFactory.java"), Resources.BrowserFactory, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "BrowserManager.java"), Resources.BrowserManager, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "Asserts.java"), Resources.Asserts, mapOfProperties); + WriteToFile(Path.Combine(testSourcePath, "Configuration.java"), Resources.Configuration, mapOfProperties); + + // Generate Test Resources... + var testResourcesPath = Path.Combine(directory, "src", "test", "resources"); + WriteToFile(Path.Combine(testResourcesPath, "configuration.json"), Resources.ConfigurationJson, mapOfProperties); + + // Save Configuration & Object Repository Files... + ObjectRepositoryUtilities.SerializeAsJson(configuration.RepositoryPath, new ObjectRepository()); + ConfigurationUtilities.SerializeAsJson(configuration.ConfigurationPath, configuration); + } + + protected static void WriteToFile(string destinationFile, string text, Dictionary mapOfProperties) + { + foreach (var property in mapOfProperties) + text = text.Replace(property.Key, property.Value); + + var directory = Path.GetDirectoryName(destinationFile); + if (!Directory.Exists(directory)) + Directory.CreateDirectory(directory); + + using (var fileStream = File.Create(destinationFile)) + { + using (var streamWriter = new StreamWriter(fileStream)) + streamWriter.WriteLine(text); + } + + Console.WriteLine(destinationFile); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorTest.cs b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorTest.cs new file mode 100644 index 0000000..97da55d --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/CodeGeneratorTest.cs @@ -0,0 +1,338 @@ +using Expressium.Configurations; +using Expressium.ObjectRepositories; +using System.Collections.Generic; +using System.IO; + +namespace Expressium.CodeGenerators.Java.Selenium +{ + internal class CodeGeneratorTest : CodeGeneratorObject + { + internal CodeGeneratorTest(Configuration configuration, ObjectRepository objectRepository) : base(configuration, objectRepository) + { + } + + internal void Generate(ObjectRepositoryPage page) + { + var filePath = GetFilePath(page); + + if (IsSourceCodeModified(filePath)) + return; + + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + SaveSourceCode(filePath, listOfLines); + } + + internal string GeneratePreview(ObjectRepositoryPage page) + { + var sourceCode = GenerateSourceCode(page); + var listOfLines = GetSourceCodeAsFormatted(sourceCode); + return GetSourceCodeAsString(listOfLines); + } + + internal string GetFilePath(ObjectRepositoryPage page) + { + try + { + return Path.Combine(GetTestSourcePath(), TestFolders.uitests.ToString(), page.Name + "Tests.java"); + } + catch + { + return null; + } + } + + internal List GenerateSourceCode(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.AddRange(GeneratePackage()); + listOfLines.Add($""); + listOfLines.AddRange(GenerateImports(page)); + listOfLines.Add($""); + listOfLines.AddRange(GenerateTagProperties(page)); + listOfLines.AddRange(GenerateClass(page)); + listOfLines.Add($"{{"); + listOfLines.AddRange(GeneratedDataVariables(page)); + listOfLines.AddRange(GenerateSetUpMethod(page)); + listOfLines.AddRange(GenerateTitleTestMethod(page)); + listOfLines.AddRange(GenerateFillFormTestMethods(page)); + listOfLines.AddRange(GenerateTableTestMethods(page)); + listOfLines.Add($"}}"); + + return listOfLines; + } + + internal List GeneratePackage() + { + return new List + { + $"package {GetPackage()}.{TestFolders.uitests};" + }; + } + + internal List GenerateImports(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add("import org.junit.jupiter.api.*;"); + listOfLines.Add("import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.models}.*;"); + + if (objectRepository.Pages.Count > 0) + listOfLines.Add($"import {GetPackage()}.{CodeFolders.pages}.*;"); + + if (page.Model) + listOfLines.Add($"import {GetPackage()}.factories.*;"); + + return listOfLines; + } + + internal List GenerateTagProperties(ObjectRepositoryPage page) + { + return new List + { + $"@TestInstance(PER_CLASS)", + $"@Tag(\"{TestFolders.uitests}\")", + $"@DisplayName(\"Validate Navigation & Content of {page.Name}\")" + }; + } + + internal List GenerateClass(ObjectRepositoryPage page) + { + return new List + { + $"public class {page.Name}Tests extends BaseTest" + }; + } + + internal List GeneratedDataVariables(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"private {page.Name} {page.Name.CamelCase()};"); + + if (page.Model) + { + listOfLines.Add($"private {page.Name}Model {page.Name.CamelCase()}Model = {page.Name}ModelFactory.getDefault();"); + } + else + { + if (page.HasFillFormControls()) + { + listOfLines.Add($""); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + if (control.IsTextBox() || control.IsComboBox() || control.IsListBox()) + { + if (string.IsNullOrWhiteSpace(control.Value)) + listOfLines.Add($"private String {control.Name.CamelCase()} = \"{CodeGeneratorUtilities.GenerateRandomString(6)}\";"); + else + listOfLines.Add($"private String {control.Name.CamelCase()} = \"{control.Value}\";"); + } + else if (control.IsCheckBox() || control.IsRadioButton()) + { + if (string.IsNullOrWhiteSpace(control.Value)) + listOfLines.Add($"private boolean {control.Name.CamelCase()} = true;"); + else + { + if (control.Value.ToLower() == "true") + listOfLines.Add($"private boolean {control.Name.CamelCase()} = true;"); + else + listOfLines.Add($"private boolean {control.Name.CamelCase()} = false;"); + } + } + } + } + } + } + + listOfLines.Add($""); + + return listOfLines; + } + + internal List GenerateSetUpMethod(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + listOfLines.Add($"@BeforeAll"); + listOfLines.Add($"public void setUp() {{"); + + if (!string.IsNullOrWhiteSpace(configuration.CodeGenerator.InitialLoginPage) && !configuration.CodeGenerator.InitialLoginPage.Contains(page.Name)) + listOfLines.Add($"initializeBrowserWithLogin();"); + else + listOfLines.Add($"initializeBrowser();"); + listOfLines.Add($""); + + listOfLines.Add($"// TODO - Implement potential missing page navigations..."); + listOfLines.Add($""); + + var listOfNavigationLines = GetNavigationMethods(objectRepository, page.Name); + if (listOfNavigationLines != null) + listOfLines.AddRange(listOfNavigationLines); + + listOfLines.Add($"{page.Name.CamelCase()} = new {page.Name}(logger, driver);"); + + if (page.Model) + { + listOfLines.Add($"{page.Name.CamelCase()}.fillForm({page.Name.CamelCase()}Model);"); + } + else + { + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + listOfLines.Add($"{page.Name.CamelCase()}.set{control.Name}({control.Name.CamelCase()});"); + } + } + + listOfLines.Add($"}}"); + listOfLines.Add($""); + + return listOfLines; + } + + internal List GetNavigationMethods(ObjectRepository objectRepository, string name) + { + return GetNavigationMethods(objectRepository, name, name); + } + + internal List GetNavigationMethods(ObjectRepository objectRepository, string origin, string name) + { + foreach (var page in objectRepository.Pages) + { + if (page.Name == origin) + continue; + + if (page.Name == name) + continue; + + foreach (var control in page.Controls) + { + if (control.Target == name) + { + var listOfLines = new List(); + + var listOfParentLines = GetNavigationMethods(objectRepository, origin, page.Name); + if (listOfParentLines != null) + listOfLines.AddRange(listOfParentLines); + + listOfLines.Add($"var {page.Name.CamelCase()} = new {page.Name}(logger, driver);"); + listOfLines.Add($"{page.Name.CamelCase()}.click{control.Name}();"); + listOfLines.Add($""); + + return listOfLines; + } + } + } + + return null; + } + + internal List GenerateTitleTestMethod(ObjectRepositoryPage page) + { + return new List + { + $"@Test", + $"public void validate_Page_Title() {{", + $"asserts.equalTo({page.Name.CamelCase()}.getTitle(), \"{page.Title}\", \"Validating the {page.Name} Title...\");", + $"}}" + }; + } + + internal List GenerateFillFormTestMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsFillFormControl()) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_Property_{control.Name}() {{"); + + if (page.Model) + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.is{control.Name}(), {page.Name.CamelCase()}Model.is{control.Name}(), \"Validating the {page.Name} property {control.Name}...\");"); + else + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.get{control.Name}(), {page.Name.CamelCase()}Model.get{control.Name}(), \"Validating the {page.Name} property {control.Name}...\");"); + } + else + { + if (control.IsCheckBox() || control.IsRadioButton()) + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.is{control.Name}(), {control.Name.CamelCase()}, \"Validating the {page.Name} property {control.Name}...\");"); + else + listOfLines.Add($"asserts.equalTo({page.Name.CamelCase()}.get{control.Name}(), {control.Name.CamelCase()}, \"Validating the {page.Name} property {control.Name}...\");"); + } + + listOfLines.Add($"}}"); + } + } + + return listOfLines; + } + + internal List GenerateTableTestMethods(ObjectRepositoryPage page) + { + var listOfLines = new List(); + + foreach (var control in page.Controls) + { + if (control.IsTable()) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Number_Of_Rows() {{"); + listOfLines.Add($"asserts.greaterThan({page.Name.CamelCase()}.{control.Name.CamelCase()}.getNumberOfRows(), -1, \"Validating the {page.Name} {control.Name} number of rows...\");"); + listOfLines.Add($"}}"); + + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Number_Of_Columns() {{"); + listOfLines.Add($"asserts.greaterThan({page.Name.CamelCase()}.{control.Name.CamelCase()}.getNumberOfColumns(), -1, \"Validating the {page.Name} {control.Name} number of columns...\");"); + listOfLines.Add($"}}"); + + var numberOfHeaders = 0; + if (!string.IsNullOrWhiteSpace(control.Value)) + numberOfHeaders = control.Value.Split(';').Length; + + if (numberOfHeaders > 1) + { + var listOfHeaders = control.Value.Split(';'); + foreach (var header in listOfHeaders) + { + var name = header.Trim(); + + if (CodeGeneratorUtilities.IsValidClassName(name)) + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Cell_Text_{name}() {{"); + listOfLines.Add($"asserts.isNotNull({page.Name.CamelCase()}.{control.Name.CamelCase()}.getCellText(1, \"{name}\"), \"Validating the {page.Name} {control.Name} table cell Text {name}...\");"); + listOfLines.Add($"}}"); + } + } + } + else + { + listOfLines.Add($""); + listOfLines.Add($"@Test"); + listOfLines.Add($"public void validate_Page_{control.Name}_Cell_Text() {{"); + listOfLines.Add($"asserts.isNotNull({page.Name.CamelCase()}.{control.Name.CamelCase()}.getCellText(1, 2), \"Validating the {page.Name} {control.Name} table cell Text...\");"); + listOfLines.Add($"}}"); + } + } + } + + return listOfLines; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Expressium.CodeGenerators.Java.Selenium.csproj b/Expressium.CodeGenerators.Java.Selenium/Expressium.CodeGenerators.Java.Selenium.csproj new file mode 100644 index 0000000..97ec69f --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Expressium.CodeGenerators.Java.Selenium.csproj @@ -0,0 +1,35 @@ + + + + net8.0 + + + + + <_Parameter1>Expressium.CodeGenerators.Java.Selenium.UnitTests + + + + + + + + + + + + Resources.resx + True + True + + + + + + Designer + Resources.Designer.cs + ResXFileCodeGenerator + + + + diff --git a/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.Designer.cs b/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.Designer.cs new file mode 100644 index 0000000..88ebf52 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.Designer.cs @@ -0,0 +1,270 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Expressium.CodeGenerators.Java.Selenium.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Expressium.CodeGenerators.Java.Selenium.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Asserts. + /// + internal static string Asserts { + get { + return ResourceManager.GetString("Asserts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BasePage. + /// + internal static string BasePage { + get { + return ResourceManager.GetString("BasePage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTable. + /// + internal static string BaseTable { + get { + return ResourceManager.GetString("BaseTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTest. + /// + internal static string BaseTest { + get { + return ResourceManager.GetString("BaseTest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BaseTestFixture. + /// + internal static string BaseTestFixture { + get { + return ResourceManager.GetString("BaseTestFixture", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BrowserFactory. + /// + internal static string BrowserFactory { + get { + return ResourceManager.GetString("BrowserFactory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BrowserManager. + /// + internal static string BrowserManager { + get { + return ResourceManager.GetString("BrowserManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Configuration. + /// + internal static string Configuration { + get { + return ResourceManager.GetString("Configuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ConfigurationJson. + /// + internal static string ConfigurationJson { + get { + return ResourceManager.GetString("ConfigurationJson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to GitIgnore. + /// + internal static string GitIgnore { + get { + return ResourceManager.GetString("GitIgnore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logger. + /// + internal static string Logger { + get { + return ResourceManager.GetString("Logger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PomXml. + /// + internal static string PomXml { + get { + return ResourceManager.GetString("PomXml", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Randomizer. + /// + internal static string Randomizer { + get { + return ResourceManager.GetString("Randomizer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebButton. + /// + internal static string WebButton { + get { + return ResourceManager.GetString("WebButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebCheckBox. + /// + internal static string WebCheckBox { + get { + return ResourceManager.GetString("WebCheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebComboBox. + /// + internal static string WebComboBox { + get { + return ResourceManager.GetString("WebComboBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebControl. + /// + internal static string WebControl { + get { + return ResourceManager.GetString("WebControl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebLink. + /// + internal static string WebLink { + get { + return ResourceManager.GetString("WebLink", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebListBox. + /// + internal static string WebListBox { + get { + return ResourceManager.GetString("WebListBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebRadioButton. + /// + internal static string WebRadioButton { + get { + return ResourceManager.GetString("WebRadioButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebTable. + /// + internal static string WebTable { + get { + return ResourceManager.GetString("WebTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebText. + /// + internal static string WebText { + get { + return ResourceManager.GetString("WebText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to WebTextBox. + /// + internal static string WebTextBox { + get { + return ResourceManager.GetString("WebTextBox", resourceCulture); + } + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.resx b/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.resx new file mode 100644 index 0000000..2f29601 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Properties/Resources.resx @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Asserts.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BasePage.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTest.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BaseTestFixture.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BrowserFactory.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\BrowserManager.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Configuration.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\ConfigurationJson.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\GitIgnore.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Logger.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\PomXml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\Randomizer.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebButton.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebCheckBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebComboBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebControl.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebLink.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebListBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebRadioButton.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebText.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\WebTextBox.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/Asserts.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/Asserts.txt new file mode 100644 index 0000000..53a79b5 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/Asserts.txt @@ -0,0 +1,112 @@ +package $Package$; + +import org.junit.jupiter.api.Assertions; +import org.slf4j.Logger; + +public class Asserts { + private final Logger logger; + + public Asserts(Logger logger) { + this.logger = logger; + } + + public void equalTo(Object actual, Object expected, String message) { + try { + Assertions.assertEquals(expected, actual, message); + logger.info(message); + logger.info("Expected to be equal [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void isTrue(boolean actual, String message) { + try { + Assertions.assertTrue(actual, message); + logger.info(message); + logger.info("Expected to be equal [true] and was [true] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [true] but was [false] - FAILED"); + } + } + + public void isFalse(boolean actual, String message) { + try { + Assertions.assertFalse(actual, message); + logger.info(message); + logger.info("Expected to be equal [false] and was [false] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [false] but was [true] - FAILED"); + } + } + + public void isNull(Object actual, String message) { + try { + Assertions.assertNull(actual, message); + logger.info(message); + logger.info("Expected to be equal [null] and was [null] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be equal [null] but was [" + actual + "] - FAILED"); + } + } + + public void isNotNull(String actual, String message) { + try { + Assertions.assertNotNull(actual, message); + logger.info(message); + logger.info("Expected to be different from [null] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be different from [null] but was [null] - FAILED"); + } + } + + public void isNotEmpty(String actual, String message) { + try { + Assertions.assertFalse(actual == null || actual.isEmpty(), message); + logger.info(message); + logger.info("Expected to be different from [empty] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be different from [empty] but was [empty] - FAILED"); + } + } + + public void greaterThan(int actual, int expected, String message) { + try { + Assertions.assertTrue(actual > expected, message); + logger.info(message); + logger.info("Expected to be greater than [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be greater than [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void lessThan(int actual, int expected, String message) { + try { + Assertions.assertTrue(actual < expected, message); + logger.info(message); + logger.info("Expected to be less than [" + expected + "] and was [" + actual + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to be less than [" + expected + "] but was [" + actual + "] - FAILED"); + } + } + + public void doesContain(String actual, String expected, String message) { + try { + Assertions.assertTrue(actual != null && actual.contains(expected), message); + logger.info(message); + logger.info("Expected to contain [" + expected + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to contain [" + expected + "] - FAILED"); + } + } + + public void doesNotContain(String actual, String expected, String message) { + try { + Assertions.assertFalse(actual != null && actual.contains(expected), message); + logger.info(message); + logger.info("Expected to not contain [" + expected + "] - PASSED"); + } catch (AssertionError e) { + throw new RuntimeException(message + "\nExpected to not contain [" + expected + "] - FAILED"); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BasePage.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BasePage.txt new file mode 100644 index 0000000..5d745dd --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BasePage.txt @@ -0,0 +1,110 @@ +package $Package$; + +import org.openqa.selenium.*; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.slf4j.Logger; +import $Package$.controls.WebControl; +import java.time.Duration; + +public class BasePage { + protected final Logger logger; + protected final WebDriver driver; + + public static int pageTimeOut = 10000; + + public BasePage(Logger logger, WebDriver driver) { + this.logger = logger; + this.driver = driver; + + waitForPageDocumentReadyStateEqualsComplete(); + } + + public String getTitle() { + logger.info("getTitle()"); + return driver.getTitle(); + } + + public String getURL() { + logger.info("getURL()"); + return driver.getCurrentUrl(); + } + + protected void waitForPageDocumentReadyStateEqualsComplete() { + try { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(pageTimeOut)); + wait.until(d -> ((JavascriptExecutor) d).executeScript("return document.readyState").equals("complete")); + } catch (Exception e) { + throw new RuntimeException("Page document ready state was expected to be completed within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageTitleEquals(String title) { + try { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(pageTimeOut)); + wait.until(ExpectedConditions.titleIs(title)); + } catch (Exception e) { + throw new RuntimeException("Page title was expected to be equal to '" + title + "' but was '" + driver.getTitle() + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageTitleContains(String title) { + try { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(pageTimeOut)); + wait.until(ExpectedConditions.titleContains(title)); + } catch (Exception e) { + throw new RuntimeException("Page title was expected to contain '" + title + "' but was '" + driver.getTitle() + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageUrlEquals(String url) { + try { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(pageTimeOut)); + wait.until(ExpectedConditions.urlToBe(url)); + } catch (Exception e) { + throw new RuntimeException("Page URL was expected to be equal to '" + url + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageUrlContains(String url) { + try { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(pageTimeOut)); + wait.until(ExpectedConditions.urlContains(url)); + } catch (Exception e) { + throw new RuntimeException("Page URL was expected to contain '" + url + "' within " + pageTimeOut + " milliseconds..."); + } + } + + protected void waitForPageElementIsVisible(WebControl control) { + control.waitForElementIsVisible(); + } + + protected void waitForPageElementIsEnabled(WebControl control) { + control.waitForElementIsEnabled(); + } + + public void navigateBack() { + logger.info("navigateBack()"); + driver.navigate().back(); + } + + public void navigateForward() { + logger.info("navigateForward()"); + driver.navigate().forward(); + } + + public void navigateRefresh() { + logger.info("navigateRefresh()"); + driver.navigate().refresh(); + } + + public void scrollToTop() { + logger.info("scrollToTop()"); + ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, 0);"); + } + + public void scrollToBottom() { + logger.info("scrollToBottom()"); + ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);"); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTable.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTable.txt new file mode 100644 index 0000000..a0022f9 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTable.txt @@ -0,0 +1,35 @@ +package $Package$; + +import $Package$.controls.WebTable; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.slf4j.Logger; + +public class BaseTable extends BasePage { + protected final WebTable baseControl; + + public BaseTable(Logger logger, WebDriver driver, By baseLocator) { + super(logger, driver); + baseControl = new WebTable(driver, baseLocator); + } + + public int getNumberOfRows() { + logger.info("getNumberOfRows()"); + return baseControl.getNumberOfRows(); + } + + public int getNumberOfColumns() { + logger.info("getNumberOfColumns()"); + return baseControl.getNumberOfColumns(); + } + + public String getCellText(Object rowId, Object columnId) { + logger.info("getCellText(" + rowId + ", " + columnId + ")"); + return baseControl.getCellText(rowId, columnId); + } + + public String getCellText(String cellText) { + logger.info("getCellText(" + cellText + ")"); + return baseControl.getCellText(cellText); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTest.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTest.txt new file mode 100644 index 0000000..2dda802 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTest.txt @@ -0,0 +1,22 @@ +package $Package$; + +import org.openqa.selenium.WebDriver; + +public class BaseTest extends BaseTestFixture { + public void initializeBrowser() { + driver = browserManager.getDriver(); + } + + public void initializeBrowserWithLogin() { + initializeBrowser(); + + throw new RuntimeException("Implementation of initializeBrowserWithLogin is missing..."); + + // TODO - Implement potential missing login sequence... + + // LoginPage loginPage = new LoginPage(logger, driver); + // loginPage.setUsername(configuration.username); + // loginPage.setPassword(configuration.password); + // loginPage.clickLogin(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTestFixture.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTestFixture.txt new file mode 100644 index 0000000..0ae2966 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BaseTestFixture.txt @@ -0,0 +1,58 @@ +package $Package$; + +import org.junit.jupiter.api.*; +import org.openqa.selenium.WebDriver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.nio.file.Paths; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class BaseTestFixture { + protected final Configuration configuration; + protected final BrowserManager browserManager; + + protected Logger logger; + protected Asserts asserts; + + protected WebDriver driver; + + public BaseTestFixture() { + configuration = Configuration.getCurrentConfiguration(); + browserManager = new BrowserManager(configuration); + } + + @BeforeAll + protected void initializeFixture() { + logger = LoggerFactory.getLogger(getClass().getSimpleName()); + asserts = new Asserts(logger); + driver = browserManager.getDriver(); + + logger.info(""); + logger.info("// Initialize Test Fixture"); + logger.info("Company: " + configuration.company); + logger.info("Project: " + configuration.project); + logger.info("Environment: " + configuration.environment); + logger.info("Url: " + configuration.url); + } + + @AfterAll + protected void finalizeFixture() { + logger.info(""); + logger.info("// Finalize Test Fixture"); + + if (browserManager.isInitialized()) { + if (configuration.screenshots) { + String filePath = Paths.get("Screenshots", getClass().getSimpleName() + ".png").toString(); + browserManager.saveScreenshot(filePath); + } + + browserManager.quit(); + } + } + + @BeforeEach + protected void initializeTest(TestInfo testInfo) { + logger.info(""); + logger.info("// " + testInfo.getDisplayName()); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserFactory.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserFactory.txt new file mode 100644 index 0000000..f2fa321 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserFactory.txt @@ -0,0 +1,92 @@ +package $Package$; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.firefox.FirefoxOptions; +import org.openqa.selenium.edge.EdgeDriver; +import org.openqa.selenium.edge.EdgeOptions; + +public class BrowserFactory { + public enum BrowserTypes { + Chrome, Firefox, Edge + } + + public static WebDriver initialize(Configuration configuration) { + if (BrowserTypes.Chrome.name().equals(configuration.browserType)) + return initializeChromeBrowser(configuration); + else if (BrowserTypes.Firefox.name().equals(configuration.browserType)) + return initializeFirefoxBrowser(configuration); + else if (BrowserTypes.Edge.name().equals(configuration.browserType)) + return initializeEdgeBrowser(configuration); + else + throw new IllegalArgumentException("Specified browser type '" + configuration.browserType + "' is unknown..."); + } + + private static WebDriver initializeChromeBrowser(Configuration configuration) { + ChromeOptions options = new ChromeOptions(); + options.addArguments("--disable-notifications"); + + if (configuration.maximize) + options.addArguments("start-maximized"); + + if (configuration.headless) { + options.addArguments("--headless"); + options.addArguments("--window-size=" + configuration.windowWidth + "," + configuration.windowHeight); + } else if (configuration.windowSize) { + options.addArguments("--window-size=" + configuration.windowWidth + "," + configuration.windowHeight); + options.addArguments("--window-position=10,10"); + } + + WebDriver driver = new ChromeDriver(options); + + if (configuration.url != null) + driver.get(configuration.url); + + return driver; + } + + private static WebDriver initializeFirefoxBrowser(Configuration configuration) { + FirefoxOptions options = new FirefoxOptions(); + + if (configuration.headless) { + options.addArguments("--headless"); + options.addArguments("--width=" + configuration.windowWidth); + options.addArguments("--height=" + configuration.windowHeight); + } else if (configuration.windowSize) { + options.addArguments("--width=" + configuration.windowWidth); + options.addArguments("--height=" + configuration.windowHeight); + } + + WebDriver driver = new FirefoxDriver(options); + + if (configuration.url != null) + driver.get(configuration.url); + + return driver; + } + + private static WebDriver initializeEdgeBrowser(Configuration configuration) { + EdgeOptions options = new EdgeOptions(); + options.addArguments("--disable-notifications"); + + if (configuration.maximize) + options.addArguments("start-maximized"); + + if (configuration.headless) { + options.addArguments("--headless"); + options.addArguments("--window-size=" + configuration.windowWidth + "," + configuration.windowHeight); + } else if (configuration.windowSize) { + options.addArguments("--window-size=" + configuration.windowWidth + "," + configuration.windowHeight); + options.addArguments("--window-position=10,10"); + } + + WebDriver driver = new EdgeDriver(options); + + if (configuration.url != null) + driver.get(configuration.url); + + return driver; + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserManager.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserManager.txt new file mode 100644 index 0000000..4594b15 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/BrowserManager.txt @@ -0,0 +1,47 @@ +package $Package$; + +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class BrowserManager { + private final Configuration configuration; + private WebDriver driver; + + public BrowserManager(Configuration configuration) { + this.configuration = configuration; + } + + public WebDriver getDriver() { + if (driver == null) { + driver = BrowserFactory.initialize(configuration); + } + return driver; + } + + public boolean isInitialized() { + return driver != null; + } + + public void saveScreenshot(String filePath) { + if (driver != null) { + try { + File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + Files.copy(screenshot.toPath(), Paths.get(filePath)); + } catch (IOException e) { + // ignore + } + } + } + + public void quit() { + if (driver != null) { + driver.quit(); + driver = null; + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/Configuration.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/Configuration.txt new file mode 100644 index 0000000..9cc171a --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/Configuration.txt @@ -0,0 +1,55 @@ +package $Package$; + +import $Package$.controls.WebControl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; + +public class Configuration { + public String company; + public String project; + public String environment; + public boolean loggings; + public boolean screenshots; + public String url; + public String username; + public String password; + public String browserType; + public boolean maximize; + public boolean headless; + public boolean windowSize; + public int windowWidth; + public int windowHeight; + public boolean highlight; + public int highlightTimeOut; + + public static Configuration getCurrentConfiguration() { + String profile = System.getenv("PROFILE"); + if (profile == null || profile.isEmpty()) profile = "Development"; + + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode root = mapper.readTree(new File("src/test/resources/configuration.json")); + JsonNode profileNode = root.path("Profiles").path(profile); + + Configuration config = mapper.treeToValue(profileNode, Configuration.class); + + if (config == null) + throw new RuntimeException("Configuration profile '" + profile + "' is unknown..."); + + if (config.username == null || config.username.isEmpty()) + config.username = System.getenv("USERNAME"); + + if (config.password == null || config.password.isEmpty()) + config.password = System.getenv("PASSWORD"); + + WebControl.highlight = config.highlight; + WebControl.highlightTimeOut = config.highlightTimeOut; + + return config; + } catch (IOException e) { + throw new RuntimeException("Failed to load configuration: " + e.getMessage()); + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/ConfigurationJson.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/ConfigurationJson.txt new file mode 100644 index 0000000..c1eb0e6 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/ConfigurationJson.txt @@ -0,0 +1,22 @@ +{ + "Profiles": { + "Development": { + "company": "$Company$", + "project": "$Project$", + "environment": "Development", + "loggings": true, + "screenshots": true, + "url": "$Url$", + "username": "john.doe@microsoft.com", + "password": "1234567890", + "browserType": "$BrowserType$", + "maximize": true, + "headless": false, + "windowSize": false, + "windowWidth": 1920, + "windowHeight": 1080, + "highlight": true, + "highlightTimeOut": 150 + } + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/GitIgnore.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/GitIgnore.txt new file mode 100644 index 0000000..b092dd9 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/GitIgnore.txt @@ -0,0 +1,27 @@ +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# IDE +.idea/ +*.iml +.classpath +.project +.settings/ +*.class + +# Logs +*.log +Loggings/ +Screenshots/ + +# OS +.DS_Store +Thumbs.db diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/Logger.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/Logger.txt new file mode 100644 index 0000000..cb7a36f --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/Logger.txt @@ -0,0 +1,10 @@ +package $Package$; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoggerUtility { + public static Logger initialize(String name) { + return LoggerFactory.getLogger(name); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/PomXml.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/PomXml.txt new file mode 100644 index 0000000..f29d081 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/PomXml.txt @@ -0,0 +1,71 @@ + + + 4.0.0 + + $Package$ + $Company$-$Project$-web-api + 1.0.0 + jar + + + 11 + 11 + UTF-8 + + + + + + org.seleniumhq.selenium + selenium-java + 4.25.0 + + + + + org.junit.jupiter + junit-jupiter + 5.11.3 + test + + + + + org.slf4j + slf4j-api + 2.0.16 + + + + + org.apache.logging.log4j + log4j-slf4j2-impl + 2.24.1 + + + + org.apache.logging.log4j + log4j-core + 2.24.1 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.18.1 + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.1 + + + + diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/Randomizer.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/Randomizer.txt new file mode 100644 index 0000000..79bc4b0 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/Randomizer.txt @@ -0,0 +1,30 @@ +package $Package$; + +import java.security.SecureRandom; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Randomizer { + private static final SecureRandom random = new SecureRandom(); + private static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + public static String getRandomString(int length) { + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + sb.append(CHARS.charAt(random.nextInt(CHARS.length()))); + } + return sb.toString(); + } + + public static int getRandomInteger(int minValue, int maxValue) { + return random.nextInt(maxValue - minValue) + minValue; + } + + public static String getUniqueId() { + return "ID" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssnn")); + } + + public static String getDateTimeId() { + return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebButton.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebButton.txt new file mode 100644 index 0000000..f69a7cf --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebButton.txt @@ -0,0 +1,21 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebButton extends WebControl { + public WebButton(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebButton(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public void click() { + waitForElementIsEnabled(); + highlightElementAsAction(); + highlightElementClear(); + clickElement(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebCheckBox.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebCheckBox.txt new file mode 100644 index 0000000..21c0467 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebCheckBox.txt @@ -0,0 +1,29 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebCheckBox extends WebControl { + public WebCheckBox(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebCheckBox(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public void setChecked(boolean value) { + waitForElementIsEnabled(); + if ((!isSelected() && value) || (isSelected() && !value)) { + highlightElementAsAction(); + clickElement(); + highlightElementClear(); + } + } + + public boolean getChecked() { + waitForElementIsVisible(); + highlightElementAsValidation(); + return isSelected(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebComboBox.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebComboBox.txt new file mode 100644 index 0000000..d06d14b --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebComboBox.txt @@ -0,0 +1,55 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.Select; +import java.util.List; +import java.util.stream.Collectors; + +public class WebComboBox extends WebControl { + public WebComboBox(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebComboBox(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public void setText(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + new Select(getElement()).selectByVisibleText(value); + highlightElementClear(); + } + + public void selectByIndex(int value) { + waitForElementIsEnabled(); + highlightElementAsAction(); + new Select(getElement()).selectByIndex(value); + highlightElementClear(); + } + + public void selectByValue(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + new Select(getElement()).selectByValue(value); + highlightElementClear(); + } + + public String getSelected() { + waitForElementIsVisible(); + highlightElementAsValidation(); + Select select = new Select(getElement()); + if (select.getFirstSelectedOption() != null) + return select.getFirstSelectedOption().getText().trim(); + return null; + } + + public List getOptions() { + return new Select(getElement()).getOptions().stream() + .map(e -> e.getText()) + .collect(Collectors.toList()); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebControl.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebControl.txt new file mode 100644 index 0000000..2bea950 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebControl.txt @@ -0,0 +1,103 @@ +package $Package$.controls; + +import org.openqa.selenium.*; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import java.time.Duration; +import java.util.List; + +public class WebControl { + protected WebDriver driver; + protected By locator; + protected By childLocator; + + public static int elementTimeOut = 10000; + public static boolean highlight = false; + public static int highlightTimeOut = 150; + + public WebControl(WebDriver driver, By locator) { + this.driver = driver; + this.locator = locator; + } + + public WebControl(WebDriver driver, By locator, By childLocator) { + this.driver = driver; + this.locator = locator; + this.childLocator = childLocator; + } + + public WebElement getElement() { + if (childLocator != null) { + WebElement parent = driver.findElement(locator); + return parent.findElement(childLocator); + } + return driver.findElement(locator); + } + + public List getChildElements(By childBy) { + return driver.findElement(locator).findElements(childBy); + } + + public String getAttribute(String value) { + return getElement().getDomProperty(value); + } + + public boolean isVisible() { + return getElement().isDisplayed(); + } + + public boolean isEnabled() { + return getElement().isEnabled(); + } + + public boolean isSelected() { + return getElement().isSelected(); + } + + public void waitForElementIsVisible() { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(elementTimeOut)); + wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + } + + public void waitForElementIsEnabled() { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(elementTimeOut)); + wait.until(ExpectedConditions.elementToBeClickable(locator)); + } + + public void highlightElementAsAction() { + if (highlight) { + try { + ((JavascriptExecutor) driver).executeScript( + "arguments[0].style.border='3px solid blue';", getElement()); + Thread.sleep(highlightTimeOut); + ((JavascriptExecutor) driver).executeScript( + "arguments[0].style.border='';", getElement()); + } catch (Exception ignored) {} + } + } + + public void highlightElementAsValidation() { + if (highlight) { + try { + ((JavascriptExecutor) driver).executeScript( + "arguments[0].style.border='3px solid green';", getElement()); + Thread.sleep(highlightTimeOut); + ((JavascriptExecutor) driver).executeScript( + "arguments[0].style.border='';", getElement()); + } catch (Exception ignored) {} + } + } + + public void highlightElementClear() { + if (highlight) { + try { + ((JavascriptExecutor) driver).executeScript( + "arguments[0].style.border='';", getElement()); + } catch (Exception ignored) {} + } + } + + public void clickElement() { + getElement().click(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebLink.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebLink.txt new file mode 100644 index 0000000..4ce6c45 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebLink.txt @@ -0,0 +1,14 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebLink extends WebButton { + public WebLink(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebLink(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebListBox.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebListBox.txt new file mode 100644 index 0000000..4201e15 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebListBox.txt @@ -0,0 +1,14 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebListBox extends WebComboBox { + public WebListBox(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebListBox(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebRadioButton.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebRadioButton.txt new file mode 100644 index 0000000..a45fecd --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebRadioButton.txt @@ -0,0 +1,29 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebRadioButton extends WebControl { + public WebRadioButton(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebRadioButton(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public void setSelected(boolean value) { + waitForElementIsEnabled(); + if (!isSelected() && value) { + highlightElementAsAction(); + clickElement(); + highlightElementClear(); + } + } + + public boolean getSelected() { + waitForElementIsVisible(); + highlightElementAsValidation(); + return isSelected(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebTable.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebTable.txt new file mode 100644 index 0000000..3c32df5 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebTable.txt @@ -0,0 +1,61 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import java.util.List; + +public class WebTable extends WebControl { + public WebTable(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebTable(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public int getNumberOfRows() { + return getChildElements(By.xpath("./tbody/tr")).size(); + } + + public int getNumberOfColumns() { + return getChildElements(By.xpath("./thead/tr/th")).size(); + } + + public String getCellText(Object rowId, Object columnId) { + By cellLocator = getCellElement(rowId, columnId, null); + WebText control = new WebText(driver, locator, cellLocator); + return control.getText(); + } + + public String getCellText(String cellText) { + By cellLocator = By.xpath("./tbody/tr/td[contains(normalize-space(),'" + cellText + "')]"); + WebText control = new WebText(driver, locator, cellLocator); + return control.getText(); + } + + protected By getCellElement(Object rowId, Object columnId, String subXPath) { + String sub = subXPath != null ? subXPath : ""; + if (rowId instanceof Integer && columnId instanceof Integer) { + return By.xpath("./tbody/tr[" + rowId + "]/td[" + columnId + "]" + sub); + } else if (rowId instanceof Integer && columnId instanceof String) { + return getCellElement(rowId, getColumnIndex((String) columnId), subXPath); + } else if (rowId instanceof String && columnId instanceof Integer) { + return By.xpath("./tbody/tr[td[contains(normalize-space(),'" + rowId + "')]]/td[" + columnId + "]" + sub); + } else if (rowId instanceof String && columnId instanceof String) { + return getCellElement(rowId, getColumnIndex((String) columnId), subXPath); + } else { + throw new IllegalArgumentException("Invalid argument types for getCellElement..."); + } + } + + protected int getColumnIndex(String columnName) { + List columns = getChildElements(By.xpath("./thead/tr/th")); + for (int i = 0; i < columns.size(); i++) { + if (columns.get(i).getText().equals(columnName)) { + return i + 1; + } + } + throw new RuntimeException("The column name '" + columnName + "' was not found..."); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebText.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebText.txt new file mode 100644 index 0000000..e5b29f3 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebText.txt @@ -0,0 +1,20 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebText extends WebControl { + public WebText(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebText(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public String getText() { + waitForElementIsVisible(); + highlightElementAsValidation(); + return getElement().getText().trim(); + } +} diff --git a/Expressium.CodeGenerators.Java.Selenium/Resources/WebTextBox.txt b/Expressium.CodeGenerators.Java.Selenium/Resources/WebTextBox.txt new file mode 100644 index 0000000..a8c1500 --- /dev/null +++ b/Expressium.CodeGenerators.Java.Selenium/Resources/WebTextBox.txt @@ -0,0 +1,30 @@ +package $Package$.controls; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +public class WebTextBox extends WebControl { + public WebTextBox(WebDriver driver, By locator) { + super(driver, locator); + } + + public WebTextBox(WebDriver driver, By locator, By childLocator) { + super(driver, locator, childLocator); + } + + public void setText(String value) { + if (value == null) return; + waitForElementIsEnabled(); + highlightElementAsAction(); + getElement().clear(); + getElement().sendKeys(value); + highlightElementClear(); + } + + public String getText() { + waitForElementIsVisible(); + highlightElementAsValidation(); + String val = getElement().getDomProperty("value"); + return val != null ? val.trim() : ""; + } +} diff --git a/ExpressiumOSS.sln b/ExpressiumOSS.sln index d4e1735..b354c9c 100644 --- a/ExpressiumOSS.sln +++ b/ExpressiumOSS.sln @@ -25,6 +25,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.CSharp.Selenium.UnitTests", "Expressium.CodeGenerators.CSharp.Selenium.UnitTests\Expressium.CodeGenerators.CSharp.Selenium.UnitTests.csproj", "{E9BFC3CF-48E1-53F4-6601-4DF928446F51}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.Java.Selenium", "Expressium.CodeGenerators.Java.Selenium\Expressium.CodeGenerators.Java.Selenium.csproj", "{B2345678-C345-D456-E567-F6789012345A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.Java.Selenium.UnitTests", "Expressium.CodeGenerators.Java.Selenium.UnitTests\Expressium.CodeGenerators.Java.Selenium.UnitTests.csproj", "{C3456789-D456-E567-F678-A7890123456B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.Java.Playwright", "Expressium.CodeGenerators.Java.Playwright\Expressium.CodeGenerators.Java.Playwright.csproj", "{D4567890-E567-F678-A789-B8901234567C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Expressium.CodeGenerators.Java.Playwright.UnitTests", "Expressium.CodeGenerators.Java.Playwright.UnitTests\Expressium.CodeGenerators.Java.Playwright.UnitTests.csproj", "{E5678901-F678-A789-B890-C9012345678D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +83,22 @@ Global {E9BFC3CF-48E1-53F4-6601-4DF928446F51}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9BFC3CF-48E1-53F4-6601-4DF928446F51}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9BFC3CF-48E1-53F4-6601-4DF928446F51}.Release|Any CPU.Build.0 = Release|Any CPU + {B2345678-C345-D456-E567-F6789012345A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2345678-C345-D456-E567-F6789012345A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2345678-C345-D456-E567-F6789012345A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2345678-C345-D456-E567-F6789012345A}.Release|Any CPU.Build.0 = Release|Any CPU + {C3456789-D456-E567-F678-A7890123456B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3456789-D456-E567-F678-A7890123456B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3456789-D456-E567-F678-A7890123456B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3456789-D456-E567-F678-A7890123456B}.Release|Any CPU.Build.0 = Release|Any CPU + {D4567890-E567-F678-A789-B8901234567C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4567890-E567-F678-A789-B8901234567C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4567890-E567-F678-A789-B8901234567C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4567890-E567-F678-A789-B8901234567C}.Release|Any CPU.Build.0 = Release|Any CPU + {E5678901-F678-A789-B890-C9012345678D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5678901-F678-A789-B890-C9012345678D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5678901-F678-A789-B890-C9012345678D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5678901-F678-A789-B890-C9012345678D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE