How to initialize WebElements in Selenium page object - c#

I am new to Selenium and looking forward to learn more, I am using Selenium WebDriver with C#.
This is how I initiate a WebElement:
CarouselSliderNextButton = DriverInitializer.driver
.FindElement(By.XPath("//a[#class='buttons next']"));
But if the element doesn't exist for some reason; hidden for instance, then it doesn't work. I know that I can check if the element exists before I can initiate, but would love to hear from experts if I am doing this the right way.

I am not claiming to be an expert, but this is what I think:
You do not "initiate" a web element
You find a web element
First of all, you need to find the element you want to locate from html file. You may use Google or Firefox in developer mode to find it. I recommend you to install "Firebug" for Firefox, it is very useful.
There are multiple reasons why an element you can "see" from HTML file but you can not locate:
1: this element is on an iframe, this case requires you to locate this iframe first then locate the element
2: this element is not visible yet, for example, a drop down arrow button will only appear if you hover your mouse over a certain area first.
But you are heading to the right direction.

If you're trying to intialise the WebElement, I use:
WebElement element = driver.findElement(By.tagName("div"));
as most DOMs have div tags.
Then after trying to find an element that exists (and isn't a div tag), check:
if (element.getTagName().equals("div")){
System.out.println("Element not found...");
}

var instantEstimateDiv: WebElement? = null => Kotlin
WebElement? instantEstimateDiv= null; => JAVA

Related

C# Selenium XPath , call click function of a link text

enter image description here
I need to click the 'Practice Form' tag highlighted in the attached image using C# Selenium here.
The url of form is https://demoqa.com/forms
and the upon clicking 'Practice Form' it will be redirected to https://demoqa.com/automation-practice-form.
I need to achieve this through clicking, not by navigating.
This XPATH should perfectly work:
//span[contains(.,'Practice Form')]//ancestor::li[#class='btn btn-light ']
Short explanation:
You find span containing specified text
You go to ancestor to get button's xpath.
You need to find it with selenium and use Selenium's click()
This is one of xpaths you can use.
Another option is just going a level up:
//span[contains(.,'Practice Form')]/..
I like both.
Option 3:
//span[contains(.,'Practice Form')]//parent::li[contains(#class,'btn btn-light')]
I am not sure why yours isn't working, but this works fine for me:
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.demoqa.com/forms");
driver.FindElement(By.XPath("//span[contains(.,'Practice Form')]//parent::li[#id='item-0']")).Click();
It takes me to:
https://www.demoqa.com/automation-practice-form
With the Student Registration form shown in the middle
BTW in your original comments you said you had to use XPath for this because that field is "dynamic". It is not dynamic. The element has more than one ID: item-0, maybe that is what you meant by couldn't use ID. But the element itself is not "dynamic"
This simple XPath works for me
//span[text()='Practice Form']
You may use the below xpath
//li[#class[contains(.,'btn-light')]][contains(.,'Practice Form')]

C# + Selenium: automation wait

The below code is not working and it always throws No such element exception at line 2.
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(element)));
There could be 2 issues here:
You are trying to find the element before its visible for that you can wait for the element by doing
wait.Until(ExpectedConditions.ElementExists(By.XPath(element)));
where element is the XPath of the element you are trying to find.
You are not finding the element using the correct XPath. If you are using an absolute XPath, avoid doing because while absolute XPath can find the element faster, if the DOM structure changes your path may no longer work.
It is also possible that you are not running your browser in fullscreen, at least this was a valid issue I was facing when my current projects' GUI got changed over. Adding driver.Manage().Window.Maximize(); to my ClassInitialize fixed the issue in a whim.
Another option is that maybe your element is either embedded into an iframe or is overlapped by one.
As mentioned in this answer https://stackoverflow.com/a/44724688/6045154 , I have solved a similar issue with:
IWebElement button = driver.FindElement(By.ClassName("transfer__button"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].click();", button);
Of course this needs to be edited to find your element by the right selector.

C# Selenium can't find element with WebDriverWait, i can see and click on it manually

Element im trying to locate:
WebDriverWait wait = new WebDriverWait(browser, TimeSpan.FromSeconds(60));
wait.Until(ExpectedConditions.ElementExists(By.XPath("//use[#xlink:href='#core_mail']")));
File.WriteAllText("html.txt", browser.PageSource);
that just times out.. and the page loads way before 60 seconds.
svg has a default namespace. You have to account for it:
//svg:use[#xlink:href='#core_mail']
Or ignore it with local-name():
//*[local-name() = 'use' and #xlink:href='#core_mail']
Though, to be fair, you don't have to dive into the markup that deeply, your "email" button is much higher in the tree - see the very first parent element partially visible on the screenshot - that's your desired element you probably want to locate instead.

WebDriver - element is not clickable Chrome

I have following problem. I run test on Firefox and Chrome. On Firefox test run correctly but on Chrome SauceLabs give a message:
unknown error: Element is not clickable at point (717, 657). Other
element would receive the click: <div class="col-md-9 col-sm-12"
style="margin-top:8px;">...</div> (Session info: chrome=36.0.1985.125)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.3 x86_64)
I choose element by unique css selector in both test in the same way:
driver.FindElement(By.CssSelector("button.btn-xs:nth-child(1)")).Click();
Any ideas what is wrong here?
I am assuming that you have the correct element you need, ie the XPath is correct.
Here are few ways out:
Try to Click on the parent element instead.
Try .Submit() instead of .Click()
Try to execute the JavaScript that will be executed on the OnClick event of the element you are trying to click.
I have used the 3rd way with success all the time.
Another one
Do a .SendKeys(Keys.Enter) on that element (or a Space key)
Since you've tagged the question as Google-Chrome too - I suppose that this is happening mostly with ChromeDriver. I had the same issues with one of my previous projects (Asp .Net MVC). I found that when some elements are not visible for this Driver if they are not in the screen_visible_area. Please note that they are loaded (HTML, CSS3, JS etc.) properly.
So after a lot of reading and testing, I found that my workaround is simply scroll to the WebElement - so it is in the visible part of the screen. Actually this issue was not for all elements and I didn't find better solution for it.
unknown error: Element is not clickable at point (..., ...)
Is not descriptive error for this case, because like you I also thought that is Selector-related.
Just to be full answer - I had the same problems with IEDriver too. My implementation was to use the Browser scroll down/up options and just "send the screen" where the problematic element is.
Simple JSExecutor code that you can use:
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(110,350)", "");
or
jse.executeScript("scroll(0, 250);");
or
driver.executeScript("window.scrollBy(110,350)", "");
Other topic-related useful resources are here.
Update
When it comes to the .sendKeys() I also used the browser accessibility features. All you need to do is just count how many TAB clicks your test need in order to get to the targeted web_element. Then just call .click().
Try this simple code:
element.sendKeys(Keys.TAB);
or
element.sendKeys("\t")
or
Actions builder = new Actions(driver);
builder.keyDown(Keys.TAB).perform()
I realize this is a super old question, but it came up while searching a nearly identical problem in the present day. After attempting many of the fixes described here and getting new exceptions for my trouble (mostly stale element and http request timeouts) I stumbled across this issue on Selenium's GitHub.
As described in the post, Chrome had advanced beyond the abilities of my version of chromedriver.exe--my v2.30 driver had known issues with clicking elements due to changes in Chrome v61 scrolling mechanics. Updating to the latest chromedriver.exe solved all my problems.
tl/dr: ensure your version of chromedriver is compatible with the version of Chrome being tested.
I was getting issue that login button is not clickable in chrome even xpath was correct. after browsing many sites, i came to the solution - use .submit() instead of .click() and it worked perfectly.
driver.findElement(By.xpath("//button[#id='loginBtn']")).click();
driver.findElement(By.xpath("//button[#id='loginBtn']")).submit();
If you're doing anything complicated in your CSS, Chrome can get confused (this has happened to me) and think that the element you're trying to click is covered by another element even though this is not the case.
One way to resolve this is to help Chrome understand the situation correctly by adding z-indexes (you'll need to add relative or absolute positioning also) to unambiguously place the correct element on top of the other.
For me, it was creating this command instead.
driver.FindElementByXPath("id('gender1')").SendKeys(Keys.Space);
For my case, I was interacting with radio control.
I have had this problem on FF. This issue happens when your field is not in the view area. The slick way to resolve this issue is to zoom out your browser:
TheNotClickableField.SendKeys(Keys.Control + "-" + "-");
you might want to zoom out more or less according to your page size.
I.
If the button is on the bottom of the page, the following code could be used to get you to the bottom via JavaScript from where the click can be executed:
(driver as IJavaScriptExecutor).ExecuteJavaScript("window.scrollTo(0,document.body.scrollHeight - 150)");
The same action could be done via C# with the Actions class provided by Selenium.
This will get you to the bottom of the page----->
new Actions(Driver).SendKeys(Keys.End).Perform();
Keys.End could be switched with Keys.PageDown // Keys.Space
II.
If you want to get to the exact position of the element you can:
1.Get the element's Y location---> var elementToClick = driver.findElement(By.{Anything}(""));
2.Execute the following JS---> (driver as IJavaScriptExecutor).ExecuteScript(string.Format("window.scrollTo(0,{0})", elementToClickYLocation.Location.Y));
3.Click the element---> elementToClick.click();

Test if an element is focused using Selenium Webdriver

I'm really surprised I can't find references on the internet to testing for element focus using Selenium Webdriver.
I'm wanting to check when when a form submission is attempted with a mandatory field missed, focus is moved to the empty field. But I cannot see any way to do this using the WebDriver API.
I will be able to find the focused element using a JavascriptExecutor. But reading the FAQ makes me think there must be some way to perform the check using the driver itself.
Thanks for any help.
driver.switchTo().activeElement() will return the currently focused WebElement. Equality is well defined for WebElement, so you can call element.equals(driver.switchTo().activeElement()).
Calling the slightly misleading named driver.switchTo().activeElement() does not in fact switch focus, neither does driver.findElement(), so you do not need to switchTo().defaultContent() after; in fact, doing so would probably blur the current element.
driver.switchTo().activeElement();
returns the currently focused element.
Makes sure you switch back after using
driver.switchTo().defaultContent();
Also if nothing is focused the body of the document is returned.
Take a look at this question as well.
In Selenium how do I find the "Current" object
You can find the active element using selector 'dom=document.activeElement'. Then you can assert whether it's the element you want it to be focused or not.
The WebDriver is supposed to change focus when you use Driver.FindElement calls. So you're last element in the Driver context is active.
NOTE: This breaks for any elements injected dynamic (e.g. jQuery), so you'd need to go the script route then.
#danielwagner-hall The boolean bb = driver.switchTo().activeElement().equals(driver.findElement(By.id("widget_113_si‌​gnup_username"))); will always pass but it doesn't prove that the element is brought into focus if the element is out of view.
NB: Unable to comment as not enough reputation points.
One way of approaching this could be to use webElement.getLocation().getX(); getY() methods and reference the coordinates on the page and verify its focus.

Categories

Resources