eclipse xpath element button location - selenium

I cannot locate this element by xpath or another option.
<button tabindex="0" class="jss65 jss59" type="button">
<span class="jss64">
<svg class="jss68" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="presentation">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
<path fill="none" d="M0 0h24v24H0z"></path>
</svg>
</span>
<span class="jss77"></span>
</button>```

You can locate this button using relative xPaths. For example, the following relative xPath worked for me when locating this element:
//button[#class="jss65 jss59"]
For further information on how to customize your relative xPath, I would encourage reading up on this article: https://www.guru99.com/xpath-selenium.html
Personally, however, if you have the option of changing this element, I would highly encourage the use of id within the <button> tag. This way, you have the option of locating the element by id, rather than by relying on xPath. Since id is designed to always be unique per page, it can often be a much easier and reliable solution over xPath when locating an element.

Related

Find Xpath to an element depending on the value of another element in a table row

I'm new to Xpath so if this doesn't contain all relevant information apologies & let me know what you need to solve it.
I am trying to find an Xpath to an "expand arrow" element which expands a row in a table. The "expand arrow" element isn't unique so I would like to select it based on text contained in another element on the same row. The layout is as follows:
<td id="__table2-rows-row10-col0">
<div class="sapUiTableCellFlex">
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
<div id="__hbox27-__clone101">
<div id="__data70-__clone101">
<div id="__data71-__clone101">
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I'd like to select the element with title = "Expand Node"
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
based on the element with title or text = "sys-admin"
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I've played around with various options but I can't seem to get it to work. Any ideas would be much appreciated!
Thanks
To locate the element with title as Expand Node with respect to the element with title or text as sys-admin you can use either of the following Locator Strategies:
xpath and title attribute:
"//span[#title='sys-admin']//ancestor::span[#title='Expand Node']"
xpath and text() attribute:
"//span[text()='sys-admin']//ancestor::span[#title='Expand Node']"
I eventually got it to work using the following xpath:
//span[#title='sys-admin']/../../preceding-sibling::span[#title='Expand Node']

How to write Xpath for next Div using Sibling

I want to read the Tax Price using the sibling concept, so I have I've written below XPath, but it's not working
My code:
//div[#class='grid_3 d-grid_10']//label[contains(text(), 'Tax')]/following-sibling::div
HTML:
<div class="grid_3 d-grid_10">
<label class="m-confirmation-modal-print-detail-capgrey"> Tax:</label>
</div>
<div class="grid_1 d-grid_2">
<label class="m-confirmation-modal-print-price text-align-right"> $10.50</label>
</div>
To read the Tax Price i.e. $10.50 using text Tax within the ancestor node, you need to locate the <label> node with text as Tax: first. Then with respect to this node you need to locate the following <div> node which have a decedent node containing the required text i.e. $10.50 and to achieve that you can use the following solution:
XPath:
//label[#class='m-confirmation-modal-print-detail-capgrey' and contains(.,'Tax')]//following::div[1]/label
The second <div> is a sibling of the first one, not of the child <label>. You need to go back to the parent <div> first using .. or parent::div
//div[#class='grid_3 d-grid_10']//label[contains(text(), 'Tax')]/parent::div/following-sibling::div
As suggested in the comments you can simplify it by starting the xpath with the "Tax" <label>
//label[contains(text(), 'Tax')]/parent::div[#class='grid_3 d-grid_10']/following-sibling::div
You can use this :
//label[contains(text(), 'Tax')]/../following-sibling::div

How to identify an element whose id is dynamically changing and has no other attributes in selenium?

I've this html body for a kendo dropdown list which has only one attribute i.e. id which is dynamically changing, how do i identify this object on every page refresh accurately.
other attributes like class and tab index already are present with same values multiple times on the same page for other dropdowns-
<span role="listbox" unselectable="on" class="k-dropdown-wrap k-state-default" id="dde13a91-2bf3-4e41-af72-bee1b881a8d9" dir="ltr" readonly="false" tabindex="0" aria-disabled="false" aria-readonly="false" aria-haspopup="true" aria-expanded="false" aria-owns="48f666d8-4c3c-43a8-a4dc-8e7a9961a0ef" aria-activedescendant="ca3c4431-3ebf-46c0-9510-a64a32eae108-C.US.0000110896">
<span unselectable="on" class="k-input">
<!---->
<!---->2018 ALBERTSONS / Beverage Mixes
</span>
<span unselectable="on" class="k-select">
<span class="k-i-arrow-s k-icon"></span>
</span>
<!---->
</span>
If there is a always present value in dropdown, You can try to find this value by text or something, and then get a parent:
XPath: Get parent node from child node
Other way is to get it by xpath of structure, like: div[3]/.../span etc. It is not good as every change can fail Your test, but if You have no other options, then You might want to try this.
To click on the element with the only attribute-text as 2018 ALBERTSONS / Beverage Mixes you need to induce WebDriverWait for the element to be clickable and you can use the following solution:
(Java) xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[#class='k-dropdown-wrap k-state-default' and #role='listbox']//span[#class='k-input']"))).click();
I found a workaround to locate the element:
First get the xpath of the span tag inside the dropdown using it's text as below:
//text()[contains(.,'2018 ')]
since '2018 ' is common irrespective of adjacent text
Then move up to the parent tag of the dropdown to locate the dropdown frame which can be collapsed on click:
//text()[contains(.,'2018 ')]/parent::/parent::
then simply click on the element which is located.
driver.findElement(By.xpath("//text()[contains(.,'2018 ')]/parent::/parent::")).click();

Splinter Is it possible to use browser.fill without name as a query

I would like to use an absolute xpath to fill in a search bar. The ids and classes are dynamically generated and there is no name variable or instance. So it feels like I'm stuck without a tool to fill in boxes without the named variable.
Is there a way around this? Can I somehow change the absolute xpath to look like its a name assignment and then query and fill based on the new 'type' I assigned the absolute xpath?
Is there a method for this in Selenium if not available in Splinter?
I've select by CSS and I'm finding this error 'selenium.common.exceptions.InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated'
Edit:
<div class="type-ahead-input-container" role="search">
<div class="type-ahead-input-wrapper">
<div class="type-ahead-input">
<label class="visually-hidden" for="a11y-ember10393">
Search
</label>
<!---->
<input id="a11y-ember10393" class="ember-text-field ember-view" aria-
autocomplete="list" autocomplete="off" spellcheck="false"
placeholder="Search" autocorrect="off" autocapitalize="off" role="combobox"
aria-expanded="true" aria-owns="ember11064" data-artdeco-is-focused="true"/>
<div class="type-ahead-input-icons">
<!---->
</div>
</div>
<!---->
</div>
</div>
As you have asked Is there a method for this in Selenium, the Answer is Yes.
Selenium supports Sikuli. Sikuli automates anything you see on the screen. It uses image recognition to identify and control GUI components. It is useful when there is no easy access to a GUI's internal or source code.
You can find more about Sikuli here.
Let me know if this answers your question.
When you get an error-message like that, it could be that your search result is not what you expected. It could be that you are getting more than one result, ie a list. On a list you can not input.
You can find the input boxes with an xpath, select the prefered one from the list (by trying) and put a text in it with the WebDriverElement _set_value method. That is not appropriate because of the _, but it is usefull.
input_list = browser.find_by_xpath('//div[#class="type-ahead-input"]/input[#class="ember-textfield ember-view"]')
input_list[1]._set_value('just a text to see whether it is working')

Get preceding sibling with Xpath

I have a link that hidden the element when the page is resized, so im trying to get that element, by previous element.
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
<i class="icon icon-doc-new"></i>
<span class="hidden-sm dropdown-label">Create</span>
<span class="caret hidden-sm"></span>
</a>
To get the "normal" element i use the Xpath :
.//*[#id='main-menu']/li/a/span[contains(text(), 'Create')]
then i would like to get element <i class="icon icon-doc-new"></i>
something like this
.//*[#id='main-menu']/li/a/span[contains(text(), 'Create')]/precending-sibling::i[0] //(also tried different indexes]
Have tried a couple of other methods but with no go either.
Any tips`?
Try to use below XPath:
.//*[#id='main-menu']/li/a[span[text()="Create"]]/i
So, you actually need parent element if I'm correct and not preceding sibling.
Try with .//*[#id='main-menu']/li/a/span[contains(text(), 'Create')]/parent::a
If you want preceding sibling then try with .//*[#id='main-menu']/li/a/span[contains(text(), 'Create')]/precending-sibling::i
Try any of these below mentioned xpath
//span[#class='caret hidden-sm']/..//preceding-sibling::span[text()= 'Create']
Explanation of xpath:- Use class attribute of <span> tag and move ahead with another <span> tag along with text method using preceding-sibling keyword.
OR
//span[#class='caret hidden-sm']/..//preceding-sibling::span[#class='hidden-sm dropdown-label']
Explanation of xpath:- Use class attribute of <span> tag and move ahead with another <span> tag along with class attribute using preceding-sibling keyword.