I am working on automation tests using Appium and Robotframework. The keyword Element Should Contain Text seems to return empty if the input field is disabled. How to verify a disabled input field has a given value?
<input type="text" id="myId" name="myName" disabled />
I get the following error:
Element 'myId' should have contained text 'myValue' but its text was ''.
Make sure your code is correct and you are passing the correct id/classname. If this does not work please post the HTML code you are using. Adding some of the sample example which you can try out :-
If your tag is something like this below -
<input disabled="true" id='data'>
Your code should be -
WebElement webElement = driver.findElements(By.id('my-id'));
webElement.getAttribute("disabled")
or
WebElement.getAttribute("id")
For this tag -
<input id="j_idt93:j_idt93" type="text" disabled="disabled" maxlength="2000" value="Pārtraukts">
To get the value attribute -
String value = driver.findElement(By.id("j_idt93:j_idt93")).getAttribute("value");
If this does not work you may have to use the javascript executor -
String value = (String)((JavascriptExecutor) driver).executeScript("Java script query in here to return value","");
Your query should be -
return document.getElementById("j_idt93:j_idt93").getAttribute("value");
Let me know if this does not work.
Its true selenium returns empty if I assert text in disabled fields by using Element or page contains text... However we can compare the text in field by using Get Value and then comparing the field value with the value you want to assert by should be equal.
In your case what you can do is,
${valueInField} Get Value myId
should be equal ${valueInField} ${myValue}
I solved this problem.
*** Keywords ***
Should Not Be Empty
[Arguments] ${locator}
${getValueOfTextField}= Get Element Attribute ${locator} value
Should Not Be Empty ${getValueOfTextField}
I didn't get the value out, but I'm sure it's not empty.
Related
I have a page with multiple textboxes and dropdowns with values that I am trying to validate. The values in them will be dynamic in each run.
The HTML looks something like:
<input readonly="readonly" class="form-control valid" data-val="true" data="ABC" aria-invalid="false" xpath="1">
What I want to do is grab the value of "data" for each textbox. I have used scriptAll before in such a case when I was grabbing text by using innerText. However, that won't work with a regular value such as in the HTML above.
I did try one solution that worked:
driver.value(//input[#data])
However, that just grabs the first textbox value, is there a way I can combine scriptAll with driver.value? OR would I be better off doing some JS here?
Thank you in advance!
Yes, refer the docs for scriptAll(): https://github.com/karatelabs/karate/tree/master/karate-core#scriptall
Use whatever JS works to get an attribute value. Haven't tried, but this should work, you get the idea:
* def list = scriptAll('input', "_.getAttribute('data')")
The page contains a multi-select dropdown (similar to the one below)
The html code looks like the below:
<div class="button-and-dropdown-div>
<button class="Multi-Select-Button">multi-select button</button>
<div class="dropdown-containing-options>
<label class="dropdown-item">
<input class="checkbox">
"
Name
"
</label>
<label class="dropdown-item">
<input class="checkbox">
"
Address
"
</label>
</div>
After testing in firefox developer tools, I was finally able to figure out the xPath needed in order to get the text for a certain label ...
The below XPath statement will return the the text "Phone"
$x("(//label[#class='dropdown-item'])[4]/text()[2]")
The label contains multiple text items (although it looks like there is just one text object when looking at the UI) in the label element. There are actually two text elements within each label element. The first is always empty, the second contains the actual text (as shown in the below image when observing the element through the Firefox developer tool's console window):
Question:
How do I modify the XPath shown above in order to use in Selenium's FindElement?
Driver.FindElement(By.XPath("?"));
I know how to use the contains tool, but apparently not with more complex XPath statements. I was pretty sure one of the below would work but they did not (develop tool complain of a syntax error):
$x("(//label[#class='dropdown-item' and text()[2][contains(., 'Name')]]")
$x("(//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
I am using the 'contains' in order to avoid white-space conflicts.
Additional for learning purposes (good for XPath debugging):
just in case anyone comes across this who is new to XPath, I wanted to show what the data structure of these label objects looked like. You can explore the data structure of objects within your webpage by using the Firefox Console window within the developer tools (F12). As you can see, the label element contains three sub-items; text which is empty, then the inpput checkbox, then some more text which has the actual text in it (not ideal). In the picture below, you can see the part of the webpage that corresponds to the label data structure.
If you are looking to find the element that contains "Name" given the HTML above, you can use
//label[#class='dropdown-item'][contains(.,'Name')]
So finally got it to work. The Firefox developer environment was correct when it stated there was a syntax problem with the XPath strings.
The following XPath string finally returned the desired result:
$x("//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
In my case, there are some legacy web sites, in which not all the inputs have
id attribute properly set. Such as this:
<div class="form-group">
<label>Amount</label>
<input id="unreasonablename" type="text" value=""></input>
</div>
But human testers can still test it by typing amount value in the input right behind "Amount". I'd like to make web driver do the same thing:
webDriver.inputAfter("Amount", 100); //I do not want to use "unreasonablename" to find the input.
But how can I find the input element after the text "Amount"? Thanks.
There is a relative question here: In Selenium Webdriver, how to get a text after an element?. But I'm not familiar with xpath and do not know if my case can be solved in the same way.
To find the <input> element just after the text Amount you can use the findElement() method along with the Locator Strategy as follows :
webDriver.findElement(By.xpath("//label[contains(.,'Amount')]//following::input[1]"));
you can try following_sibling as
webDriver.findElement(By.xpath("//*[text()='Amount']/following-sibling::Input"));
try this :
driver.findElement(By.xpath("//label[text()='Amount']/following-sibling::input")).sendKeys("amount to be sent");
you can write some generic method like below. It can be used for all the required fileds by passing the label name and input value as argument
void enterInputAfterLabel(String labelname,String value){
driver.findElement(By.xpath("//label[text()='"+labelname+"']]/input")).sendKeys(value);
}
Consider sample below:
//edit.html
<input type="number" step="1" value.bind="number" />
<div repeat.for="num of number">${num}</div>
//edit.ts
export class Edit {
number: number = 2;
}
I expect to see 2 divs on first page load and number of divs should change when I change number in input. Instead I get error
Value for 'number' is non-repeatable
I figured it out. If you bind input field to variable, even when variable is number, it will be changed to string when changed by user. In my case, number became string once changed in input field. I used this gist to help me solve this problem:
https://gist.github.com/jdanyow/d9d8dd9df7be2dd2f59077bad3bfb399
It offers custom element and attribute for binding numbers to input fields.
HTML:
<input type="text" size="15" maxlength="79" value="" name="username">
As you can see, no ID. The HTML above is a textbox that i want to auto fill in whit my value as soon as i start the webpage whit my code.
this is what i found:
WebBrowser1.Document.Forms(0).GetElementsByTagName("username")(0).SetAttribute("value", (Text))
But whit this i get the error:
Value of '0' is not valid for 'index'. 'index' should be between 0 and -1.
Parameter name: index
What am i doing wrong?
This isn't going to find any elements:
WebBrowser1.Document.Forms(0).GetElementsByTagName("username")
"Tag name" doesn't mean the value of the name attribute, it means the name of the HTML tag itself. Like this:
WebBrowser1.Document.Forms(0).GetElementsByTagName("input")
Of course, this is likely to return multiple matched elements, so you'll need to further identify which one you want to modify. The point being that you should do some error checking to make sure that it finds anything, because trying to index an empty collection will result in an error:
WebBrowser1.Document.Forms(0).GetElementsByTagName("username")(0)
Since the collection has no elements, there is nothing at index 0.
May be u could try
Me.WebBrowser1.Document.GetElementByName("username").SetAttribute("Value", txtUsername.Text)