Selenium WebDriver PageFactory FindsBy Using jQuery Selector?

To explain my question, I gave a small script:

Say I have a login page.

public class LoginPage { [FindsBy(How = How.Id, Using = "SomeReallyLongIdBecauseOfAspNetControlsAndPanels_username"] public IWebElement UsernameField { get; set; } [FindsBy(How = How.Id, Using = "SomeReallyLongIdBecauseOfAspNetControlsAndPanels_password"] public IWebElement PasswordField { get; set; } [FindsBy(How = How.Id, Using = "submitButtonId")] public IWebElement SubmitButton { get; set; } private readonly IWebDriver driver; public LoginPage(IWebDriver driver) { this.driver = driver; if(!driver.Url.Contains("Login.aspx")) { throw new NotFoundException("This is not the login page."); } PageFactory.InitElements(driver, this); } public HomePage Login(Credentials cred) { UsernameField.sendKeys(cred.Username); PasswordField.SendKeys(cred.Password); SubmitButton.Click(); return new HomePage(driver); } } [TestFixture] public class Test : TestBase { private IWebDriver driver; [SetUp] public void SetUp() { driver = StartDriver(); // some function which returns my driver in a wrapped event or something so I can log everything it does. } [Test] public void Test() { new LoginPage(driver) .Login(new Credentials { Username = "username", Password = "password" }) .SomeHomePageFunction() } 

In the end, I know that the page configuration will change, the identifier will basically remain the same, but in my projects everything changes quickly. I know that xPath is another alternative, but because of how the pages are created based on certain criteria, it will still be painful, since the path will not always be the same.

With the current code above, the page loads, and PageFactory initializes the elements through the page builder. Everything is great. This is what I am using at the moment.

Currently, if some things are not always created on the page before a certain step. I usually do the following:

 private const string ThisIsTheUserNameFieldId = "usernamefield"; 

Then click the web browser using the following:

 // Navigate to login page // code here // Enter in credentials driver.FindElement(By.Id(ThisIsTheUserNameFieldId)).SendKeys(cred.Username); 

Not as well structured as PageFactory, but it is certainly a requirement that I cannot get around.

I recently came across jQuery Selector code for use with C # .Net, which extends the functionality of RemoteWebDriver, where I can use the jQuery selector to find my elements on the page.

Selenium jQuery for C # .Net (including source)

 // So I can do things like this: driver.FindElement(By.jQuery("a").Find(":contains('Home')").Next()) 

Does anyone know how I can extend the [FindsBy] attribute in Selenium WebDriver so that I can use something like the following (pseudocode)?

 [FindsBy(How = How.jQuery, Using = "div[id$='txtUserName']")] public IWebElement UsernameField { get; set; } 
+4
source share
1 answer

This does not apply to [FindsBy] , but did you know that you can use the elements returned by javascript ?:

 var driver = new FirefoxDriver { Url = "http://www.google.com" }; var element = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("return document.getElementsByName('q')[0];"); element.SendKeys("hello world"); 

You can easily extend this to enable the jquery selector by first introducing jquery (taken from JQuerify and modified):

 const string js = @"{var b=document.getElementsByTagName('body')[0]; if(typeof jQuery=='undefined'){var script=document" + @".createElement('script'); script.src='http://code.jquery.com/jquery-latest.min.js';var head=document" + @".getElementsByTagName('head')[0],done=false;script.onload=script.onreadystatechange=function(){if(!" + @"done&&(!this.readyState||this.readyState=='loaded'||this.readyState=='complete')){done=true;script." + @"onload=script.onreadystatechange=null;head.removeChild(script);}};head.appendChild(script);}}"; ((IJavaScriptExecutor)driver).ExecuteScript(js); 

And then run javascript to select the item you want:

 var driver = new FirefoxDriver { Url = "http://www.google.com" }; var element = (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(@"return $('input[name*=""q""]')[0];"); element.SendKeys("hello world"); 
+4
source

Source: https://habr.com/ru/post/1384950/


All Articles