Validating form data that uses a selector with Selenium - selenium

I am attempting to automate checking the values of a form. I figured out how to check the values submitted via send_keys, but anything submitted via a selector is giving me trouble. I'm a n00b when it comes to automation.
This works:
driver.find_element_by_xpath("//*[#name='CurrentAddress.LineOne'][#value='123 Something Lane']")
This does not:
driver.find_element_by_xpath("//*[#name='CurrentAddress.StateAbbrev'][#value='TX']")
The code that governs the CurrentAddress.StateAbbrev is
<select class="form-control" data-val="true" data-val-required="* State is required" id="CurrentAddress_StateAbbrev" name="CurrentAddress.StateAbbrev"><option value=""></option>
When I try to validate the State, I get this:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#name='CurrentAddress.StateAbbrev'][#value='TX']"}
The form value stores the input as 'TX' but the page shows the State as 'TEXAS'. I've tried looking for either, but it still cannot locate the element. Attempting to locate it via either #name or #id doesn't change the outcome.

I haven't tested this code, but it should work.
//Rather than creating the object of WebElement create object of Select
Select stateDropdown = new Select(driver.findElement(By.xpath("//select[#class='form-control']"));
//To select by visible text, pass the text
stateDropdown.selectByVisibleText("");
//Get text of first selected option
String selectedValue = stateDropdown.getFirstSelectedOption().getText();

This ended up working for me:
driver.find_element_by_xpath("//*[#class='form-control']/option[text()='TEXAS']")

Related

Unable to access the element in the frame

I am still dipping my toes in selenium , I am SAP guy working on Selenium automation POC. my requirement is to click on the drop down and select a value from the droplist.
I have extensively looked at the previous posts but could not find any answers. I have tried all the suggestions from the post but nothing seems to be working for me.
Please can you help me how to access this drop down value.
HTML code is attached in the pic along with the element that I am trying to access
My selenium code :
driver.switchTo().frame(driver.findElement(By.name("SMFrame")));
System.out.println("TExt" + driver.findElement(By.xpath("//div[#class='file-type']")).getText());
Error:
error -- > no such element: Unable to locate element: {"method":"xpath","selector":"//div[#class='file-type']"}
Image
Assuming you are correctly getting into the iframe
Right now you are selecting a div above the actual dropdown element (the select-dropdown tag). You may want to try changing your xpath to search for the tag like so:
//div[#class='file-dropdown']/select-dropdown
Also you should be creating a dropdown object like this. Then calling a method on it to select the dropdown option you are looking for:
Select dropdown = new Select(driver.findElement(By.xpath("//div[#class='file-dropdown']/select-dropdown");
System.out.println(dropdown.selectByVisibleText("text that you are looking for in the options"));
This is a good explanation of how to do it: https://www.javatpoint.com/selenium-webdriver-handling-drop-downs

Require help in identifying element in testcafe

I am new to automation testing and coding. I am using testcafe in one of my project to automate the functional testing.
In one of the webpage there is a field which only accept numeric values and gives error message if any alphanumeric values are entered.
As a part of my validation I need to capture this error message.
Issue which I am facing here is I am not able to determine which element it is in DOM.
For example gmail user name can be considered for this and error message that we get while we try to enter invalid user message.
This is how the DOM looks like for the field
<div class="flex-content space-100 space-large-reset ">
<label for="uid">Unique ID Number</label>
<input type="password" id="uid" maxlength="9" value="123js" class="abyss-textinput abyss-form-invalid">
<div class="abyss-error-message">Please enter a valid Unique ID Number.</div></div>
Value ="123js" is the incorrect value which i entered which generated error message mentioned in next line.
Thanks in advance.
Firstly, I'll confess I'm no authority on testcafe, just learning myself.
That being said I've assertions which work as follows:
await t.expect(Selector('h2').withText('Some text').exists).ok();
In you case if there's no id/class you can use to narrow the search it could be fairly inefficient (there are likely a lot of divs/spans in your app). Could you provide some info about the dom used to display the errors ?
As a #Iain_b said, you can use a Selector and the ok() assertion to check presence of the error message. You can use Adjacent sibling combinator to select the error's <div> tag. However the element can be inserted into the DOM tree after validation is failed, or be there since page loading and just become visible after validation is failed.
So for the first case you should use something like:
await t.expect(Selector('#uid + .abyss-error-message').withText('Please enter a valid Unique ID Number').exists).notOk();
await t.typeText('#uid', '#$dfgh');
await t.expect(Selector('#uid + .abyss-error-message').withText('Please enter a valid Unique ID Number').exists).notOk();
and for the second:
await t.expect(Selector('#uid + .abyss-error-message').withText('Please enter a valid Unique ID Number').visible).notOk();
await t.typeText('#uid', '#$dfgh');
await t.expect(Selector('#uid + .abyss-error-message').withText('Please enter a valid Unique ID Number').visible).notOk();
Thanks for the help guys..
I was able to find the element using below mentioned condition
Selector ('.abyss-error-message').withText('Please enter a valid UID')

how to get the readonly field value using selenium

I have read only field on Webpage as
<div id="dspIdDescriptionDet-inputEl" class="x-form-display-field" role="input" aria-invalid="false" data-errorqtip="" style="width: 100%;">2010-RR3 XIIIA9 20360726 FLT</div>
When I'm trying to get the display value ("2010-RR3 XIIIA9 20360726 FLT") using getText() or getAttribute("Value") using Webdriver, its fetching nothing.
error on eclipse:
expected:<2010-RR3 XIIIA9 20360726 FLT> but was:<null>
code:
driver.findElement(By.xpath(".//*[#id='dspIdDescriptionDet-i‌​nputEl']")).getAttri‌​bute("value"))
For getting the text of an element which has a unique id try using:
driver.findElement(By.id("dspIdDescriptionDet-inputEl")).getText()
Moving my comment to an answer since it turned out to be the issue...
I would try adding a wait. It may be that the element is present but it takes a bit for the data to populate into the field.

Selenium preceding-sibling::text() not working

I am having issues with selenium using the next xpath "./preceding-sibling::text()"
I don't understand why, my first thought was that IE wasn't supporting that xpath statement but it didnt work on chrome neither.
What I am trying to do is to verify if a radio button have a certain text "near" it. For example if a radio button is like this
<div>
<label> Yes <input name='radioBtn'></input></label>
<label> No <input name='radioBtn'></input></label>
</div>
This is a simplified scenario where I need to check the "yes" radio button, so what I am doing is to search for the radiobutton and check if it preceding-sibling::text(), but selenium is cant find any element. I know the Xpath works because I test it on chrome developer tools and it returns the text "Yes".
I can't do something like 'input[1]' because I can't be sure that the first one will be always that have the Yes text.
Any idea why isn't this working on selenium? and if there is any work around?
I got to a work around but is kind of specific to the problem. But let's answer the questions 1 at the time.
Any idea why isn't this working on selenium?
It's not working because selenium don't support text elements, so even when selenium find the element it cant map it to a selenium object, i didn't see it because my code hided the selenium exception. The Exception throw is the next one:
An unhandled exception of type
'OpenQA.Selenium.InvalidSelectorException' occurred in WebDriver.dll
Additional information: invalid selector: The result of the xpath
expression "./preceding-sibling::text()" is: [object Text]. It should
be an element
Is there any work around?
Yes it is. What I did was to run a java script using the selenium IJavaScriptExecutor. With the script I revised the preceding sibling text and return it as a string so if the text was equal to the thing I was looking for (i.e Yes) trhat means that is the radio button I was looking for.
The code looks is similar to this (it can have some sintax errors since I didn't copied from the source):
string script = "function GetPrecedingText(node){"+
"var result = document.evaluate('./preceding-sibling::text()[1]', node, null, XPathResult.STRING_TYPE, null);"+
"return (result==null) ? '' : result.stringValue.trim();}"+
"return GetPrecedingText(arguments[0])";
string result = ((driver as IJavaScriptExecutor).ExecuteScript(script, SeleniumElement)).toString();
Hope someone can find this useful :) and thanks for all that tried to help me :)

How to find value of email field using Selenium2Library

I am writing regression tests for a web application using robot framework and the Selenium2Library library. I have a simple test which changes all of the fields of an "account settings" type form (think username, password, email, etc.), then revisits the page and makes sure all of the data was saved. Like so:
*** Test Cases ***
Sample Test
Change All Account Details
New Account Details Should Be Saved
*** Keywords ***
Change All Account Details
Navigate to Account Page
Input Text accountSettingFrom_firstname Test
Input Text accountSettingFrom_lastname Dummy
Input Text accountSettingFrom_email new_email#example.com
# etc etc, eventually save the form
New Account Details Should Be Saved
Go To ${ACCOUNT_URL}
Textfield Value Should Be accountSettingFrom_firstname Test
Textfield Value Should Be accountSettingFrom_lastname Dummy
Textfield Value Should Be accountSettingFrom_email new_email#example.com
I get the following error on the final step (Textfield Value Should Be accountSettingFrom_email new_email#example.com) when running this test: Value of text field 'accountSettingFrom_email' should have been 'new_email#example.com' but was 'None'
I have taken screenshots the moment before that step runs, and I have added a pause and manually confirmed that the value attribute of 'accountSettingFrom_email' is indeed 'new_email#example.com'. HTML of the element at time the check occurs:
<input type="email" name="accountSettingFrom[email]" value="new_email#example.com" class="foo bar" required="required" tabindex="3" maxlength="128" url="/foo/bar" userid="foobar" id="accountSettingFrom_email">
You'll notice that the first two Textfield Value Should Be keywords pass. The only difference I can discern between the three elements is that 'accountSettingFrom_email' is type="email" instead of type="text", but if the the keyword is successfully locating the element, then why can't it grab the value of the value attribute?
So am I doing something wrong? I feel like this or some similar keyword must exist to test this, without having to resort to writing a custom library.
You have hit some bugs in Selenium2Library. When Selenium2Library was created, HTML5 was not ratified. Internally the library is filtering out your element because it has a type other than 'text' (made sense before HTML5). Textfield Value Should Be can only find your element if it has tag name input and attribute value 'text' for type.
See https://github.com/robotframework/Selenium2Library/issues/546
Also due to how Textfield Value Should Be is implemented, the error you are getting makes you think the element was found when in fact it was not because it was filtered out.
See https://github.com/robotframework/Selenium2Library/issues/547
In contrast, Input Text and Input Password have never filtered on element tag or attribute.
I would try Get Element Attribute instead to get the attribute named value instead. According to the API it should be
accountSettingFrom_email#value