 virtual attendees. Hello Portland, if you are streaming there. And thank you all for having me. My name is Ava, Ava Roten, and I'm here to talk about accessibility. That's going to be a little bit different. This is a success story. This is a story. Accessibility first, and everyone wins. More composable, intuitive, and testable. We've all heard of mobile first. I'm going to flip it on its head a little bit. Once again, I am Ava Roten. I go by she, her, and I am a software engineer at AlloView. At AlloView, we build software for K through 12 school districts. And I'm very proud of what we do there. We build this all in EmberJS, and I've been doing Ember for, oh, the past seven years or so at different companies. You can find me on GitLab or on GitHub at the things in the doobly-doo. So we'll be discussing a project feature that was saved by accessibility. It might not have gotten off the ground otherwise. So I'm very excited to share the story with you. During the course of the story, we'll be talking about adding functionality with composable components. So we'll discuss composability, composable components, and what that means, how I did it in this case. We'll talk about equitable and discoverable user experience design, and we'll talk about what those things mean. And finally, we'll talk about automation testing and how it relates to all of these topics. And hopefully, you'll see something you haven't quite seen before in an automation testing with an Ember, or at least you'll see some of the newer ways of how automation testing can be done in some of the latest Ember practices, which has me really excited. And so here's the story. I had a feature. This is several years back now, and on my team, we were given a ticket. This ticket had a feature on it called item reordering. This feature was so simple that it had no design. We just wrote it up. Users should be able to move around items on the sidebar in order to reorder them to their heart's content. Okay, that sounds good. It sounds simple. Maybe a little too simple. So, okay, mouse, drag and drop. That makes sense. I can make that happen. What about touch? Do we support touch devices? And of course, when you ask that kind of question, it sounds great. Yeah, support touch. Just go through the extra loops that you need to do, loopholes, jumping through hoops, that you need to do in order to make touch work. No big deal, maybe. What about accessibility? Okay, so the room goes dead. It goes real quiet. And I need to explain a little bit more what I'm talking about. So firstly, you're already seeing on the screen several times now, A11y or A11y. And if you expand that out, it becomes the word accessibility. It's a sort of acronym, if you will, that means accessibility. Perhaps you've seen that before. Perhaps you haven't. Accessibility has 11 characters in it. And so we shortened it down for things like this presentation or for documentation to simply mean accessibility. But we're also going to be talking about equity. So what is equity? Well, let's think about the idea of what I was being assigned to do. I was tasked with delivering a feature that I felt like maybe not everybody could use. Okay, drag and drop sounds simple enough. A user can use their mouse to move up and down, click on something and drag it and let it go. That requires some fine motor control, it sounds like. And also touch on a mobile device. But it doesn't have anything to do with a keyboard input or a screen reader or some other ways that maybe users are interacting with our app. Imagine using no hands and you're using the eyes in order to click on things and move them around. Clicking and dragging is a very difficult thing to do without a standard mouse or touch interface. And so I felt like it was potentially unfair that we were maybe unintentionally locking out some users from accessing parts of the app. This entire feature that I was assigned to work on wasn't necessarily accessible to everybody, literally not able to be used by everybody. And so I felt like there was a lack of equity. Not that everybody is entirely equal, that everybody can use in the same exact way drag and drop, but in an equitable way that I was hoping users to be able to interact with this via the keyboard through a different input medium. 15% of the world lives with some form of disability. And a great many talks have been given already, trying to sell accessibility, trying to be the person up on stage who is selling to you why accessibility is important. I'm merely wishing to set the stage for my motivations here about what really got me thinking about this in return in respects to this presentation, in respects to this feature. There are different degrees of disabilities. Sometimes there are invisible disabilities. Sometimes there are visible disabilities that are just varying forms of ability, right? Limited mobility, muscle slowness, tremors, low vision, color blindness, partial hearing loss, things of this nature. And this is just a few examples of the varying ways that you can have a varying degree of ability. That maybe something isn't completely inaccessible to you, but might be more difficult. That perhaps you would even just prefer to interact with a device in a different way. Many times I find myself preferring to interact with a device via the keyboard. Everybody has their own reasons, whether it be ability or otherwise. And I want to design for those kinds of things. Luckily, web assistive technologies can commonly help us with vision, hearing, and movement varying abilities. We can use these web technologies in order to piece together interactivity in a way that can allow more people equitable access to these kinds of features. At the end of the day, I build software for humans. I wouldn't be happy with myself if I shipped some software that was completely unusable to some users just because we lacked some foresight. And so, I did my research. I came across the W3C website. They have a list of patterns if you dig down deep enough. And I was looking at some of their approved web patterns. And for what it's worth, W3C stands for the World Wide Web Consortium. And so, they have a lot of really great, well researched, accessible UI patterns that you can borrow from. This one in particular caught my eye. It's called an example of list boxes with rearrangeable options. I'll scroll down here. Here's an example with a single select list box. So, this is using a select that has been kind of made larger and also some buttons beneath it. I can use my mouse to click on any of these, or I can click on these buttons down here at the bottom. But I want to use my keyboard to try to interact with this. I will hit Tab and I can focus into this element. The first thing it does is it automatically selects the first item in the list for me as a visual selection. I can see it very obviously become a bright blue and I see a dotted border around the outside of the entire list telling me that the entire list has been selected with a sub-selection inside of it. I can then use my arrow keys to move down my selection, but not the item itself. And then up in order to go back up with my selection. At the bottom of my list, I can see that there is an up button and a down button. There's also a not important button, which is not important for this demo, but the up and down actually allows me to deprioritize, for example, in this case, proximity of fast food can go down just by hitting the spacebar or enter key on the down button while I had a selected item. I can then shift tab back to my list and pick another item like neighborhood walkability and I can tab to the up button and activate it with enter or space. The first time I arrived on this page, I felt it was very intuitive. We were working with something that was using some raw HTML elements. I've already been trained to know how to use. I know that spacebar and enter key can activate them. I know that they are readily built to be accessible, that users will be told how to interact with them if they are semantically written correctly. So that already makes me feel a lot better about these items and I know how to interact with them. It's very discoverable, the user experience of if anybody came here and unintentionally hit tab and found themselves selecting the entire list, almost guaranteed that if they knew about how keyboard inputs worked, they would try to use similar key combos in order to interact with this list. And so you wouldn't even need necessarily a tutorial to tell them how this works, which is excellent. Down further on the list, we also have some great accessibility information around REI labels and how they can be dynamic, but that's going to be a little bit outside the scope of this presentation for now. By highly encourage you to read this kind of documentation, W3C is excellent at providing it. Next in my list of to-dos was to find a add-on that was sort of the basis instead of having to reinvent the wheel on drag and drop with an ember. We have a fantastic ecosystem of add-ons out there that do a great many things that people have built for us that we can then pull into our ember applications, often as simple as in this case, running ember install ember sortable. That is fantastic. Ember sortable I found on the ember observer website under the category of components drag and drop. It was very easy to come across. It's also very highly ranked by ember observable and highly scored. The rank on this plugin at the current moment is 26 out of the top 100 add-ons and it's in the top 10% of downloads. I can see how many open issues there are and when the latest commit is. So I felt very good about leveraging this add-on. Ember sortable provided mouse drag and drop, touch drag and drop, and it provided a really great ember observer ranking. So I felt like there was no reason not to try to use this for the project and that's what I did. The component structure as given to us by ember sortable is a component of sortable group and another another component of sortable item. These components are shipped to be composable by default. As in a sortable item can be placed inside of a yielded sortable group. And so I decided to follow that pattern. Instead of doing a reopen on these components or even forking the entire add-on to add an accessibility, I added my own custom wrappers. I generated these sortable group accessible and sortable item accessible custom wrappers. And so it looks a little bit like this where you can see the nesting of each of these items put together in a list. There's an each loop inside of there for each of our items and everything else is just kind of nested going down. And I was able to not even have to touch the original ember sortable code for this to work. So here's the final result. Here's a demo application that you can access at that little URL at the bottom right of gitlab.com slash gaity slash sortable dash recipes. I will put this I will place this URL in the discord the ember conf channel there in case anybody wants to access it where you can see the code and also all the slides for this presentation. So in this I have a demo application where I have sortable recipes. Right now we have peanut butter cookies on our list. I can add another meal like this blackberry fool which has hazelnuts and butter and other things in it. So now I have a list of several items and I can drag and drop these lists. Let's say I wanted blackberry fool to be higher on my list. I can just click and drag using ember sortable in order to reorder these items and some kind of a priority or however I wish to use this list. This is really great. This also works for touch right out of the box without me having to do any work on my part. With the accessibility components that I added in and wrapped around these I can also hit tab and I can tab to the point where I select the entire list and then the entire list gets a different colored outline around it and I see buttons appear for an up sort and a down sort. I can now use my arrow keys in order to move my selection down and my selection up much like the W3C pattern did and I can tab into these buttons and I can press space or enter in order to activate the reordering of these items. I can of course shift tab in order to move it back up and I can just activate these buttons as much as I wish and none of this blocks the interactivity of being able to for example tab to the links that are under here. So these are actual links so here's the link for peanut butter cookies and here's the link for blackberry fool. I can hit enter in order to activate one of these anchor links and it'll take me to that page. I can also click on any of these items in order to activate them as well. No functionality is lost while doing these kind of interactive things. In fact Ember, pardon me, Ember CLI template lint does not throw any kind of warnings for this kind of composability as long as you build it kind of carefully in regards to having nested interactivity because you can build these as separate elements very carefully with your interactability. And so this felt great and worked great and when I showed it off to some of the other co-workers they actually really liked how it was going. So let's dive into some implementation details. If you want the full details of this you're able to pull up the GitLab repository and dig in for yourself. All the tests are passing for this repository and you can see how all the tests are done and how the components are done for this demo code. One of the things I wanted to talk about for composable components are splatter boots. Splatter boots are relatively new to the Ember framework and with the introduction of glimmer components and template only Ember components we no longer have a wrapper div assumed on our component on the outside. And so if we want to pass in attributes like a tab index or a class we can now do so by passing a dot dot dot attributes within of our within our components template and it will automatically figure out all the things that you passed in and render out something like this at the bottom where you have a tab with a tab index of zero and a class that we defined of border and a focus border of teal. What's nice about this is that you're able to split out the levels of concerns. The attributes that are going to be assigned within for example in this case the index like application kind of route the index route template we're able to say we want this one to have these classes and we don't have to have sortable group accessible component either worry about the classes itself or have to expose a class api of some kind or have to have a wrapper div that would allow you to pass these things in instead we're allowed to use splatter boots to intelligently pass these things down wherever we wish within the component now on to events and modifiers within our sortable group accessible component I have many many even more than shown here event modifiers because we're listening for things like focus and blur key up key down into a spacebar things like that one line two you can see an example of a modifier this is a modifier that ships with ember it's called one and one is tied to the div itself and so it knows what the event is pardon it knows what the element is and it listens for in this case a focus event and when I this div gets a focus event it'll fire off the event to this handle focus action and in that action is where I handle all the focusing logic similarly a line down is blur and then on line four I could have done the same thing I could have done on key up and then assigned a key up handler in my component but instead I opted to write my own ember modifier I wanted to do that so that instead of having to have the component itself listen for every single possible key up event and then doing some kind of a switch case or a series of ifs about which event is being fired for which key like what key is being entered on the keyboard and then ignoring a lot of it I wanted to abstract that into its own modifier and so that's what I did here at the bottom of the screen you can see there is a modifiers key up file this is the entire modifier it's just eight lines of code the most important lines of code are on line six and seven line six adds an event listener on to our element that listens for a key up and then on seven we undo it we say remove that event listener when it's no longer needed for this modifier the rest of the logic is just listening for an event and firing off a function when it gets on listening for the event and also narrowing down to that desired key so okay let's with shift gears us a little bit we're going to talk about some testing details many of you have probably seen ember test mod ember test helpers up at the top of your testing file if you were to generate a new component right now you would likely get an import that will import from ember test helpers a line like render render is the most common one that you see and it's how you can render out your rendering tests your application tests things like that one of the first ones that people end up finding out about when they want to write more tests is click and so these are asynchronous and you can await a render and you can await a click event and then you can assert some kind of data has been changed or some kind of ui state has been changed within your tests something that people are not as aware of commonly is trigger event and trigger key event so what we're using those now if we go back to our key up example we're going to write a test for that we can write a test just like this it's asynchronous so work with me here we're going to be on line seven where we are going to render out a div and that div is going to have a modifier of key up and it'll pass up a function to this dot key up and we'll handle that in a moment so now we have a div with our modifier on it with key up and on line nine beneath it we have an await trigger key event and it will be first past an element that we're going to put the event onto and then a string of what type of event which is a key up event and then finally what key this could be a key code like number 13 or it could be a string that starts with an uppercase like enter we don't hit line 10 yet because this is asynchronous so after line nine gets hit it's going to trigger that key event which will trigger our modifier with the key up event listener and this case is going to go as line seven says up to this dot key up and you can see that on line two this that key up so this that key up receives an event which we are going to destructure we're going to take out of the event object just key now on line three we're going to make sure that key is an assert equal to enter now line four we will just go ahead and assert a step of key up now if you haven't seen step before it's one of my favorite bits of key unit uh on q unit you can assign steps which will then add automatically to an array anything you want typically strings now in line 10 we can then verify those steps for run and so we can verify an array of one string in this case of key up was fired if for some reason line nine did not trigger this key up function then this test would fail as it did not get all the steps that they expected to get and verify steps and so to cover this one more time we make a div we can put a modifier onto it in a test we can then fire something like a trigger key event and then we can listen for what that key is in this case and make a step and then verify those steps occurred similarly in application testing we could test the entire page logic for something at a higher level and so in the index test for example we could assert in the DOM this is using q unit DOM which is another add on we could use q unit DOM to say assert in the DOM the first element has text of item one so what this is really doing is we're going to find all the items like item as zero index and item at one index and we're going to assert that it has a certain text inside of it you can also do this with dot text content if you wish to but at any rate this is going to verify the beginning state is what we expected to be item one and then item two now we're going to test reordering we want to see if we can flip those and then test for that the next line down we await a trigger event which is a lot like what the user is going to do where they're going to focus by hitting tab onto the entire list itself so we're going to hit focus as an event onto the entire list and then that'll make the up arrow and the down arrow up here and we'll await a click emulating a click event on that down arrow so now that's asynchronous and we said await for that click to occur all the ember run loop runs through and now we can do another assertion afterward so we can now just take the same test that we did a second ago with the same assertions and we can just flip the items now we expect item two to be first and item one to be second accessibility just allowed us to test reordering when I first got to this I did not think that we would be able to promise that we could have automation testing for drag and drop and while technically we did not in this case automation test the drag and drop of the mouse or the touch but we were able to make sure that we can guarantee that the list can be restarted with keyboard inputs and that was a big win for us we had a lot of different team wins in fact throughout this project we had a very quick feedback loop with development because once we had tests written we were able to do test-driven development from then on and we were able to see when tests would go red if we broke something and stayed green well while it was still good we were able to work with design to continually improve on this functionality and all the different visuals passing in splatributes of more classes to adjust the visual style of things very quickly we also had a very quick feedback loop with project managers who were instantly able to see that we achieved the baseline functionality of mouse drag and drop and touch drag and drop and then gave us a little bit more time to work on the keyboard interactivity we got quick sign off for ux which was excellent we're able to see how it was working in every step in the process because we were doing composable components and we had less stress than qa because we were able to deliver an automation tested um page the entire feature was automation tested from beginning to end and so instead of them having to do manual testing for every release from here on end we were able to have that automation tested for them and then finally we had less scope creep because instead of having to come back to this either in the final days or months later down the road to have to force and accessibility for this feature it was just already built in there didn't have to worry about it now something I find very interesting ember sortable version two came out after most of my work was done for this feature and I've implemented this into the demo project where now we have version two of ember sortable and now I have a list here of peanut butter cookies and lasagna um and now you can I just love that combination you can click and drag just like we were able to before but also without any of my composable components ember sortable out of the box supports keyboard events I can tab to the list I can hit enter I can use my arrow keys to move them up and down and hit enter again to finalize my selection it's a bit of a different UI pattern but I actually really like the way that it feels and it's shipped by default and it's part of the main ember sortable library which is excellent you get these kind of things for free by leveraging open source community projects on top of that in order to do an upgrade from what I had shown previously to this version all I have to do is delete those two composable components and then rewire this back up very slightly and it just works I can move forward by just deleting code that's something you always want and so where do we go from there something I did not talk about but is very important it's accessible screen announcements screen announcements letting the user know that something has changed such as the order of items in a list another thing is ember sortable version 2.2 now has an alpha which has modifiers as the main way that you write ember sortable components so instead of having composable components you could actually write something like an ordered list that would have a modifier of a sortable group and li like a list item element that has a modifier of a sortable item I find it to be very exciting there's also ember accessibility testing and ember cli template lint that I feel go hand in hand to help you avoid some accessibility um plot holes plot holes uh pot holes that you could run into where you're like oh no I accidentally forgot to put a roll on my button for example what is the very real case that happened to us recently and so what did we discuss we were talking about adding functionality with composable components and all the different advantages that came with composable components such as being able to upgrade more easily over time having faster feedback loops and being able to not have to modify core functionality from another add-on for example we talked about equitable and discoverable user experience design while looking at some of the w3c patterns and also just the reasons why you would want to do these things and then the final result and how good it feels then we also talked about automation testing and automation testing accessibility but this is something that is not commonly done but I would love to see more of it once again I work at all of you as a software engineer we are hiring and we are working right now with k through 12 school districts to not only help them through the coronavirus epidemic that is happening right now but also throughout the year as they are budgeting in order to make a more equitable education system for everybody um we build ember software so we are ember through and through and we develop software with shape up by base camp so if you're looking for something that's an alternative to agile take a look at all of you lastly I have a challenge for you hire somebody different than you that might sound completely off topic but it's really not if you hire somebody that's different than you in regards to I don't care if it's race religion orientation gender maybe they like legos and you like mega blocks it doesn't matter the more different people you have on your team the more likely you're going to have people asking important questions such as is this accessible and that's when it's fired us to do this on our team so I encourage you try to hire somebody that's different than you if you have the opportunity you won't regret it and lastly I ask you to make accessibility a priority at your next design meeting