XPATH- How to select radio button and text in a single xpath expression? - xpath

I have Radio button with value as "CREDIT_CARD" and the text of the radio button as "New". Now i need to select a radio button which has text "New".
<div>
<input type="radio" onchange="javascript:toggleAdvancedDisplay('pay_detail','CREDIT_CARD');" value="CREDIT_CARD" name="payment_type" style="margin:0; vertical-align: middle;"/>
<span class="value">New</span>
I tried the below xpath, but it doesn't locate the expected element.
/fieldset[1]/div/div/div[2]/input[#value='CREDIT_CARD']/fieldset[1]/div/div/div[2]/span[contains(text(), 'New')]
What is it i am doing wrong here?

You can try :
xpath = //input[#value='CREDIT_CARD' and following-sibling::span[contains(., 'New')]]
This will get input tag with CREDIT_CARD as value and whose sibling contains New as text.

The <span> element is not a child of the <input> element, but it is the next sibling. XPath should be:
/fieldset[1]/div/div/div[2]/input[#value='CREDIT_CARD' and following-sibling::span[1] = 'New']

Try this. Does this locate the element you're looking for?
xpath = //*[#value="CREDIT_CARD"]/span[contains(.,"New")]

Related

document.querySelectorAll("span + a") didn't work?

I have a HTML like this.
<span class="vm-video-side-notification-text-item">
Includes copyrighted content
</span>
I use
var x = document.querySelectorAll("span + a");
alert(x.length);
the alert is "0"... I don't know why.
I see the w3school says
element+element
div + p
Selects all <p> elements that are placed immediately after <div> elements
so I try span + a. Can anyone correct my mistake?
You're conflating elements with tags.
While the start tag of the a is directly after the start tag of the span indeed, the a element is inside the span element.
So, in order for your example to work, you can either
change the query selector to "span > a" for "any a directly inside a span"
var x = document.querySelectorAll("span > a");
alert(x.length);
or change the html to have the a element after the span element
<span class="vm-video-side-notification-text-item">
</span>
Includes copyrighted content
(... but not both!)

How to click on repeated button on a page?

I have a table layout like this:
<tbody>
<tr>
<td> 1 </td>
<td> <button> Click me </button>
</tr>
<tr>
<td> 2 </td>
<td> <button> Click me </button>
</tr>
....
</tbody>
I only know the value of the first td (1,2, etc). Is there anyway to click on the appropriate second td (the button) while only knowing the first td? For example, can I dynamically get 2 and know to click on the second "Click me" button instead of the first one?
yes there is way:
Basically, the buttons you want to click are siblings to the td elements you already know of.
Please try using locating an element via xpath sibling to locate those buttons:
//td[contains(text(),'1')]/following-sibling::* //this reads, first locate an element of td type whose text() attribute contains '1', then find its immediate sibling.
//td[contains(text(),'2')]/following-sibling::* //this reads, first locate an element of td type whose text() attribute contains '2', then find its immediate sibling.
You need an XPath:
twoClickMeButton = driver.find_element(:xpath,"//td[text()='2']/../td/button")

Finding the text of a label using Capybara

Finding the text of a label using Capybara
Background: I have a KBA page and a set of question and answers, the answers are in the form of 5 possible answers using radio buttons. So I need to cycle through each label for each radio button to match up with valid answers in a yaml file.
HTML:
<div class="questions"></div>
<div class="answers"></div>
<p>
<label>
<input id="answers_question_0_1" type="radio" checked="checked" value="1" name="answers[question_0]"></input>
RADIO BUTTON TEXT 1
</label>
</p>
<p></p> #another radio button and label text 2
<p></p> #another radio button and label text 3
<p></p> #another radio button and label text 4
<p></p> #another radio button and label text 5
My test code:
def answer_questions
.
.
.
i=0
def answers
page.all('.answers')
end
#This is accessing the answer value from the selected correct question from the kba.yml file
valid_answers = this variable contains the valid answer to the question
#********THIS IS THE PROBLEM BLOCK*****************************
#Set the radio buttons if they match one of the answers
#correct_answer = answers[i].all(:radio_button).find do |radio|
valid_answers.include?(radio.parent.text)
end
#********THIS IS THE PROBLEM BLOCK*****************************
i +=1
unless #correct_answer
p "Unable to answer question: #{question_text}" and next
end
#correct_answer.select
end
The problem lies in the "problem block" noted in the above code snippet. I can't figure out how to get the text that is tied to one label/p tag per radio button, instead ALL radio button's text are returned and checked against the variable "valid_answers" and that always fails.
I basically want radio.button.text to equal "RADIO BUTTON TEXT 1" for it's respective radio button. But instead radio.button.text returns:
RADIO BUTTON TEXT 1 RADION BUTTON TEXT 2 RADIO BUTTON TEXT 3 etc.
I'm guessing it shouldn't be radio.parent.text but something else, which I'm not sure.
It looks like you're making this more complicated than it needs to be - you should just be able to do
answers[i].choose("the text of the radio button you want to select")
You can catch an exception if the value isn't found and output your warning there.
Note: parent in a Capybara element is not the HTML parent of that element - it's the element that a finder was called on when locating the given element - so in your case it's the .answers element. If you do want access to the nodes actual HTML parent element you can call element.find(:xpath, '..')

document type does not allow element "div" here; missing one of "object", "applet", "map", "iframe", "button", "ins", "del" start-tag

I am getting a w3c validation error here as
The mentioned element is not allowed to appear in the context in which you've placed it; the other mentioned elements are the only ones that are both allowed there and can contain the element mentioned. This might mean that you need a containing element, or possibly that you've forgotten to close a previous element.
One possible cause for this message is that you have attempted to put a block-level element (such as "<p>" or "<table>") inside an inline element (such as "<a>", "<span>", or "<font>").
This is my source code
<ul class="link">
<li><span>1<div class="clr"> </div><label>Vul Postcode in </label></span></li>
<li><span>2<div class="clr"> </div><label>Restaurants </label></span></li>
<li><span>3<div class="clr"> </div><label>Menukaart</label></span></li>
<li><span>4<div class="clr"> </div><label>Afrekenen</label></span></li>
</ul>
Please help me to find out the issue,
Thanks
Pallavi
You have a block element (div) inside of an inline element (span). This is not allowed.
Solution 1: Change span to div:
<div>2<div class="clr"> </div><span class="label">Restaurants </span></div>
(You have to use HTML5 (<!DOCTYPE html>), otherwise block elements wouldn’t be allowed inside of a elements.)
Solution 2: Change div to span:
<span>2<span class="clr"> </span><span class="label">Restaurants </span></span>
Note that you can’t have label inside of an a element (I changed the label to span here). Use the label element only when you have a form.

How to press/click the button using Selenium if the button does not have the Id?

I have 2 buttons Cancel and Next button on the same page but it has only one id (see the below code). I wanted to press Next but every time it is identifying the cancel button only not Next button. How to resolve this issue?
<td align="center">
<input type="button" id="cancelButton" value="Cancel" title="cancel" class="Submit_Button" style="background-color: rgb(0, 0, 160);">
<input type="submit" value="Next" title="next" class="Submit_Button">
</td>
Use xpath selector (here's quick tutorial) instead of id:
#python:
from selenium.webdriver import Firefox
YOUR_PAGE_URL = 'http://mypage.com/'
NEXT_BUTTON_XPATH = '//input[#type="submit" and #title="next"]'
browser = Firefox()
browser.get(YOUR_PAGE_URL)
button = browser.find_element_by_xpath(NEXT_BUTTON_XPATH)
button.click()
Or, if you use "vanilla" Selenium, just use same xpath selector instead of button id:
NEXT_BUTTON_XPATH = '//input[#type="submit" and #title="next"]'
selenium.click(NEXT_BUTTON_XPATH)
In Selenium IDE you can do:
Command | clickAndWait
Target | //input[#value='Next' and #title='next']
It should work fine.
use the text and value attributes instead of the id
driver.findElementByXpath("//input[#value='cancel'][#title='cancel']").click();
similarly for Next.
For Next button you can use xpath or cssSelector as below:
xpath for Next button: //input[#value='Next']
cssPath for Next button: input[value=Next]
You don't need to use only identifier as elements locators. You can use a few ways to find an element. Read this article and choose the best for you.
You can use xpath for for identifying that element.
You can achieve this by using cssSelector
// Use of List web elements:
String cssSelectorOfLoginButton="input[type='button'][id='login']";
//****Add cssSelector of your 1st webelement
//List<WebElement> button
=driver.findElements(By.cssSelector(cssSelectorOfLoginButton));
button.get(0).click();
I hope this work for you

Resources