How can I locate an element by header or any particular property value in Protractor? - protractor

I have an element that have no Id defined. Class name do not allow me to identify the element uniquely.
That's why I would like to locate it using role or header property:
<p-dialog header="Deleting" showeffect="fade" role="dialog"
class="ng-tns"> </p-dialog>
How should I do that in Protractor / Selenium Webdriver?
I can do that by means of xpath, but as I understand it's rather suggested to avoid it at all.
Do I need to define my own locator using addLocator or is there simpler solution?

Protractor recommend to use css selector as first option, xpath as the secondary option when css selector can resolve your problem in some cases.
The primary reason of such recommendation considered followings:
xpath is not fast than css selector
xpath is case sensitive in some browser
for lower IE, like 6 not support xpath natively
xpath generally is longer than css selector to find same element
But css selector has two shortage which xpath is able to do:
can't find element by text
can't find parent element (only can find downward)
For your case, you can try following locator:
// css selector
p-dialog[header="Deleting"]
p-dialog[role="dialog"]
p-dialog[header="Deleting"][role="dialog"]

Related

What do you call input class="gLFyf" vs input.gLFyF (vocabulary help needed)

In Chrome DevTools, the element tab shows the constructed DOM and I can click on elements in the DOM which also highlights the element on the page. Image of both versions shown in DevTools
If the DOM shows:
<input class="gLFyf">
Then the page highlight will show:
input.gLFyF
I realise these are two ways of writing the same thing, I also realise the former is HTML style and the latter follows CSS conventions. However, I lack the vocabulary to properly refer to either.
What do I call each format?
Eg. would it make sense to refer to <input class="gLFyf"> as HTML syntax and input.gLFyF as CSS syntax? Is there a more widely accepted way to differentiate and name them?
gLFyf is the name of the class which is an attribute that can be referred to in the stylesheet to match styles with elements of that class on the page.
A class leads with a period (.) - whereas an ID would lead with a hash (#).
So .gLFyf is a class.
And #gLFyf would be an ID.
It is a class, whether viewing HTML markup or the DOM inspector. They both refer to the same thing as you already state.
This may be of some use/reference.

Trying to understand a CSS chain

can anybody explain the following code snippet (used in CSS):
[type="checkbox"]:checked
I've tried to find this on various sites, I understand the pseudo class on the end but the square brackets have really got me stumped.
Thanks for reading.
this [type="checkbox"] is an attribute selector
[attr=value]
Represents an element with an attribute name of attr and whose value is exactly "value".
:checked is:
a pseudo class selector represents any radio (<input type="radio">),
checkbox (<input type="checkbox">) or option (<option> in a <select>)
element that is checked or toggled to an on state. The user can change
this state by clicking on the element, or selecting a different value,
in which case the :checked pseudo-class no longer applies to this
element, but will to the relevant one.
Which means you have a checkbox element checked
[type="checkbox"] is an attribute selector.
This specific selector will match any element that has the attribute type and that attribute's value is checkbox. Most would identify this as a selector for and input but is not specific enough to be limited to that element type. Other elements that accept the type attribute are <button> <command>, <embed>, <object>, <script>, <source>, <style> and <menu>.
You'll often see input pre-pended to a selector like the one above, i.e. input[type="checkbox"], when targeting specific types of input.
The square brackets target an attribute such as type for an input elemet.
In your case you're selecting a checked checkbox.

How can we get value from DOM Properties in JMeter?

I'm trying to record a scenario of SAP CRM.
But I have a problem due to that everytime I login SAP CRM generates a new hashed token and will be used in URL like below:
See Image 1 Here
I tried to check where is the information stored, and in firebug and I found it in DOM tab:
See Image 2 Here
Is there any way to get the value from this DOM Properties using Jmeter?
Usually the choices are in:
CSS/JQuery Extractor
XPath Extractor
Regular Expression Extractor
Choose the one, you're most familiar with. Usually it is Regular Expression Extractor, however parsing HTML with regular expressions is not a good idea, moreover you will be very sensitive to DOM changes (part of the element goes to next line, attributes change positions, etc.).
So I would recommend choosing between CSS and XPath, but choose them wisely. I.e. if the number of styles on the page is not too big - go for CSS, if there are a lot of styles but the DOM itself is not very complicated - choose XPath.

Find CURRENTLY selected <option> with XPath

What's the correct XPath syntax to check if an option element is currently selected, or just to get the selected option element from a select element, on an open page with which the user, and JavaScript, may have interacted? Is this even possible with XPath, or does it lack the ability to look at DOM properties?
I can't find any documentation on this, and have (speculatively) tried:
//option[#selected=true]
//option[#selected="selected"]
//option[#selected]
but none of these work; they simply don't match any elements.
(In case it matters, I've tried this both using the $x function in the Chrome developer console, and using the find_elements_by_xpath method in Selenium for Python.)
Short answer: it's not possible.
Longer answer: XPath can look at HTML attributes, but it can't look at DOM properties. Selecting an <option> element in a <select> changes the selected property of the <option> to true, and also changes the value property of its parent <select> element, but it doesn't affect the attributes of either, so it is invisible to XPath.
To find <option> elements that have the selected attribute set, which is often how a page author might determine which option is initially selected, you can use //option[#selected]. But this does not find the currently selected <option>; changes that the user makes to the selection are invisible to XPath. There's no guarantee it will even find the initially selected option, since it's possible that the page author didn't put the selected attribute on any elements and either let the browser select the first option by default or had some JavaScript select the initial option via the selected property.
The multiple other answers here claiming that a selector like //option[#selected] can detect selection changes made by the user after the page loads are simply completely wrong.
Of course, if you're able to use CSS selectors instead of XPath selectors, then option:checked will do the job.
The problem could be the " (double quotes).
//select/option[#selected='selected'] - Will match the selected option, i am using this successfully.
//select/option[#selected='selected' and #value='specific value'] - Will only match the selected option if it has a 'specific value', i'm also using this.
If you are still having trouble, it could be an entirely different problem, perhaps there is no option node. I hope this helps.
I think we can use a knowledge from #Mark's answer and account that. Let's just find a node which HAS desired attribute:
tree.xpath('//select/option[#selected]/text()')[0].strip()
I tried "//option[#selected=''] and it has worked for me.
it is able to highlight the selected option within Page objects model.
I would try //option[#selected='true']
i.e. driver.findElements(By.xpath("//option[#selected='true']")).getText();

innerHTML of an element without id or name attributes

Why is the following code NOT working without id or name attribute specified for the anchor element?
<html>
<body>
First link
<p>innerHTML of the first anchor:
<script>document.write(document.anchors[0].innerHTML);</script>
</p>
</body>
</html>
But if I add an id (or name) attribute, like that:
<a id="first" href="#">First link</a>
It starts to work.
Why is id or name attribute so important? I don't refer to it in my javascript code. I don't use "getElementById" or anything, but it still wants an id to be specified.
P.S. I tested only in IE7 (not the best browser, but I don't have access to anything better at the moment, and it can't stop me from learning :)
UPDATE:
Thanks to Raynos who gave me an idea of HTMLCollection in his answer, I've gotten a deeper understanding of what's going on here, by searching the web.
When we use document.anchors collection, we're actually referring to a collection of a elements with the name attribute that makes an a element behave as an anchor, and not (only) as a link.
We don't have to specify the name attribute if we want to refer to a elements as links. In this case we just need to use a different instance of HTMLCollection object which is document.links.
So the original code will work without name attribute if we modify it to:
document.write(document.links[0].innerHTML);
What a nice feeling of enlightenment! :)
WHATWG says:
The anchors attribute must return an HTMLCollection rooted at the Document node, whose filter matches only a elements with name attributes.
the document.anchors collection needs <a> elements with a name attribute.
IE is known to have bugs where it treats id's and name's as the "same" thing. So that would probably explain why it works for <a> elements with an id attribute.
As an aside, document.write and .innerHTML are evil.
Why don't you use this:
document.getElementsByTagName('a')[0].innerHTML