diff --git a/TestWare.sln b/TestWare.sln index 94e8bd89..56ee7b42 100644 --- a/TestWare.sln +++ b/TestWare.sln @@ -40,13 +40,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Reporting", "Reporting", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Engines.Selenoid", "src\Engines\TestWare.Engines.Selenoid\TestWare.Engines.Selenoid.csproj", "{0B7E3DFE-AB55-4C0C-81C6-6A6F517475EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestWare.Samples.Selenoid.Web", "samples\TestWare.Samples.Selenoid.Web\TestWare.Samples.Selenoid.Web.csproj", "{672C5D48-DD50-4AA3-8974-50B95746EA07}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Samples.Selenoid.Web", "samples\TestWare.Samples.Selenoid.Web\TestWare.Samples.Selenoid.Web.csproj", "{672C5D48-DD50-4AA3-8974-50B95746EA07}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Engines.MongoDB", "src\Engines\TestWare.Engines.MongoDB\TestWare.Engines.MongoDB.csproj", "{4DFC2BE5-D3EF-4F39-AAD4-B8213DE92A11}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestWare.Samples.MongoDB", "samples\TestWare.Samples.MongoDB\TestWare.Samples.MongoDB.csproj", "{5378DE68-675E-440D-AAA9-7D3AF8AA680E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Samples.MongoDB", "samples\TestWare.Samples.MongoDB\TestWare.Samples.MongoDB.csproj", "{5378DE68-675E-440D-AAA9-7D3AF8AA680E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestWare.AllureReport", "src\Core\TestWare.AllureReport\TestWare.AllureReport.csproj", "{91F2B723-A68B-4711-969B-89897B3C6161}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.AllureReport", "src\Core\TestWare.AllureReport\TestWare.AllureReport.csproj", "{91F2B723-A68B-4711-969B-89897B3C6161}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWare.Engines.Common", "src\Engines\TestWare.Engines.Common\TestWare.Engines.Common\TestWare.Engines.Common.csproj", "{FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -114,6 +116,10 @@ Global {91F2B723-A68B-4711-969B-89897B3C6161}.Debug|Any CPU.Build.0 = Debug|Any CPU {91F2B723-A68B-4711-969B-89897B3C6161}.Release|Any CPU.ActiveCfg = Release|Any CPU {91F2B723-A68B-4711-969B-89897B3C6161}.Release|Any CPU.Build.0 = Release|Any CPU + {FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -137,6 +143,7 @@ Global {4DFC2BE5-D3EF-4F39-AAD4-B8213DE92A11} = {A2E4E1F7-CB61-48DC-AA38-A74F7DC74CA2} {5378DE68-675E-440D-AAA9-7D3AF8AA680E} = {58B1446D-98A3-46A2-A668-305F0170B39F} {91F2B723-A68B-4711-969B-89897B3C6161} = {DCCEF363-0EBE-46EA-B02B-CD59010626F6} + {FFD6A200-D2F1-4CBE-8FDC-320C7839AAB9} = {A2E4E1F7-CB61-48DC-AA38-A74F7DC74CA2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4F88CB24-23C8-4E0E-8B83-29023C1642B8} diff --git a/samples/TestWare.Samples.MongoDB/TestWare.Samples.MongoDB.csproj b/samples/TestWare.Samples.MongoDB/TestWare.Samples.MongoDB.csproj index 5f7c44b4..4319e2de 100644 --- a/samples/TestWare.Samples.MongoDB/TestWare.Samples.MongoDB.csproj +++ b/samples/TestWare.Samples.MongoDB/TestWare.Samples.MongoDB.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Engines/TestWare.Engines.Appium/AppiumManager.cs b/src/Engines/TestWare.Engines.Appium/AppiumManager.cs index b044a99a..637b7b25 100644 --- a/src/Engines/TestWare.Engines.Appium/AppiumManager.cs +++ b/src/Engines/TestWare.Engines.Appium/AppiumManager.cs @@ -68,7 +68,7 @@ public string CollectEvidence(string destinationPath, string evidenceName) } var screenshot = ((ITakesScreenshot)appiumDriver).GetScreenshot(); - screenshot.SaveAsFile(Path.Combine(destinationPath, $"{evidenceName}.png"), ScreenshotImageFormat.Png); + screenshot.SaveAsFile(Path.Combine(destinationPath, $"{evidenceName}.png")); } catch { diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/AbstractFindsByAttribute.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/AbstractFindsByAttribute.cs similarity index 99% rename from src/Engines/TestWare.Engines.Selenium/Extras/AbstractFindsByAttribute.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/AbstractFindsByAttribute.cs index 0f1f81da..828a5701 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/AbstractFindsByAttribute.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/AbstractFindsByAttribute.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Base class for attributes to mark elements with methods by which to find a corresponding element on the page. diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/ByAll.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByAll.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenoid/Extras/ByAll.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByAll.cs index 8316c44a..2790fa5c 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/ByAll.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByAll.cs @@ -5,7 +5,7 @@ using System.Text; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Mechanism used to locate elements within a document using a series of lookups. This class will diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/ByChained.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByChained.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenoid/Extras/ByChained.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByChained.cs index a7dd1a72..e3acc07e 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/ByChained.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByChained.cs @@ -5,7 +5,7 @@ using System.Text; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Mechanism used to locate elements within a document using a series of other lookups. This class diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/ByFactory.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByFactory.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenoid/Extras/ByFactory.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByFactory.cs index b37ad2fb..b2f2c9f7 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/ByFactory.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByFactory.cs @@ -3,7 +3,7 @@ using System.Reflection; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Provides instances of the object to the attributes. diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/ByIdOrName.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByIdOrName.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenium/Extras/ByIdOrName.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByIdOrName.cs index 36e875e1..9d2b2343 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/ByIdOrName.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ByIdOrName.cs @@ -3,7 +3,7 @@ using System.Globalization; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Finds element when the id or the name attribute has the specified value. diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/CacheLookupAttribute.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/CacheLookupAttribute.cs similarity index 87% rename from src/Engines/TestWare.Engines.Selenium/Extras/CacheLookupAttribute.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/CacheLookupAttribute.cs index 95e1a73f..07c5edf0 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/CacheLookupAttribute.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/CacheLookupAttribute.cs @@ -1,5 +1,5 @@  -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Marks the element so that lookups to the browser page are cached. This class cannot be inherited. diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/DefaultElementLocator.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultElementLocator.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenoid/Extras/DefaultElementLocator.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultElementLocator.cs index 33e735a6..d422341d 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/DefaultElementLocator.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultElementLocator.cs @@ -3,7 +3,7 @@ using System.Collections.ObjectModel; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// A default locator for elements for use with the . This locator diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/DefaultPageObjectMemberDecorator.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultPageObjectMemberDecorator.cs similarity index 99% rename from src/Engines/TestWare.Engines.Selenium/Extras/DefaultPageObjectMemberDecorator.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultPageObjectMemberDecorator.cs index 7fd57faf..4ab22a84 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/DefaultPageObjectMemberDecorator.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/DefaultPageObjectMemberDecorator.cs @@ -5,7 +5,7 @@ using OpenQA.Selenium; using TestWare.Engines.Selenium.Extras.MemberBuilders; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Default decorator determining how members of a class which represent elements in a Page Object diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/ExpectedConditions.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ExpectedConditions.cs similarity index 99% rename from src/Engines/TestWare.Engines.Selenium/Extras/ExpectedConditions.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ExpectedConditions.cs index 7a80173a..040bfa97 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/ExpectedConditions.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/ExpectedConditions.cs @@ -3,7 +3,7 @@ using System.Text.RegularExpressions; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Supplies a set of common conditions that can be waited for using . @@ -73,7 +73,7 @@ public static Func UrlMatches(string regex) return (driver) => { var currentUrl = driver.Url; - var pattern = new Regex(regex, RegexOptions.IgnoreCase); + var pattern = new Regex(regex, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10)); var match = pattern.Match(currentUrl); return match.Success; }; diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/FindsByAllAttribute.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAllAttribute.cs similarity index 95% rename from src/Engines/TestWare.Engines.Selenium/Extras/FindsByAllAttribute.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAllAttribute.cs index 168bb0f2..bd88807c 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/FindsByAllAttribute.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAllAttribute.cs @@ -1,5 +1,5 @@  -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Marks elements to indicate that found elements should match the criteria of diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/FindsByAttribute.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAttribute.cs similarity index 98% rename from src/Engines/TestWare.Engines.Selenium/Extras/FindsByAttribute.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAttribute.cs index 8853dc6e..cb3467b8 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/FindsByAttribute.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsByAttribute.cs @@ -3,7 +3,7 @@ using System.ComponentModel; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Marks program elements with methods by which to find a corresponding element on the page. Used diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/FindsBySequenceAttribute.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsBySequenceAttribute.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenium/Extras/FindsBySequenceAttribute.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsBySequenceAttribute.cs index 92831391..ed1b14c0 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/FindsBySequenceAttribute.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/FindsBySequenceAttribute.cs @@ -1,6 +1,6 @@  -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Marks elements to indicate that each on the field or diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/How.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/How.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenoid/Extras/How.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/How.cs index 25e59507..e3034062 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/How.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/How.cs @@ -1,5 +1,5 @@  -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Provides the lookup methods for the FindsBy attribute (for using in PageObjects) diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/IElementLocator.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IElementLocator.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenoid/Extras/IElementLocator.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IElementLocator.cs index 446e6b69..8fe81455 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/IElementLocator.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IElementLocator.cs @@ -2,7 +2,7 @@ using System.Collections.ObjectModel; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Interface describing how elements are to be located by a . diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/IPageObjectMemberDecorator.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IPageObjectMemberDecorator.cs similarity index 94% rename from src/Engines/TestWare.Engines.Selenium/Extras/IPageObjectMemberDecorator.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IPageObjectMemberDecorator.cs index 9c45442d..14e3246b 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/IPageObjectMemberDecorator.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/IPageObjectMemberDecorator.cs @@ -2,7 +2,7 @@ using System.Reflection; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Interface describing how members of a class which represent elements in a Page Object diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/IMemberBuilder.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/IMemberBuilder.cs similarity index 97% rename from src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/IMemberBuilder.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/IMemberBuilder.cs index 59ad7312..fd0678ea 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/IMemberBuilder.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/IMemberBuilder.cs @@ -18,6 +18,7 @@ using System.Diagnostics.CodeAnalysis; using OpenQA.Selenium; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenium.Extras.MemberBuilders; diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WebElementBuilder.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WebElementBuilder.cs similarity index 97% rename from src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WebElementBuilder.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WebElementBuilder.cs index 770b365c..e6e6d462 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WebElementBuilder.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WebElementBuilder.cs @@ -18,6 +18,7 @@ using System.Diagnostics.CodeAnalysis; using OpenQA.Selenium; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenium.Extras.MemberBuilders; diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WebElementListBuilder.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WebElementListBuilder.cs similarity index 100% rename from src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WebElementListBuilder.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WebElementListBuilder.cs diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementBuilder.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementBuilder.cs similarity index 94% rename from src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementBuilder.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementBuilder.cs index 406245ea..750aa20e 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementBuilder.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementBuilder.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using OpenQA.Selenium; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenium.Extras.MemberBuilders; diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementListBuilder.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementListBuilder.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementListBuilder.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementListBuilder.cs index 8b9f088c..175bfa9a 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/MemberBuilders/WrappedElementListBuilder.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/MemberBuilders/WrappedElementListBuilder.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using OpenQA.Selenium; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenium.Extras.MemberBuilders; diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/PageFactory.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/PageFactory.cs similarity index 99% rename from src/Engines/TestWare.Engines.Selenoid/Extras/PageFactory.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/PageFactory.cs index be394019..4fc46dfb 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/PageFactory.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/PageFactory.cs @@ -3,7 +3,7 @@ using System.Reflection; using OpenQA.Selenium; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Provides the ability to produce Page Objects modeling a page. This class cannot be inherited. diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/RetryingElementLocator.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/RetryingElementLocator.cs similarity index 99% rename from src/Engines/TestWare.Engines.Selenium/Extras/RetryingElementLocator.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/RetryingElementLocator.cs index 3acbf4a1..86859b52 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/RetryingElementLocator.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/RetryingElementLocator.cs @@ -3,7 +3,7 @@ using System.Collections.ObjectModel; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// A locator for elements for use with the that retries locating diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WebDriverObjectProxy.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebDriverObjectProxy.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenium/Extras/WebDriverObjectProxy.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebDriverObjectProxy.cs index 30885e29..28f46984 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WebDriverObjectProxy.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebDriverObjectProxy.cs @@ -1,6 +1,6 @@ using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Represents a base proxy class for objects used with the PageFactory. diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementEnumerable.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementEnumerable.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenium/Extras/WebElementEnumerable.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementEnumerable.cs index 0e27ede9..2841bf49 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementEnumerable.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementEnumerable.cs @@ -1,6 +1,6 @@ using TestWare.Engines.Selenium.Extras; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Due to Linq optimized execution in dotnet core for IList, some methods lead to multiple elements retrieval. diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementListProxy.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementListProxy.cs similarity index 97% rename from src/Engines/TestWare.Engines.Selenium/Extras/WebElementListProxy.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementListProxy.cs index 9d3376ba..92834ab6 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementListProxy.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementListProxy.cs @@ -3,7 +3,7 @@ using System.Collections; using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Represents a proxy class for a list of elements to be used with the PageFactory. diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementProxy.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementProxy.cs similarity index 94% rename from src/Engines/TestWare.Engines.Selenoid/Extras/WebElementProxy.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementProxy.cs index 96ec06b8..5c71fde4 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementProxy.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WebElementProxy.cs @@ -5,7 +5,7 @@ using OpenQA.Selenium.Interactions.Internal; using OpenQA.Selenium.Internal; -namespace TestWare.Engines.Selenoid.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Intercepts the request to a single @@ -63,9 +63,6 @@ public IWebElement WrappedElement public string GetCssValue(string propertyName) => WrappedElement.GetCssValue(propertyName); - [Obsolete ("Deprecated on IWebElement")] - public string GetProperty(string propertyName) => WrappedElement.GetProperty(propertyName); - public void SendKeys(string text) => WrappedElement.SendKeys(text); public void Submit() => WrappedElement.Submit(); diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementFactory.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementFactory.cs similarity index 96% rename from src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementFactory.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementFactory.cs index 55906ade..5a663dbd 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementFactory.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementFactory.cs @@ -1,6 +1,6 @@ using OpenQA.Selenium; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; internal static class WrapsElementFactory { diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementListProxy.cs b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementListProxy.cs similarity index 97% rename from src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementListProxy.cs rename to src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementListProxy.cs index 8e9cc2e3..fc9736d0 100644 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WrapsElementListProxy.cs +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/Extras/WrapsElementListProxy.cs @@ -4,7 +4,7 @@ using OpenQA.Selenium; using TestWare.Engines.Selenium.Extras; -namespace TestWare.Engines.Selenium.Extras; +namespace TestWare.Engines.Common.Extras; /// /// Represents a proxy class for a list of elements to be used with the PageFactory. diff --git a/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/TestWare.Engines.Common.csproj b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/TestWare.Engines.Common.csproj new file mode 100644 index 00000000..bec319ca --- /dev/null +++ b/src/Engines/TestWare.Engines.Common/TestWare.Engines.Common/TestWare.Engines.Common.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/ByAll.cs b/src/Engines/TestWare.Engines.Selenium/Extras/ByAll.cs deleted file mode 100644 index 7dda4a55..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/ByAll.cs +++ /dev/null @@ -1,109 +0,0 @@ -#nullable enable - -using System.Collections.ObjectModel; -using System.Globalization; -using System.Text; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Mechanism used to locate elements within a document using a series of lookups. This class will -/// find all DOM elements that matches all of the locators in sequence, e.g. -/// -/// -/// The following code will find all elements that match by1 and then all elements that also match by2. -/// -/// driver.findElements(new ByAll(by1, by2)) -/// -/// This means that the list of elements returned may not be in document order. -/// > -public class ByAll : By -{ - private readonly By[] bys; - - /// - /// Initializes a new instance of the class with one or more objects. - /// - /// One or more references - public ByAll(params By[] bys) - { - this.bys = bys; - } - - /// - /// Find a single element. - /// - /// Context used to find the element. - /// The element that matches - public override IWebElement FindElement(ISearchContext context) - { - var elements = this.FindElements(context); - if (elements.Count == 0) - { - throw new NoSuchElementException("Cannot locate an element using " + this.ToString()); - } - - return elements[0]; - } - - /// - /// Finds many elements - /// - /// Context used to find the element. - /// A readonly collection of elements that match. - public override ReadOnlyCollection FindElements(ISearchContext context) - { - if (this.bys.Length == 0) - { - return new List().AsReadOnly(); - } - - IEnumerable? elements = null; - foreach (By by in this.bys) - { - ReadOnlyCollection foundElements = by.FindElements(context); - if (foundElements.Count == 0) - { - // Optimization: If at any time a find returns no elements, the - // only possible result for find-all is an empty collection. - return new List().AsReadOnly(); - } - - if (elements == null) - { - elements = foundElements; - } - else - { - elements = elements.Intersect(by.FindElements(context)); - } - } - if (elements == null) - { - elements = new List().AsReadOnly(); - } - - return elements.ToList().AsReadOnly(); - } - - /// - /// Writes out a comma separated list of the objects used in the chain. - /// - /// Converts the value of this instance to a - public override string ToString() - { - StringBuilder stringBuilder = new StringBuilder(); - foreach (By by in this.bys) - { - if (stringBuilder.Length > 0) - { - stringBuilder.Append(','); - } - - stringBuilder.Append(by); - } - - return string.Format(CultureInfo.InvariantCulture, "By.All([{0}])", stringBuilder.ToString()); - } -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/ByChained.cs b/src/Engines/TestWare.Engines.Selenium/Extras/ByChained.cs deleted file mode 100644 index d302c713..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/ByChained.cs +++ /dev/null @@ -1,111 +0,0 @@ -#nullable enable - -using System.Collections.ObjectModel; -using System.Globalization; -using System.Text; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Mechanism used to locate elements within a document using a series of other lookups. This class -/// will find all DOM elements that matches each of the locators in sequence -/// -/// -/// The following code will will find all elements that match by2 and appear under an element that matches -/// by1. -/// -/// driver.findElements(new ByChained(by1, by2)) -/// -/// -public class ByChained : By -{ - private readonly By[] bys; - - /// - /// Initializes a new instance of the class with one or more objects. - /// - /// One or more references - public ByChained(params By[] bys) - { - this.bys = bys; - } - - /// - /// Find a single element. - /// - /// Context used to find the element. - /// The element that matches - public override IWebElement FindElement(ISearchContext context) - { - ReadOnlyCollection elements = this.FindElements(context); - if (elements.Count == 0) - { - throw new NoSuchElementException("Cannot locate an element using " + this.ToString()); - } - - return elements[0]; - } - - /// - /// Finds many elements - /// - /// Context used to find the element. - /// A readonly collection of elements that match. - public override ReadOnlyCollection FindElements(ISearchContext context) - { - if (this.bys.Length == 0) - { - return new List().AsReadOnly(); - } - - List? elems = null; - foreach (By by in this.bys) - { - List newElems = new List(); - - if (elems == null) - { - newElems.AddRange(by.FindElements(context)); - } - else - { - foreach (IWebElement elem in elems) - { - try - { - newElems.AddRange(elem.FindElements(by)); - } - catch (StaleElementReferenceException) - { - // Elements has gone stale during search. - } - } - } - - elems = newElems; - } - - return elems!.AsReadOnly(); - } - - /// - /// Writes out a comma separated list of the objects used in the chain. - /// - /// Converts the value of this instance to a - public override string ToString() - { - StringBuilder stringBuilder = new StringBuilder(); - foreach (By by in this.bys) - { - if (stringBuilder.Length > 0) - { - stringBuilder.Append(','); - } - - stringBuilder.Append(by); - } - - return string.Format(CultureInfo.InvariantCulture, "By.Chained([{0}])", stringBuilder.ToString()); - } -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/ByFactory.cs b/src/Engines/TestWare.Engines.Selenium/Extras/ByFactory.cs deleted file mode 100644 index 3cda7f11..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/ByFactory.cs +++ /dev/null @@ -1,64 +0,0 @@ -#nullable enable -using System.Globalization; -using System.Reflection; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Provides instances of the object to the attributes. -/// -internal static class ByFactory -{ - /// - /// Gets an instance of the class based on the specified attribute. - /// - /// The describing how to find the element. - /// An instance of the class. - public static By From(FindsByAttribute attribute) - { - var how = attribute.How; - var usingValue = attribute.Using; - switch (how) - { - case How.Id: - return By.Id(usingValue); - case How.Name: - return By.Name(usingValue); - case How.TagName: - return By.TagName(usingValue); - case How.ClassName: - return By.ClassName(usingValue); - case How.CssSelector: - return By.CssSelector(usingValue); - case How.LinkText: - return By.LinkText(usingValue); - case How.PartialLinkText: - return By.PartialLinkText(usingValue); - case How.XPath: - return By.XPath(usingValue); - case How.Custom: - if (attribute.CustomFinderType == null) - { - throw new ArgumentException("Cannot use How.Custom without supplying a custom finder type"); - } - - if (!attribute.CustomFinderType.IsSubclassOf(typeof(By))) - { - throw new ArgumentException("Custom finder type must be a descendent of the By class"); - } - - ConstructorInfo? ctor = attribute.CustomFinderType.GetConstructor(new Type[] { typeof(string) }); - if (ctor == null) - { - throw new ArgumentException("Custom finder type must expose a public constructor with a string argument"); - } - - By finder = (By)ctor.Invoke(new object?[] { usingValue }); - - return finder; - } - - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Did not know how to construct How from how {0}, using {1}", how, usingValue)); - } -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/DefaultElementLocator.cs b/src/Engines/TestWare.Engines.Selenium/Extras/DefaultElementLocator.cs deleted file mode 100644 index cb9cd5fe..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/DefaultElementLocator.cs +++ /dev/null @@ -1,79 +0,0 @@ -#nullable enable - -using System.Collections.ObjectModel; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// A default locator for elements for use with the . This locator -/// implements no retry logic for elements not being found, nor for elements being stale. -/// -public class DefaultElementLocator : IElementLocator -{ - - /// - /// Initializes a new instance of the class. - /// - /// The used by this locator - /// to locate elements. - public DefaultElementLocator(ISearchContext searchContext) - { - this.SearchContext = searchContext; - } - - /// - /// Gets the to be used in locating elements. - /// - public ISearchContext SearchContext { get; } - - /// - /// Locates an element using the given list of criteria. - /// - /// The list of methods by which to search for the element. - /// An which is the first match under the desired criteria. - public IWebElement LocateElement(IEnumerable bys) - { - if (bys == null) - { - throw new ArgumentNullException(nameof(bys), "List of criteria may not be null"); - } - - string? errorString = null; - foreach (var by in bys) - { - try - { - return this.SearchContext.FindElement(by); - } - catch (NoSuchElementException) - { - errorString = (errorString == null ? "Could not find element by: " : errorString + ", or: ") + by; - } - } - - throw new NoSuchElementException(errorString); - } - - /// - /// Locates a list of elements using the given list of criteria. - /// - /// The list of methods by which to search for the elements. - /// A list of all elements which match the desired criteria. - public ReadOnlyCollection LocateElements(IEnumerable bys) - { - if (bys == null) - { - throw new ArgumentNullException(nameof(bys), "List of criteria may not be null"); - } - - List collection = new List(); - foreach (var by in bys) - { - ReadOnlyCollection list = this.SearchContext.FindElements(by); - collection.AddRange(list); - } - - return collection.AsReadOnly(); - } -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/How.cs b/src/Engines/TestWare.Engines.Selenium/Extras/How.cs deleted file mode 100644 index 4ff44fce..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/How.cs +++ /dev/null @@ -1,53 +0,0 @@ - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Provides the lookup methods for the FindsBy attribute (for using in PageObjects) -/// -public enum How -{ - /// - /// Finds by - /// - Id, - - /// - /// Finds by - /// - Name, - - /// - /// Finds by - /// - TagName, - - /// - /// Finds by - /// - ClassName, - - /// - /// Finds by - /// - CssSelector, - - /// - /// Finds by - /// - LinkText, - - /// - /// Finds by - /// - PartialLinkText, - - /// - /// Finds by - /// - XPath, - - /// - /// Finds by a custom implementation. - /// - Custom -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/IElementLocator.cs b/src/Engines/TestWare.Engines.Selenium/Extras/IElementLocator.cs deleted file mode 100644 index bbd210b5..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/IElementLocator.cs +++ /dev/null @@ -1,35 +0,0 @@ - -using System.Collections.ObjectModel; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Interface describing how elements are to be located by a . -/// -/// -/// A locator must always contain a way to retrieve the to -/// use in locating elements. In practice, this will usually be implemented by passing -/// the context in via a constructor. -/// -public interface IElementLocator -{ - /// - /// Gets the to be used in locating elements. - /// - ISearchContext SearchContext { get; } - - /// - /// Locates an element using the given list of criteria. - /// - /// The list of methods by which to search for the element. - /// An which is the first match under the desired criteria. - IWebElement LocateElement(IEnumerable bys); - - /// - /// Locates a list of elements using the given list of criteria. - /// - /// The list of methods by which to search for the elements. - /// A list of all elements which match the desired criteria. - ReadOnlyCollection LocateElements(IEnumerable bys); -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/PageFactory.cs b/src/Engines/TestWare.Engines.Selenium/Extras/PageFactory.cs deleted file mode 100644 index 391fda02..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/PageFactory.cs +++ /dev/null @@ -1,202 +0,0 @@ -#nullable enable - -using System.Reflection; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Provides the ability to produce Page Objects modeling a page. This class cannot be inherited. -/// -public class PageFactory -{ - /// - /// Initializes a new instance of the class. - /// Private constructor prevents a default instance from being created. - /// - protected PageFactory() - { - } - - /// - /// Initializes the elements in the Page Object with the given type. - /// - /// The of the Page Object class. - /// The instance used to populate the page. - /// An instance of the Page Object class with the elements initialized. - /// - /// The class used in the argument must have a public constructor - /// that takes a single argument of type . This helps to enforce - /// best practices of the Page Object pattern, and encapsulates the driver into the Page - /// Object so that it can have no external WebDriver dependencies. - /// - /// - /// thrown if no constructor to the class can be found with a single IWebDriver argument - /// -or- - /// if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static T InitElements(IWebDriver driver) - { - return InitElements(new DefaultElementLocator(driver)); - } - - /// - /// Initializes the elements in the Page Object with the given type. - /// - /// The of the Page Object class. - /// The implementation that - /// determines how elements are located. - /// An instance of the Page Object class with the elements initialized. - /// - /// The class used in the argument must have a public constructor - /// that takes a single argument of type . This helps to enforce - /// best practices of the Page Object pattern, and encapsulates the driver into the Page - /// Object so that it can have no external WebDriver dependencies. - /// - /// - /// thrown if no constructor to the class can be found with a single IWebDriver argument - /// -or- - /// if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static T InitElements(IElementLocator locator) - { - Type pageClassType = typeof(T); - ConstructorInfo? ctor = pageClassType.GetConstructor(new Type[] { typeof(IWebDriver) }); - if (ctor == null) - { - throw new ArgumentException("No constructor for the specified class containing a single argument of type IWebDriver can be found"); - } - - if (locator == null) - { - throw new ArgumentNullException(nameof(locator), "locator cannot be null"); - } - - if (!(locator.SearchContext is IWebDriver driver)) - { - throw new ArgumentException("The search context of the element locator must implement IWebDriver", nameof(locator)); - } - - var page = (T)ctor.Invoke(new object[] { driver }); - InitElements(page, locator); - return page; - } - - /// - /// Initializes the elements in the Page Object. - /// - /// The driver used to find elements on the page. - /// The Page Object to be populated with elements. - /// - /// thrown if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static void InitElements(ISearchContext driver, object page) - { - InitElements(page, new DefaultElementLocator(driver)); - } - - /// - /// Initializes the elements in the Page Object. - /// - /// The driver used to find elements on the page. - /// The Page Object to be populated with elements. - /// The implementation that - /// determines how Page Object members representing elements are discovered and populated. - /// - /// thrown if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static void InitElements(ISearchContext driver, object page, IPageObjectMemberDecorator decorator) - { - InitElements(page, new DefaultElementLocator(driver), decorator); - } - - /// - /// Initializes the elements in the Page Object. - /// - /// The Page Object to be populated with elements. - /// The implementation that - /// determines how elements are located. - /// - /// thrown if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static void InitElements(object page, IElementLocator locator) - { - InitElements(page, locator, new DefaultPageObjectMemberDecorator()); - } - - /// - /// Initializes the elements in the Page Object. - /// - /// The Page Object to be populated with elements. - /// The implementation that - /// determines how elements are located. - /// The implementation that - /// determines how Page Object members representing elements are discovered and populated. - /// - /// thrown if a field or property decorated with the is not of type - /// or IList{IWebElement}. - /// - public static void InitElements(object page, IElementLocator locator, IPageObjectMemberDecorator decorator) - { - if (page == null) - { - throw new ArgumentNullException(nameof(page), "page cannot be null"); - } - - if (locator == null) - { - throw new ArgumentNullException(nameof(locator), "locator cannot be null"); - } - - if (decorator == null) - { - throw new ArgumentNullException(nameof(locator), "decorator cannot be null"); - } - - if (locator.SearchContext == null) - { - throw new ArgumentException("The SearchContext of the locator object cannot be null", nameof(locator)); - } - - const BindingFlags PublicBindingOptions = BindingFlags.Instance | BindingFlags.Public; - const BindingFlags NonPublicBindingOptions = BindingFlags.Instance | BindingFlags.NonPublic; - - // Get a list of all of the fields and properties (public and non-public [private, protected, etc.]) - // in the passed-in page object. Note that we walk the inheritance tree to get superclass members. - Type? type = page.GetType(); - var members = new List(); - members.AddRange(type.GetFields(PublicBindingOptions)); - members.AddRange(type.GetProperties(PublicBindingOptions)); - while (type != null) - { - members.AddRange(type.GetFields(NonPublicBindingOptions)); - members.AddRange(type.GetProperties(NonPublicBindingOptions)); - type = type.BaseType; - } - - foreach (var member in members) - { - // Examine each member, and if the decorator returns a non-null object, - // set the value of that member to the decorated object. - object? decoratedValue = decorator.Decorate(member, locator); - if (decoratedValue == null) - { - continue; - } - - if (member is FieldInfo field) - { - field.SetValue(page, decoratedValue); - } - else if (member is PropertyInfo property && property.CanWrite) - { - property.SetValue(page, decoratedValue, null); - } - } - } -} diff --git a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementProxy.cs b/src/Engines/TestWare.Engines.Selenium/Extras/WebElementProxy.cs deleted file mode 100644 index 3448a478..00000000 --- a/src/Engines/TestWare.Engines.Selenium/Extras/WebElementProxy.cs +++ /dev/null @@ -1,96 +0,0 @@ -#nullable enable -using System.Collections.ObjectModel; -using System.Drawing; -using OpenQA.Selenium; -using OpenQA.Selenium.Interactions.Internal; -using OpenQA.Selenium.Internal; - -namespace TestWare.Engines.Selenium.Extras; - -/// -/// Intercepts the request to a single -/// -internal class WebElementProxy : WebDriverObjectProxy, IWrapsElement, IWebElement, ILocatable, IFindsElement -{ - private IWebElement? cachedElement; - - public WebElementProxy(IElementLocator locator, IEnumerable bys, bool cache) - : base(locator, bys, cache) - { - } - - /// - /// Gets the IWebElement object this proxy represents, returning a cached one if requested. - /// - public IWebElement WrappedElement - { - get - { - if (!this.Cache || this.cachedElement == null) - { - this.cachedElement = this.Locator.LocateElement(this.Bys); - } - - return this.cachedElement; - } - } - - #region Forwarded WrappedElement calls - - public string TagName => WrappedElement.TagName; - - public string Text => WrappedElement.Text; - - public bool Enabled => WrappedElement.Enabled; - - public bool Selected => WrappedElement.Selected; - - public Point Location => WrappedElement.Location; - - public Size Size => WrappedElement.Size; - - public bool Displayed => WrappedElement.Displayed; - - public void Clear() => WrappedElement.Clear(); - - public void Click() => WrappedElement.Click(); - - public IWebElement FindElement(By by) => WrappedElement.FindElement(by); - - public ReadOnlyCollection FindElements(By by) => WrappedElement.FindElements(by); - - public string GetAttribute(string attributeName) => WrappedElement.GetAttribute(attributeName); - - public string GetCssValue(string propertyName) => WrappedElement.GetCssValue(propertyName); - - [Obsolete ("Deprecated on IWebElement")] - public string GetProperty(string propertyName) => WrappedElement.GetProperty(propertyName); - - public void SendKeys(string text) => WrappedElement.SendKeys(text); - - public void Submit() => WrappedElement.Submit(); - - public Point LocationOnScreenOnceScrolledIntoView - => ((ILocatable)WrappedElement).LocationOnScreenOnceScrolledIntoView; - - public ICoordinates Coordinates - => ((ILocatable)WrappedElement).Coordinates; - - public override int GetHashCode() => WrappedElement.GetHashCode(); - - public override bool Equals(object? obj) => WrappedElement.Equals(obj); - - public IWebElement FindElement(string mechanism, string value) - => ((IFindsElement)WrappedElement).FindElement(mechanism, value); - - public ReadOnlyCollection FindElements(string mechanism, string value) - => ((IFindsElement)WrappedElement).FindElements(mechanism, value); - - public string GetDomAttribute(string attributeName) => WrappedElement.GetDomAttribute(attributeName); - - public string GetDomProperty(string propertyName) => WrappedElement.GetDomProperty(propertyName); - - public ISearchContext GetShadowRoot() => WrappedElement.GetShadowRoot(); - - #endregion Forwarded WrappedElement calls -} diff --git a/src/Engines/TestWare.Engines.Selenium/SeleniumManager.cs b/src/Engines/TestWare.Engines.Selenium/SeleniumManager.cs index 082e6029..164bfbb1 100644 --- a/src/Engines/TestWare.Engines.Selenium/SeleniumManager.cs +++ b/src/Engines/TestWare.Engines.Selenium/SeleniumManager.cs @@ -94,7 +94,7 @@ public string CollectEvidence(string destinationPath, string evidenceName) { var instanceName = ContainerManager.GetNameFromInstance(webDriver); var ss = ((ITakesScreenshot)webDriver).GetScreenshot(); - ss.SaveAsFile(Path.Combine(destinationPath, $"{evidenceName} - {instanceName}.png"), ScreenshotImageFormat.Png); + ss.SaveAsFile(Path.Combine(destinationPath, $"{evidenceName} - {instanceName}.png")); } catch (WebDriverException) { } diff --git a/src/Engines/TestWare.Engines.Selenium/TestWare.Engines.Selenium.csproj b/src/Engines/TestWare.Engines.Selenium/TestWare.Engines.Selenium.csproj index 36441f58..c0914bb9 100644 --- a/src/Engines/TestWare.Engines.Selenium/TestWare.Engines.Selenium.csproj +++ b/src/Engines/TestWare.Engines.Selenium/TestWare.Engines.Selenium.csproj @@ -7,11 +7,12 @@ - + + diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/AbstractFindsByAttribute.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/AbstractFindsByAttribute.cs deleted file mode 100644 index cb7f20f2..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/AbstractFindsByAttribute.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System.ComponentModel; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Base class for attributes to mark elements with methods by which to find a corresponding element on the page. -/// In order to define custom FindsBy attribute, inherit from this class and implement Finder property. -/// -[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public abstract class AbstractFindsByAttribute : Attribute, IComparable -{ - /// - /// Gets an explicit object to find by. - /// - public abstract By Finder { get; } - - /// - /// Gets or sets a value indicating where this attribute should be evaluated relative to other instances - /// of this attribute decorating the same class member. - /// - [DefaultValue(0)] - public int Priority { get; set; } - - /// - /// Determines if two instances are equal. - /// - /// One instance to compare. - /// The other instance to compare. - /// if the two instances are equal; otherwise, . - public static bool operator ==(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - // If both are null, or both are same instance, return true. - if (ReferenceEquals(one, two)) - { - return true; - } - - // If one is null, but not both, return false. - if (one is null || two is null) - { - return false; - } - - return one.Equals(two); - } - - /// - /// Determines if two instances are unequal. - /// s - /// One instance to compare. - /// The other instance to compare. - /// if the two instances are not equal; otherwise, . - public static bool operator !=(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - return !(one == two); - } - - /// - /// Determines if one instance is greater than another. - /// - /// One instance to compare. - /// The other instance to compare. - /// if the first instance is greater than the second; otherwise, . - - public static bool operator >(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - return one.CompareTo(two) > 0; - } - - public static bool operator >=(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - return one.CompareTo(two) >= 0; - } - - public static bool operator <=(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - return one.CompareTo(two) <= 0; - } - - /// - /// Determines if one instance is less than another. - /// - /// One instance to compare. - /// The other instance to compare. - /// if the first instance is less than the second; otherwise, . - public static bool operator <(AbstractFindsByAttribute one, AbstractFindsByAttribute two) - { - return one.CompareTo(two) < 0; - } - - /// - /// Compares the current instance with another object of the same type and returns an - /// integer that indicates whether the current instance precedes, follows, or occurs - /// in the same position in the sort order as the other object. - /// - /// An object to compare with this instance. - /// A value that indicates the relative order of the objects being compared. The return value has these meanings: - /// - /// ValueMeaning - /// Less than zeroThis instance precedes in the sort order. - /// ZeroThis instance occurs in the same position in the sort order as . - /// Greater than zeroThis instance follows in the sort order. - /// - /// - public int CompareTo(object obj) - { - if (obj == null) - { - throw new ArgumentNullException(nameof(obj), "Object to compare cannot be null"); - } - - AbstractFindsByAttribute? other = obj as AbstractFindsByAttribute ?? throw new ArgumentException("Object to compare must be a AbstractFindsByAttribute", nameof(obj)); - - if (Priority != other.Priority) - { - return Priority - other.Priority; - } - - return 0; - } - - /// - /// Determines whether the specified Object is equal - /// to the current Object. - /// - /// The Object to compare with the - /// current Object. - /// if the specified Object - /// is equal to the current Object; otherwise, - /// . - public override bool Equals(object obj) - { - if (obj == null) - { - return false; - } - - AbstractFindsByAttribute? other = obj as AbstractFindsByAttribute; - if (other == null) - { - return false; - } - - if (other.Priority != Priority) - { - return false; - } - - if (other.Finder != Finder) - { - return false; - } - - return true; - } - - /// - /// Serves as a hash function for a particular type. - /// - /// A hash code for the current Object. - public override int GetHashCode() - { - return Finder.GetHashCode(); - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/ByIdOrName.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/ByIdOrName.cs deleted file mode 100644 index 1816e508..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/ByIdOrName.cs +++ /dev/null @@ -1,72 +0,0 @@ - -using System.Collections.ObjectModel; -using System.Globalization; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Finds element when the id or the name attribute has the specified value. -/// -public class ByIdOrName : By -{ - private readonly string elementIdentifier = string.Empty; - private readonly By idFinder; - private readonly By nameFinder; - - /// - /// Initializes a new instance of the class. - /// - /// The ID or Name to use in finding the element. - public ByIdOrName(string elementIdentifier) - { - if (string.IsNullOrEmpty(elementIdentifier)) - { - throw new ArgumentException("element identifier cannot be null or the empty string", nameof(elementIdentifier)); - } - - this.elementIdentifier = elementIdentifier; - this.idFinder = By.Id(this.elementIdentifier); - this.nameFinder = By.Name(this.elementIdentifier); - } - - /// - /// Find a single element. - /// - /// Context used to find the element. - /// The element that matches - public override IWebElement FindElement(ISearchContext context) - { - try - { - return this.idFinder.FindElement(context); - } - catch (NoSuchElementException) - { - return this.nameFinder.FindElement(context); - } - } - - /// - /// Finds many elements - /// - /// Context used to find the element. - /// A readonly collection of elements that match. - public override ReadOnlyCollection FindElements(ISearchContext context) - { - List elements = new List(); - elements.AddRange(this.idFinder.FindElements(context)); - elements.AddRange(this.nameFinder.FindElements(context)); - - return elements.AsReadOnly(); - } - - /// - /// Writes out a description of this By object. - /// - /// Converts the value of this instance to a - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "ByIdOrName([{0}])", this.elementIdentifier); - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/CacheLookupAttribute.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/CacheLookupAttribute.cs deleted file mode 100644 index 7d9be172..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/CacheLookupAttribute.cs +++ /dev/null @@ -1,10 +0,0 @@ - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Marks the element so that lookups to the browser page are cached. This class cannot be inherited. -/// -[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)] -public sealed class CacheLookupAttribute : Attribute -{ -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/DefaultPageObjectMemberDecorator.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/DefaultPageObjectMemberDecorator.cs deleted file mode 100644 index 78dd05fe..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/DefaultPageObjectMemberDecorator.cs +++ /dev/null @@ -1,154 +0,0 @@ -#nullable enable - -using System.Collections.ObjectModel; -using System.Reflection; -using OpenQA.Selenium; -using TestWare.Engines.Selenoid.Extras.MemberBuilders; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Default decorator determining how members of a class which represent elements in a Page Object -/// are detected. -/// -public class DefaultPageObjectMemberDecorator : IPageObjectMemberDecorator -{ - private static readonly List _memberBuilders = new List { - new WebElementBuilder(), - new WebElementListBuilder(), - new WrappedElementBuilder(), - new WrappedElementListBuilder() - }; - - /// - /// Locates an element or list of elements for a Page Object member, and returns a - /// proxy object for the element or list of elements. - /// - /// The containing information about - /// a class's member. - /// The used to locate elements. - /// A transparent proxy to the WebDriver element object. - public virtual object? Decorate(MemberInfo member, IElementLocator locator) - { - FieldInfo? field = member as FieldInfo; - PropertyInfo? property = member as PropertyInfo; - - Type? targetType = null; - if (field != null) - { - targetType = field.FieldType; - } - - if (property != null && property.CanWrite) - { - targetType = property.PropertyType; - } - - if (targetType == null) - { - return null; - } - - IList bys = CreateLocatorList(member); - if (bys.Count > 0) - { - bool cache = ShouldCacheLookup(member); - return CreateObject(targetType, locator, bys, cache); - } - - return null; - } - - public virtual object CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache) - { - foreach (var builder in _memberBuilders) - { - if (builder.CreateObject(memberType, locator, bys, cache, out object? createdObject)) - { - return createdObject; - } - } - - throw new ArgumentException($"Type of member '{memberType.Name}' is not IWebElement or IList"); - } - - /// - /// Determines whether lookups on this member should be cached. - /// - /// The containing information about - /// the member of the Page Object class. - /// if lookups are to be cached; otherwise, . - protected static bool ShouldCacheLookup(MemberInfo member) - { - if (member == null) - { - throw new ArgumentNullException(nameof(member), "member cannot be null"); - } - - var cacheAttributeType = typeof(CacheLookupAttribute); - bool cache = member.GetCustomAttributes(cacheAttributeType, true).Length > 0 - || member.DeclaringType?.GetCustomAttributes(cacheAttributeType, true).Length > 0; - - return cache; - } - - /// - /// Creates a list of locators based on the attributes of this member. - /// - /// The containing information about - /// the member of the Page Object class. - /// A list of locators based on the attributes of this member. - protected static ReadOnlyCollection CreateLocatorList(MemberInfo member) - { - if (member == null) - { - throw new ArgumentNullException(nameof(member), "member cannot be null"); - } - - var useSequenceAttributes = Attribute.GetCustomAttributes(member, typeof(FindsBySequenceAttribute), true); - bool useSequence = useSequenceAttributes.Length > 0; - - var useFindAllAttributes = Attribute.GetCustomAttributes(member, typeof(FindsByAllAttribute), true); - bool useAll = useFindAllAttributes.Length > 0; - - if (useSequence && useAll) - { - throw new ArgumentException("Cannot specify FindsBySequence and FindsByAll on the same member"); - } - - List bys = new List(); - var attributes = Attribute.GetCustomAttributes(member, typeof(AbstractFindsByAttribute), true); - if (attributes.Length > 0) - { - Array.Sort(attributes); - foreach (var attribute in attributes) - { - var castedAttribute = (AbstractFindsByAttribute)attribute; - - var findsByAttribute = attribute as FindsByAttribute; - if (findsByAttribute != null && findsByAttribute.Using == null) - { - findsByAttribute.Using = member.Name; - } - - bys.Add(castedAttribute.Finder); - } - - if (useSequence) - { - ByChained chained = new ByChained(bys.ToArray()); - bys.Clear(); - bys.Add(chained); - } - - if (useAll) - { - ByAll all = new ByAll(bys.ToArray()); - bys.Clear(); - bys.Add(all); - } - } - - return bys.AsReadOnly(); - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/ExpectedConditions.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/ExpectedConditions.cs deleted file mode 100644 index 501844cd..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/ExpectedConditions.cs +++ /dev/null @@ -1,602 +0,0 @@ - -using System.Collections.ObjectModel; -using System.Text.RegularExpressions; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Supplies a set of common conditions that can be waited for using . -/// -/// -/// -/// IWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3)) -/// IWebElement element = wait.Until(ExpectedConditions.ElementExists(By.Id("foo"))); -/// -/// -public sealed class ExpectedConditions -{ - /// - /// Prevents a default instance of the class from being created. - /// - private ExpectedConditions() - { - } - - /// - /// An expectation for checking the title of a page. - /// - /// The expected title, which must be an exact match. - /// when the title matches; otherwise, . - public static Func TitleIs(string title) - { - return (driver) => { return title == driver.Title; }; - } - - /// - /// An expectation for checking that the title of a page contains a case-sensitive substring. - /// - /// The fragment of title expected. - /// when the title matches; otherwise, . - public static Func TitleContains(string title) - { - return (driver) => { return driver.Title.Contains(title); }; - } - - /// - /// An expectation for the URL of the current page to be a specific URL. - /// - /// The URL that the page should be on - /// when the URL is what it should be; otherwise, . - public static Func UrlToBe(string url) - { - return (driver) => { return driver.Url.ToLowerInvariant().Equals(url.ToLowerInvariant()); }; - } - - /// - /// An expectation for the URL of the current page to be a specific URL. - /// - /// The fraction of the url that the page should be on - /// when the URL contains the text; otherwise, . - public static Func UrlContains(string fraction) - { - return (driver) => { return driver.Url.ToLowerInvariant().Contains(fraction.ToLowerInvariant()); }; - } - - /// - /// An expectation for the URL of the current page to be a specific URL. - /// - /// The regular expression that the URL should match - /// if the URL matches the specified regular expression; otherwise, . - public static Func UrlMatches(string regex) - { - return (driver) => - { - var currentUrl = driver.Url; - var pattern = new Regex(regex, RegexOptions.IgnoreCase); - var match = pattern.Match(currentUrl); - return match.Success; - }; - } - - /// - /// An expectation for checking that an element is present on the DOM of a - /// page. This does not necessarily mean that the element is visible. - /// - /// The locator used to find the element. - /// The once it is located. - public static Func ElementExists(By locator) - { - return (driver) => { return driver.FindElement(locator); }; - } - - /// - /// An expectation for checking that an element is present on the DOM of a page - /// and visible. Visibility means that the element is not only displayed but - /// also has a height and width that is greater than 0. - /// - /// The locator used to find the element. - /// The once it is located and visible. - public static Func ElementIsVisible(By locator) - { - return (driver) => - { - try - { - return ElementIfVisible(driver.FindElement(locator)); - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// An expectation for checking that all elements present on the web page that - /// match the locator are visible. Visibility means that the elements are not - /// only displayed but also have a height and width that is greater than 0. - /// - /// The locator used to find the element. - /// The list of once it is located and visible. - public static Func> VisibilityOfAllElementsLocatedBy(By locator) - { - return (driver) => - { - try - { - var elements = driver.FindElements(locator); - if (elements.Any(element => !element.Displayed)) - { - return null; - } - - return elements.Any() ? elements : null; - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// An expectation for checking that all elements present on the web page that - /// match the locator are visible. Visibility means that the elements are not - /// only displayed but also have a height and width that is greater than 0. - /// - /// list of WebElements - /// The list of once it is located and visible. - public static Func> VisibilityOfAllElementsLocatedBy(ReadOnlyCollection elements) - { - return (driver) => - { - try - { - if (elements.Any(element => !element.Displayed)) - { - return null; - } - - return elements.Any() ? elements : null; - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// An expectation for checking that all elements present on the web page that - /// match the locator. - /// - /// The locator used to find the element. - /// The list of once it is located. - public static Func> PresenceOfAllElementsLocatedBy(By locator) - { - return (driver) => - { - try - { - var elements = driver.FindElements(locator); - return elements.Any() ? elements : null; - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// An expectation for checking if the given text is present in the specified element. - /// - /// The WebElement - /// Text to be present in the element - /// once the element contains the given text; otherwise, . - public static Func TextToBePresentInElement(IWebElement element, string text) - { - return (driver) => - { - try - { - var elementText = element.Text; - return elementText.Contains(text); - } - catch (StaleElementReferenceException) - { - return false; - } - }; - } - - /// - /// An expectation for checking if the given text is present in the element that matches the given locator. - /// - /// The locator used to find the element. - /// Text to be present in the element - /// once the element contains the given text; otherwise, . - public static Func TextToBePresentInElementLocated(By locator, string text) - { - return (driver) => - { - try - { - var element = driver.FindElement(locator); - var elementText = element.Text; - return elementText.Contains(text); - } - catch (StaleElementReferenceException) - { - return false; - } - }; - } - - /// - /// An expectation for checking if the given text is present in the specified elements value attribute. - /// - /// The WebElement - /// Text to be present in the element - /// once the element contains the given text; otherwise, . - public static Func TextToBePresentInElementValue(IWebElement element, string text) - { - return (driver) => - { - try - { - var elementValue = element.GetAttribute("value"); - if (elementValue != null) - { - return elementValue.Contains(text); - } - else - { - return false; - } - } - catch (StaleElementReferenceException) - { - return false; - } - }; - } - - /// - /// An expectation for checking if the given text is present in the specified elements value attribute. - /// - /// The locator used to find the element. - /// Text to be present in the element - /// once the element contains the given text; otherwise, . - public static Func TextToBePresentInElementValue(By locator, string text) - { - return (driver) => - { - try - { - var element = driver.FindElement(locator); - var elementValue = element.GetAttribute("value"); - if (elementValue != null) - { - return elementValue.Contains(text); - } - else - { - return false; - } - } - catch (StaleElementReferenceException) - { - return false; - } - }; - } - - /// - /// An expectation for checking whether the given frame is available to switch - /// to. If the frame is available it switches the given driver to the - /// specified frame. - /// - /// Used to find the frame (id or name) - /// - public static Func FrameToBeAvailableAndSwitchToIt(string frameLocator) - { - return (driver) => - { - try - { - return driver.SwitchTo().Frame(frameLocator); - } - catch (NoSuchFrameException) - { - return null; - } - }; - } - - /// - /// An expectation for checking whether the given frame is available to switch - /// to. If the frame is available it switches the given driver to the - /// specified frame. - /// - /// Locator for the Frame - /// - public static Func FrameToBeAvailableAndSwitchToIt(By locator) - { - return (driver) => - { - try - { - var frameElement = driver.FindElement(locator); - return driver.SwitchTo().Frame(frameElement); - } - catch (NoSuchFrameException) - { - return null; - } - }; - } - - /// - /// An expectation for checking that an element is either invisible or not present on the DOM. - /// - /// The locator used to find the element. - /// if the element is not displayed; otherwise, . - public static Func InvisibilityOfElementLocated(By locator) - { - return (driver) => - { - try - { - var element = driver.FindElement(locator); - return !element.Displayed; - } - catch (NoSuchElementException) - { - // Returns true because the element is not present in DOM. The - // try block checks if the element is present but is invisible. - return true; - } - catch (StaleElementReferenceException) - { - // Returns true because stale element reference implies that element - // is no longer visible. - return true; - } - }; - } - - /// - /// An expectation for checking that an element with text is either invisible or not present on the DOM. - /// - /// The locator used to find the element. - /// Text of the element - /// if the element is not displayed; otherwise, . - public static Func InvisibilityOfElementWithText(By locator, string text) - { - return (driver) => - { - try - { - var element = driver.FindElement(locator); - var elementText = element.Text; - if (string.IsNullOrEmpty(elementText)) - { - return true; - } - - return !elementText.Equals(text); - } - catch (NoSuchElementException) - { - // Returns true because the element with text is not present in DOM. The - // try block checks if the element is present but is invisible. - return true; - } - catch (StaleElementReferenceException) - { - // Returns true because stale element reference implies that element - // is no longer visible. - return true; - } - }; - } - - /// - /// An expectation for checking an element is visible and enabled such that you - /// can click it. - /// - /// The locator used to find the element. - /// The once it is located and clickable (visible and enabled). - public static Func ElementToBeClickable(By locator) - { - return (driver) => - { - var element = ElementIfVisible(driver.FindElement(locator)); - try - { - if (element != null && element.Enabled) - { - return element; - } - else - { - return null; - } - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// An expectation for checking an element is visible and enabled such that you - /// can click it. - /// - /// The element. - /// The once it is clickable (visible and enabled). - public static Func ElementToBeClickable(IWebElement element) - { - return (driver) => - { - try - { - if (element != null && element.Displayed && element.Enabled) - { - return element; - } - else - { - return null; - } - } - catch (StaleElementReferenceException) - { - return null; - } - }; - } - - /// - /// Wait until an element is no longer attached to the DOM. - /// - /// The element. - /// is the element is still attached to the DOM; otherwise, . - public static Func StalenessOf(IWebElement element) - { - return (driver) => - { - try - { - // Calling any method forces a staleness check - return element == null || !element.Enabled; - } - catch (StaleElementReferenceException) - { - return true; - } - }; - } - - /// - /// An expectation for checking if the given element is selected. - /// - /// The element. - /// given element is selected.; otherwise, . - public static Func ElementToBeSelected(IWebElement element) - { - return ElementSelectionStateToBe(element, true); - } - - /// - /// An expectation for checking if the given element is in correct state. - /// - /// The element. - /// selected or not selected - /// given element is in correct state.; otherwise, . - public static Func ElementToBeSelected(IWebElement element, bool selected) - { - return (driver) => - { - return element.Selected == selected; - }; - } - - /// - /// An expectation for checking if the given element is selected. - /// - /// The locator used to find the element. - /// given element is selected.; otherwise, . - public static Func ElementToBeSelected(By locator) - { - return ElementSelectionStateToBe(locator, true); - } - - - /// - /// An expectation for checking if the given element is in correct state. - /// - /// The element. - /// selected or not selected - /// given element is in correct state.; otherwise, . - public static Func ElementSelectionStateToBe(IWebElement element, bool selected) - { - return (driver) => - { - return element.Selected == selected; - }; - } - - /// - /// An expectation for checking if the given element is in correct state. - /// - /// The locator used to find the element. - /// selected or not selected - /// given element is in correct state.; otherwise, . - public static Func ElementSelectionStateToBe(By locator, bool selected) - { - return (driver) => - { - try - { - var element = driver.FindElement(locator); - return element.Selected == selected; - } - catch (StaleElementReferenceException) - { - return false; - } - }; - } - - /// - /// An expectation for checking the AlterIsPresent - /// - /// Alert - public static Func AlertIsPresent() - { - return (driver) => - { - try - { - return driver.SwitchTo().Alert(); - } - catch (NoAlertPresentException) - { - return null; - } - }; - } - - /// - /// An expectation for checking the Alert State - /// - /// A value indicating whether or not an alert should be displayed in order to meet this condition. - /// alert is in correct state present or not present; otherwise, . - public static Func AlertState(bool state) - { - return (driver) => - { - var alertState = false; - try - { - driver.SwitchTo().Alert(); - alertState = true; - return alertState == state; - } - catch (NoAlertPresentException) - { - alertState = false; - return alertState == state; - } - }; - } - - private static IWebElement ElementIfVisible(IWebElement element) - { - return element.Displayed ? element : null; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAllAttribute.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAllAttribute.cs deleted file mode 100644 index c63e00f6..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAllAttribute.cs +++ /dev/null @@ -1,30 +0,0 @@ - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Marks elements to indicate that found elements should match the criteria of -/// all on the field or property. -/// -/// -/// -/// When used with a set of , all criteria must be -/// matched to be returned. The criteria are used in sequence according to the -/// Priority property. Note that the behavior when setting multiple -/// Priority properties to the same value, or not -/// specifying a Priority value, is undefined. -/// -/// -/// -/// // Will find the element with the tag name "input" that also has an ID -/// // attribute matching "elementId". -/// [FindsByAll] -/// [FindsBy(How = How.TagName, Using = "input", Priority = 0)] -/// [FindsBy(How = How.Id, Using = "elementId", Priority = 1)] -/// public IWebElement thisElement; -/// -/// -/// -[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] -public sealed class FindsByAllAttribute : Attribute -{ -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAttribute.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAttribute.cs deleted file mode 100644 index 092d5119..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsByAttribute.cs +++ /dev/null @@ -1,94 +0,0 @@ -#nullable enable - -using System.ComponentModel; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Marks program elements with methods by which to find a corresponding element on the page. Used -/// in conjunction with the , it allows you to quickly create Page Objects. -/// -/// -/// -/// You can use this attribute by specifying the and properties -/// to indicate how to find the elements. This attribute can be used to decorate fields and properties -/// in your Page Object classes. The of the field or property must be either -/// or IList{IWebElement}. Any other type will throw an -/// when is called. -/// -/// -/// -/// [FindsBy(How = How.Name, Using = "myElementName")] -/// public IWebElement foundElement; -/// -/// [FindsBy(How = How.TagName, Using = "a")] -/// public IList{IWebElement} allLinks; -/// -/// -/// -/// You can also use multiple instances of this attribute to find an element that may meet -/// one of multiple criteria. When using multiple instances, you can specify the order in -/// which the criteria is matched by using the property. -/// -/// -/// -/// // Will find the element with the name attribute matching the first of "anElementName" -/// // or "differentElementName". -/// [FindsBy(How = How.Name, Using = "anElementName", Priority = 0)] -/// [FindsBy(How = How.Name, Using = "differentElementName", Priority = 1)] -/// public IWebElement thisElement; -/// -/// -/// -public class FindsByAttribute : AbstractFindsByAttribute -{ - protected By? finder; - - public FindsByAttribute() { } - - /// - /// Create instance - /// - /// Method used to look up the element - /// Value to lookup by - public FindsByAttribute(How how, string @using) - { - How = how; - Using = @using; - } - - /// - /// Gets or sets the method used to look up the element - /// - [DefaultValue(How.Id)] - public How How { get; set; } - - /// - /// Gets or sets the value to lookup by (i.e. for How.Name, the actual name to look up) - /// - public string? Using { get; set; } - - /// - /// Gets or sets a value indicating the of the custom finder. The custom finder must - /// descend from the class, and expose a public constructor that takes a - /// argument. - /// - public Type? CustomFinderType { get; set; } - - /// - /// Gets an explicit object to find by. - /// - public override By Finder - { - get - { - if (this.finder == null) - { - this.finder = ByFactory.From(this); - } - - return this.finder; - } - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsBySequenceAttribute.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/FindsBySequenceAttribute.cs deleted file mode 100644 index 23097957..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/FindsBySequenceAttribute.cs +++ /dev/null @@ -1,30 +0,0 @@ - - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Marks elements to indicate that each on the field or -/// property should be used in sequence to find the appropriate element. -/// -/// -/// -/// When used with a set of , the criteria are used -/// in sequence according to the Priority property to find child elements. Note that -/// the behavior when setting multiple Priority -/// properties to the same value, or not specifying a Priority value, is undefined. -/// -/// -/// -/// // Will find the element with the ID attribute matching "elementId", then will find -/// // a child element with the ID attribute matching "childElementId". -/// [FindsBySequence] -/// [FindsBy(How = How.Id, Using = "elementId", Priority = 0)] -/// [FindsBy(How = How.Id, Using = "childElementId", Priority = 1)] -/// public IWebElement thisElement; -/// -/// -/// -[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] -public sealed class FindsBySequenceAttribute : Attribute -{ -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/IPageObjectMemberDecorator.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/IPageObjectMemberDecorator.cs deleted file mode 100644 index d1fb93ce..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/IPageObjectMemberDecorator.cs +++ /dev/null @@ -1,22 +0,0 @@ -#nullable enable - -using System.Reflection; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Interface describing how members of a class which represent elements in a Page Object -/// are detected. -/// -public interface IPageObjectMemberDecorator -{ - /// - /// Locates an element or list of elements for a Page Object member, and returns a - /// proxy object for the element or list of elements. - /// - /// The containing information about - /// a class's member. - /// The used to locate elements. - /// A transparent proxy to the WebDriver element object. - object? Decorate(MemberInfo member, IElementLocator locator); -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/IMemberBuilder.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/IMemberBuilder.cs deleted file mode 100644 index 4c8960ae..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/IMemberBuilder.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics.CodeAnalysis; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras.MemberBuilders; - -/// -/// Interface for page object members creation -/// -internal interface IMemberBuilder -{ - /// - /// Create page object member - /// - bool CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache, - [NotNullWhen(true)] out object createdObject); -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementBuilder.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementBuilder.cs deleted file mode 100644 index 3afe823c..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementBuilder.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics.CodeAnalysis; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras.MemberBuilders; - -/// -/// Creates member of type -/// -internal class WebElementBuilder : IMemberBuilder -{ - public bool CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache, [NotNullWhen(true)] out object createdObject) - { - createdObject = null; - - if (memberType == typeof(IWebElement)) - { - createdObject = new WebElementProxy(locator, bys, cache); - return true; - } - - return false; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementListBuilder.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementListBuilder.cs deleted file mode 100644 index b53937eb..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WebElementListBuilder.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras.MemberBuilders; - -/// -/// Creates member of type -/// -internal class WebElementListBuilder : IMemberBuilder -{ - public bool CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache, [NotNullWhen(true)] out object createdObject) - { - createdObject = null; - - if (memberType == typeof(IList)) - { - createdObject = new WebElementListProxy(locator, bys, cache); - return true; - } - - return false; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementBuilder.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementBuilder.cs deleted file mode 100644 index 642b1018..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementBuilder.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras.MemberBuilders; - -internal class WrappedElementBuilder : IMemberBuilder -{ - public bool CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache, [NotNullWhen(true)] out object createdObject) - { - createdObject = null; - - if (typeof(IWrapsElement).IsAssignableFrom(memberType)) - { - var webElement = new WebElementProxy(locator, bys, cache); - createdObject = WrapsElementFactory.Wrap(memberType, webElement); - return true; - } - - return false; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementListBuilder.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementListBuilder.cs deleted file mode 100644 index 32524227..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/MemberBuilders/WrappedElementListBuilder.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras.MemberBuilders; - -internal class WrappedElementListBuilder : IMemberBuilder -{ - public bool CreateObject(Type memberType, IElementLocator locator, IEnumerable bys, bool cache, [NotNullWhen(true)] out object createdObject) - { - createdObject = null; - - if (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(IList<>)) - { - var elementType = memberType.GetGenericArguments()[0]; - - if (typeof(IWrapsElement).IsAssignableFrom(elementType)) - { - var listType = typeof(WrapsElementListProxy<>).MakeGenericType(memberType.GetGenericArguments()[0]); - createdObject = Activator.CreateInstance(listType, new object[] { locator, bys, cache }); - } - } - - return createdObject != null; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/RetryingElementLocator.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/RetryingElementLocator.cs deleted file mode 100644 index 3f7b503d..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/RetryingElementLocator.cs +++ /dev/null @@ -1,133 +0,0 @@ -#nullable enable - -using System.Collections.ObjectModel; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// A locator for elements for use with the that retries locating -/// the element up to a timeout if the element is not found. -/// -public class RetryingElementLocator : IElementLocator -{ - private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(5); - private static readonly TimeSpan DefaultPollingInterval = TimeSpan.FromMilliseconds(500); - private TimeSpan timeout; - private TimeSpan pollingInterval; - - /// - /// Initializes a new instance of the class. - /// - /// The object that the - /// locator uses for locating elements. - public RetryingElementLocator(ISearchContext searchContext) - : this(searchContext, DefaultTimeout) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The object that the - /// locator uses for locating elements. - /// The indicating how long the locator should - /// retry before timing out. - public RetryingElementLocator(ISearchContext searchContext, TimeSpan timeout) - : this(searchContext, timeout, DefaultPollingInterval) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The object that the - /// locator uses for locating elements. - /// The indicating how long the locator should - /// retry before timing out. - /// The indicating how often to poll - /// for the existence of the element. - public RetryingElementLocator(ISearchContext searchContext, TimeSpan timeout, TimeSpan pollingInterval) - { - this.SearchContext = searchContext; - this.timeout = timeout; - this.pollingInterval = pollingInterval; - } - - /// - /// Gets the to be used in locating elements. - /// - public ISearchContext SearchContext { get; } - - /// - /// Locates an element using the given list of criteria. - /// - /// The list of methods by which to search for the element. - /// An which is the first match under the desired criteria. - public IWebElement LocateElement(IEnumerable bys) - { - if (bys == null) - { - throw new ArgumentNullException(nameof(bys), "List of criteria may not be null"); - } - - string? errorString = null; - DateTime endTime = DateTime.Now.Add(this.timeout); - bool timeoutReached = DateTime.Now > endTime; - while (!timeoutReached) - { - foreach (var by in bys) - { - try - { - return this.SearchContext.FindElement(by); - } - catch (NoSuchElementException) - { - errorString = (errorString == null ? "Could not find element by: " : errorString + ", or: ") + by; - } - } - - timeoutReached = DateTime.Now > endTime; - if (!timeoutReached) - { - Thread.Sleep(this.pollingInterval); - } - } - - throw new NoSuchElementException(errorString); - } - - /// - /// Locates a list of elements using the given list of criteria. - /// - /// The list of methods by which to search for the elements. - /// A list of all elements which match the desired criteria. - public ReadOnlyCollection LocateElements(IEnumerable bys) - { - if (bys == null) - { - throw new ArgumentNullException(nameof(bys), "List of criteria may not be null"); - } - - List collection = new List(); - DateTime endTime = DateTime.Now.Add(this.timeout); - bool timeoutReached = DateTime.Now > endTime; - while (!timeoutReached) - { - foreach (var by in bys) - { - ReadOnlyCollection list = this.SearchContext.FindElements(by); - collection.AddRange(list); - } - - timeoutReached = collection.Count != 0 || DateTime.Now > endTime; - if (!timeoutReached) - { - Thread.Sleep(this.pollingInterval); - } - } - - return collection.AsReadOnly(); - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WebDriverObjectProxy.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/WebDriverObjectProxy.cs deleted file mode 100644 index f31d4ebd..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WebDriverObjectProxy.cs +++ /dev/null @@ -1,38 +0,0 @@ -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Represents a base proxy class for objects used with the PageFactory. -/// -internal abstract class WebDriverObjectProxy -{ - /// - /// Create WebDriverObjectProxy - /// - /// The implementation that - /// determines how elements are located. - /// The list of methods by which to search for the elements. - /// to cache the lookup to the element; otherwise, . - protected WebDriverObjectProxy(IElementLocator locator, IEnumerable bys, bool cache) - { - this.Locator = locator; - this.Bys = bys; - this.Cache = cache; - } - - /// - /// Gets the implementation that determines how elements are located. - /// - protected IElementLocator Locator { get; } - - /// - /// Gets the list of methods by which to search for the elements. - /// - protected IEnumerable Bys { get; } - - /// - /// Gets a value indicating whether element search results should be cached. - /// - protected bool Cache { get; } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementEnumerable.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementEnumerable.cs deleted file mode 100644 index f6c46a92..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementEnumerable.cs +++ /dev/null @@ -1,28 +0,0 @@ -using TestWare.Engines.Selenoid.Extras; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Due to Linq optimized execution in dotnet core for IList, some methods lead to multiple elements retrieval. -/// In this class IList is wrapped in IEnumerable to disable that 'optimized' evaluation. -/// -public static class WebElementEnumerable -{ - public static IEnumerable Select(this IList webElements, Func selector) - => webElements.ToEnumerable().Select(selector); - - public static IEnumerable Where(this IList webElements, Func selector) - => webElements.ToEnumerable().Where(selector); - - public static List ToList(this IList webElements) - => webElements.ToEnumerable().ToList(); - - public static TElement[] ToArray(this IList webElements) - => webElements.ToEnumerable().ToArray(); - - private static IEnumerable ToEnumerable(this IList enumerable) - { - foreach (var element in enumerable) - yield return element; - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementListProxy.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementListProxy.cs deleted file mode 100644 index b7d6f68d..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WebElementListProxy.cs +++ /dev/null @@ -1,65 +0,0 @@ -#nullable enable - -using System.Collections; -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Represents a proxy class for a list of elements to be used with the PageFactory. -/// -internal class WebElementListProxy : WebDriverObjectProxy, IList -{ - private IList? _items; - - public WebElementListProxy(IElementLocator locator, IEnumerable bys, bool cache) - : base(locator, bys, cache) - { - } - - private IList Items - { - get - { - if (_items == null || !Cache) - { - _items = Locator.LocateElements(Bys); - } - return _items; - } - } - - #region Forwarded Items calls - - public IWebElement this[int index] - { - get { return Items[index]; } - set { Items[index] = value; } - } - - public int Count => Items.Count; - - public bool IsReadOnly => Items.IsReadOnly; - - public void Add(IWebElement item) => Items.Add(item); - - public void Clear() => Items.Clear(); - - public bool Contains(IWebElement item) => Items.Contains(item); - - public void CopyTo(IWebElement[] array, int arrayIndex) => Items.CopyTo(array, arrayIndex); - - public IEnumerator GetEnumerator() => Items.GetEnumerator(); - - public int IndexOf(IWebElement item) => Items.IndexOf(item); - - public void Insert(int index, IWebElement item) => Items.Insert(index, item); - - public bool Remove(IWebElement item) => Items.Remove(item); - - public void RemoveAt(int index) => Items.RemoveAt(index); - - IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator(); - - #endregion -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementFactory.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementFactory.cs deleted file mode 100644 index 00c286a9..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementFactory.cs +++ /dev/null @@ -1,35 +0,0 @@ -using OpenQA.Selenium; - -namespace TestWare.Engines.Selenoid.Extras; - -internal static class WrapsElementFactory -{ - public static T Wrap(IWebElement webElement) where T : IWrapsElement - { - return (T)Wrap(typeof(T), webElement); - } - - public static object Wrap(Type wrapsElementType, IWebElement webElement) - { - var iWebElementConstructor = wrapsElementType.GetConstructor(new[] { typeof(IWebElement) }); - - // Option 1 - T has constructor with IWebElement parameter - if (iWebElementConstructor != null) - { - return iWebElementConstructor.Invoke(new object[] { webElement }); - } - - // Option 2 - T has parameterless constructor, and setter on WrappedElement property - var parameterlessConstructor = wrapsElementType.GetConstructor(Array.Empty()); - var wrappedElementProperty = wrapsElementType.GetProperty(nameof(IWrapsElement.WrappedElement)); - - if (parameterlessConstructor != null && wrappedElementProperty?.CanWrite == true) - { - var wrappedInstance = parameterlessConstructor.Invoke(Array.Empty()); - wrappedElementProperty.SetValue(wrappedInstance, webElement); - return wrappedInstance; - } - - throw new NotSupportedException($"Cannot create instance of type '{wrapsElementType.FullName}'"); - } -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementListProxy.cs b/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementListProxy.cs deleted file mode 100644 index 1eb83214..00000000 --- a/src/Engines/TestWare.Engines.Selenoid/Extras/WrapsElementListProxy.cs +++ /dev/null @@ -1,71 +0,0 @@ -#nullable enable - -using System.Collections; -using OpenQA.Selenium; -using TestWare.Engines.Selenoid.Extras; - -namespace TestWare.Engines.Selenoid.Extras; - -/// -/// Represents a proxy class for a list of elements to be used with the PageFactory. -/// -internal class WrapsElementListProxy : WebDriverObjectProxy, IList where T : IWrapsElement -{ - private IList? _items; - - public WrapsElementListProxy(IElementLocator locator, IEnumerable bys, bool cache) - : base(locator, bys, cache) - { - } - - private IList Items - { - get - { - // Find elements, and wrap them in IWrapsElement instances. - // If caching enabled - use previously found elements, if any. - if (_items == null || !Cache) - { - _items = Locator - .LocateElements(Bys) - .Select(WrapsElementFactory.Wrap) - .ToList(); - } - return _items; - } - } - - #region Forwarded Items calls - - public T this[int index] - { - get { return Items[index]; } - set { Items[index] = value; } - } - - public int Count => Items.Count; - - public bool IsReadOnly => Items.IsReadOnly; - - public void Add(T item) => Items.Add(item); - - public void Clear() => Items.Clear(); - - public bool Contains(T item) => Items.Contains(item); - - public void CopyTo(T[] array, int arrayIndex) => Items.CopyTo(array, arrayIndex); - - public IEnumerator GetEnumerator() => Items.GetEnumerator(); - - public int IndexOf(T item) => Items.IndexOf(item); - - public void Insert(int index, T item) => Items.Insert(index, item); - - public bool Remove(T item) => Items.Remove(item); - - public void RemoveAt(int index) => Items.RemoveAt(index); - - IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator(); - - #endregion -} diff --git a/src/Engines/TestWare.Engines.Selenoid/Pages/PageBase.cs b/src/Engines/TestWare.Engines.Selenoid/Pages/PageBase.cs index 2199ae4d..56e21892 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Pages/PageBase.cs +++ b/src/Engines/TestWare.Engines.Selenoid/Pages/PageBase.cs @@ -2,7 +2,7 @@ using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Support.UI; using TestWare.Core.Libraries; -using TestWare.Engines.Selenoid.Extras; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenoid.Pages; diff --git a/src/Engines/TestWare.Engines.Selenoid/Pages/WebPage.cs b/src/Engines/TestWare.Engines.Selenoid/Pages/WebPage.cs index f04d6d70..78a4fb9d 100644 --- a/src/Engines/TestWare.Engines.Selenoid/Pages/WebPage.cs +++ b/src/Engines/TestWare.Engines.Selenoid/Pages/WebPage.cs @@ -1,5 +1,5 @@ using OpenQA.Selenium; -using TestWare.Engines.Selenoid.Extras; +using TestWare.Engines.Common.Extras; namespace TestWare.Engines.Selenoid.Pages; diff --git a/src/Engines/TestWare.Engines.Selenoid/TestWare.Engines.Selenoid.csproj b/src/Engines/TestWare.Engines.Selenoid/TestWare.Engines.Selenoid.csproj index 7706752c..1c51a306 100644 --- a/src/Engines/TestWare.Engines.Selenoid/TestWare.Engines.Selenoid.csproj +++ b/src/Engines/TestWare.Engines.Selenoid/TestWare.Engines.Selenoid.csproj @@ -7,11 +7,12 @@ - + +