<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 4, 2017 at 9:33 AM, Honza Pokorny <span dir="ltr"><<a href="mailto:honza@redhat.com" target="_blank">honza@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">About 10 years ago, we were promised a fully semantic version of HTML.<br>
No more nested divs to structure your documents.  However, all we got<br>
was a few generic, and only marginally useful elements like <footer> and<br>
<article>.<br>
<span class="gmail-"><br>
On 2017-08-03 18:59, Ana Krivokapic wrote:<br>
> Hi TripleO devs,<br>
><br>
> In our effort to make the TripleO UI code friendlier to automation<br>
> testing[1], there is an open review[2] for which we seem to have some<br>
> difficulty reaching the consensus on how best to proceed. There is already<br>
> a discussion happening on the review itself, and I'd like to move it here,<br>
> rather than having it in a Gerrit review.<br>
><br>
> The tricky part is around adding HTML element ids to the Nodes page. This<br>
> page is generated by looping through the list of registered nodes and<br>
> displaying complete information about each of them. Because of this, many<br>
> of the elements are repeating on the page (CPU info, BIOS, power state,<br>
> etc, for each node). We need to figure out how to make these elements easy<br>
> for the automation testing code to access, both in terms of locating a<br>
> single group within the page, as well as distinguishing the individual<br>
> elements of a group from each other. There are several approaches that<br>
> we've come up so far:<br>
><br>
> 1) Add unique IDs to all the elements. Generate unique `id` html attributes<br>
> by including the node UUID in the value of the `id` attribute. Do this for<br>
> both the higher level elements (divs that hold all the information about a<br>
> single node), as well as the lower level (the ones that hold info about<br>
> BIOS, CPU, etc). The disadvantage of this approach is cluttering the UI<br>
> codebase with many `id` attributes that would otherwise not be needed.<br>
<br>
</span>While this is useful for addressing a particular element, I think it<br>
would still require quite a bit of parsing.  You'd find yourself writing<br>
string-splitting code all over the place.  It would make the code harder<br>
to read without providing much semantic information --- unless of course<br>
every single element had some kind of ID.</blockquote><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class="gmail-"><br>
> 2) Add CSS classes instead of IDs. Pros for this approach: no need to<br>
> generate the clumsy ids containing the node UUID, since the CSS classes<br>
> don't need to be unique. Cons: we would be adding even more classes to HTML<br>
> elements, many of which are already cluttered with many classes. Also,<br>
> these classes would not exist anywhere in CSS or serve any other purpose.<br>
<br>
</span>I like this option the best.  It seems to be the most natural way of<br>
adding semantic information to the bare-bones building blocks of the<br>
web.  Classes are simple strings that add information about the intended<br>
use of the element.  Using jQuery-like selectors, this can make for some<br>
easy-to-understand code.  Do you want to grab the power state of the<br>
currently expanded node in the list?<br>
<br>
    $('#node-list div.node.expanded').find('.<wbr>power-state')<br>
<br>
By default, Selenium can query the DOM by id, by class name, and by<br>
xpath.  It can be extended to use pyquery which is the Python<br>
implementation of the jQuery css selector.  I think many of the<br>
automation implementation headaches can be solved by using pyquery.<br>
<br>
<a href="https://blogs.gnome.org/danni/2012/11/19/extending-selenium-with-jquery/" rel="noreferrer" target="_blank">https://blogs.gnome.org/danni/<wbr>2012/11/19/extending-selenium-<wbr>with-jquery/</a></blockquote><div><br></div><div>I agree with this solution. Using IDs for unique elements in the page and classes for elements which are repeating (list items) seems most natural</div><div>to me. In combination with pyquery it should be sufficient IMHO.</div><div><br></div><div>Also, to make sure that classes won't repeat and it is simple to identify the desired element, we should use BEM [2] similarly as we do with IDs</div><div><br></div><div>Also note that incrementally we are extracting presentational components into separate building blocks (see [1] for example), which makes the code much more readable and classnames won't be cluttered any more.</div><div>e.g. instead of having code such as </div><div><font face="monospace, monospace"><div className="nodesList__listItem list-group-item list-view-pf-stacked list-view-pf-expand-active">content of item</div></font></div><div><font face="arial, helvetica, sans-serif">we'll have </font></div><div><font face="monospace, monospace"><ListGroupItem className="nodesList__listItem">content of the item</ListGroupItem></font></div><div>IIUC this is the semanticity Honza is looking for.</div><div> </div><div>[1] <a href="https://github.com/patternfly/patternfly-react/pull/50/files#diff-b2dff316cba6ec51de4d1712eef132d0R76">https://github.com/patternfly/patternfly-react/pull/50/files#diff-b2dff316cba6ec51de4d1712eef132d0R76</a></div><div>[2] <a href="https://codepen.io/Merri/post/advanced-bem-with-react-components">https://codepen.io/Merri/post/advanced-bem-with-react-components</a></div><div><br></div><div>-- Jirka</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
Furthermore, I think that classes can be used effectively when<br>
describing transient state like the expanded/collapsed state of a<br>
togglable element.  It's easy to implement on the client side, and it<br>
should be helpful on the automation side.<br>
<br>
Relying on patternfly presentational class names won't suffice.</blockquote><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class="gmail-"><br>
> 3) Add custom HTML attributes. These usually start with the 'data-' prefix,<br>
> and would not need to be unique either. Pros: avoids the problems described<br>
> with both approaches above. Cons: AFAIU, the React framework could have<br>
> problems with custom attributes (Jirka can probably explain this better).<br>
> Also, casual readers of the code could be confused about the purpose of<br>
> these attributes, since no other code present in the UI codebase is using<br>
> them in any way.<br>
<br>
</span>This seems pretty drastic.  I wonder if there is a way we could extend<br>
the React component class to give us automatic and painfree ids.<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
> It seems that a perfectly optimal solution does not exist here and we will<br>
> have to compromise on some level. Let's try and figure out what the best<br>
> course of action here is.<br>
><br>
> [1] <a href="https://blueprints.launchpad.net/tripleo/+spec/testing-ids" rel="noreferrer" target="_blank">https://blueprints.launchpad.<wbr>net/tripleo/+spec/testing-ids</a><br>
> [2] <a href="https://review.openstack.org/#/c/483039/" rel="noreferrer" target="_blank">https://review.openstack.org/#<wbr>/c/483039/</a><br>
><br>
> --<br>
> Regards,<br>
> Ana Krivokapic<br>
> Senior Software Engineer<br>
> OpenStack team<br>
> Red Hat Inc.<br>
</div></div></blockquote></div><br></div></div>