How to get field value - selenium c# - c#

Im trying to get field value (having link inside) for future use, so i want to place it under parameter.
the problem is the his class name used if 7 more fields so he isnt unique.
is there a way to get this field value using the label value above this field (called "Get direct link")?
<div class="form-group">
<label>Get direct link:</label>
<input class="form-control" type="text" style="cursor: auto;
value="http://ds2.dev.polebeary.com/api/download/1521723231257836/qa_yaakov_tevel.dmg" readonly="">
</div>"
need the link (who can be change of course..)

What you need here is XPath. Find this element by using following XPath expression.
//div[#class="form-group"][label[text()="Get direct link:"]]/input
Means: Select input field which is in a div. That div has an attribute class = "form-group" and at least have a child with name label, and that label has text "Get direct link:" in it.
For C# syntax
if you are using IWebDriver:
var element = driver.FindElement(By.XPath("//div[#class="form-group"][label[text()="Get direct link:"]]/input"));
if you are using WebDriverWait:
var element = waitDriver.Until(ExpectedConditions.ElementIsVisible(By.XPath("//div[#class="form-group"][label[text()="Get direct link:"]]/input")));

Related

Selenium C# - Find element by Id dynamically (Id name unknown)

I'm trying to find an element where the Id name has changed (and I'm not sure what it's been changed to), so I need to find it dynamically instead. The current code is:
[FindsBy(How = How.Id, Using = "address.surname")]
public IWebElement AddressLastname_Input { get; set; }
public void AddressEnter_function(IWebDriver D, DataRow UserDetail)
{
log.sendkeylog(AddressLastname_Input,
UserDetail["LastName"].ToString(),
"Enter LastName Address Section", drv: D);
}
The corresponding HTML:
<div class="form-group">
<label class="control-label " for="address.surname">
Last name<span> <font color="red">*</font></span>
</label>
<input id="address.surname" name="lastName" class="form-control form-
control" required="required" type="text" value="">
</div>
The error I get is "Cannot find element by Id". Is there a way of finding it without knowing the specific Id name/text?
It's hard to answer without seeing your HTML markup, but if Id and name keep changing, perhaps you can try locating it via CSS or even better, XPath?
XPath has proven to be more reliable for me albeit a bit slower.
WebDriver.FindElement(By.XPath("//input[#class='login']")).Click();
In your code, form-control class should give you a hint so maybe you want to run an xpath that searches for elements of type input, that have the class form-control and optionally checking value as well?
This request is not making sense to me 100%. If the element is not found, is it on an iFrame or modal by chance?
Is the id changing? If so you could try:
//div[#class='form-group']/input[#name='lastName']
or
//label[#for='address.surname']/following-sibling::input

Get Checkbox label text Selenium C#

I'm trying to get the text value of checkbox label. Here is an HTML code
<div id="content" class="large-12 columns">
<div class="example">
<h3>Checkboxes</h3>
<form id='checkboxes'>
<input type="checkbox"> checkbox 1</br>
<input type="checkbox" checked> checkbox 2
</form>
</div>
So What I have tried so far
Driver.FindElement(By.XPath("//input[#type='checkbox']")).Text;
Driver.FindElement(By.XPath("//input[#type='checkbox']")).GetAttribute("value");
Driver.FindElement(By.XPath("//input[#type='checkbox']")).GetAttribute("name");
Driver.FindElement(By.XPath("//input[#type='checkbox']")).GetAttribute("innerText");
Driver.FindElement(By.XPath("//input[#type='checkbox']")).GetAttribute("innerHTML");
Here is a screenshot
All this attempts return "".
Any ideas how to get it or Javascript is my only option ?
The xpath for a text following an input tag is //input[1]/following-sibling::text()[1] but there are serious limitations for Selenium to run expressions like this. It only can handle tag elements. Try to get the parent and retrieve texts from there.
string[] texts = Driver.FindElement(By.XPath("//form[#id='checkboxes']"))
.GetAttribute("innerText")
.Split("\r\n".ToCharArray()
);
Then texts[0] returns:
checkbox 1
Add an class or id attribute to the checkboxes and then try to find the element by css selector like: Driver.FindElement(By.CssSelector(""))
You can try following to get the required text from the two checkboxes:
Driver.FindElement(By.XPath("//form[#id='checkboxes']/input[#type='checkbox'][1]")).Text
Driver.FindElement(By.XPath("//form[#id='checkboxes']/input[#type='checkbox'][2]")).Text
Let me know, if above code does not work for you.
You can also use CSS Selector to get the checkbox label:
Element CheckBox = Driver.FindElement(By.CssSelector("input[type='checkbox']"));
string firstChkBoxTxt = CheckBox.FirstOrDefault().GetAttribute("innerText");
string secondChkBoxTxt = CheckBox.LastOrDefault().GetAttribute("innerText");

How to sendkeys to a <p> tag through C# and Selenium

i want to sendkeys "description" within a textarea. I have tried all the possible ways but does not work.
HTML of the element :
<div class="ta-scroll-window ng-scope ta-text ta-editor form-control" ng-hide="showHtml">
<div class="popover fade bottom" style="max-width: none; width: 305px;">
<div class="arrow"></div>
<div class="popover-content"></div>
</div>
<div class="ta-resizer-handle-overlay">
<div class="ta-resizer-handle-background"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-tl"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-tr"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-bl"></div>
<div class="ta-resizer-handle-corner ta-resizer-handle-corner-br"></div>
<div class="ta-resizer-handle-info"></div>
</div>
<div id="taTextElement737852736512107" contenteditable="true" ta-bind="ta-bind" ng-model="html" ta-keep-styles="true" class="ng-pristine ng-valid ta-bind ng-empty ng-touched" an-form-object-name="Açıklama" name="Açıklama">
<p>
<br>
</p>
</div>
</div>
Code trial :
Dim action2 = New Actions(driver)
Dim cekbul2 = driver.FindElement(By.XPath("//*#id=""taHtmlElement737852736512107""]"))
cekbul2.SendKeys("Açıklama")
Console.Write("textarea send description")
or
Dim cekbul2 = driver.FindElement(By.XPath("//textarea[#class='ng-pristine ng-untouched ng-valid ng-scope ta-bind ta-html ta-editor form-control ng-empty ng-hide' and #id='taHtmlElement737852736512107']"))
The error is :
"no such element: Unable to locate element does not work" give error
Your html does not have a text area input field inside it.
When you use an xPath that says
'//textarea' this means that you are looking for an element that has tags of <textarea> </textarea>
It looks like your html is actually div's that are styled up to look like text areas.
That is why your second attempt will never work - because you are looking for a textarea where none exists.
Typically, in the situation where a div is styled up to work like a text area or textbox, you will find that the div has a backing input behind it.
These must be located between the
<form> and </form> tags in the html - otherwise the server would never be able to receive the data. (Html 5 provides new ways of working with this - but that is another story)
Can you examine your full html, and see if you can find the actual text area objects or the input type objects that end up containing the text content.
Type some dummy text, and use an html inspector tool within chrome or firefox to look for your dummy text.
If however, the post is completed by javascript - you may find that the javascript does not use inputs or text areas for containing the text and instead posts it external to any form elements. This is common with richtext emulators such as forum post pages.
If that is the case- you may need to experiment and find the appropriate html element that you need to send keys to in order for the content to work.
Also - could you try
Dim cekbul2 = driver.FindElement(By.XPath("//div[#id='taHtmlElement737852736512107']"))
I couldnt help but notice it had an xPath syntax error - you had no starting [ square bracket ] - also, in programming it is sometimes considered lazy a bad practice to wildcard / work with dynamics. I recommend always using the tag type for your xpaths, as opposed to '//*'
Worse case scenario, I would say that you could probably get around this by using Javascript execution. Eg: Directly setting the text, instead of 'sending the key strokes'.
However, this does not emulate human behavior - but it may be a necessary evil depending on your situation.
To send text to the <p> tag you have to use the ExecuteScript() method from IJavaScriptExecutor Interface and you can use the following code block :
((IJavaScriptExecutor)driver).ExecuteScript("document.getElementsByTagName("p")[0].innerHTML="Hasan Sarıkaya";");
I want to highlight some points here
Most probably your locator which you are using is not correct.
There are three way which I know to enter text using selenium
1)Use driver.findElement(yourLoator).sendKeys("Stringvalue");
2)You can use action class to send keys
3)You can use javascript executor to change innerHtml code
Personally ill not prefer the third solution, because we are testers I believe changing dom attribute is a good practice
Hope this will give you some help. please Let me know in case any query.

Find node from known starting point in totally dynamic webpage using c# and XPath?

I am trying to write automated smoketest for an internal website. The problem is the website is almost primarily dynamically generated. So any kind of unique identifier like ID is a combination of known string prefix and ends with a radomized number.
I also can NOT depend on the order, so using things like div[2] or span[25] will not be reliable, UNLESS there is some way to grab the count of the span/div/input based on where I am currently located in the DOM by the KNOWN TEXT VALUE.
For example I can find the known text value. If I can somehow programatically determine that the span for this known text value is 55 , and I know that it is nested 2 deep from the other element I am looking for, then I could do something like "//span[55 - 2]/input".
The best I can do is navigate the DOM to some KNOWN text value, and work up OR down from there.
Given that, in the example below, how would I navigate to the INPUT element, when starting from the KNOWN TEXT VALUE???
<span id="RandomlyGenerated35673">
<span id="RandomlyGeneratedNum58532">
<span id="RandomlyGenerated78539">
<span/>
<span/>
<span id="RandomlyGenerated78539">KNOWN TEXT VALUE</span>
</span>
</span>
<input class="GENERIC-NON-UNIQUE" type="button" value="GENERIC-NON-UNIQUE"/>
</span>
You can use the following axis:
//span[. = 'KNOWN TEXT VALUE']/following::input[#type = 'button']

Using Selenium, how to click a radio button based on associated label

I'm using Selenium in C#, and I need to be able to specify which radio button on a website to click based on the text of the label that is associated with that radio button. I need to be able to pass that text in as a parameter. Here is a sample of what the code for the radio buttons looks like (this is for three buttons):
<input id="radSelect152_222_1369" class="bgRadioNotChecked" type="radio" onclick="BGQ.Ajax.SelectAnswer(this, '152','1369','3', '547');" value="1369" onfocus="BGQ.View.setLastElement(true);" name="radSelect152_222">
<label class="inline" for="radSelect152_222_1369">Watermelon</label>
<input id="radSelect152_222_1370" class="bgRadioNotChecked" type="radio" onclick="BGQ.Ajax.SelectAnswer(this, '152','1370','3', '547');" value="1370" onfocus="BGQ.View.setLastElement(true);" name="radSelect152_222">
<label class="inline" for="radSelect152_222_1370">Papaya</label>
<input id="radSelect152_222_1371" class="bgRadioNotChecked" type="radio" onclick="BGQ.Ajax.SelectAnswer(this, '152','1371','3', '547');" value="1371" onfocus="BGQ.View.setLastElement(true);" name="radSelect152_222">
<label class="inline" for="radSelect152_222_1371">Mango</label>
I want to be able to specify "Mango" in an Excel input file (I have all the file input stuff working fine) and have Selenium click the associated radio button. One approach that I read that I've been trying is to do the following:
Find the element that has the target text ("Mango") as its text
Get the FOR attribute from that element
Find the input that has an id equal to that FOR attribute
Click that input element.
Problem is, I'm pretty new to Selenium and can't quite figure the syntax for how to do these four steps. Can someone show me the way, with specific code examples? Also, or alternatively, is there a better/smarter way to do this? If so, please be specific.
I've included here the method I've started to write, in which I pass in the target text. I know it's wrong (especially in the By.XPath part).
public void ClickRadioButtonByLabelText(string labelText)
{
// (1) Find the element that has the label text as its text
IWebElement labelForButton = commondriver.FindElement(By.XPath(//label[text()='labelText']));
// (2) Get the FOR attribute from that element
string forAttribute
// (3) Find the input that has an id equal to that FOR attribute
// (4) Click that input element
}
Thanks.
You have two options.
Option 1 - do it all within a single XPath query
The XPath query would be:
//input[#id=//label[text()='TestCheckBox']/#for]
That is, get input that has an id which comes from the for attribute from a label that has the text of "TestCheckBox"
Option 2 - get the attribute from the label and then find the element in seperate steps
public void ClickRadioButtonByLabelText(string labelText)
{
// (1) Find the element that has the label text as its text
IWebElement labelForButton = commondriver.FindElement(By.XPath("//label[text()='labelText']"));
// (2) Get the FOR attribute from that element
string forAttribute = labelForButton.GetAttribute("for");
// (3) Find the input that has an id equal to that FOR attribute
IWebElement radioElement = commondriver.FindElement(By.Id(forAttribute));
// (4) Click that input element
radioElement.Click();
}

Categories

Resources