Different ID of element in different browser instance (python-selenium-chrome) - html

I was locating the elements for selenium through the inspect function of my actual browser (chrome) and never had any issues. Now i had a case where the located element couldn't be found and i figured out that in my selenium chrome instance, the element has another ID then in my "normal" one and that's why i can't locate it.
This is the case with some other elements too and i can't spot the pattern.
In "Ikognito"-mode of chrome, i get the same values as in my normal browser, and the ids that my selenium browser gets are the same aswell everytime i launch the programm.
Does anybody have an explanation for this ?
Is this common practise upon web developers and whats the way to go about this issue on future projects ?
Do i always have to run my selenium browser first and then extract the elements IDs out of there ?

Although locating elements by id is the preferred way, it is not the only one, the are way more options like:
name attribute
link text for a elements
partial link text for a elements
HTML tag name
class attribute
CSS selector
XPath selector
The latter one - XPath is the most powerful as it's almost a programming language. Unlike other selector strategies XPath selectors have full awareness of DOM page, can lookup all attributes, text, parent/child objects, traverse axes and if it's not enough you can go for functions and operators to precisely select whatever element is needed.
With regards to dynamic IDs - it's quite a common practice when the page is not deterministic and the content is dynamic. Theoretically you can ask your application developers to come up with a custom HTML attribute which will be used for automation and maybe user tracking, but if for some reason it is not possible - you will have to define another way of locating the element.s

Related

Aren't DOM searches for elements with classes depth first?

I was under the impression that when a browser (generally) searches for an element that has a class it is a depth first search.
Recently I was asked to put some code together for a colleague, and asked to identify forms on a page with the substring of 'webform' in the class. I knew there was a form on a page I tested and used the following JS:
document.querySelector("[class*=webform]")
However, this returned the body element of the page whose class attribute had the substring of 'webform' in it. Generally (this question being browser dependant) is the searching in the DOM for elements containing a certain class depth first? Is it totally implementation or browser dependant (as in querySelector will use one method and another function will use a different method)?
Many thanks.
#hungerstar is right. Apologies for the brain fart, seems I need to brush up on my trees a little!
So in conclusion, it proved that it is depth-first. Great!

CSS selector fragment support

Fragments (or hashes) in URL are widely used to specify some specific fragment in a document.
For example, the fragment below
http://example.com/page.pnp#<fragment>
Usually references something like <div id="<fragment>" /> or <a name="<fragment>" /> in a HTML document.
There is a standard to support CSS selectors as a fragment, like so:
http://example.com/page.pnp#css(<CSS selector>)
Are there any applications using it? Would it be nice for browser to support it? For example, browser could display only the selected fragments of the page or highlight the selected fragments. Or provide an option for developers to highlight the selected fragments with CSS or JS. Can somebody submit it to the relevant browser devs as a feature request?
What are other ways to reference specific content in a HTML page? For example, if I want to comment on some specific element in a HTML page, what are any other ways to specify that position in the document, preferably by using URI, or some other convenient identifier?
The document you link to isn't really a standard; it even says "Unofficial Draft" in the subtitle, and under where it says Status:
This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.
... so it is completely inappropriate to refer to it as a "standard". A better term for this would be "concept" or "experiment".
That being said, rudimentary implementations exist (or at least, they did at the time it was first published) in the form of browser extensions; you can find links to these in section 8.
AFAIK, though, there hasn't been any activity around this at all after the first few months since the community group for this was formed and I joined. Either it never gained traction or it just wasn't very feasible to implement after all.
For now, as always, fragment identifiers can only point to elements with the respective id attribute, or named anchors. It seems it'll remain that way for the foreseeable future.
For Chrome, There's a Jquery Fragement selector extension:
With the advent of edge extensions it will likely become easy to implement in edge.

How to navigate accross shadow DOMs recursively

I want to validate a custom polymer element. To do this, I want in javascript to access all my nested polymer elements to see if they are valids.
I can't find an easy way to do this.
this.querySelectorAll does not find my inputs that are nested in other polymer elements. It seems I can't use "/deep/" in these selectors.
Is there an easy way to do this ? Or do I have to do a recursive javascript methods that will call a querySelectorAll in all elements with shadow roots ?? (I guess performances will get ugly...)
Thanks for your help.
If there is no fast solution, I will probably try the other way around (have my inputs register to the parent)
Answer:
element.querySelectorAll() will find some elements when using /deep/, however, it only goes so far (1 shadow dom level). This would indeed necessitate recursive calls from each ElementNode.
Note:
This type of behavior largely goes against the core tenets of HTML (i.e. that the web page works no matter how well-formed the content is). In other words, all elements are valid no matter their placement.
As an example, I have made a custom element that only renders specific child elements and hides all others. This still keeps in line with the above tenet, as an element's base rendering is controlled by the element/agent, but allows for the developer/designer to customize its presentation aside from the standard presentation.

How to extend multiple elements with Polymer

I know there is this question on multiple inheritance/composition. However, it seems like this question is more about how to reuse functionality from multiple existing elements in other elements. And obviously, the solution for that are mixins.
I would like to know, how I can actually "decorate" existing elements without really borrow functionality from them. We know there is this extends property one can use to extend an existing element with Polymer.
So making a normal <button> behave like a mega-button is as simple as attaching <button is="mega-button"> and write a component for it. But it turns out, that it's not possible to extend multiple elements. So something like extends="foo bar" doesn't work. What if I want to build a web component, that can actually be applied to different elements?
For example, I don't want to only extend <button> elements with mega-button but probably also an <a> element so that it looks like and behaves like a mega-button too?
The mixin approach doesn't really help here (as far as I get it), because they do nothing more then providing shared logic for different web components. That means, you create multiple components, and reuse logic (packed in a mixin) from a mixin.
What I need is a way to create one web component that can be applied to multiple elements.
Any idea how to solve that?
UPDATE
Addy answered with some approaches to handle that use case. Here's a follow up question based on one approach
How to find out what element is going to be extended, while registering my own in Polymer
And another one on Is it possible to share mixins across web components (and imports) in Polymer?
UPDATE 2
I've written an article and concludes my experiences and learnings about inheritance and composition with polymer: http://pascalprecht.github.io/2014/07/14/inheritance-and-composition-with-polymer/
If you need to have just a single import that has support for being applied to multiple elements, your element could include multiple element definitions which may or may not take advantage of Polymer.mixin in order to share functionality between your decorating elements.
So pascal-decorator.html could contain Polymer element definitions for <pascal-span> and <pascal-button>, both of which mixin logic from some object defined within pascal-decorator.html. You can then do <button is="pascal-button"> and <button is="pascal-span"> whilst the logic for doing so remains inside the same import.
The alternative (if you strictly want to do this all in one custom element, which imo, makes this less clean) is to do something like checking against the type of element being extended, which could either be done in the manner you linked to or by checking as part of your element registration process.
In general, I personally prefer to figure out what logic I may need to share between elements that could be decorated, isolate that functionality into an element and then just import them into dedicated elements that have knowledge about the tag (e.g <addy-button>, <addy-video> etc).

Why is it a bad thing to have multiple HTML elements with the same id attribute?

Why is it bad practice to have more than one HTML element with the same id attribute on the same page? I am looking for a way to explain this to someone who is not very familiar with HTML.
I know that the HTML spec requires ids to be unique but that doesn't sound like a convincing reason. Why should I care what someone wrote in some document?
The main reason I can think of is that multiple elements with the same id can cause strange and undefined behavior with Javascript functions such as document.getElementById. I also know that it can cause unexpected behavior with fragment identifiers in URLs. Can anyone think of any other reasons that would make sense to HTML newbies?
Based on your question you already know what w3c has to say about this:
The id attribute specifies a unique id for an HTML element (the id
attribute value must be unique within the HTML document).
The id attribute can be used to point to a style in a style sheet.
The id attribute can also be used by a JavaScript (via the HTML DOM)
to make changes to the HTML element with the specific id.
The point with an id is that it must be unique. It is used to identify an element (or an anything: if two students had the same student id schools would come apart at the seems). It's not like a human name, which needn't be unique. If two elements in an array had the same index, or if two different real numbers were equal... the universe would just fall apart. It's part of the definition of identity.
You should probably use class for what you are trying to do, I think (ps: what are you trying to do?).
Hope this helps!
Why should I care what someone wrote in some document?
You should care because if you are writing HTML, it will be rendered in a browser which was written by someone who did care. W3C created the spec and Google, Mozilla, Microsoft etc... are following it so it is in your interest to follow it as well.
Besides the obvious reason (they are supposed to be unique), you should care because having multiple elements with the same id can break your application.
Let's say you have this markup:
<p id="my_id">One</p>
<p id="my_id">Two</p>
CSS is forgiving, this will color both elements red:
#my_id { color:red; }
..but with JavaScript, this will only style the first one:
document.getElementById('my_id').style.color = 'red';
This is just a simple example. When you're doing anything with JavaScript that relies on ids being unique, your whole application can fall apart. There are questions posted here every day where this is actually happening - something crucial is broken because the developer used duplicate id attributes.
Because if you have multiple HTML elements with the same ID, it is no longer an IDentifier, is it?
Why can't two people have the same social security number?
You basicaly responded to the question. I think that as long as an elemenet can no longer be uniquely identified by the id, than any function that resides on this functionality will break. You can still choose to search elements in an xpath style using the id like you would use a class, but it's cumbersome, error prone and will give you headaches later.
The main reason I can think of is that multiple elements with the same id can cause strange and undefined behavior with Javascript functions such as document.getElementById.
... and XPath expressions, crawlers, scrapers, etc. that rely on ids, but yes, that's exactly it. If they're not convinced, then too bad for them; it will bite them in the end, whether they know it or not (when their website gets visited poorly).
Why should a social security number be unique, or a license plate number? For the same reason any other identifier should be unique. So that it identifies exactly one thing, and you can find that one thing if you have the id.
The main reason I can think of is that multiple elements with the same
id can cause strange and undefined behavior with Javascript functions
such as document.getElementById.
This is exactly the problem. "Undefined behavior" means that one user's browser will behave one way (perhaps get only the first element), another will behave another way (perhaps get only the last element), and another will behave yet another way (perhaps get an array of all elements). The whole idea of programming is to give the computer (that is, the user's browser) exact instructions concerning what you want it to do. When you use ambiguous instructions like non-unique ID attributes, then you get unpredictable results, which is not what a programmer wants.
Why should I care what someone wrote in some document?
W3C specs are not merely "some document"; they are the rules that, if you follow in your coding, you can reasonably expect any browser to obey. Of course, W3C standards are rarely followed exactly by all browsers, but they are the best set of commonly accepted ground rules that exist.
The short answer is that in HTML/JavaScript DOM API you have the getElementById function which returns one element, not a collection. So if you have more than one element with the same id, it would not know which one to pick.
But the question isn't that dumb actually, because there are reasons to want one id that might refer to more than one element in the HTML. For example, a user might make a selection of text and wants to annotate it. You want to show this with a
<span class="Annotation" id="A01">Bla bla bla</span>
If the user selected text that spans multiple paragraphs, then the needs to be broken up into fragments, but all fragments of that selection should be addressable by the same "id".
Note that in the past you could put
<a name="..."/>
elements in your HTML and you could find them with getElementsByName. So this is similar. But unfortunately the HTML specifications have started to deprecate this, which is a bad idea because it leaves an important use case without a simple solution.
Of course with XPath you can do anything use any attribute or even text node as an id. Apparently the XPointer spec allows you to make reference to elements by any XPath expression and use that in URL fragment references as in
http://my.host.com/document.html#xpointer(id('A01'))
or its short version
http://my.host.com/document.html#A01
or, other equivalent XPath expressions:
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[#id = 'A01'])
and so, one could refer to name attributes
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[#name = 'A01'])
or whatever you name your attributes
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[#annotation-id = 'A01'])
Hope this helps.