Finding elements in the shadow DOM - selenium

Protractor 1.7.0 has introduced a new feature: a new locator by.deepCss which helps to find elements within a shadow DOM.
Which use cases does it cover? When would you want to reach elements in the shadow DOM?
The reason I ask the question is that I'm missing on the motivational part of the matter - I thought about protractor mainly as a high-level framework that helps to mimic real user interactions. Accessing shadow trees sounds like a very deep down technical thing and why would you want to do it is confusing me.

To answer your question, here's a related question: "what information does shadow dom provide that looking at raw html does not?"
The following snippet creates a shadom dom (view via chrome or firefox):
<input type="date">
If you click on the arrow, a pop up opens with all the dates, and you can select it.
Now imagine you are building a hotel reservation app and you made a custom shadow dom date picker, where it would black out (and not allow user to select) dates when rooms are unavailable.
Looking at the raw html, you see <input type="date">, and the value/dates that a user selected. However, how would you test that the black out UI is working as intended? For that you would need to examine the shadow dom, where the pop up resides.

The reason I ask the question is that I'm missing on the motivational part of the matter - I thought about protractor mainly as a high-level framework that helps to mimic real user interactions. Accessing shadow trees sounds like a very deep down technical thing and why would you want to do it is confusing me.
Doesn't seem so in this website that shows an introduction to shadow DOM. It says that:
Shadow DOM separates content from presentation thereby eliminating naming conflicts and improving code expression.
Shadow DOM mainly helps with separating content to avoid naming conflicts and improving your code expression, making it neater and better (I assume). I am sorry to say that I don't actually use Selenium, so here is a website with plenty more information: http://webcomponents.org/polyfills/shadow-dom/
I hope this helps you!

Related

Vuetify Datatables accessibility

I'm adding accessibility to my project and I have a basic vuetify data table, just like this example, but I can't find a way to make the checkboxes accessible using the tab key on the keyboard, Is there any way to do this? I know there's something called 'tabIndex' and I've used it before, but I don't know how to use it here. Can you guys help me or guide me on how to do it? Thanks!
It is very difficult to impossible to “add accessibility” at the end of a project.
Getting keyboard navigation and aria attributes right in 3rd party components is nearly impossible. You’d need to apply plenty of hacks or bind deeply into the component’s DOM, which breaks once the library gets updated.
With Vuetify you chose a library that has accessibility on top of their list, but unfortunately the data table with checkboxes cannot be used by keyboard at all, and is lacking plenty of other ARIA attributes. They don’t seem to keep up to that promise for that component.
As with any 3rd party library, if you find an issue, you should try to report a bug upstream and fix it together with their developers.
Correct behaviour of data grids
The expected behaviour of tables in web applications is that of a Data Grid.
A data grid is a composite UI component, so it’s expected that the whole component receives focus only once by means of Tab. Then, you’d navigate with arrow keys inside the table, using Space to select rows or Enter to interact with a cell.
See Keyboard Navigation Inside Components
You can try keyboard navigation in AG-Grid
The pattern to apply in code would be a roving tab index:
Only one child element of the table has tabindex="0", while all others have tabindex="-1". Key bindings then will move the 0 around in the component.
So this is quite some effort to implement.
Simple Alternative
As far as I known, it is acceptable—sometimes even expected—by concerned users, for web applications to behave more like websites, where everything is focussed by means of Tab.
This might be ok if the only possible interaction in your table is to select checkboxes, and if you provide possibilities to Bypass Blocks by offering landmarks or headlines. You should test it with some screen reader users.
For this to work, you would indeed only need to add tabindex="0" to the checkbox.
Then, again, the checkbox does not expose any other accessibility information, it’s an ignorant <div>. It should at least be:
<div role="checkbox" aria-label="Select row 5" aria-checked="false" tabindex="0">
See the Checkbox Pattern
All this might be possible, see Vuetify Accessibility (a11y)
Other Accessibility Criteria
Right now, you mention keyboard navigation. This is a great place to start with, since it is the foundation necessary for most assistive technology.
The Web Content Accessibility Guidelines (WCAG) are the reference to look for if you want to achieve compliance. Level AA (including level A) is the one recommended as a baseline.
But be aware that keyboard navigation is only one of 13 guidelines. Exposing state (checked, selected) to assistive technology, or getting contrasts right are examples for other criteria.
For web applications, it’s a good approach to advance the improvements based on critical paths in the story map, similar to an MVP, meaning that you would advance per process/task and make sure that each step in that process is accessible to the audience you prioritised based on the nature of the application.
Usability testing with people with disabilities is also a very good approach that can be applied in parallel, which centres the initiative more on the actual use cases.

Identifying the same Web Elements with Selenium

I am an Automation Engineer, I am currently trying to create test cases for a webpage that are sustainable ( that I can run at a later time and have still pass)
Here is my problem:
I am trying to select multiple web buttons that have the same exact class name. Now I can 'select' these buttons but these are only temporary x paths that are subject to change.
I need UNIQUE ID's (or some way of distinguishing them) for the same web elements. The only difference in the x paths are:
HTML format code that I can find each button, however if one button is moved my tests will fail.
HTML code that is the class name + nth of the button. But again my tests will fail if a button is taken out of the webpage.
//*[#id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[1]/div/a/div
//*[#id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[2]/div/a/div
//*[#id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[3]/div/a/div
^^The above code is how I currently find each button with Selenium
If I copy each classes x path this is what I get
<div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 392 -->Set +<!-- /react-text --></a></div>
<div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 386 -->Set +<!-- /react-text --></a></div>
<div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 398 -->Set +<!-- /react-text --></a></div>
I have talked to the Development team about this issue however they tell me that assigning Unique ID's to these web elements is a big no-no. (something to do with globalization of the project when we go to production) Even if they did assign Unique Id's they tell me that they would have to strip them before the project can be sent to production. Which ultimately would render my tests useless in the end...
I now come to Stack Overflow for help, everything I look up online cannot give me an answer, however this does seem to be a valid question between QA and Development departments.
Is there a way to assign Id's to a web element so that a tester using selenium can identify them and yet it will not affect a Developers ability to use that element through an entire project?
Edit:
With the framework that my company uses, I am not actually writing any code in selenium. I save the Xpath to an object and then later in a manual test call that object with a pre-existing method. I can ONLY select Xpaths to be saved in an object.
I'll talk to Dev later to have them explain the big 'no-no' so that I may be able to communicate that with all of you..Thank you for your time and input
For example:
BirthDateSet= someXpath
Click() using {BirthDateSet}
Here are some pictures to help give you a visual
You can simplify your XPathto make it less sensitive to possible changes in DOM:
//div[#class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"][N] # Where N is button index
If this part 2z6Ak of class name is dinamically generated, try:
//div[starts-with(#class, "src-js-components-DateControl-___DateControl__icon___")][N] # Where N is button index
Another way of reaching to the required button using xpath is following:
//*[#id='tenant-details-accordion']/descendant::div[contains(#class, 'DateControl__icon')][1]
Above xpath should be able to select the first occurring button. Similarly, for the second occurring button, the xpath will become:
//*[#id='tenant-details-accordion']/descendant::div[contains(#class, 'DateControl__icon')][2]
Hence, you can continue to replace the predicate([2]) based on occurrence level of the required button on page.
you can ask devs to add attribute to those buttons
so instead of:
<button class="common_class_name">
<button class="common_class_name">
<button class="common_class_name">
for each button you will see
<button class="common_class_name" test-id="uniqueAttributeForButton1">
<button class="common_class_name" test-id="uniqueAttributeForButton2">
<button class="common_class_name" test-id="uniqueAttributeForButton3">
etc
And in your tests you can find those buttons using css selector
e.g. C# code:
var buttonLocator = "[test-id=\"uniqueAttributeForButton1\"]";
WebElement button = driver.FindElement(By.CssSelector(buttonLocator));
if devs doesnt want to add unique IDs or attributes (it's weird why they don't want to do that) you could try something like this:
//return div class 'col-sm-4' which contain text 'Activation Date'
var parentDiv = driver.FindElement(By.XPath("//div[contains(#class, 'col-sm-4') and contains(., 'Activation Date')]"));
//should return div with icon you want e.g. Click
var childElement = parentDiv.FindElement(By.CssSelector(".DateControl__icon"));
childElement.Click();
You can go with the nth approach to find your unique element or with another, that won't solve your real problem which is that your colleague developers aren't cooperating with you. The automated tests are supposed to be (among other things) a service for the developers to know they haven't broken anything as fast as possible, but if they aren't giving any effort, then WHY should you invest in it at all..?
They probably won't even look at the results. Especially when your locators are in the form of div[2]/div[3]... which would break very often and you'll lose their trust in the automation.
I'm no front-end expert but I've seen enterprise products in production with G10N and L10N and other long words, that have id's in their HTML, so if I were you I'd dig deeper to understand why? that big no-no, which sounds very odd to me...
So you asked the wrong question, it should be something like ~ How to add unique id's to the HTML using React in a global web application? and the ones who should be asking it are the developers.
As a side note, as many people tend to think, automation is not mainly about moving manual tests to automated it also finds "bugs" in the communication inside the company. To quote a great blog post on this subject:
Counter-intuitively, the bigger obstacles when developing automation
are either low priority bugs or even things that are not bugs
whatsoever. These obstacles can be symptoms of a bad design, bad
development practices and even symptoms of inefficient communication
patterns in the organization (that are usually caused by the
organizational structure! Conway’s law is a classic example for this).
Good luck!
EDIT:
Thanks for the code.. So if you look at your code, you can see that although what you're after have similar attributes, there are elements in the page that would allow you to identify what you're after. So let's say you want the SET link after Birth Date, then use:
//div[contains(text(),'Birth Date')]/div/a/div
So to reuse this xpath, just replace the text String.format("//div[contains(text(),'%s')]/div/a/div", labelName);
OLD: if you want to temporarily assign the elements an attribute, I believe you can do that through javascript element.setAttribute() which you can run through the executeScript() function.
Don't the buttons have text? Are you saying that the buttons swap places with one another? or don't you want to use the index of the buttons?
I understand you want to select the "Set +" buttons, correct?
If so you can try to find all buttons under the #id="tenant-details-accordion" element with a specific text like that:
//*[#id="tenant-details-accordion"]//*[text()='Set +']

Aurelia Composition

I am trying to create some composition but I am not getting anything I'd expect. In almost every instance I've tried a similar setup I get something different which is wrong so this GistRun is representative only as far as it illustrates that at least "something" is wrong.
I've searched high and low for more information on the specific functionality and syntax of compose but I can't seem to solve the issues.
In the before mentioned GistRun you can see that the Container element is not rendered correctly, the h1 is not rendered and that #containerless is being ignored.
In similar scenarios I've had containerless ignored on the compose element resulting in the rendering being ignored and I've had the entire thing not working with named slots.
I have a feeling that I'm doing something wrong and I can't quite figure out what it is. If someone knows what I'm doing wrong or can point me to a solution I would be much obliged.
Part of the reason things aren't working as you expect is that your gist is based off of a very old version of the framework. I've updated your gist to the latest version of Jeremy Danyow's Aurelia bundle here: https://gist.run/?id=1b304bb0c6dc98b23f4a3994acc280e4 The old version of the framework you were using in your gist still used the content element for content projection.
There are a couple of reasons your gist wouldn't run (aside from what I mentioned above). First, the compose element (and any custom elements you create) are not self-closing. This is per the Custom Element spec. So <compose view="test.html" /> wont' work. Second, there is an existing issue regarding containerless elements being used with content projection. After talking with the team, this issue is unlikely to be resolved as containerless custom elements aren't really supported by the Shadow DOM v1 spec. If you remove the containerless attribute from the compose element, your demo works. Finally, you forgot to add <require from="container"></require> at the top of your app.html file. Thus Aurelia was unaware that <ck-container> is an Aurelia custom element. Unless you have globally registered a custom element (or any other view resource), you MUST require it in to any view where you wish to use it.
Now, let's discuss the use of containerless. The containerless decorator and attribute shouldn't be used simply to "clean up" your HTML. They should only be used when absolutely necessary to achieve your goals. "Making my HTML pretty" is never absolutely necessary. When you use containerless you are creating a custom element that likely cannot ever be used as a standard custom element. Again, the Aurelia team discourages you from using containerless elements unless necessary.
An example of a valid reason to use containerless is expained in our documentation here: http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/cheat-sheet/4

Need help on selenium hidden elements

I am trying to use selenium to automatically log in the following website:
here is the link https://www.theice.com/
After I click on the log in, a log in screen comes up - I don't know what this is: frame,panel ...
I have not been successful in detecting what elements,properties this screen has through selenium. Thus I am not able to fill in the necessary info through selenium.
Can anyone shed some light on this?
SiKing is correct, here. Nothing too fancy going on with the DOM. Use your favorite DOM inspector and examine the elements and you should be able to identify the locators.
In this case, it looks like the front end devs were thorough and gave major elements 'id' tags. Once you can establish a relationship from an element to it's id, you'll just need to code the selenium commands to interact with them.
While there are a number of good tools for this, I like to recommend FireBug and FirePath addons for Firefox. Similarly to Chrome's inspector, hovering over a DOM element in the inspector will highlight the element itself on the page. FirePath can assist with CSS selectors and XPath if need be.
Without knowing your method of development (code by hand or SeleniumIDE) or you chosen language, I'd simply recommend reading the Selenium docs over at http://docs.seleniumhq.org/docs/03_webdriver.jsp#selenium-webdriver-api-commands-and-operations to get a feel for the means by which elements can be identified and subsequently used.
Incidentally, this site is an example of a good front end design (at least from a cursory glance). Locating elements, once you're familiar with the concepts, should be relatively simple. Play around with it, the best way to learn is by doing (that's why I haven't just given you the solution), you'll get it.
Best of luck.
(Also, I've not meant this message as 'talking down' to you. I'm not familiar with your level of understanding here, so I'm just starting with the basics).
Edit:
It occurred to me, after writing my initial response, that you may encounter an issue with the modal being displayed. After clicking the 'log in' link, you may want to add a wait to your test to ensure enough time for the modal to appear before interacting with it's elements. A simple Thread.sleep() could work here, but I hate recommending that unless it's a last resort situation (we all know sleeps suck, but sometimes it just needs to be done)... Instead, read up on the WebDriverWait class (assuming java) and the ExpectedConditions class. You could pass a locator for the root modal element, or a child thereof into wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("yourLocator")); which will wait until the condition is satisfied (or a timeout occurs) rather than the Thread.sleep() making a hard pause and possibly waiting for a needlessly long amount of time.
The point is, since the modal display isn't instantaneous, WebDriver may choke if it tries to interact with an element that hasn't yet appeared. Using a wait will relieve this problem.

What is the point of getEl() in extjs4

I have a listener that is called when a tab is activated.
, listeners: {
activate: function(tab){
var first = tab.down('input'), // will be null
firstEl = tab.getEl().down('input'); // will contain first input element
I'm not having a lot of luck understanding the relationship between tab and tab.getEl(). If this was jquery, $(tab) would give me a jquery element which would largely expand on my set of options. extjs seems to be almost backwards in this regards, or at least more complicated.
I'm trying to understand when and why I need getEl() so that it is less of a development crapshoot about what will and won't work. In other places I do things like:
showFieldHelpOnBlur = function(ctrl) {
ctrl.up('form').down('#helptext').update("");
}
without the getEl(). In this case form is an element tag just like input (above), but I don't need the getEl() before I use it. In general the two sets of functionality that share the same names but don't work the same are frustrating, and the docs don't seem to give any clue as to why there are multiple methods with the same names that do different things, or do similar things in a different way.
Found some similar issues with focus(), but those might make more sense if I just understood why are there are 2 seemingly parallel sets of methods for what are essentially DOM elements wrapped in additional functionality.
I think at the core of your confusion is how you approach the development using ExtJS vs JQuery.
JQuery is all about DOM manipulation and low level API. ExtJS approach is very different, it wants you to think of your page structure as a hierarchy of ExtJS components that are responsible for rendering appropriate HTML. So ExtJS is essentially saying: "Don't worry about html, we'll take care of it - you focus on the larger components, layouts, events, etc. "
You will say "Whoa Nelly! What do you mean don't worry about html? I want control!" And ExtJS will respond OK - we have a wrapper object called Element (http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.dom.Element) you can use it to do DOM manipulation just like you are used to with JQuery .. but be cautious. Because if you manage your own HTML we can't be responsible for what happens to your layouts and components that are not managed by the framework.
My advice is this - when in Rome do like Romans do :)
If you are going to be using ExtJS to build apps - embrace the way ExtJS is designed to work. Learn the different layout mechanics and numerous component types available to you out of the box. Use the MVC development pattern to beautifully organize your code. Use the examples to your advantage. Study the architecture and component guides - these are very useful. Understanding ComponentQuery class is a must (all those up/down methods and query).
At the end, when you have gained comfort using ExtJS components and their style of development you will be very efficient at building your UI compositions and can build much more complex applications than before.
Good Luck!
Pro Tip: Do yourself a favor and get Illuminations for Developers plugin for Firebug - it will open your eyes to see things using component structure rather than HTML elements.