Nightwatch seeing my element but its not interactable - html

I'm runing a nightwatch test on Loadero and its failing.
I'm trying to test if an element is available, and if it is, to click on it.
I believe that below, I'm saying only try click the button if it exists.
client.elements("css selector", "div[aria-describedby='dialogWindowTooSmall button.ui-button']", function (result) {
if (result.value.length) {
client.click('div[aria-describedby="dialogWindowTooSmall"] button.ui-button)');
}
})
But I'm getting an error.
The first line seems to execute fine. I get two ELEMENT ids back
[ { ELEMENT: '0.7754195696252344-2' },
{ ELEMENT: '0.7754195696252344-3' } ] }
but the click function fails:
Error while running .clickElement() protocol action: An element command could not be completed because the element is not visible on the page. – element not interactable
Surely if the element is found, its clickable?
(i have tried to paste more of the log here but it loses all formatting and is impossible to read)
Thanks!

No, if the element is present on the page, it does not mean that the element is also interactable (or clickable). For an element to be interactable, it also needs to be "visible" on the page and not just "present" on the page. It can happen if the element is hidden or outside the viewport of the page.
When you try to perform a 'click' operation on an element, Selenium first tries to locate the element and if the element is not visible in the view, it tries to scroll to the element to bring it into the view and then click on the center-point of the element.
Now, if Selenium is unable to bring the element into the view, it throws element not interactable error. If it is able to bring the element into the view but the center-point of the element is covered by some other element, it throws element click intercepted error. Otherwise, it successfully performs the 'click' operation on the element.
For reference: https://w3c.github.io/webdriver/#element-click

Related

Chrome: Inspect element tree position lost after page reload

during localhost developing I inspenct element and add some css rule, when it's ok I write changes in css file, after this I reload page to see if all is in the exact position, but tree position of elements are lost during refresh! Every time I inspect element to find my last position in the code again.
In the past other chrome version save the tree structure and after page reload it returns to last element clicked by me in inspect element section. How can do it?
I agree sometimes it's annoying to move down the tree at every refresh. One workaround is to use ctrl + shift + c shortcut and target the element with your mouse.
On top of that, I've made a AutoHotkey script (windows) to trigger this shortcut when I double right-click on my mouse. This way, I just target the element with my mouse and double right-click it to open the DOM tree where I want. It's very effective unless there's some z-index properties that prevents you to go straight to a nested element.
This plugin does the job:
#IfWinActive ahk_class Chrome_WidgetWin_1 ; Chrome browser
$RButton::
SetTimer , Fast, 200
Fast_Count+=1
return
Fast:
if (Fast_Count>=2){
Send, ^+c
Fast_Count = 0
} else if (Fast_Count=1) {
MouseClick, right
Fast_Count = 0
} else {
Fast_Count = 0
}
return
Use the little arrow in a square (red square on picture below) and click on the element you need. Navigating to it should be trivial that way.

Why does $x return items outside of the context?

I am attempting to use an xpath locator within a context for a Codeception test using the Selenium driver with Firefox. Specifically, I am trying to click the second link in the message body of an email, viewed with roundcube.
The body of the email is in the div with xpath //div[#class="rcmBody"]
I can get the link with this path: (//div[#class="rcmBody"]//a)[2]
But for some reason when I try //a[2] within the context of the body div, it returns all a elements within the iframe.
An example from codeception: (after selecting the correct iframe)
$I->click('//a[2]', '//div[#class="rcmBody"]')
This causes the web driver to click the second link in the iframe which comes before the body div begins.
I can also test this from directly in chrome:
$x('//a', $x('//div[#class="rcmBody"]')[0])
This returns a list of all a elements within the iframe, not within the context.
How can I get the context part to work?
Add a dot to the beginning of XPath to make it context-specific:
$I->click('(.//a)[2]', '//div[#class="rcmBody"]')
HERE^
Note that the parenthesis here are also important to get the desired a descendant of the parent.

How to make a custom web component focusable?

I'm writing a custom web component that is meant to be interactive. How can I tell the browser that this custom component should receive focus?
I wish that my custom element…
could be focused (by tab-navigation);
could receive keypresses when focused;
could be matched by :focus pseudo-selector.
I'm not using any external library, just plain HTML5 APIs.
Based on this demo that I found in this question, I have this answer:
Just add the tabindex attribute to the elements you want to be focusable.
// Add this to createdCallback function:
if (!this.hasAttribute('tabindex')) {
// Choose one of the following lines (but not both):
this.setAttribute('tabindex', 0);
this.tabIndex = 0;
}
// The browser automatically syncs tabindex attribute with .tabIndex property.
Clicking on the element will give it focus. Pressing tab will work. Using :focus in CSS will also work. keydown and keyup events work, although keypress doesn't (but it's deprecated anyway). Tested on Chrome 44 and Firefox 40.
Also note that this.tabIndex returns -1 even if the HTML attribute is missing, but this has a different behavior than setting tabindex="1":
<foo></foo>: No tabindex attribute, the element is not focusable.
<foo tabindex="-1"></foo>: The element is not reachable through tab-navigation, but it is still focusable by clicking.
References:
http://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute
https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
https://github.com/whatwg/html/issues/113
#Denilson, I would like to provide you with some more information.
As you said, this.tabIndex = 0 works when your webcomponent contains no focusable elements. If it does, it gets more complicated.
For example, if your component contains one or more inputs, then first the "whole" component gets focus, and only later, when tabbing, each inner inputs get focus, one by one. This is usually not what you want. Usually, when the component gets focus this should mean its first input gets focus immediately.
Also, there is a reverse tabbing problem. If your first input has focus and you press SHIFT-TAB, then the "whole" component gets focus, and you are forced to press SHIFT-TAB twice to move to the previous element.
I found this to solve all focus and tabbing problems:
// At first, the component may get focus and accept tabbing.
createdCallback = function () { this.tabIndex = 0; }
// When the component gets focus, pass focus to the first inner element.
// Then make tabindex -1 so that the component may still get focus, but does NOT accept tabbing.
focus = function (e) { firstFocusableInnerElement.focus(); this.tabIndex = -1; }
// When we completely left the component, then component may accept tabbing again.
blur = function (e) { this.tabIndex = 0; }
Note: As of now (Sep 2015) if an inner element gets focus, then the "whole" element is not matched by the :focus pseudo-selector (tested only in Chrome). If find this behavior to be just plain wrong. The focus event was fired, and the blur event was not. So the element should have focus, right? I hope they change this in the future.
Short answer: delegatesFocus is what you need here, not tabindex.
Details:
Assuming that you have interactive elements inside the shadow DOM, there is no satisfying way to make the component programmatically focusable with tabindex:
if you set it to 0 you add the host element to the tab sequence ("sequential keyboard navigation") and you have an extra tab stop
if you set it to -1 you remove not only the host element but any interactive element inside its shadow DOM from the tab sequence, so the whole thing becomes inaccessible for keyboard users
There's a web component API just for this: ShadowRoot.delegatesFocus, see here. Set this to true and you'll get:
calling .focus() on the host or clicking on any non focusable part of the component focuses the first focusable element in the shadow DOM
:focus styles are applied to the host in addition to the focused element within
tab sequence is unchanged (it should already work the way you want)
It's supported since shadow DOM v1.
One very pragmatic approach I use, if possible and suitable, is just to put a <button type='button'> around my custom element.
This maybe does not fit as solution for you, I mention it anyway for others stepping into this question / problem.
It handles all focus matters, including a focus rectangle an so on.
To tame a <button> is less work than it seems (think especially about the line-height the button changes)

Inconsistent click handling when using :active pseudo class

Can anyone explain why the click handler is not invoked consistently in this example?
http://jsfiddle.net/4QBnf/
For instance, if you click in the upper left half of the div, it does not reliably increment the counter.
If I remove the padding-top from this block it works just fine:
.click-check:active {
background-color:blue;
padding-top: 25px;
}
I have tested this in a number of different browsers and it behaves the same way.
I found two possible issues with your code. You can view the fixes here:
http://jsfiddle.net/4QBnf/6/
CSS Box Model vs jQuery Box Model
Whenever you click on the top half of your box, you aren't technically clicking on .click-check, you are actually clicking on .count. This image shows the location of .count relative to .click-check:
jQuery counts this as a click on .click-check, but CSS doesn't. The number increments, but the CSS "active" effect isn't applied.
You can resolve this by removing the .count div and placing everything inside of .click-check.
jQuery Counter
The second issue is with your jQuery code. The code currrently reads:
$('.click-check').click(function() { $('.count').html(count++); });
count isn't increased until after this line is done. This means that the first click appears to have no effect.
This line will increment count, then display it to the user:
$('.click-check').click(function() { $('.click-check').html(++count); });
I've applied both updates to your example here:
http://jsfiddle.net/4QBnf/6/
Update
An alternate way to resolve the issue is to do everything through jQuery. This synchronizes all of the appearance and logic into a single box-model interpretation.
var count=0;
$('.click-check').mousedown(function() {
$('.click-check').addClass("active");
$('.click-check').html(++count);
setTimeout(function(){
$('.click-check').removeClass("active");
}, 50);
});
http://jsfiddle.net/4QBnf/15/

hyperlink to open different web page with specific element in focus AND active

This problem refers to the main (header) nav menu on THIS PAGE.
When any of the items in the "Services" drop-down submenu is clicked, I want the "Services" page to open (in the existing browser window) AND for a specific anchor tag element on the "Services" page to be in focus. I've achieved this OK. BUT, when the targetted anchor tag is in focus, I want it to also behave just like a manual mouse hover had been performed on its parent div, ie there should be a slide-down of text corresponding to the focussed element.
For a manual demo, go HERE and hover on one of the vertical list items - text will slide down to the right of the list.
HTML for the "Services" submenu link:
<li> collaborative law</li>
HTML for the targetted "a" tag and its parent div (ie "a" tag that should be in focus on "Services" page):
<div id="mylist1"><h3>Collaborative Solutions</h3></div>
Script to drive the hover behaviour of the focussed "a" tag and its parent div:
//fades in desired text after fading out whatever text is already displayed:
$(document).ready(function() {
$('#mylist1').mouseover(function() { //note first list item must be called mylist1 to avoid conflict with other code
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});
//capture click events as well:
/* $('#mylist1').click(function() {
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});*/
//capture focus events on <a> as well:
$('#myTag1').focus(function() {
if ( !$('#text1').is(":visible") ) { //prevents re-display if desired text already displayed
$(".shownText").slideUp(100).removeClass('.shownText');
$('#text1').slideDown(300, 'linear');
}
});
});
Note the main nav menu has been created using jquery, via a Dreamweaver extension.
What I have so far:
When the "Services" page opens, the correct target is in focus (as shown by the browser address bar). However, this focus is not triggering the expected text slide-down event. When I hit tab, the next list div goes into focus (as expected) & the appropriate text slide down occurs.
Am I hoping for too much? Have I misunderstood the limitations of 'in focus'" Will Mt Hotham have a killer snow season this year ?
Your sage advice is greatly welcomed!
Kirk
I'm not sure your use of "in focus" is quite what I expect... Having a fragment in the url doesn't necessarily give focus to that element, it just moves the display down to it. I assume the reason it works for tabbing is that tabbing does focus on elements and I assume it starts at the element that has been scrolled to.
What I'd suggest is breaking out your display script into a named function (so it can be used from elsewhere) and then on page load you can pull out the fragment from the url (eg #famLaw). Using that fragment you should be able to find the right element on the page and focus it.
It should be noted also that pulling the display text into a separate function has the advantage of consolidating your code - you are basically duplicating the code in the onfocus and onready events so breaking it out makes for easier maintenance and reuse. :)
P.S. I guess yes for Mt Hotham. I'd never heard of it before but I'm going to be optimistic.