I'm using Nightwatch.js to perform e2e testing on my Vue.js application. My application contains long forms, which "hides" the buttons outside of the view while performing the tests.
I looked into many questions that suggests the usage of getLocationInView, but the documentation clearly says
Determine an element's location on the screen once it has been scrolled into view
I tried using something like
browser
.url("http://localhost:8080")
.setValue("#email", "valid4#mail.ca")
.getLocationInView("#myElement")
.submit() //defined elsewhere
.waitForElementVisible("#error", 3000);
This snippet is supposed to click on a button at the bottom of the form, that's what submit() does but when I get the error screenshot to find that no scrolling down whatsoever has happened, leading the button to stay out of focus and therefore unclicked!
is there a way to ultimately scroll to the bottom of the page so I can pass the tests without having to change or at least with minimum changes to my original code?
Rather than using submit, use elementIdClick .
The documentation says that this method would scroll the element into view. This would click the button to submit the form rather than attempting to submit the form without interacting with the button.
This seems like a more 'authentic' way to test since users would click the button at the button of the form anyways. Otherwise as you know, the test will keep failing since the button is not in view.
EDIT:
Check out this answer as well: nightwatch.js - scroll until element is visible
Clicking a button requires scrolling to that button to bring it on the screen first, but apparently setValue will do the scrolling itself. so instead of scrolling then clicking, I set the value of the button in this way:
browser
.url("http://localhost:8080")
.setValue("#email", "valid4#mail.ca")
.setValue("#submitButton", " ") //<---this line
.waitForElementVisible("#error", 3000)
this is like setting focus to the element (the button) then hitting the space bar.
This is not of course the best way to do it, but I think it might be a helpful workaround if your form does not have space and enter restricted from submitting/triggering the button.
Related
I'm trying to make an accessible popup/dropdown like the example on W3's website. If you click on the keyboard users approach 1 menu, and then tab into the Space Bears menu item, pressing enter will open the menu. Then, if you press tab, you go through the menu. Once the focus is out of the menu, the dropdown automatically disappears. This is the functionality that I'm trying to emulate. I got the rest working, but their JavaScript snippet doesn't explain how to hide the popup on focusout.
I got the following solution of my own, which uses a timeout. The timeout is there, because without it, the activeElement is the body. I need to wait that short bit for the focus to be on an element. I feel like there could be a more reliable approach, rather than relying on a timeout, though.
Note that I called it a modal in my code, but it's likely not actually a "modal". This was just what I named it.
$('.js-modal *').on('focusout', function() {
setTimeout(function() {
var is_in_modal = $(document.activeElement).closest('.js-modal').length;
if (!is_in_modal) {
close_modals();
}
}, 10);
});
Your idea of something that disappears automatically when you go out of it is a bad idea.
You'd better switch to a more classic solution, like a true modal, as already well described by the other answer.
It's a bad idea because it's confusing.
Let's imagine this scenario: we have five elements 1, 2, 3, 4 and 5. 3 and 4 are initially hidden and appear when 2 is focused.
I'm initially on element 1:
I press tab and go to element 2. Element 3 and 4 appear, but since I'm blind, I may not have noticed it at all.
I press tab again. I go to element 3
I press tab. I go to element 4
I press again tab. I go to element 5. Elements 3 and 4 disappear but again, I may not have noticed it.
OK, well, I finally want to go back to element 3, so I press Shift+Tabb. I expect to land on element 4, but went on 2 instead. Where is element 3 ?
I hope that with this little scenario, you understand the problem. If I'm not aware at all that elements appear or disappear, I find elements in a different order than I expect.
If at that moment I don't understand the logic and don't find back the element 3, great are the chances that I leave the site forever.
You aren't convainced ?
I imagine you have been told to do that to have the same logic for keyboard users than with mouse users.
With the mouse, you click on the menu, it opens, but closes as soon as you leave its area.
Note that it's also a poor idea in terms of accessibility, because you require the user to be quite precise. Following precise paths with the mouse isn't' always easy, especially for elder people or people with movement difficulties.
For that reason, we usually recommand to no longer use menus like that, and change their behavior to make them disappear only when clicking outside of it. So, mouse users with some movement difficulties have all their time and freedom to select what they want to select.
For keyboard users, that's kind of the same thing. If I'm blind, I expect focusable elements to always have the same tab order, and expect changes in that order only when I make a conscient action like press enter to expand/collapse a menu.
If I'm sighted and use the keyboard for whatever reason, I don't expect elements to appear or disappear on screen when just pressing tab.
Still not convainced ?
So ask yourself another question: how do I use your interface with a smarphone ?
With a touch device, there's no real focus, as well as there's no real mouseover, until you click on a precise element to interact with it. It's problematic, isn't it ?
You don't have at all these notions, so you must react on clicks. You don't have choice, and that's good.
automatically disappears when the users uses keyboard/TAB navigation to focus out of it.
This is the exact opposite of the behaviour of a modal.
You should trap focus inside your modal and it should close with the Esc key and via a close button (accessible via keyboard).
This article is a good starting place to learn about Modals, although I disagree with the method for point 5 "While Open, Prevent Tabbing to Outside the Dialog" - this should also include using aria-hidden on every element outside the modal as otherwise screen reader users can end up outside the modal (as they may navigate via links or headings etc.) when they shouldn't be.
Final thought - are you sure you need a modal? There may be a better pattern you could use if the above does not apply to your use case.
I'm having a hard time finding any resources that talk about best practice, default behaviours and so forth.
Basically, I have a button on a page. It doesn't do anything, I essentially have a canvas element and just needed a way for the user to be able to tab onto the page.
So using a switch device, I can navigate to the button, and on clicking on the button, it jumps me back up to the url address bar. The behaviour I'm after is on selecting the button it still stays on the same page.
I've tested other websites and it looks like the default behaviour is that once you select a button it jumps to the top of the page.
Could anyone point me in the direction of any resources or anything that confirms or talks about this?
I essentially only have this:
<button tabindex="1" class="action_button">Action trigger button</button>
and a
<canvas></canvas> element
Perhaps this relates to the default type of buttons being submit.
Does adding type="button" to the button change the behaviour you're seeing?
Yes, this will happen unless you add some script to the button. If you have no other action for the button you can use this:
function() {return false;}
But if the button doesn't do anything you should remove it - people who rely on keyboard navigation don't usually like having to work their way though unnecessary controls. If there is nothing interactive then don't make them tab into the page. (Also there is no need to add tabindex to a button, it takes focus natively.)
I ran into an incredibly obscure-seeming bug and want to document it for posterity. Here’s what happened:
I’m displaying an HTML form to the user with many text fields and a submit button at bottom. Just above the submit button is a warning message that appears or disappears depending on whether the user has filled in all the required information. During testing (automated using Capybara, or manual in the browser) I fill in each field down the page, then click on the Submit button, but the first click doesn’t register. A second click submits the form as expected.
I found that if I disable my custom Javascript, no second click is required. After some process-of-elimination I determined that one Jquery line was responsible for the failure: $(‘#warning-message’).hide();. Comment out this line, and filling out and submitting the form works as expected. Re-enable this line, and form submission requires that extra click. What the frak?
I eventually figured out this was because, both during manual testing and when simulated by Capybara-webkit, when you click on an element like a submit button, that’s registered as a specific X/Y coordinate on the screen. You're not clicking on the DOM element, you're clicking on a coordinate. Because of the (lazy) way I set up this page, when I fill out all the required elements then click Submit, upon clicking the submit button a Jquery change event is triggered which causes $(‘#warning-message’).hide();, which in turn causes the submit button to jump up outside of the area that I had clicked on, so the submit event never gets triggered in the first place because the browser doesn't realize that I clicked on a button.
I’m still not clear what to make of this, but it’s definitely not a bug per se, so much as a misunderstanding (on my part) of how browser events are handled. I’ve worked around the issue by wrapping the warning div in a fixed-height container so unrelated Jquery change events can't cause the submit button to jump around.
Anyway I hope this helps someone.
I'm using jquery's bPopup() to open a modal window. When the user clicks a button, jquery loads an ajax page and then shows the modal windows. Due to this small delay when loading the page, the button remains active, and if the user clicks twice, it will fire twice, making two ajax requests to the server and opening two windows.
Is there a simple way to prevent this from happening? Since it's relatively a common problem, I wonder if there's a "right" way the pros handle it.
I've tried assigining the popup to a window.object, so that it would be overwritten on the second call, but it's still opening two popups.
That depends on what UX you're after, but I'd suggest you disable the button.
That way your user will:
Know the click was "registered".
Not try to click again.
Not crash / confuse you code.
EDIT
According to the comment, the "button" is actually not a <button>, but an element with an onclick handler. So:
You can disable the click handler by reversing what you did to set it (removeEventHandler, onclick=null...), but you'd then have to set it back once the pop-up is done, and that might be quite annoying.
You'd have to somehow manipulate the UI to indicate the button was clicked and is disabled. Could probably be quite simple to do with a CSS class.
But really, you're probably better off having 2 "versions" of your button element (<div>...), with only 1 visible at a time, with the other hidden via display: none. The "clicked" version should not have a click event handler set at all. Then, when the button is clicked, you immediately switch between the 2 (can be done with a single CSS class), and once the pop-up is done, switch back.
I want to display a notification for the user that will remain constantly visible in the form of a page action until the user does something. I am using this code right now:
chrome.tabs.getSelected(null, function (tab) {
chrome.pageAction.show(tab.id);
});
But that only creates a page action icon on the active tab when the extension is loaded. Instead, I want the icon to show all the time no matter what page or tab the user is on. It also needs to go away when the user does what is necessary to deal with the notification.
I was thinking of two ideas. The first was looping through and adding a page action to every tab, then hooking the new tab and navigation events and adding it to each of those. My second idea was hooking the active tab change event and adding it to the active tab then removing it from the former tab when changing tabs next.
But I thought that there's still probably a better way I didn't think of or didn't know about. So what's the best way to accomplish this?
You need to hook into the onActivated event if you want to get notified of tab changes.
However, that would not be enough, since the page action will reset on navigation. So you'll need to hook into almost every tabs API event to ensure your logic. Also, think of the cleanup required afterwards.
That really does seem like a poor job for a page action. There is also an important consideration that this UI element is not associated, by a typical user, with something that needs attention. Have you considered using notifications instead?
You could use chrome.notifications Rich Notifications together with the priority trick, or just web notifications. In either case it'll be something displayed to the user in a way that is appropriate for "something needs your attention". You can then hook into its onclick event.
If you do want a button, browserAction is totally appropriate. You can dynamically change picture, add a text badge to the icon to attract attention, or just plain disable the button (not hide, but grey out) when there's nothing to do.
According to the documentation, page actions are supposed to be used only for single pages. If you want something to show up on all pages, you should use a browserAction.
Alternatively you can try and set "<all_urls>" in the permissions, but I haven't tested if it actually works.