XPath select second element of many unless only one exists - html

I have a webpage with three <input> elements that all have the same name attribute. Ideally, I would like to select the second of these elements except sometimes there is only one element on the page and I want to instead select that element.
Ideally I would like something like (pseudo-code since max doesn't exist)
(//input[#name='myname'])[max(1, last()-1)]
I thought that maybe I could do something like the following except it yields all three elements
(//input[#name='myname'])[last()-1 or 1]
What is the best way to accomplish this using XPath?

Maybe grab both and then only the last one.
If there's two or more, it gets the second. If there's only one, it grabs that one.
((//input[#name='myname'])[position()=1 or position()=2])[last()]

Related

How to use the initial element as search box in select2?

I essentially want the same functionality in a "single" select as in a "multiple" select. In the multiple select, the original element is also the search box:
In single select, there is a separate span for the result (in the example below it displays ProfitLoss) and the search box (newsearch).
Is there a way to collapse those two elements into one, where one simply edits the original element (in the example, one would edit the element containing "profitloss")?
I tried setting minimumResultsForSearch to -1, that did not do anything. ChatGPT also did not come with any useful answers.
It's possible to customize HTML in handling events
First, You have to implement "multiple" select (Design the select field the same like the single one)
After then, you can do some customize in HTML by capturing the event
1. selecting
2. change
So, when the user selects the option, the selecting and select events are fired where you do your logic to customize the HTML, remove the item, OR add the item. It work like single select
I hope you got the idea

Issue creating the correct CSS Selector

I have been at this for a while and am throwing in the towel for help. I am trying to scrap this page specifically I am trying to get access to every table row that has information in it as highlighted green in the following picture. I do no need the table headers, just the rows.
With Scrapy I am able to get to each section area (where it says "Main Campus") with the following selector
response.css('.datadisplaytable .datadisplaytable')
I use .datadisplaytable twice because the tables I am trying to select are inside a table with that class. After that what seems logical to me to get to the table row I am after would be to use the following selector
response.css('.datadisplaytable .datadisplaytable tbody:nth-child(2)')
However, I get nothing with this selector. What am I doing wrong?
Your selector is a bit off. You're not trying to get the 2nd <tbody/> tag.
.datadisplaytable .datadisplaytable tbody tr:nth-child(n+2)
That will get you all the rows, and skip the header for each table.

How to select a child node by conditionally excluding a parents previous sibling

I have a question regarding using (what is to me) some complex XPath queries in Selenium IDE (thought they do apply to XPath in general).
Firstly, here is my scenario.
I'm writing some automated tests for a feature of a website I am working on that only certain items for sale on the website have. I'm trying to engineer the test in such a way that changes in data will not break it. Here is an abstraction of what I'm testing:
Given a set of search results, certain products within the results will have a feature (let's call the feature attributes), I want to click on the first result (which may change in the future) that has a single price and attributes.
I am using Selenium IDE 2.5.0 / FF 28.
Here is a JsFiddle I created that simulates the markup / DOM structure I have to work with (the markup cannot be changed): http://jsfiddle.net/xDaevax/3qUHB/6/
Here is my XPath query:
//div[contains(#class, 'primary')]//div[contains(#class, 'results')]//div[#class='price-range']/span[not(contains(#class, 'seperate'))]/../../..//a[#class='detail-link']
Essentially, the problem is this: All three have the same wrapping markup and css class information, but they differ in the price-range class due to the second element (the one I'm after) does not have "separate" or "minimum" CSS class elements.
I have made it this far with the XPath selector, but am stuck. I assume that when I traverse back up the DOM with the "/../..", I am losing the conditional XPath clause I previously used.
I apologize for the vagueness of the details, but due to contractual restrictions, I'm being as generic as possible.
Any suggestions on how to achieve the selection I want would be greatly appreciated. Please let me know if I need to clarify any of the requirements or steps I have tried.
Edit:
Here is a succinct description of the desired outcome.
In the markup example given, I want to select and click the link in the middle result element only. This is because the middle element has the desired "attributes" that once the link is clicked, it will take you to the product page which has additional things needing tested. That being said, the data could change: today it is the second element in the list, but maybe tomorrow it is the 7th element of 16 total elements.
My current logic for the XPath (though my solution does not work) is as follows: The element I am interested in is distinguishable from the other results because of two things: 1), it has a detail hyperlink (that will later be clicked) and 2) it does not have a range of prices (unlike the first result). Because the first result also has a hyperlink, the only difference between the two is that the first result has a minimum and separator markup element, while the second does not (my target link will always have a single price and not a range). Based on this information, I tried to write XPath that will select the first hyperlink that is not contained within an element that has a price range.
This expression will select all three div elements:
//div[contains(#class, 'primary')]
//div[contains(#class, 'results')]
//div[#class='price-range']
If I understood your requirements correctly, the price-range div must have a sibling that is an <a href> element, so we can filter out the last div by adding that restriction in a predicate: [../a[#href]]. So this expression selects only the first two divs:
//div[contains(#class, 'primary')]
//div[contains(#class, 'results')]
//div[#class='price-range']
[../a[#href]]
Now you can add one more predicate to remove the items that don't have a single price. You chose the separate class as the criterion, so we can change that last predicate and add another restriction to it: [../a[#href] and not(span[contains(#class,'separate')])]. Now your expression selects the div that you want:
//div[contains(#class, 'primary')]
//div[contains(#class, 'results')]
//div[#class='price-range']
[../a[#href] and not(span[contains(#class,'separate')])]
This is a location path, which creates a context. From this context, you can navigate anywhere you want. You can get the sibling <a href> adding a new step with its relative path: ../a. So, finally, this expression selects the link at the same level as your div:
//div[contains(#class, 'primary')]
//div[contains(#class, 'results')]
//div[#class='price-range']
[../a[#href] and not(span[contains(#class,'separate')])]
/../a
Or in one line:
//div[contains(#class, 'primary')]//div[contains(#class, 'results')]//div[#class='price-range'][../a[#href] and not(span[contains(#class,'separate')])]/../a

Slick (mootools) selector engine documentation

Mootools slick selector engine documentation seems kind of sparse / unfriendly.
http://mootools.net/docs/core/Slick/Slick
An example:
Normally i can reach the last child of an element with:
$('wrapper').getLast().setStyle('background-color','green');
how do i utilize the new slick engine to achieve the same?
And where is the documentation?
Should i just learn CSS3 selectors?
In their example they use $$('p.foo !^') to get the last child of p class foo whatever that means. (do they mean the last instance of p.foo in the $$ array or the last child of the last element???)
Here i tried to fiddle a bit, the last two doesn't work:
http://jsfiddle.net/XLVr6/1/
The example bellow will select the last child of the element with id="wrapper. It will only return one element.
$$('#wrapper !^').setStyle('background-color','red');
or better way as only one element is needed, as it is faster:
document.getElement('#wrapper !^').setStyle('background-color','red');
However, if it's written like this where we select the last child of all p-elements on the page with class="wrapper"
$$('p.wrapper !^').setStyle('background-color','red');
Another way to do it is like this, however next example is faster:
('someId').getLast().setStyle('background-color','red');
As pointed out by Dimitar this is a better (faster) way to do it:
document.getElement('#someId :last-child')
As for your fiddle, the two last selectors should be written like this:
$$('#wrapper :last-child').setStyle('background-color','red');
$$('#wrapper !^').setStyle('background-color','red');
Please note the space between "wrapper" and ":last-child", that is because we are selecting the last child of a the child elements of "wrapper".

xpath help can't get the text?

I am unable to get the text from this website: http://mp3bear.com...so now I just want to get the title of the song that is displayed on it.. here is what i wrote as the code:
//table/tr[2]/td[2]
so now I want to get second row from second column... it doesn't display anything.... is there any thing special when
I can't find any table element on this site, the tables are constructed with divs.
Therefore the expression for the second row of the second column of the table is.
//div[#id='listwrap']/div[3]/div[2]
There are some xpath implementations that don't allow indexing of child elements in this manner. In this case you could use
//div[#id='listwrap']/div[position()='3']/div[position()='2']
Edit:
In that case you need this expression:
//div[#id='listwrap']/div[3]/div[2]/a/text()
as the title is contained in a 'a' element and you use the xpath function text() to get the text value of the 'a' element
tested in firepath.