What exactly does aria-controls do for the user? How is it affected by AJAX usage? - ajax

I have a set of tabs with proper roles and attributes for accessibility support. The content that tab controls gets loaded in via ajax. But each wrapper for the content loaded in also has proper tab pane roles and attributes.
The problem is, when I run an automated audit using Chrome Accessibility Tools, the test fails stating that the corresponding ID of the tab pane is missing for all of the tabs except the one that's currently active (because that wrapper with ID has been loaded). The exact error states: "ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM."
Since the ID will exist once the tab with the corresponding aria-controls attribute is active, is this really an error? Or is this just a case of a false positive because it's an automated test and they can only do so much.
In summary, What does aria-controls do and does it really need to refer to an ID that currently exists in the DOM?

aria-controls give your assisting technology a way to move to the controlled element.
If this element is not in the DOM or can't be accessed, then yes it's an error.

The two (the element with aria-controls as well the element with the referenced id) must exist at the same time, whether at page render or via JS injection.
The DOM is parsed by the UA/AT combo before the user even gets to the control or your script fires to make it exist. If you use JS injection then you need to make sure the DOM is re-parsed.
This would apply to aria-owns as well.

I don't know whether the following would work in your architecture, but it would solve the error problem:
Design the tabs so they are all in the page at the time it loads. Format those that should not be shown to be outside the viewport using absolute positioning and something like "left: -99em." Use AJAX to reset the positioning when the time has come to display the tabs. The result is that the ARIA ID dependencies will always be valid because the tabs are always part of the DOM.

Related

Apex main region header with dynamic value

I have tried everything I know to make title of header replicate items value, including substitution string &P10_TITLE_TEXT. inside headers title property. Generally, this would work for normal region, but in my case I try to modify value of pages main region, which is rendering first, before any other item. My assumption is that title text is not showing because it cannot see items value yet.
Is there a simple way to refresh title header after items are ready, or perhaps another better solution?
PS: This is main header of the modal dialog page, that has no property for setting static id, and it's template is less adjustable then normal regions.
Try the following javascript in "Execute When Page Loads" of the modal page:
$('.ui-dialog-title',parent ? parent.document : document).text( apex.items. P10_TITLE_TEXT.value );
Pre-Rendering computations may be the solution here.
You can try creating a computation before Regions under Pre-Rendering to set &P10_TITLE_TEXT.. There will be no need to "refresh". This is if you are simply loading it once.
If you are trying to set headers based on input every time you change it, I would advise separating into two pages so you can submit the page and APEX can reload and process, or just use javascript.

UFT is waiting the entire object sync timeout before clicking a webelement

Alright, in my web application there's a dropdown that UFT picks up as a 'WebElement' instead of a 'WebList'. The options available in this dropdown are all just 'divs' and the data within the div is dynamic. Has anyone had to deal with this before? I even tried using the absolute xpath within the object repository, but that seems to be inconsistent. Whenever I run my test the first time it interacts with the dropdown it will wait the entire object sync timeout before selecting the element. Then I have it going back to select another item from the dropdown and it goes instantly. This isn't the approach I want to take with this as the abs xpath could break at any time. I've been reading blog posts etc from as far back as 2008, and tried every person's suggestion but I can't reliably click a dropdown and select something. I can give more detail if needed, but any help here would be appreciated.
When UFT waits the object synchronization timeout and then succeeds to perform the action it's usually because it has been using smart identification. Look in the report to see if this is the case (or just disable smart identification and see what happens).
If this is the case, you should try to fine-tune the description to succeed on the description and not resort to smart identification.
I got it! This behaviour was being caused by the 'browser' being different in that part of my code. I think this happened due to some of the same items being added into the OR from different pages.
Instead of having:
Browser("Browser1").Page("Page1").WebElement("Element I want").
It was:
Browser("Browser2").Page("Page1").WebElement("Element I want").
Once this was corrected in the OR everything worked as expected.

How can I find what triggered a dirtyforms popup?

I have a form that normally works with respect to dirtyforms. However, there is one circumstance where a jquery-ui datapicker calendar will pop up the "are your sure" dialog when a date is clicked.
I emphasize that this normally works correctly. The situation is related to the initial conditions of the form data source. Things work when the object being referenced is existing, but not if it is new. So I am sure somewhere there is a difference in the initial conditions of the form. But in theory the form should be identical.
How can I find what is causing the popup so I can fix my issue?
Well, I did find what was causing my problem by comparing the HTML of the working and non-working situations. (Not an easy task since there were many non-relevant differences.)
Seems that the original coder did a strange thing. Left out some Javascript function declarations when the page was "new" but of course did not eliminate the calls on those functions.
So I guess that the javascript errors were the root cause. At least when I include those function declarations everything works correctly.
By default, most anchor links on the page will trigger the dialog. We don't have a hard-coded selector of all potential 3rd party widgets, you must manually take inventory of whether these widgets use hyperlinks and ignore them if they are causing errant behavior.
See ignoring things for more information.
I was unable to reproduce this behavior using Dirty Forms 2.0.0, jQuery UI 1.11.3, and jQuery 1.11.3. However, in previous versions of Dirty Forms, you can probably use the following code to ignore the hyperlink clicks from the DatePicker.
$('.ui-datepicker a').addClass($.DirtyForms.ignoreClass);

Behat/Mink - trouble finding buttons

My application under test has been developed by external suppliers so I have no control over the HTML structure. The application is extremely Javascript and Ajax heavy, with numerous dynamically generated buttons and auto-complete lists.
In other words, the characteristics of the pages are that they are filled with:
Elements with no fixed IDs (IDs are generated on the fly and have
numbers or other text dynamically added to them)
The same happens with some classes
Most of the times the buttons have no text associated with them since they are either custom coded 'down' arrows for lookup lists
(which aren't lookup lists but hidden divs) or '+' and '-' icons to
maximise or minimise portions of the content. -
It is therefore very difficult to identify these elements, especially the buttons.
I am trying to write a generic 'I click on the button near y' type of step so that it is not necessary to hardcode each and every button (assuming I can even get something to identify them with) into each and every test.
The thinking behind this is that normally there is a label of some sort close to the button at least.
What I want to to is to find the text label, then see if there is a button inside the same scope, and if there is not, move 'back' through the parent elements, and check if there is a button inside the scope of each parent level, up to 5 parents.
There might be all sorts of problems with this approach but I am just curious to see if this will work in general. I have run into some problems.
First I tried to use Xpaths, so I got the Xpath of the parent through :
$parentelement = $element->getParent();
$parentXpath->getXpath();
This would give me an Xpath of : (//html//span[text()='Cost center'])[1] and moving up through the parent elements all the time, they would become successively:
(//html//span[text()='Cost center'])[1]/..[1]
(//html//span[text()='Cost center'])[1]/..[1]/..[1]
and so forth.
The actual button is located in: (//html//span[text()='Cost center'])[1]/..[1]/..[1]//button but it has to go through all the parent elements in order to get there, so it will start with (//html//span[text()='Cost center'])[1]//button and should end with (//html//span[text()='Cost center'])[1]/..[1]/..[1]//button where it should find the button.
Trying to use Xpath I used:
$button_element = $session->getPage()->find('xpath',$parentXpath."//button")
I soon saw that the 'find' command appends an //html to the front of your xpath string so the Xpath that it tried to use ended up being (for each parent Xpath, but using this one as an example):
(//html(//html//span[text()='Cost center'])[1]/..[1])
I then stripped out the brackets as well as the //html, leaving me with:
//span[text()='Cost center'][1]/..[1]
but when I tried:
$button_element = $session->getPage()->find('xpath',$strippedParentXpath."//button")
I got the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '(//html//span[text()='Cost center'][1]/..[1]//button)[1]' is not a valid XPath expression
However, Firepath can execute this expression and does not show a syntax error for it, although it does not find the actual button (since the button is actually located one level up, where Firepath DOES find it).
So my question 1 is: What is wrong with my Xpath that I can't use it in the find? It actually looks as if //span[text()='Cost center'][1]//button does not throw the same exception, since as I said, I am looping through the parent Xpaths, and it starts with //span[text()='Cost center'][1]//button. It crashes on //span[text()='Cost center'][1]/..[1]//button.
My second option was to get the parent element each time, starting with finding the text on the page, but then to search for a button inside the scope of the parent element using the findbutton functionality.
Looping through the parent elements (up to a maximum of 5):
$parentelement = $parentelement->getParent();
$butonelement = $parentelement->findbutton('xxx');
In other words, find ANY button in the scope of the parent element. The problem I have is how to specify a generic 'button'.
One has to associate SOME text with the button (depicted by the 'xxx' above).
But this is a typical example of buttons in the application:
<button class="autocomplete_button" type="button" id="button_OM_1"> </button>
Where the class is used more than once, and the ID is auto-generated and not the same number all the time. There is no text associated with the button since the class specifies an image.
Question 2: So how can I use 'findbutton' to generically find a 'button' no specific distinguishing characteristics? Please note that I actually did try findbutton("button"), taking the chance that there might be a 'button' somewhere in a button, but this did not work either. At least, it doesn't work consistently and by that I mean that the same test randomly seems to either find or not find the same button when I run the test a couple of times.
After doing some more investigation on this issue I have found the following:
My method of trying to find the closest button to a piece of text via traversing 'up' through the scope of the divs and spans around the text (using xpath) is actually working.
What is NOT working is SAHI, which I am using as the web driver. In other words, it is not a Behat/Mink problem, it is SAHI specific issue.
I tried the same code using Selenium2 and it executes perfectly.
I still require an answer to question 2 - how can I use findbutton() without a specific parameter such as the ID, name or value but I will see if I can find an answer to that question separately and on the Behat user group since I do think that is a Behat/Mink specific issue.
I normaly use css selector and with that, I use to navigate to the class and ID's that the button is inside. it is easier than xpath I think, like you can use
$this->getSession ()->getPage ()->find ( 'css', '.parrent1 .parrent2 .autocomplete_button ' );
I think this will help you as you know which button your gonna use in each scenario

Deleting elements using Watir

Does anyone know how to delete an element from the source using Watir? There doesn't seem to be a method for removing elements. Perhaps I'm missing something.
If you know JavaScript, you could execute any JavaScript code on the page.
Example:
browser.execute_script("some javascript code")
I am not a JavaScript ninja, but this question could help you: JavaScript: remove element by id.
Remove elements by css:
browser.execute_script("[...document.querySelectorAll('.some.class')].map(e => {e.parentNode.removeChild(e)})")
We can remove it with javascript. Here's an example to remove a breadcrumbs div element but it's id:
browser.execute_script("bd = document.getElementById('breadcrumbs'); bd.parentNode.removeChild(bd);")
The Purpose for Watir is to do web testing, which is to say drive the browser as if a user was interacting with it. That means doing the things a user could do, clicking on stuff, filling in input fields, etc. It also means being able to verify what is there on the screen that the user can see or interact with.
Since a user cannot delete elements, there is no means by which to do that using the tool.
If the application provides a way for users to 'remove' or 'delete' something, like closing a simulated window, removing a tab etc, then you need to do that by simulating what the user would do (usually clicking on some specific element) in order for that to happen.

Resources