Not able to locate input element using Selenium WebDriver - c#

I am new to Selenium. In a specific scenario I am not able to catch an input element. below is the code:
<ul class = "form1">
<li class="firstName">
<input placeholdervalue="First name" tabindex="1" placeholder="First name" class="text" placeholdevalue="First name" data-input-rule="name" data-value-rule="required" maxlength="20" type="text">
</li>
</ul>
I want to locate input element. I tried locating it using locator By.ClassName, By.CssSelector("input[class='text placeholder']") and also tried:
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("input[className='text' and placeholdevalue='First name'"))).SendKeys("Vipul");
but input element is not getting selected.
Please let me know the right way to select input element.

I would use a dot notation to match the classes of ul, li and input elements:
By.CssSelector("ul.form1 li.firstName input.text")
If the element still cannot be found, then there could two most commonly met reasons:
it is inside an iframe and you need to switch to it
you need to wait for the element to appear
I'll expand these items in case you would still have problems finding the element.

Thanks for the reply.
It worked with this,
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("ul.form1 li.firstName input.text"))).SendKeys("Vipul");
Is this the right way of using wait?
Also, can anybody point out to resources which explain working with frames using selenium webdriver?
-Amit

Related

How to find two different elements but with same information using XPath

I'm trying to find an element that repeats itself in the same page. I tried to use the following XPath's that I was able to find in FirePath, but I didn't have any success running it through my selenium automation tests.
This are the two XPath:
//div[#id='selectGenericMult']/child::div/child::input']
(//*[#id='selectGenericMult']/child::div/child::input)[last()]
And this the information on my page:
<input class="ui-select-search input-xs ng-pristine ng-valid ng-touched" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Selecione" ng-disabled="$select.disabled" ng-hide="$select.disabled" ng-click="$select.activate()" ng-model="$select.search" role="combobox" aria-label="Select box" ondrop="return false;" style="width: 1331px;" type="text"/>
Screenshot with the two fields and part of the HTML code
Another screenshot with the the HTML code of both input text, showed on the first screenshot
Ok, so I finally had some time to look over it (not really, but made time) and this should work for both elements, per your screenshot. You may need to tweak them a lil', hopefully not though.
First Element:
//div[contains(#class,"ng-scope")]//input
Second Element:
//div[#class="col-md-12"]//input
I tested them on my end and they work fine. Let me know if it's not working for you somehow.
I would suggest looking into how xpath works and study it, it's actually quite fun once you get the hang of it. You are able to find anything on the screen with just some simple parameters.
Good luck!
Use below Xpath
//input[#class='ui-select-search input-xs ng-pristine ng-valid ng-touched' and #role='combobox' and #aria-label='Select box']
It will return you all element with same tag
Hope it will help you :)
To find the element as per the HTML you provided you can use the following unique xpath:
//input[#class='ui-select-search input-xs ng-pristine ng-valid ng-touched'][#placeholder='Selecione']

Selenium - Discerning Between Identical <articles>, C#

I'm trying to have my program sit on a webpage and wait for specific tagName within an article to appear. Problem is, I need Selenium to check the article contains two tagNames before clicking it, that's where I'm stumped. The way I have my code setup right now, it doesn't click anywhere. It just sits on the page, I suspect because there's more than one article with the same main tagName that I'm trying to find. Here's the HTML:
<article>
<div class ="inner-article">
<a href ="/shop/shirts/iycbmgtqw/x9vdawcjg" style="height:150px;">
<img alt="Xrtqh7ar444" height="150" src="//d17ol771963kd3.cloudfront.net/120885/vi/xrTQH7Ar444.jpg" width="150">
</a>
<h1>
EXAMPLE_CODE
</h1>
<p>
EXAMPLE_COLOUR
</p>
</div>
</article>
All other items on this page have an identical class, and some have identical tagNames. I want to search for when there's a specific combination of two tagNames in an article. I realize xPath is an option, but I would like to code it before knowing an xPath, where the name of the item is the only available information.
And here's the code I'm working with at the moment:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMinutes(10));
IWebElement test = driver.FindElement(By.TagName(textBox12.Text));
test.Click();
where textBox12.Text is "EXAMPLE_CODE". Am I correct in assuming that WebDriver doesn't click anything because there is more than one element with the tagName "EXAMPLE_CODE", and is there a possible way to make it first look for "EXAMPLE_CODE" and then check the secondary: "EXAMPLE_COLOUR"?
Thanks!!
You are using By.TagName incorrectly. Tag refers to the type of element you are trying to find. In this case for the link it is 'a'. Or in case of a div it is 'div'. Te correct way of finding with tagname for a link would be - By.TagName("a").
You need to match text and you will need to use xpath. Assuming that the code is unique you should try.
XPath to get the code href -- //div[class='inner-article']/h1/a[.=EXAMPLE_CODE]
XPath to get the color href -- //div[class='inner-article']/h1/a[.=EXAMPLE_CODE]/following-sibling::a

ElementNotVisibleException try to use Xpath to Enter data into a textbox with Selenium

I am using Selenium in C# to Enter data into textboxes on a webpage:
But i am getting this error:
OpenQA.Selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
I'm using #name, but there are 2 controls on the page with name="MinPrice"
heres the HTML:
<div class="form-group for-sale">
<label>Min Price</label>
<input class="form-control" name="MinPrice" min="0" placeholder="Minimum Price" value="" type="number"></input>
and this is the xpath I'm using:
txtMinPrice = Driver.Instance.FindElement(By.Name("MinPrice"));
I also tried using XPath, but similar results:
txtMinPrice = Driver.Instance.FindElement(By.XPath("//input[contains(#name,'MinPrice') and type='number']"));
If anyone has any type of idea....this is driving me nuts.
ElementNotVisibleException exception occurs when selenium can find an element in the DOM but it is not rendered on the screen.
When I have encountered this error before it has been generally caused by one of three things:
Selenium is trying to interact with an object that is present in the DOM but has not yet rendered on the screen, in which case you might consider adding some type of delay. (Avoid sleep if you can but it is useful for debugging)
The element is below the visible screen, in which case you would need to scroll to interact with it.
There is an overlapping element that is blocking the display of the element.
Add a sleep(10) in to make sure everything on the page has loaded first before any user actions are preformed. If that doesn't work also add
driver.manage().window().maximize() at the start of your test to make sure all the page elements is in view.
If that doesn't work its your xpath. Try something like //*[#class="form-group for-sale"]/input
Or use the Firefinder add on in mozilla firefox to check your xpath is valid and exists on the page.
Selenium is good at scrolling down to view an item, but when it comes to Scrolling back up it's a PiA, and usually throws that exception. I usually just do something like
element.SendKeys(Keys.Home);
Thread.Sleep(100);

How do I access this element in C# using Selenium?

I am trying to find the following element and enter text into it. I have tried a number of different ways to access the element but always get the same error. My current line of code
searchTerm = driver.FindElement(By.Id("keyword"));
generates the same error
Unable to locate element: {"method":"id","selector":"keyword"}
The element, shown below, clearly has the Id 'keyword'.
<input maxlength="100" size="20" value="" name="keyword" id="keyword" title="keyword" class="FORMshrt2">
I used firebug to capture the complete XPath for this element.
/html/body/div/span/table[3]/tbody/tr/td/table[1]/tbody/tr[2]/td/div[1]/span/form/div[3]/table[3]/tbody/tr[2]/td/table/tbody/tr[1]/td/table/tbody/tr[11]/td[2]/span/input
How do I access this element?
Try closing tag input with /> like explained here.
<input maxlength="100" size="20" value="" name="keyword" id="keyword" title="keyword" class="FORMshrt2" />
I don't know if Selenium expects this closing tag, but everything else look ok.
The element might not have appeared at the moment you've started looking for it. Wait for the element to become present in the DOM:
IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementExists((By.Id("keyword"))));
Use wait statement then try the below code
you can just try the following code, which may help for your case,
Thread.Sleep(5000);
driver.FindElement(By.XPath("//input[#class='FORMshrt2']")).Click();
driver.FindElement(By.XPath("//input[#class='FORMshrt2']")).SendKeys("your text");
By using your class name i'm identifying the element, first clicking on it and then passing the string.

Finding Button within Button Group Class Using Selenium Webdriver in C#

My end goal is to be able to click Yes or No on a webpage.
Using fire bug I can see the Yes and No buttons reside in a class called "btn-group"
<div class="btn-group btn-group-default answer-toggle" aria-label="..." role="group">
<button class="btn ng-pristine ng-valid active btn-secondary ng-touched" btn-radio="true" ng-model="consultation.previousSoundVoid" ng-class="{'btn-secondary': consultation.previousSoundVoid}" type="button">
Yes
</button>
<button class="btn ng-pristine ng-untouched ng-valid" btn-radio="false" ng-model="consultation.previousSoundVoid" ng-class="{'btn-secondary': consultation.previousSoundVoid == false}" type="button">
No
</button>
</div>
I think I could find Element by XPath but I am trying to improve my Selenium skill.
I am hoping there is a way to first find the "btn-group" class then somehow choose Yes or No within that.
Or be able to create variables for both the Yes and No options. If I do:
var button = Driver.Instance.FindElements(By.ClassName("btn"));
It returns 21 options. I found that:
button[15].Text returns "Yes"
button[16].Text returns "No"
Instead of having to look through all 21 results and worrying about if the index changes, can I search the results by text somehow?
The best way is to identify those element using text and xpath since they do not have any unique id
//button[.='Yes']
Desperate to use cssSelector?
.btn.ng-pristine.ng-valid.active.btn-secondary.ng-touched
since it is a compound class
You can also go for nth-child() with css
[role='group']>button:nth-child(1)
whereas 2 will let you select the button with text No
Case 1: When answer-toggle is unique in the HTML page
Driver.Instance.FindElements(By.XPath("//div[contains(#class,'answer-toggle')]//button[contains(text(),'Yes')]")).Click();
This will first locate a div that has answer-toggle in its class name and the find a button that has text Yes
Case 2: answer-toggle is not unique in your HTML page the you can use the complete class name as follows
Driver.Instance.FindElements(By.XPath("//div[#class='btn-group btn-group-default answer-toggle']//button[contains(text(),'Yes')]")).Click();
or
Driver.Instance.FindElements(By.XPath("//div[#class,'btn-group btn-group-default answer-toggle']//button[contains(text(),'Yes')]")).Click();
Case 3: If there is only one button in your HTML page that has text "Yes"
Driver.Instance.FindElements(By.XPath("//button[contains(text(),'Yes')]")).Click();
Same thing applies for No button. You just have to replace Yes with No.
There are definitely multiple options to locate the buttons, but I think that answer-toggle class sounds a good thing to rely on:
var buttons = Driver.Instance.FindElements(By.CssSelector("div.answer-toggle button.btn"));

Categories