What is the purpose of checking the presence of elements rather than visibility of element?
As a Quality Tester, I should be on visibility of elements.
Can anyone provide me some good examples?
As mentioned in the link given by sisanared it explains differences between each method nicely, in short checking present of element only check whether element exist in your html page regardless it visibility and enable flag.
Usually presence of element used when you put some element as hidden, and you need to make sure that element present before you start your test in a page. For example I usually ask developer to add isPageReady element which rendered as hidden to indicate the page and other javascript codes have been loaded successfully since in modern web sometimes it is not enough to only wait using selenium default wait for page load.
Visible element, is on the other hand will be visible to user, and you usually used for interaction, like type, click, etc.
Related
The webpage I'm testing has a collection of 35 checkboxes.
The input tag is styled in such a way that it is positioned outside the visible part of the page (-9999px). When I want to click on it an ElementNotVisibleException appears. I can click on the label of the checkbox instead so this is not a problem but how to get the information if a checkbox is selected or not. The only way I can imagine is by analysing the page source. Is there another more convenient possibility to get this information?
Things you could try:
you should already have a method like isChecked() to test this, find that method
find the element and check his attribute for when is checked (example checked="checked")
write another selector for that element and check that this selector exists(not visible), example with css: input#elementID[checked=checked] or by value, depending if is a checkbox or radio box
For invisible element you can get his attributes, you just are not able to interact with him and it will fail to check that is visible/displayed.
Use a method to find the element, this will return an object, and see what autocomplete offers, what methods you have available and you can use, you should have getAttribute, isChecked etc.
I have a dropdown element directive to display in essence a styled dropdown list with additional capabilities.
My dropdown controller has a function called openDropdownItems that get's executed when the list should be displayed.
Then I also have another attribute directive called setInViewWhen that provides an expression when the element should be scrolled into view when condition is true.
<x set-in-view-when="something.item === selectedItem">
This is just an example of some X element with my attribute directive applied.
The thing is that I would like my dropdown list items (LIs namely) to have this directive on them so when user navigates over them using a keyboard, it would automatically scroll them in view when they get passed visible viewport. Whether these items are displayed within a scrollable container or as a whole in a list longer than the browser viewport isn't really relevant.
The main idea is for scrolling to follow dropdown list selection. Whether that should scroll the main window.
The problem
I can make my setInViewWhen directive completely independent but that means that I would have to search for the closest scrollable container whenever condition changes on an item. This seems to be quite a bit of processing that I would like to avoid to repeat (I need to traverse the DOM upwards, checking each node's calculated stylesheet property OverflowY + some additional checks.
This basically seems redundant because whenever I get the closest scrolling ancestor all sibling elements with the same directive could reuse the calculation result.
Question 1
How can I share this knowledge between sibling directives? If I was to fire an event I could not know whether receivers are siblings or not without any additional processing.
Question 2
Instead of checking for scrollable container every time when my directive's condition becomes true I could theoretically change dropdown parent's openDropdownItems to first complete it's original execution an then also execute the scrollability check and use the result of it along with my directive's condition.
I can gain access to dropdown's controller in my directive via directive requires property and adjust it in the post-link phase.
But this also means that I couldn't use my directive outside of dropdown which I would like to as it is a generally usable directive I could attach on several elements in my app to scroll elements into view under certain conditions.
What would you suggest how to do this?
To sum up the comments:
For Question 1, there is no direct way for sibling directives to communicate with each other. I usually create a wrapper parent directive to relay the messages.
As per the comments, the condition something.item === selectedItem introduces a watch; for a list of select items this can be many watches and detrimental to performance. Even if it doesn't occur now, it is a trap and someone may be lured into using this for a long list of items in the future. I would rather have a single watch in the parent of the <li>s and add the "scroll into view" logic there.
With the previous point in mind, you could still have a standalone setInViewWhen directive (seems useful) and have the controller of your X-select replacement directive share code with it. E.g.:
a service containing the common functionality,
an angular value containing a base class (Typescript or JS) and have the controller of both the setInViewWhen and X directives extend from it
or any other solution that is convenient for your case
Related to Question 2: The children could require their parent and change a method in it (this technique is even endorsed by Angular, see ng-model and custom controls where they override ngModel.$render() by replacing it). If you do that however, there would be many children changing the method of the parent, which could lead to a mess.
Issue: I have an accessibility issue that I am struggling with. I have an angular web application. A page loading spinner/indicator is shown when content is loading. And when the page content has loaded the spinner is hidden. This "div" is never removed from DOM.
Content of the loading div are not read (by NVDAor jaws) when the loading div is shown.
<div class='loading' aria-live='polite' aria-label='Do not refresh the page' tabindex="-1">Do not refresh the page</div>
I wouldn't like to change the structure of the application but work around using 'aria tags' to resolve this, just wondering if I will have to do anything more to make aria-live work?
Updated (27/July/2016)
Further clarification: I am not removing the content from DOM but using css to show/hide content (display: none to display: block and vice versa)
aria-live triggers screen readers when an element with aria-live (or text within an element with aria-live) is added or removed from the DOM. In contrast, when you unhide a hidden element, neither elements nor text are added or removed from the DOM, so the element's aria-live property doesn’t come into play.
To get screen readers to announce “Do not refresh the page”, either of these options should do the trick:
You can create the <div class='loading' aria-live='polite'> element and its text content from scratch and then add that element to the DOM.
Or you can start with an empty <div class='loading' aria-live='polite'> element and then populate its text content.
A few other tidbits:
As long as the text inside the element is what you want to be read aloud, you can omit the element’s aria-label='Do not refresh the page' attribute.
For icing on the cake, it can’t hurt to include a role attribute on the div that has aria-live. If you’re not sure which role to use, go with role="status"—that’s a pretty safe bet.
When or if the page is at a state where you no longer need to display "Do not refresh the page”, be sure to reverse the steps above. (That is, if you went with the first option and you added the whole element to the DOM, remove that entire element from the DOM. Or if you went with the second option and you populated the element’s text content, clear out the element’s text content.)
There are several issues with dynamically added or shown/hidden live-region.
Firstly a quote from MDN - ARIA live regions:
Simply including an aria-live attribute or a specialized live region role (such as role="alert") in the initial markup as it's loaded will have no effect.
Dynamically adding an element with an aria-live attribute or specialized role to the document also won't result in any announcement by assistive technologies (as, at that point, the browser/assistive technologies are not aware of the live region yet, so cannot monitor it for changes).
Always make sure that the live region is present in the document first, and only then dynamically add/change any content.
From my personal experience, even if a live regoin exists in the DOM on page load if you use show/hide then NVDA also has a bug which requires a small delay before a text update in a live region after it was shown initially. Apparently because the region didn't exist when the first text was added, so this isn't an "update". Regarding the timeout, you'd need to set it to something greater than the browser's refresh tick. I use 100ms. Disclaimer: I am strongly against such workarounds to make up for the issues with screen readers or browsers but it might be useful for someone in some cases.
I am using angularjs and ngmap (https://ngmap.github.io).
The map is initially hidden from view (using ng-show), and i want to be able to toggle between views without having to reload the whole map.
I also want to display a kml on the map.
The map is only initialized (using lazy initialization) when that part of the page is shown.
It seems to work fine, except that sometimes the map can't zoom into the kml (using fitBounds). I think I have established that this is because the height of the containing div is zero (due to the controller code firing before the view is actually rendered), and fitBounds needs that.
I am trying to wait until I am sure the map is good and ready. I have tried the following events:
bounds_changed
tilesloaded
but neither do what I want.
Currently I am using a $timeout, but I don't like it, as I don't know how long it takes to initialize the map, and whether or not my code will fire between that time.
My next idea is to repeatedly check for the height of the map, but I would prefer something more explicit.
Another idea is to always have the map in the background, and use absolute positioning to cover it with the other information when that part is visible, but that breaks my current design.
I've decided to avoid the issue.
The map is always going to be there, but I use some ng-class s to make it "visibility: hidden" and hide an unneeded scroll bar when the map tab is unselected.
As long as the visibility is hidden (instead of display: none) the initialization and positioning of the map goes okay.
It isn't perfect (I might need to scroll the other tabs one day), but it works for me for now.
lately I have a pretty significant problem with ng-view and ng-if.Suppose there is a dropdown with two elements (element one and element two).The two elements change a property on rootScope.
I have two more items at another location (div-container, container one and two containers). These are displayed by ng-show - container one at element one and container at element two.
As soon as I click the one element one time and the property of the rootScope changes and then I reload the page, the two containers are alternately displayed without that I do something.
I have several watchers, seveleral ng-cloaks and use the routing using ng-view. I would also like to mention that the application is relatively large. Most often, the problem occurs on Android, presumably on iOS.
As soon as I click the one element one time and the property of the
rootScope changes and then I reload the page, the two containers are
alternately displayed without that I do something.
Did you mean the other two containers just show up for a second and then disappear? If that is the case then I think the condition you are providing inside ng-show is true at the loading time so they appear for a while before the condition changes and then they disappear.
You have to make sure the condition for ng-show is initially false.