Good morning. My name is Wim Leers. I'm a senior software engineer in the office of the CTO of AQUIA and working on Spark. And I'm Jesse Beach. I'm a front-end developer on the Spark team also at AQUIA. And we're here to talk to you today about how we're trying to make data and interactions accessible to everybody. So is that better? Awesome. Right. So the first thing I have to admit is that I am not a usability expert. And really neither am I. What we are are two developers who are extremely passionate about building usable, accessible, beautiful, delightful interfaces in Drupal. And I'm sure that everyone out there in this room, front-end developers, UX developers, community management people, docs writers, you're also interested in making accessible interfaces as well. But what we're really talking about is building what we like to call rich experiences. So this means an experience that is satisfying to someone regardless of their range of abilities. Sorry. Sorry. I'm just going to scroll down. So let's talk a bit about whether or not Drupal is accessible already. And the answer to this is yes in a way. As a community, we have lots of processes and guidelines in place that help us to produce an accessible product. One of these is a pledge that exists and it reads, an inclusive community. As an inclusive community, we are committed to making sure that Drupal is an accessible tool for building websites that can also be accessed by people with disabilities. We also have an accessibility checklist within Drupal. There are 11 items on this checklist. Some of them include that all non-text content has alternative text, that all data tables have headings, that users can complete and submit forms, and so on. These guidelines are here in order to provide us with a quick means of assessing the UIs and the tools that we're building. We also have tags for issues that relate them to accessibility. For instance, the Needs Accessibility Review Tag, the Needs Color Accessibility Review Tag, the A11Y tag or the ALI tag, and we also have a tag that's just the word accessibility. Using these tags identifies them as needing further input from people who can test or that they pertain to usability within Drupal. We also have an accessibility pledge that module developers can assign to their modules to call them out as supporting or in the future, perhaps, supporting usability. For D7, we had the D7AX tag, and in D8, we'll have the D8AX tag. We also have a pledge for module developers. This reads, I pledge to make this modular theme as accessible as it can be. If you find any flaws, please submit an issue, link to the issue queue, and help me fix them if you can. There are a lot of tools and a lot of means of indicating that something pertains to accessibility of calling to action folks that can help in this process, and it kind of reminds me of a pillow fight in a sense, because everyone means well. We're all trying to make accessible, usable interfaces, but when you get down into the nitty gritty of the details of doing this, it gets messy really quickly. We're trying not to hurt each other, we're trying to be gentle, but that still doesn't mean that it's easy to do. So this is where we transition into talking about oral user interfaces. Oral is a word that means to hear or it pertains to sound, and we contrast this with a visual user interface, which begs the question, does Drupal speak? And the answer is you betcha. So I really quickly want to let everyone have a listen to what Drupal sounds like when it's speaking. Hello. This is Drupal. Welcome to Portland. And thank you for attending this session. Wim and Jesse are very excited to talk about oral user interfaces, and remember, put the bird on it. Awesome. Just a little string that a screen reader was reading to us from Drupal. We have to question why we should consider speech as an output method for consent in Drupal. Because semantic HTML, you know, might be enough to express the meaning of the page or the consent in the page. But I'd like to give you two examples that illustrate why semantic information is not enough in terms of creating a rich experience. So we have here a screenshot of the admin interface. This is the config admin interface in Drupal 8. And we see that it's fairly simple. We have links that go to different forms within the config interface, account settings, site information, cron, text formats, and editors, the fairly standard configuration main screen. Now let's take away all the visual styling. And we see here a page that is the stripped-down, non-visual, semantic HTML for this configuration page. And I wonder if anyone would find this acceptable, any visual people out there would find this acceptable as an end user experience to sell to a client or to use on a daily basis. And I think most of us would say the answer is no. We expect to have our information chunked, presented to us well within the confines or the capabilities of the user agent that we're using, and in fact, optimized to the user agent that we're using. So let's have a listen to an example of Drupal speaking to us in interface, and we're going to take away the visuals. We'll start with the visuals, and then as we go in, we'll take them away. And I should just note here that this is a Drupal 8 interface. We're looking at the Tor module. I don't want to pick on the Tor module in particular. This is just the example that I pulled out. There are plenty of aspects of Drupal 8 that have really great support for spoken and semantic interfaces, and some that don't. And this just happens to be one that doesn't. And if it doesn't play within a moment, we're going to go to iMovie. Let's get out the full screen here. I don't know if you just want to pop up the open project. Sorry, I'm just going to reopen it. There we go. Okay. This one. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. You know, to talk about usability and accessibility, even iMovie is fighting me the entire way. All right. Great. I was watching everyone's faces as they were listening to that. I saw people sort of skeptically. And then as we got to the fifth or sixth dialogue, people started to wonder where in the world we were in that interaction. And that was exactly the reaction we were going for. It's very easy to get lost in an interface when you don't have the visual input, and then to not even know why you're there after a while and to know when you've finished. If we look at the markup for the tool tip that was part of the tour module, we see that we have taken steps to make this accessible. It's not just dibs on a page. We have a div with a role of dialogue. We have aria, semantic attributes. We see p tags and ht tags. There's an attempt to make this cementically accessible. But when we take that semantic underlying element and put it into an interaction, suddenly moving between those elements doesn't have any meaning. So as we've been thinking about this problem, women and I have attempted to visualize what or how Drupal does in terms of its visual versus oral interfaces and to plot them on a scale. So we've plotted them on a scale from inaccessible to delightful interaction. And if we imagine that inaccessible gets a value of zero and delightful interaction gets a value of, let's see, four because we're engineers and we count from zero, we can plot the visual content consumption experience, the visual administration experience, the oral content consumption experience, and the oral administration experience. And we see that in our opinion, both of the visual experiences, content and administration, both fall within barely usable to almost delightful, with the content consumption being the one that has the higher upper bound. If we compare that to the existing oral experience, we see that the upper bounds make it just too acceptable interaction. And the lower bounds range from barely accessible in terms of the content consumption to inaccessible in terms of the oral administration. And what we're trying to do in our work in Drupal 8 is to raise the lower bounds of these experiences to at least barely accessible as a minimum. And we would like to get all of these to barely usable because when we get to barely usable, that's when we can start talking about usability and improving these interactions towards that level of delightful, not just making them accessible. We really wanna hammer home this idea, this is something we've internalized, that accessibility is not just a word that means non-visual. What we're talking about is making interactions and data accessible to everybody. And what complicates this is that the dynamic applications that we're building into Drupal 8 undergo state and property changes. So it's not enough just to mark up information semantically. We also have to describe the transitions from the states that they begin in to the states that they end up in as we move through a dynamic application. And an example of this, and if it doesn't play, I'm not gonna bother with it. There's a video on the screen that's meant to show infinite scrolling. This is something that's very common in modern user interfaces. You can imagine something like Facebook where you scroll to the bottom of the page, or Twitter, and new items automatically get added to the bottom of the list. And as a visual person, you know this because you see them fade in, you see the list expand. It's obvious to us because we've been given cues to understand that the state of the page has changed. For a non-sided person, those cues also have to be provided by different means. And the best way to do that is to tell them through their user agent that things have been added to the page. So what it comes down to is that changes in state have to be expressed. Because what we're doing is we're building interfaces to data regardless of the means of expression for everybody. We wanna talk specifically about how we do this, how we show and announce the changes that are happening to the data and the interactions.  We're just gonna pop into iMovie really quickly. All right, so what we're about to see here is a video of new interfaces in Drupal 8. We're gonna start on a basic page. In the video, we'll tab around a bit to some of the items to show you that we're tabbing to the home link and to perhaps an edit link or an article link. We're then going to constrain the tabbing to just the contextual links by entering what we're calling edit mode. And at that point, the user interaction is constrained just to those pieces of the interface that are required to complete the interaction. The contextual links for the individual articles that contain things like edit, quick edit, configure. We're gonna edit one of those articles and go into the overlay. Inside the overlay, our choices and flow of interaction are again constrained, just those elements in the overlay. We're gonna exit the overlay back to the contextual links so we won't be able to tab through the entire page. We're still in the flow of editing. And then we're going to edit exit mode back to all of the links in the page if it wants to do that. Oh, this is so frustrating. Doesn't even wanna do that. I don't know what I'm gonna do. Let's see if we can exit. The definition of crazy is when you continue to do the same thing over and over again, expecting a different result. Let's see if we can somehow increase the size of this. So we're thinking that this selection is the thing that was preventing us from doing that. I don't have anything in full screen. Awesome, thanks. I don't know why the quick link would work and the menu item wouldn't, crazy. But we're gonna make this do this, I promise. We're gonna turn the unusable into usable. Log out, make, navigate, edit, button, not pressed. Pressed, tabbing is constrained to a set of 15 contextual links and the edit mode toggle. Press the escape key to exit. Main form, article form, article form, article form, article form, open five best cauliflower recipes, configuration options, button, not pressed. Open, quick edit. The overlay has been open to edit article five best cauliflower recipes. Tabbing is constrained to items in the administrative toolbar and the overlay. Skip to main content. If you have dismissed this message, close overlay, button, view, edit, open, devil. Navigation, five best cauliflower recipes. Main, title, this field is required. Five best cauliflower recipes, edit text required. Application, tags with hint, edit text auto completion list. Exited application, navigation, home, exit navigation, edit, view, close overlay, button, navigation, edit, button pressed. Tabbing is no longer constrained by the overlay module. Main form, article, article, article form, navigation, edit, button pressed. Not pressed, tabbing is no longer constrained by the contextual module. Mic, exit, log at home, hop home. So, I hope that was inspiring, interesting. We've been working on making these sorts of interfaces accessible now for probably three months and we're not sure if what we're doing is correct but we're hopefully moving the conversation in direction where we can start to talk about interfaces like the one you just saw. So, let's move on to talking about how we did that because that's the stuff that really gets us excited. If you don't know, ARIA stands, or ARIA is a set of technologies that enables us to create accessible, rich internet applications hence the acronym. And what ARIA does is it represents states. States like being active, being disabled, being pressed. It also allows us to represent through markup properties. Properties like a label or a form or a dialogue. ARIA attributes take non-semantic or vaguely semantic HTML and turn them into semantic, meaningful markup elements. We'll see if this wants to play. All right, so this video doesn't wanna play and I don't wanna go through the pain of trying to get iMovie to run. So what we were going to show here was the new toolbar element. We have in the toolbar element tabs across the top of the page if you've seen Triple-8. And we're using the ARIA pressed attribute to describe whether or not an A tag is pressed at the moment. In the JavaScript, we determine if the ARIA pressed value should be true or false. And when it is true, it expresses that that A tag element is an oppressed state as if it were a button. One of the most useful and I think underused ARIA elements is the ARIA live attribute. So ARIA live describes an HTML element that should be announced to the end user, the content of which should be announced to the end user when it changes. And it's very simply ARIA dash live as an attribute with one of two politeness settings, either polite or, and I always forget this, assertive, right? Yeah, assertive. I don't like to be assertive so I never remember that that's one of the values. So we use the ARIA live attribute to enable Drupal to speak to the end user. And we do this through a method on the Drupal object called Drupal announce. This is a method that's been built right into Drupal 8. I think we got this committed a month and a half to two months ago. So let's have a quick look at it. It's very simply a method on the Drupal object and we pass that method as string. And that string will be read to the end user as soon as the announce method is invoked. And because we want to be cognizant of translation, the string should be passed through the Drupal t function before it's passed the Drupal announce so that if it is translated, we get the translation read to us instead of the English string. The Drupal live announce elements where these strings are getting written to are just, is just located inside the body. So when Drupal announce is used for the first time, this div gets created and appended to the body element inside the page. So the idea for this first came up when we were developing the toolbar for Drupal 8 back in the late fall to early winter of 2012. I traveled up to Toronto to attend the Toronto camp and the accessibility sprints up there. There were a bunch of folks, Mike Gifford is in the office right now, Everett Zufelt's, I'm forgetting some people and I apologize, but there were a bunch of us there who were looking at the accessibility of the toolbar and this was one of the first times that I as a developer had to address issues of accessibility in a very real and concrete way because anything we built for Drupal 8 has to pass the gates, the accessibility gates in order to get committed. So we discussed this Drupal announce idea and built it right into the toolbar. In the late winter of 2013, we had the time to pull that out of the toolbar, make it into a general function and get it committed. And the first thing we learned upon getting that committed was that it didn't work. And it didn't work because if you call, if you replace text in a Drupal live elements or an ARIA live element quickly, all of the strings that got placed there before the last string in the series don't get read. So if you have four modules that call announce all one after the other, three of them are going to be silent. So we had to step back and figure out how to solve this problem for all of the modules in Drupal. And the way that we did that, I'm not exposing any of the details down here, but we essentially queue up all of the announcements within a 450 millisecond period and then all of those get appended to the ARIA live element and read in succession. And it works pretty nicely. And it highlighted for me the fact that we need to solve these problems in Drupal core because if we leave, contribute to solve these problems, we don't get the benefits of a common solution. We get competing solutions and loggerheaded solutions that are going to step in each other's toes. Now I want to just mention this and I know that probably most people in the room don't have the false assumption that accessibility that requires JavaScript is not really accessibility. If we look at surveys that have been done recently, asking people who use assistive technologies whether or not they use JavaScript, we see that 98.6% of people that use a screen reader also have JavaScript enabled. And I think the number that have JavaScript enabled who don't use a screen reader is something like 98.4%. So folks using screen readers actually have a higher percentage of JavaScript usage than people who don't. So you can kind of take the idea out of your head and not worry about it. So Drupal announces one of the tools that we built into Drupal 8. The other is the tabbing manager and I'm gonna let Wim speak to that. Thanks, Jesse. Quick swap of seats. So Jesse explained to Drupal that announced a component which is really important for accessibility in Drupal 8 for dynamic pages. And that was really about oral updates, about communicating change. But what is also really important is to guide the user to assist the user in navigating around the page. So guiding the flow, helping him or her navigate around the page via the keyboard. Because both screen reader users really need the keyboard, but power users might also want to use the keyboard. So I might prefer that. And that really brings us to the other big accessibility components, Drupal.stabbing manager. So why is it necessary? Well really because the specification is, it looks like this essentially. Depending upon the action to be performed by the dialogue, the object with focus before the dialogue box is open should be saved. This will allow restoring focus to this element when the dialogue box is closed. And if your eyes glaze over after hearing and reading this, that's perfectly normal. The spec is very vague. It says what should happen, as in X and Y should happen, but it doesn't specify how this should happen. Browsers don't implement this. It's really up to you, the developer, to implement this in JavaScript and make it happen. So that's why it needs to exist because managing tabbing is really difficult. If you have a contract module, we don't want to have every contract module developer solve the problem in their own way because then that will lead to conflicts and it would lead to reinvention and it would just cause problems. So what we did was take a tabbing manager. We wanted to build something like a tabbing manager. What we did was take what already existed in the overlay module in Drupal 7, which already had tabbing constraints, pull that out of there, put it into an API that is easy to use and then make sure that module developers, when there are multiple modules using tabbing constraints simultaneously, do not run into problems so that it always will work well. So what the tabbing manager really tries to do, it's really simple, this is the essence of it. It helps you with constraining tabable elements to just those that are necessary to complete a task. So it helps restricting keyboard navigation to aid with a specific task that you're currently working on. And if we would look at an example, then this would be the one for the overlay module and this is a visualization that shows which elements are tabable. So we're looking at the overlay module, the overlay is open, and what is tabable are the elements, the buttons in the toolbar and the elements that are tabable within the overlay, but the elements on the underlying page which were tabable just before opening the overlay, meaning tabbing around the entire page, those elements are no longer tabable right now. The tabbing manager has constrained it to just those elements within the overlay. So that's a high level overview of what the tabbing manager tries to do and what it tries to help you with, but let's dive into a quick how-to that shows you how you can use triple dot tabbing manager. So a tabbing manager, as you would guess, is about applying tabbing constraints and we'll be looking at an example here. The examples before have already used the contextual links module and we'll do the same here. This is a piece of code that helps with the edit mode toggle, the pencil icon, the top right of the toolbar, and let's quickly analyze this function. At the bottom of this function, you have an if test and within a if test, we're calling triple dot tabbing manager. That's the interesting part. So triple dot tabbing manager dot constrain is what you want to call when you want to constrain tabbing to a specific set of elements and we pass in a selector that specifies these elements are the ones we want tabbing to be constrained to. And what it returns is what we call a tabbing context and the tabbing context is a basic building block that the tabbing manager uses to keep track of things and to make sense of things. So we get back the tabbing context and we store it and that's all that happens. Now, if we look at the whole, what happens is at first we retrieve the tabbing context if any, if that exists and if it indeed is a tabbing context, we release it. So we always release the tabbing context and then if we have just entered edit mode, if you have clicked the edit mode toggle, meaning that you want to constrain tabbing, then we will apply a tabbing constraint. So there's two things to do. One, constrain and two, when you no longer need it, release the tabbing constraint. Constraining tabbing is one part of the equation but as Jesse already explained, when dynamic changes happen on the page such as infinite scrolling and so on, a screen reader user is not necessarily notified of this change. So how do we communicate this? Well, with the Drupal.announce component that Jesse just explained. You could do it something like this. Calling Drupal.announce and always passing it through Drupal.t to translate it of course. And we just inform the user that tabbing is a constraint, B to which elements it is constrained and C in this case what we do is we provide or we inform the user of a handy keyboard shortcut to exit the current tabbing constraint. So keeping the user informed is very, very important. So we just saw the basic usage of the tabbing manager essentially and I think everybody sees that it's pretty simple to use and that's very nice but in the case of multiple modules using it simultaneously, how can it possibly go wrong? Well, it could go wrong in many ways if each module was implementing it separately but thanks to the tabbing manager and everything being centralized. What we do is we keep a stack of tabbing context and that's where the tabbing context object of before comes in. So initially when you access a page, tabbing is not constrained of course and you're able to tab across the entire page. However, once you for example enable the edit mode toggle, tabbing is constrained to just a contextual link. So at first you have no constraint on top of that, you now have the contextual links constraint and then when you're tabbing through the different contextual links, what might happen is you enable for example, in place editing and then the contextual links tabbing constraint doesn't make sense anymore. So we apply a new one on top of the previous one that allows you to tab to the relevant elements to do in place editing and once you stop in place editing, once you've finished doing that, we release that tabbing context, that tabbing constraints and the previous one gets applied automatically again. So once you've done your in place editing thing, what happens is you're back to navigating the contextual links. So I hope the video will work, but we have a quick video showing precisely that. Maybe I should switch to iMovie as well. Yeah, let's just do it really quickly. All right, so this is the same video we saw before but now we understand a little bit better what's going underneath. So let's watch this interaction and think about the code home, home, log out, like, navigate, edit, button not pressed, pressed. Tabbing is constrained to a set of 15 contextual links and the edit mode toggle. Press the escape key to exit. Main form, article form, article form, article form, article form. Open five best cauliflower recipes, configuration options, button not pressed. Open, quick edit, edit. The overlay has been open to edit article five best cauliflower recipes. Tabbing is constrained to items in the administrative toolbar and the overlay. Skip to main content. If you have dismissed this message, close overlay, button, view, edit open, dibble, navigation, five best cauliflower recipes. Main title, this field is required. Five best cauliflower recipes, edit text required. Application, tags with hint, edit text auto completion list. Exited application, navigation, home, exit navigation, edit view, close overlay, button, navigation. So as you can see, we were just in the overlay and now we've closed the overlay and if what I just explained is correct, then we should now be tabbing between the different contextual links again because that was a previous tabbing context. Edit, button pressed. Tabbing is no longer constrained by the overlay module. Main form, article, article, article form, navigation, edit, button pressed. Not pressed, tabbing is no longer constrained by the contextual module. Mic, exit, log at home, home, home. And just now we disabled the edit mode toggle again. We toggle it off and because of that, the first tabbing constraint was removed so we're back to page level tabbing. So really what we wanted, the message we wanted to convey is to embrace modalities, to embrace different ways of interacting with contents. There's different ways of output, visual and aural, but there's also different ways of input, meaning mouse and touch that are the most common ones, but it's also possible to have different ones, like for example, keyboard navigation, but maybe some day voice input, maybe. And the way we want to, the way we are currently proposing what we think should become a best practice is by using Macbook.js we make it much easier to actually support different modalities and to add support for new ones. So we're using Backbone.js for that and this is a brief quote from the lead developer of Backbone.js, I'll read it aloud. The essential premise at the heart of Backbone has always been to try and discover the minimal set of data structuring and user interface primitives that are useful when building web applications with JavaScript. So what really is important to us is the part where it says the minimal set of data structuring, which are in the case of Backbone models and collections, as well as views. So what Backbone does is it doesn't try to impose a highly restrictive structure on your JavaScript, it doesn't define your architecture, it doesn't confine you within a certain architecture. It's really up to you, we just use it to have basic building blocks because it makes it a lot easier for other developers to jump in and use it. It also invites better documentation because the separation of concerns is what is really important. The framework isn't really important, what matters is the separation of concerns and that's what Backbone really helps achieving. Before Drupal 8, what the typical piece of JavaScript code would look like was something like this, you would have DOM event handlers and they would directly be modifying the DOM again to do rendering and this is really something that is not very nice for developer experience, it's pretty painful. But now in Drupal 8, if you're using Backbone.js, what happens is DOM event handlers do not really do anything magical anymore, they don't go deep into the system and make changes. What they do or hopefully will do is change the state of a Backbone model because the Backbone model contains a state and what we can then do is to have Backbone views linked to those Backbone models, react to those state changes and do the rendering. So there is a clear separation of concerns and this really helps to make the developer happy. It's a much better developer experience. So if we look at a very high level of what Backbone would look like, it would look something like this schema. So what we're seeing here is at the top, talking to the server, that's what Backbone.sync is for, we don't use that, that's not relevant to what we're talking about. What's relevant to us is modeling states, modeling data and we use Backbone models for that. So a Backbone model reflects the current state of whatever dynamic application that you have. If relevant to your application, it might make sense to have many models of the same type grouped in what is called a Backbone collection. What is really important though is the connection between a Backbone model that is linked to a Backbone view. So whenever the model changes or a specific thing in the model changes, we can react to that in the view and that's really the essence of what we are using. The view can then in turn render changes and that's what's presented to the end user. So if we would look at an example of before Backbone and after Backbone, this is a piece of JavaScript code in triple eight. The top one is before, the bottom one is after and both are the same code essentially, both are a DOM event handler and they are what it looked like to react to the edit mode toggle. The one at the top though, what it does is it iterates over an array containing all contextual links on the page and what it does is it directly modifies a DOM, it toggles a class. Whereas the second example, what it's doing is just iterating over a Backbone collection looking at every model and setting a specific attribute. So we're not directly modifying the DOM anymore. What we're doing is we're setting states and there is then a Backbone view that can react to this. So we've seen a basic introduction and a lot of claims about what Backbone can do to help make you, how it can help you make interfaces that serve multiple modalities. So let's dive into a quick how-to on how we can use Backbone for better accessibility. The core premise is have one model that contains a state and many views, one per modality and maybe in some cases it makes sense to merge the support for multiple modalities in a single view. So what this looks like is a model for states, a view for supporting touch inputs, a view for supporting visual outputs, a view for supporting oral outputs and so on. It really depends on you, which modalities you want to support and it's easy to support for more modalities later on. So step one, create a model.  It doesn't contain business logic.  And it's really up to the views to update it because views handle input and outputs. So whenever input happens, we can update the model to update the state. Again, we look at the contextual links module and the edit mode toggle in particular. And as you can see, there are three different attributes, three different states that it contains. The first one is viewing. It's a Boolean that indicates whether edit mode is enabled yes or no. The second one is visible is again a Boolean indicating whether the edit mode toggle should be visible at all. And this is actually something that would seem bizarre at first sight probably. But the reason is when the overlay is active, you cannot have contextual links within the overlay. So it doesn't make sense to have the edit mode toggle be visible, be usable when the overlay is open. And this is the sort of edge case that is kind of tricky to support when you're not using something like Backbone. And then you have subtle edge cases that you need to deal with. But if you build it this way, it's very easy to reason about. So we have a Boolean for that in our state. Finally, the tabbing context. This is to track the tabbing managers, tabbing context if any right now. So three states, that's all we need. Step two, we create what we call a visual view. And this particular view deals with three modalities, visual output, mouse input, and touch input. And it looks something like this. The Backbone view receives a DOM element, the edit mode toggle itself. And the first thing we do is bind a click event handler. And this handles both the mouse of course, a mouse can click, but a touch device also emulates the click event. So this covers both mouse and touch inputs. And it does a very simple thing. It toggles the is viewing Boolean in the state in the model. So this is what enables edit mode or disables it. Next, we have the initialize method. This is what Backbone uses as kind of a constructor. So you can view it as a constructor. And what it does is it listens to the model to where the state is stored. It listens to any change within the model. And whenever anything changes, it will call the render method of the Backbone view. And the render method in our case does just two things. It's the bottom two lines. It toggles a class, which one, the element hidden class, to hide the edit mode toggle whenever relevant, whenever the overlay is open. And it finds the button within the edit mode toggle and toggles a class again. That indicates whether it's toggled or not. So nothing complex. Next, we create a keyboard view because we also want screen reader users to be able to use keyboard navigation. But in this case, it's not really necessary because the click event already handles keyboard presses. So if you press the enter key, that will actually also toggle the click event. So in our case, we're lucky we don't need that. And we also don't need to focus our blur support. We just need to know if the button was toggled. Yes or no. So nothing special needs to happen. Finally, we create an oral view for screen reader users so that we can provide oral outputs. And in this case, since we only have output, we don't have any event handlers. So we have still a initialized method and we listen to model changes again. But we listen to model changes in two different ways. The first way is we listen to any change in a model. And whenever that happens, we call the render method. The render method in this case toggles the aria pressed attribute. And as you can see previously, we were looking for the button element and setting the active class if relevant. And here we're again looking for the button element but setting the aria dash pressed attribute if relevant. And as you can see, there's a clear separation of concerns here. The previous thing only was relevant for visual output and this one is only relevant for oral outputs. So if someday the aria spec is updated to have all their magical properties, it's easy to come in here in this view and add support for those as well because each modality has its own view and things are not tightly intertwined anymore. So that was the first model listener, the first change handler. The second one listened specifically to the is viewing attribute and that one was the Boolean that conveys the edit mode whether it's enabled, yes or no. Whenever that changes, meaning we enter edit mode from previously just viewing or we exit edit mode from previously being editing, we call the manage tabbing method and that's the exact same method that we saw before in the tabbing manager example. So what it does is it always releases the tabbing context if any and if and only if we're entering edit mode then we apply a new tabbing constraint to those elements relevant. So now we're already doing the tabbing constraint but we also want to make sure that whenever a tabbing constraint is applied, we again use Drupal to denounce to explain this to the user because it's a dynamic change. So that's really all there is to it. Everything will remain in sync automatically because the model contains a state, it's easy to hook up new views to support more modalities, to extend views, to make them better because everything is in a central place and everything else just listens to that and updates that. So that's really all there is to it. And we wanna, Jesse and I really wanna make clear that this is a best practice that we're currently proposing but this is not a final thing. It really depends on you guys, the developers to help us improve this and make sure that this is superseded by even better ways to deal with this. So we really need your input as well. Finally, if for me at least, Jesse will continue afterwards. If this sounds relatively scary to be working with if you're not familiar with using screen readers yet you still would like your applications, your dynamic things, your dynamic modules to become accessible, as accessible as they can be, then we have a good thing for you. We have a module that will do console.log. We'll use console.log meaning logging into your web browser's console whenever a triple of the nines call is made. It will also visualize any tabbing constraints. Whenever the tabbing constraints change, the CSS animation will occur. So you get actually visual feedback for something that isn't visual. It will highlight the things that are tabable in a red box shadow. And the one that is currently focused will get a different color back box shadow. So whatever you're doing, it makes this makes it really easy to use these new accessibility components. The URL fell accessibility with that back to Jesse. So I hope we've expressed here that a UI is a site and it's sound and it's touch. And then Drupal 8 is going to communicate through all of these modalities, using these shared tools that we're developing and the structured framework underneath. And the question is, is your module going to use these as well? So my preferences and let's move on to questions. If you do have questions, come up to the mic in the middle of the room. And if not, this presentation is available on GitHub. The whole thing, we have a link to it on the session page. Hi, this stuff looks amazing. Thanks. One thing, last time I looked into it, it seemed like, I don't know if it was half and half, but some screen reader users use the arrow keys to move up and down the screen. Is there anything we can do about that as far as constraining it? Or would you have to tell them to tab more often if they want to take advantage of features like this? You know, the answer to that is I don't know. As I've been interacting with people that use these screen readers more and more, I've realized that tabs are not necessarily the primary modes of navigating a page. And I'm really not sure how we could capture those key movements as well, but I have to assume it's within our grasp to do that. And we could, but I think we need further research. Yeah, maybe they'll just start using them more since the arrow keys just kind of go through the source, so it's hard to direct them. It's true, I don't believe that they use the tab index the way that the tab key does. And the way that we're able to constrain tabbing is to manipulate the tab index on the page, essentially setting the tab index to negative one for the things that we don't want to have tabbable and not setting a tab index on the things that should be tabbable so that we maintain the DOM order of the tabbing. But I think fundamentally we want to support how people work, and if the arrow keys are the way that they work, then we need to figure out a way to do that as well. Cool. Can I ask one more, since? Yeah, definitely. Is Backbone, is Backbone going to live with jQuery in Drupal Core, or is that something just with the accessibility module or? Actually, Backbone.js got committed to Drupal Core several months ago, so in that sense, yes, it's definitely possible to use it, and yes, Backbone and jQuery both exist in Drupal Core right now, so we're actively using it. Great, thanks. Just a quick question. Would this accessibility, would it play well with internationalization? I mean, will they work together so that you can have all of your text in a place where it can be easily translated? Yes, if it doesn't, it should, and we believe it does. So everything we're passing to the oral interfaces is going through the drupal.t function, and that is the standard means of translating strings to different language. It doesn't translate your strings for you, they have to be translated, but if they are translated, you'll get that. Just wanted to ask me, the drupal announce is being really quite useful, and the tab infrastructure, I think, is also a great addition to where we're going in. I'm glad to hear the explanation about the use of Backbone.js for this, but in drupal.t, there's still quite a lot of interfaces that are gonna need to be updated to add this in, and I don't know as the Drupal accessibility maintainer how many interfaces there are within drupal.t that would need to be changed to add this interactive element in there. Is there any way to go off it, or has anyone cataloged the number of interfaces or the number of dialogues, the number of types of interfaces that we should be potentially looking at applying this to? I mean, is it an order of, is it 10? Is it 100? Is it a thousand? And then just, on that level, would be useful to know how much work there is to go off into, I mean, now that we have the centralized tool, how do we have it consistently applied so that module maintainers stumble across it and know about it so that they then go off and are asked to go off and apply it in their own interfaces? So to, I have to admit, I don't have the answer to that question. We don't know how many interfaces there are that we would need to design. What we do have is a buff coming up on Thursday at one o'clock, check the board out front. We need everyone interested in this topic to come and help us solve these problems to measure the extent of design that's necessary to figure out the priorities for addressing them to code, to test. If you were to present Drupal Core to someone without any CSS and say, all right, go, go create the CSS, style it, do that. Your draw would hit the ground because you would think, oh, we need designers, we need developers, we need testing on every possible device. I think that's the kind of challenge that faces us right now. We're essentially presented with raw markup and we're trying to create something useful out of it or something dense and rich. You know, it's not a small feat. Well, any of this get ported back to Drupal 7 and for those of us developing in Drupal 7, what can we be doing now to push this forward? So when Drupal 8 comes, it's not gonna be this huge cliff. I don't think any of the functions we've got so far depend on anything in Drupal 8. No, it's easy to backport them, yeah. It should be easy to backport them. But the question is then, of course, we specifically built it, for example, the tabbing manager. Drupal 9 is something that is pretty standalone so anything can start using it. But the tabbing manager specifically has a mechanism to deal with multiple modules, having tabbing constraints at the same time. So in the case of, for example, the overlay module and the overlay having its own tabbing constraints right now, which is where we learned from, essentially, that might cause you to run into problems when using something as well as something else, something new custom, as well as the overlay because that already has its own tabbing management. So Drupal 9 shouldn't be a problem. Drupal tabbing manager could be a problem, depending on what you need to do. I want to thank everybody for coming. Do attend the buff on Thursday if you're interested in these topics. We're going to be talking about prioritizing testing, getting tests set up and written, and essentially creating the plan to bring a Drupal 8 to a level of accessibility support that we profess to have. It's not going to be a small effort, but I think it's a manageable effort. It's something we can accomplish before the release of Drupal 8. And just briefly, as Jesse mentioned at the core conversations thread yesterday, there's over 100 accessibility issues in the Drupal 7.8 issue queue. And so in terms of things that can be done and how people can be involved now, Drupal 8 is a great place, but there's also a lot that needs to be done in Drupal 7, and there's also modules like the accessible helper module that need help and need sort of work on adoption, but there's quite a lot of room that can be done right now to go out and to get involved. And it would be great to have somebody step forward and look at backporting the work that you guys have done in Drupal 8 to Drupal 7 and to maintain that moving forward for the existing users. Yeah, and in case you don't know how to find those issues, I just showed it on the screen. You go to Drupal.org, the Drupal project on Drupal.org, so that looks like this. Drupal.org slash project slash Drupal. You go to the issues, you click on the advanced search tab, and as the issue tag, you enter A11y, accessibility. Accessibility is better. Yeah, as I found out yesterday. Okay, both of us apparently didn't know that until yesterday. So accessibility, you search, and then you find all the issues. Great, thanks everybody. Thanks.


Hello everybody Remember I promise to come back Nice to see you all again Thank you. Oh You're all too nice. I wanted to remind you one more time that we've had some absolutely fantastic sponsors and so For all those sponsors we could not have this meeting without you and know our heartfelt gratitude I know some of the sponsors have already left but for those of you who are still here Thank you so much and let's have a round of applause for the sponsors Now I know how hard graduate students work because once I was a graduate student It happened and I know you've been sitting on pins and needles getting indigestion the whole dinner Wondering did I win? Well, I'm going to invite Kathy and Fritz up here to tell you Whether you what? Okay, thanks everybody for coming. I think this is my favorite part of the buff the banquet and Kathy's gonna say a few words and then we'll get to announcing the winners All right So the young investigator awards from the Linus Pauling Institute are rewarded to the most outstanding poster presentations By a graduate student or a postdoctoral fellow Many of the previous recipients of this war award are currently in this room And many of them have gone on to become PIs in their own laboratory. No pressure The young investigators are judged on their ability to effectively and succinctly present their research the quality of the work that they are presenting and a Personal statement outlining their research goals for the near future each of the awards will be accompanied by a certificate and a $500 gift card that can be used as cash Please see Dustin Helvey to get your gift card There that's the important hand over there That's right and and Lastly, we want to thank our sponsors for their contributions to this research award in order to encourage our graduate students and postdocs in their future work So fritz Okay, I'm gonna announce each winner and then read the title of their work And then they'll come up and accept their award. We'll get a photo and then we'll go through each of those There's there's four It was a tough job in selecting the top four And I just want to thank John McGuire who couldn't be here tonight from the OCC the oxygen oxygen Club of California He was also one of the judges Okay, so the first one goes to Martin Pierce of Oregon State University The title of his Poster was targeting therapy resistant cancer through VCL to functional conversion You want to come up? Okay I guess Siva is gonna come up and see those Calorie is his mentor Okay, the next one Okay, I hope that I say this correctly. It's Shelby Dixit from Vanderbilt University and the title of her Poster was a scorbate deficiency and mitochondrial dysfunction in the APP Peace and one mouse models of Alzheimer's disease Okay, the next one and I think one of the criteria should be short titles These are These are gonna be long so hang in there, please Okay, the next winner is Jeffrey Sasaki from the Ohio State University but This is from the OSU Oregon State University Title was green tea treatment in obese mice with non-alcoholic state Deato hepatitis Lowers hepatic NF Kappa B activation in association second with altered relative abundance of Phosphatidylcholine and biolacid metabolites. Okay, and the last is The last award goes to yang zong from Linus Pauling Institute Oregon State University The title is supplementation of mice fed a high-fat diet with xanthe humul and its derivatives changes the composition of the fecal microbiota And is associated with observed metabolic improvements


Welcome everyone to the Selenium has a new trick up its sleeve to track failures by Pooja Chiman Jagani. We are glad Pooja Jagani can join us today. So without any further delay, over to you Pooja. Thank you so much, Krishna, for the introduction. Very appreciated. Hello everyone. Welcome to today's chat. I know everyone's very curious to understand what is the new trick that Selenium has up its sleeve. Let's begin. We will talk a little bit about myself. So hello, like I already said, I'm Pooja Jagani. I'm one of the Selenium committers. I've been working with Selenium for roughly two years, strangely enough, or coincidentally, my journey with Selenium started with observability itself. And I'm also a team lead at Brastax open source office. It has been a fun journey so far. So today, what we intend to cover is just a quick outline. We'll be talking about what is observability? Why do we need it? Once we understand why do we need it, we also need to know how to do it, right? So then we'll go deep into the three pillars of observability. And out of that, we ensure that the two pillars are very strongly embedded in Selenium along with how we can use it. So we'll see it with demos. Then we move on to a typical observability pipeline. Just having observed eating your code is not enough. It has to be extended a little further with some components, especially if you're running at scale. Most of these principles are applicable even if you're a standalone, you have an application in which you want to instrument observability. So it works for that as well. And then we quickly wrap up with a small case study, because everyone has a different application, right? Sometimes you're running it as a software as a service. Sometimes it's your own application that you're running on premise. So considering one such case study, we talk about how we can provide it even as a feature, like how we can extend any observability even as a feature to your users. We'll wrap up with that. So let's begin. What is observability? It's like a famous buzzword that we have, right? So I'll give everyone just a couple of seconds to go through this Wikipedia definition and then we'll break it out. Okay, I hope everyone's gone through the definition. So I'll just read it out once again. In control theory, observability is a measure of how well internal states of a system can be inferred from the knowledge of its external outputs. It might sound weird, but let's break it down a little bit. So let's talk. So what it says, observability is measure of how well internal states of a system. In our context, the system is any software application that you're developing. For us, it's also Selenium. It could be application you're developing. It could be application you're using any particular software becomes your system in this case. What it's trying to say is how well is that system functioning? What is the current state of the system based on the data that it generates or the output it produces, right? We already do this in day to day basis. Maybe we don't realize this, but the simplest thing we do is logs, right? If you're running an application somewhere or you're using someone's application to know how well it's doing, what is it doing internally? You use logs, which is nothing but the output it generates in order to choose what information do you get. So that's exactly what observability is. It gives us a peak of what's happening inside, just based on the data we choose to expose as developers or maybe fellow developers have done the same for the products we're using. Now, okay, we know the definition. We understand what it does. Maybe we're already doing it in part, but why do we need it? Now, let me back track a little. Why do we develop products altogether? I mean, there are two goals, right? On the open source world, and since I'm from a mix of open source world and I work with the company, it's a mixed goal. But for open source world, you'll do it for the greater good to help your community to support fellow developers to give them a functionality. And as a product in any company, like any corporate or any startup will be to generate revenue. Why do you want to generate revenue? How will you do that? You do that because you have a good product and your customers are really, really happy. But now I have happy customers. A lot of them are using your products. Now it's time that your products will need to scale. It could scale in different ways in terms of a different architecture. It could scale by deploying it on cloud. It could have any other different scaling mechanisms that you need to handle multiple requests, multiple loads that you will get in terms of happy customers, right? So when all this happens, you know, slowly start looking at, hey, is my system scalable? Hey, is it available? Is it reliable? These properties creep in, but in order to do that, you need observability and I'll exactly tell you why. So at the moment your system scales, let's be honest, all our systems are not flawless. There are production engineers, on-call engineers, support role engineers who do get woken up or called in the middle of the night because there's an outage in your system. There's a bug in the system. There could be a potential downtime. All these things do happen when one is operating at a certain scale. So at that point in time, what do you need? You need to know how well your system is doing. Assume you're an on-call engineer woken up at three in the morning. You will want answers. You will want answers that you might have your software has not prepared for. You'll want answers as to what is not working. Why is it not working? How long has it not been working? Did we give a wrong output? Did we get a wrong input because of that that we were not able to do something? There'll be tons of questions and you need answers to everything. This is what observability gives you. It gives you a gateway to unknown problems. If as a development team or as a developer, one has tried to put on the user hat or even like a support engineer hat to understand that what will be useful at that point? That's exactly what observability gives you. So now your system is to help your system be scalable, reliable, available, you need observability. So now your system also becomes observable. But let's look at one more perspective as to why you need it. If you're able to identify using observability on a day-to-day basis, the potential bottlenecks, the potential problem areas, or even existing bottlenecks, and you're able to rectify like a root cause analysis at the earlier stage by just analyzing the trends of the data that's been generated. In turn, you will have a productive product. If you have a productive product, your engineers are not going to be broken up as much. They're going to be happy. They're going to be productive. So you're going to have a happy humans and happy product. It's a win-win that way and that's why observability fits in. So now the main question and that's the topic for today. Why do we need observability in Selenium? So let me talk. This comes from the perspective of Selenium Grid. For those who don't know, I think everyone must be aware of the Selenium client bindings in different languages that pretty much hopefully most people in the audience have used. And at that point in time, those language bindings, they just point them to a browser and it talks to a browser. But what if I want to run things at scale? That's when Selenium Grid comes into the picture. Selenium Grid is a server. What it does is it helps you run things at scale. If you want to do parallel testing, cross-browser testing, you want to manage the load of different browsers running on different machines with different OSs. Think of it as a small server farm, small device farm, sort of a thing that you want to run. That's where Grid helps you do that. There are added benefits and we do have dedicated talks and workshops that deep dive into it. But I'll just quickly run through the different components and why observability makes sense. So today, the Grid for Architecture has kept in mind the microservice system or the microservice architecture we have today, where monoliths are broken down into these smaller services that run independently in cloud, different machines and communicate to each other. Same thing is emulated with Selenium Grid. As you can see in this architecture diagram on the left-hand side, you see a client, which is nothing but your machine where you write your tests in the favorite test framework of yours using Selenium. When you instantiate a web driver instance, what it does is it sends a request. It could be either directly to a browser or a Selenium Grid. We will be talking a lot of things from Selenium Grid perspective since it's a server here. It will point to the Selenium Grid. Now let's quickly do a walkthrough of the different components that we have. First component it hits is the router. So when you do a remote web driver, you give it a URL to 0.2 and that is the router's address. Think of the Selenium Router as a simple forwarding proxy. It is only able to identify if it's a new request or an existing request and accordingly take action. If it's a new request, it puts it in a session queue. It's a queue where all new requests are sitting happily. Then we have this component called Distributor, which knows that, hey, I have these browsers with me. Which browsers are free, which are up and running, which have some less load that I can delegate more to us. The load balancing bit, our distributor takes care of it. So it will pick a request from the session queue and delegate it to one of the nodes. As you see in the diagram, you could have one, you could have 10, you could have 100. That is where your browser runs. Those are separate machines where you would have your operating system and browser combinations that you would like. That's what would sort of give you that server farm or a device lab feeling. That's what it's going to do. So it decides, oh, this is the correct machine. It has less load. It has the browser that it needs. Please go ahead and create a session here and start talking to the browser. It also has the web drivers. And once that is done, we maintain an internal state using some things as simple as a session map. So now you'll see, and the entire communication happens by a Pub submodel event bus. So now you see we have a lot of components. They're talking to each other. If something goes wrong to know what is happening exactly why is why we need observability in Selenium. And that's why we provide it to the user. And we also try, at least in Java, what we've tried to do, we've tried to do end to end observability. So for every Selenium command that you issue, you're able to see exactly from the time it's sent on the client side to it goes through the entire architecture and circles back and you get the request. You'll be able to look at the entire journey. Now we spoke about observability, the need for it, but there has to be a mechanism to achieve it. These are the three popular pillars. They form the foundation of observability and the key is correlating the data from each of these. Let's deep dive into one pillar at a time. First comes tracing. This is my favorite. And this is, I think, we'd also have a demo after this just to see how it's done in Selenium. So let's think about tracing. As a kid, you might have this activity like join the dots where you would have to trace a picture to see the entire picture to understand what that entire cartoon looked like. It used to come in a newspaper activity. Similar analogy applies here. Tracing gives you the whole picture of the system. Let me go back a little. In our day-to-day views tracing, I don't think most of us realize, but a simple day-to-day tracing what we use is a stack trace. When there's an error, you see a stack trace. It's able to pinpoint exactly where the error happened. It tells you what parts of the code you're able to trace through the different code steps it's taken and where the error has happened. Now let's extend the same thing to a distributed system. Now you have multiple microservices talking on the network. You want to know what is happening. In order to fulfill one request, it might go through 10 services or if you have a network of hundreds of services, it might go through hundreds of services just to do that. Maybe for once a request, it's okay. But what if there's a 100x load on your system? Now you have hundreds of requests. If your system is under stress, you're not able to track what is there. That's where tracing comes in. It allows you to track a journey of a request from start to end, from its initial step to its final destination. What did it hit? What went correct? What went wrong? What took long? To give you answers for all those questions, you have tracing. Let's quickly go through an anatomy of a trace as to what a trace is. A trace, like we said, represents a single unit of request. Typically, I think all of us that are aware like HTTP requests have something like a request ID. So think of trace ID as a unique identifier to represent the same. Now, it's not just sufficient to know that, hey, my trace has touched this service, this service, this service. Okay, it has gone through this service. But what am I getting out of it? You need to know the important work your request is done as it's gone through, right? Because there will be some work it has done which has been successful, some which has failed, which is what we are more interested in. To represent these small units of work it would have done, we would call it a span. It's called a span. Again, it has a simple span ID. And to do that work, you might be doing a branching out and doing further more steps and other units of work. So you can have child spans. Think of it as a tree. You have a parent span and child span to see what it takes to get that work done. Okay, now I know what is a trace. I understand the span. But okay, I still know it's touched this service, done this work. But I need more data, I need a lot of context. How do you add the context using attributes?  What inputs were there? What were the outputs? What went wrong? Was the DB that we connected to the correct DB? Like what's the address of the DB? What response did we get if you're connecting to a database or a third party system or some other part of code? All that information, put it in attributes and you should be good to go. And throughout this process, there might be certain events which are important at a particular time. Say you're talking to a database and it's down at the same time. If you want to know at what time stamp it happened to correlate this information. So timed events are nothing but logs. So within your spans, you need to work to mark certain important times that these are the ones where important events have happened. Again, it has more context. Events is the next part that we'll be discussing in depth in the second section, but let's continue. Now we spoke about this architecture right now just. And same way, if you see, think of a trace as a single request going from client to the router to the session queue distributor node and all the way back from the single trace. So what is a span? The fact that client was talking to a router and did a unit of work. That is a span router added to the session queue and did few steps. Those are unit of works. That is the span. Within a span, we spoke about attributes. Now attributes are nothing but we are telling the router or we're telling the session queue. Hey, the client is requested for this browser session is like, okay. And then the distributor tell you, okay, for this browser, we created this request. This was the response we gave. And this is the session we created. It gives you all the details that becomes your attribute. Again, you add logs to it just to, you know, sort of timestamp important events. So that's how that will fit in. That's how it will look in architecture. This can be mapped to any architecture on your system as well. Let's go to the fun part, which is demo. This will try to show a little bit about how we do it. So in the Selenium repo, we have this trace thing.txt, right? Based on the version which tells you exactly what tracing steps to do if you want to enable tracing. So by default, tracing is enabled. And then extension flag in Selenium to add anything to the class path. And it's important why I'll just let you know. So if you're running a Selenium Java jar, you're supposed to pass few environment variables to just export this information out. I know that, okay, I have these traces, but I just need to put it somewhere so I can have a look. You pass in the jar. It's a typical Java jar command. And you use the extension flag to add some more dependencies to export this information out, to report this information out. Okay, and it's as simple as that. But the simple thing that we suggest if you want to observe this to use Yeager, it's a simple one. It has a simple Docker image that you can use. It gives very good trace visualizations. There are other tools like Zipkin as well, but we just use, it's Yeager is just simple to stand up and run to just see this in action. And then it can be extended. I start Yeager on the right. It's just running a Docker image on the left. You see, I have a select. Sorry, I'm just been pointing that they are going to start it on left. You see, we starting a grid in a fully distributed mode. That means it will have all the components we spoke about.  Session map has started session queue has started logs are just coming in distributor has started. It's identifying what's available. Again, we're printing some logs for the details that we have. And unknown has been added a grid is beautifully set. So this is the script. I think as we said we need to add the standing up different components. This is just a quick walkthrough of what components are going through the environment variables we are passing. This is how we can do it. It's just running different jobs. It's a simple thing and passing the variables. Now I just quickly check if my Yeager is up and running because I've started a few services. We already see that few traces have come in. We'll go into detail later, but you can just see some components already have some traces and list. Now let's run a test. That's the fun because you want to see what happens at each point. So in order to do this on the client side mechanism is also very simple. So there's a documentation where it says as to if you want to do it on the client side, how it can be done. You just need to add a few dependencies. And apart from that, it's just simple form dependencies that you have. Or if it's the same thing applies or certain properties as to the environment variables that need to be set. These are pretty much the same things. And I'm just showing as to that's what we're doing is just getting mapped. Now let's quickly go over the test we have. We are creating a URL that points to the grid. We want to run tests in Firefox. Go to a URL, find an element, wait for an element. And that's pretty much it. And then, you know, just wait for an element and just put the drive. It's a simple test. I think most folks would have interacted with this. We are now running the test. Test is running.  It's just showing, okay, session is created. All done. Session is also deleted because it has gone through. Now we look at Yegor. That's the fun part. Now you'll be able to visualize it. All services have been touched upon. We are able to see that quickly see from the Java client perspective. So before we jump into that, this is also telling me what are the components and how they're talking to each other. Just a simple architecture view. And now we dig into one of my favorite traces. This is a trace that we have last when we did a quick command. It is exactly telling the steps that are happening. We're running a driver command. It has sent a request and just drilling through. Now let's go to the one with the biggest one, the first one. So what is the first trace? It is when you're creating a session. Seeing your center new session command from the client side. And you're seeing some parameters as to what did we send. And now we're going through the different steps. We've added things to the session queue at some point of time. And the different logs that we have, the different steps we set. So this is what tracing lets you do.  Okay. It's reached the distributor. So the distributor part of the new session. Now this has event logs. It's telling us that within this unit of work, the span, these are the time events that this is when it got the session. And this is when it created the exact session. Right. So that is what it is doing. So this is how tracing looks. And yes, there are more things where you can just discuss as to, okay, this was the input. This was the output that we got. It's emulating the exact same thing. So this is what tracing lets you do. Okay. And so far we get an idea as to how you can track everything from end to end. But now let's talk a little bit about the next pillar. This one pillar we've seen. We've seen how Selenium does it. You can dig deep. You can keep digging. That's what the rest of the video is doing by the way. Just going through traces in depth, seeing what has happened. But I think we get a good picture of what's happening from start to end with steps that doesn't meet and how you can use that information. Let's move on to the next pillar logs. What are logs? All of us know. We record this information daily in our code. If something goes wrong, we tell, okay, how are the logs looking? What does the log say? Do we have a error log? It's a common question that we do, right? So anytime something fails, logs tell us what has happened at that point in time. It doesn't necessarily give information about what happened just before that. So we get to that a little later. This look at a simple log statement. Now this log statement is a log statement from Selenium. It says simple. It gives your timestamp. It tells you info. It's telling you session is created by the distributor. And now you're able to see what session is created by the distributor. It feels like a big dump of a stream. Now, how can you make this better? Structure the log, right? So you had the next log is a structured log. It's just a contract or between your teams so they can understand the different key values. You can think it was a dictionary, key value map store, or even a JSON. I mean, it's all the same, right? In terms of it tells you, it gives you a little bit structure. It tells you the class, log level, log message, name, time method. But if you look at the first log statement, the second log statement, apart from the structure, what new information are you getting? You're not getting any information. Structured log maybe can be used for like something like indexing or something on those lines. But apart from that, there is no added benefit. The information that you get is the same. But what if I want more information? Like we said, observability is to help you answer unknown questions. That's where enters event logs. You've seen a little bit glimpse of it in the earlier section where we spoke about there are, you know, spans of events within them. But let's talk about. So event logs are also structured logs. Yes, they are structured because it's easier to search and index and make it a little more machine readable. That's why it's structured. But the main thing is don't think of a log as a single statement. Think of it as something that represents an entire unit of work. And that has all the information that it's needed to represent that unit of work, your inputs, your outputs, your failures, your calls to the dependency service. Everything is encapsulated in one big event. You also call it as event logs, but like a one big event. And the more context you have, the more you'll be able to answer certain questions that you did not expect. If something goes wrong, you're correlating a bunch of logs for a particular unit of work and adding it in one place. So you'll have answered to all the questions. This is again, event log in Selenium example. Similar structure like the previous one. But the structure in the previous part remains constant. Here, a part of it changes. I'll tell you what. So trace ID, it's saying this is a log for a unique request. What event time? What is the event name? Create attributes. Now this is where you add as much context as you like. So if you see our earlier logs, we were just telling, we got a session in the distributor. This is what we got. What did we do out of it? Was it successful or failed? We did not have that information at all, right? But here we are telling, okay, this is a request payload that came in. This is a browser I was requesting for. I sent this information to the session. I created this particular session ID and this is where the session is running. If something goes wrong for a session, all the information is one place. That is the power of event logs. Let's have a quick look. So the setup remains very similar to what we had in the previous tracing bit. The first two minutes there was just trying to explain if anyone wants to do tracing, like a mini tutorial just to do that. The setup is the same. I have a distributor grid running. I'm creating a error scenario. Just let me go back. I think I just keep through that a little faster than I would like. I am creating a error scenario. I had an echo driver on my machine. I just removed it. So it errors out when I request for it, right? It won't be able to find a driver. It will throw an error. And you'll see the beauty of this more in error situations. I'm running the same test that we saw earlier for Firefox now. But later out, I don't have a driver on my machine. I removed it from the path. The test is running. Yeah, it fails. Not yeah, it fails, but you know what I mean. We see an error message. There's an exception. It's giving us some more information. Now what? The fun part is checking out your trace. And I mean, I know we do this. I'm running this in a simple standalone mode, but you get the meaning. Now it tells you that Java client command has failed. You see all these red check marks. You're able to see what command, what happened. Session Q received it, but it comes with a 500 status code. Something has gone amiss. But what has gone amiss? We tried to create a new session and node is telling me unable to create a session. What went wrong? Where are the details? The distributor has the details like the event that we spoke about. This is where if you see, we're able to see when I'm trying to create a new session, this span. It has these logs. These are event logs. It gave me all the information. What was the event? It aired out. What was the exception message? Okay. What was the stack phrase? Think of it as a trace within trace. Like a mini-trace as to where did it go wrong in my code? You can encapsulate as much information as you like to just know what happened. I understand we might not draw meaning out of this in just one request, but you have hundreds and thousands of requests. You would be able to do more of a trend analysis to the whole thing. Identify patterns, identify a request that are taking a longer time and see there are statistics available. Typically tracing is given out in a small, simple raw JSON format. This is just a tool that's going ahead and displaying it. But what you do with that powerful data is totally up to you. But if you have the data, you can make decisions. That's what it's about. Again, this is like a quick overview as to what I've covered. It's also telling me what was the payroll. So again, all information, what did we send? Why did it not work? Where did it not work? Exactly which point in code did the exception come in? I have all the information I need. So that is your log event. So that's our second pillar. You've seen tracing. We've seen logs. Let's talk about metrics. So what are metrics? I think a lot of us have worked with metrics, but metrics are nothing but measurements in your system. You can measure everything in your system. You feel like you could measure the number of requests and number of errors that have happened, time taken to run a particular function. You can measure as much as possible. But that kind of a data load overload is not needed. You might just want to measure important parts. And it's for one as a developer to identify what are things worth measuring? And that's why we call metrics the golden signals of the system. So it's up to the developer to identify these critical golden systems that will have meaning when you observe them outside. If the system is there and you go through your metrics dashboard, the reading that should be able to interpret the system running fine. Is it healthy? Is it under load? So ensure that that sort of golden signal mentality is sort of etched in when planning for metrics. Common types of metrics. They're particularly divided into two types. I'm not going to deep dive. I'll just give like a one liner on each because honestly the thing with metrics so far is a lot of mechanisms are available and these terms are not as standardized. But the underlying mechanisms are pretty much constant in most of the systems. A simplest one is measurement in metrics. Let's go with a counter. Like the name says you count something that is constantly increasing. Think of a counter as an upward graph or a flat graph. Value will only be increasing or at a constant level, but it will not dip. They just keep increasing. So it's a little bit of a more vanity metric like the total number of users we've had so far, total number of requests we've so like something that's only increasing. That's not going to dip. Gorge on the other hand will help you like you know measure anything at that particular time. Think of it as a temperature. Temperature value at one point is constant and second point it changes. So that's what Gorge will help you do. Like you would want to know the number of threads in my system currently. The CPU like the percentage of CPUs currently. So Gorge will evaluate that instant. That's one solution. Distribution. Now distribution is tricky because there are more sections in it. Distribution especially that's about histogram will tell you distribution of data over a period of time. It'll give you percentile values, average values, but just a tip, average values are not very useful if you're getting average metrics. What happens is again a vanity metric, it sort of hides all the peaks and the dips. So percentiles especially on 90% 90th percentile or 99th percentile will give you a better value because you know that 99% of my values are less than this. So this is one outlier point. So when things are failing, you're interested in that outlier that caused a problem and not an average. And the last one is a meter. Meter is number of events per unit time. Number of requests per hour we've handed number of users in the last one are that have visited us. Those kind of metrics. Now, this question I'm so sure I would have gotten if I had not covered this. Why are we not collecting metrics in Selenium? It is tricky. It is not a problem we've not tried to solve but it is tricky. So why would we collect metrics? If from Selenium perspective or a project perspective, I would collect metrics to know what is failing, how often is it failing, what feature is being used the most, how often it's being used, those kind of information. But if I were to instrument metrics, I would be gathering this data from users, only then it would make sense. But it is tricky because A, the data has to be anonymous. If my code is running on someone else's machine, the data has to be anonymous. We don't need the details of the user. Second, we need permissions from the user in order to do that. If all is well and good, in an open source project, we want to keep everything open. So we need to also store the data to analyze it. Even that process has to be open as to where do you store the data? What are the API keys? Or what are the keys to talk to the database? Those kind of things are open, which is again a risk. And it's a little bit of tricky problem to make sure it's a totally open process and also we're getting accurate metrics. It's as good as someone running, say they're learning Selenium and someone just running a test in a loop to do something. We don't know if it's a proper metrics that we can actually use.  They're doing a test-driven development and doing the other way around. So that's why it becomes a little tricky. But if you have your own application that you have full control over, it's not a service or library that you provide, then it may be good to have metrics because they are pretty useful. Interrupt, Pooja. You have eight minutes time remaining. Thank you. Okay, thank you. So now comes observability pipeline. Again, this is very similar to what we've already seen. We saw instrumentation in Selenium. We've added the traces, we've added the event logs. If you would add metrics in your application, that's instrumentation. We added some external dependencies. If you remember, that becomes your reporter. Data is collected. It has to be thrown out or pushed or written somewhere in batches or line by line, however you do it. But in a large-scale system, you would do like a batch processing because that is not efficient. And if you're doing that, it's up to you. You might directly want to write it to a storage layer and then use it or have something in between as a buffer in case any component is down. So you could have potentially a pipeline or a caching area or a staging area, whatever you like to call it, where you would store this information till it's written successfully over the network in a storage layer. Storage layer. Like we see, Yegor was everything. It was doing the reporting part. You can visualize it. But if you're running at scale, these are components have to be separated out so that amount, that data that's being generated almost every second or every second is handled. So then you'll have a storage layer which is able to understand this kind of data or at least store it in the format required to reap the benefits of observability. You need to either visualize the data which can potentially be again used for alerting or your own calls or your figuring out potential bottlenecks. That sort of thing. So this is a typical pipeline that fits in. It fits in for Selenium. It fits in for any other application just in order to have this another data stream that we're going through. Now just a last quick little demo that I have. It says observability as a feature. Now let's think of a use case and again Selenium fits into this. The reason we have observability is because when you run a Selenium jar, it's a black box stream. So now with observability, you're getting the insights. But yes, you have more control when you're running it on your own premises. But what if you have a tool that some other companies are providing as a service? For example, Browstack provides as the infrastructure to run tests and we can do that using Selenium. But what if the user still wants to get some insight in this situation? It's difficult. So what they have done is they've provided observability as a feature. We just have a quick look. Again, we are running a similar test. In this case, I'm just pointing to the cloud vendor that I have. I'm just running a simple test. Session is created. Things are going okay. Okay. Test is done successfully. This is just a dashboard where it's showing the test I just ran. So what it's doing is apart from providing me different kinds of already logs that I need. It's also giving us additional telemetry session, right? Where I can go ahead and download these logs. So what I've done is I have downloaded the logs and I'm trying to just visualize them. It's again, very similar to what we've seen earlier. But again, yes. So this is my Yeager. You can also write it in a non-docker format. You can download a Yeager agent. I put just let me speed up apologies. Yeah. So what I did is in the agent itself, I just downloaded. So this badger.tart.gz is the downloaded logs. Like, so like I said earlier, tracing information along with event logs is provided as JSON. So if that is downloadable, it could just be used by any tool or to do what we did. So now we are doing exactly the same thing. We started Yeager just to read those logs. So we have that up and running. And now what we quickly do is we go ahead and visualize it. So the same power is in our hands. But now if you think about it, the kind of power that we had was in terms of a, it's a black box to run something on cloud. You don't know what's happening. So you got some insights to that. But what it's running internally and what is of interest like Selenium, we are getting more insights into it as to what went correct. What didn't work out? Was everything okay? What did we send in? Again, the same questions get answered. So just to conclude, we can think of it as if you have your own application, you have a lot more control. But if you're also providing application in, as a service, you can provide observability as a feature so the users can leverage it the way already Selenium is doing it. If you have a service that, you know, other services use like cloud vendors are using it. It's also possible that if you're a cloud vendor and you have underlying services, you can abstract the data out again, provided to the user as long as the data or the observability information is available, it can be provided in different ways. And again, there are uses for it as we discussed. So that's it. That was for me today. I hope I have not overloaded everyone with a lot of information. Thank you so much, everyone. Really appreciate everyone joining in. I think we have a few minutes for questions. Krishna, could you help me out? Yeah, so we have one question currently. So can you tell about port numbers left and right? This is a question from someone from the attendees. Okay. So the port number left and right, I think you might have seen that in the Docker bit. It's more of a Docker concept. Right. It tells you that if it's a Docker concept where you have ports within the Docker that you want to expose in your host system, so port on the left is your host system port and on the right is what is in the Docker. But it does not seem to be any more for the questions. If anyone have any questions, we still have time. You can post it in the Q&A section. So the question and the question is, can we add JGOR UI with Selenoid? I think you should be able to do it as long as underlying it's using Selenium. If it's using Selenium and traces are on, you should be able to do that. No further questions yet. Let's wait a few seconds if anybody have any question. Yeah. So can we make the logs more structured for JavaScript using? It can be. So currently we have this for Java. We have seen few people use it. But if there are people or there we have audience who are interested in having this sort of structured logging available for JavaScript. JavaScript can be instrumented. We don't have that right now, but we will definitely consider it as something we have in the pipeline for future releases. Feel free to make a feature request on Selenium repo and we'll be more than happy to discuss and take it further. So can JGOR be used for APM? Not yet. I think we got this question yesterday during Manoj's and my workshop as well. I think APM is going through some restructuring. But it's the conversation we can again definitely have with them once in the future releases. They have that. Then that can be extended, but it honestly depends on APM's implementation of how they are using Selenium and underlying Selenium. So what are some practical cases when tracing logs that can be helpful as a user? Yeah. So like we said, so currently if you're running a grid, if you have a grid that you're running at a scale, imagine a grid running with 100 nodes and you're running a test suite of 1000 tests, you have so many requests going in, you don't know what is happening where, but you see a set of failures. And maybe those set of failures are not ported into your test, something has happened on the browser site or something has happened within Selenium or grid that has not worked out correctly, maybe a node crashed. It was not able to find a particular node. It's the infrastructure that you set up that could be a problem. So to get that information is where you can use tracing. Like I showed it was not able to find Gecko driver on my machine. It crashed. So you have to set up a node where the correct drivers are not there for that motion. And you'll be able to dig deep and see exactly what went wrong. It also could be when you're sending requests on a network, there are some latencies. So you would be able to study things like, oh, these requests at this particular unit of work if they're slowing down. Maybe there is a problem with the network. It also could be a transient error. So those latencies I was seeing yesterday and that data, I'm not seeing that today. So this makes the data is very useful. Obviously, single data point is not enough to identify a trend or a pattern, but when done at a big scale, or that's when you get deeper insights. We have run out of time. So thank you Pooja so much for sharing your experience with us today.


Everybody forced here up in 2022 tops dynasty baseball hobby five bucks case number 10 Left side serial numbers. Let's do the random right now. You guys know how it goes names number same amount of time Same amount of times put them side by side Then that's how we know who's got which number here we go. We'll go five times here four and one Future Philly Shohei Otani Names five times One two three four and five Eric W done to Eric W and the numbers five times one two three four five one down to five Eric got one again at that random luck All right Eric W one seven Ryan D six ammo ten John a three Simon s nine Ryan D four Eric W two John a eight Eric W five Let's do it Here comes your link find them find the results anytime elite in sports cards calm Yeah, I saw that Patrick. I wish I could see less things about him though Can I mute that like name on like Twitter and stuff you can right you could like mute phrases and things, right? I used to do it when like movies would come out if people like spoil them. I used to do the all the time Like Marvel and Star Wars and stuff Unless Elon broke that too Wonder how much longer Twitter will go. It'll be there in some form and for a while at least You can't filter out those. Oh my god. Oh Man, I know exactly what this card is right away Look at this Look at those hats. Oh Boy, this is gonna be three short stops. I know the card already. Oh my god. Oh My god three of five Triple patch auto Cal Ripken jr. Derek Jeter Fernando Tatis jr John a number three Get the camera It's up Alistair. Happy Sunday, man. Whoo. What's up map? Get the camera Oh man That's something else right there technically three colors on the on the outside patches the Jeter looks like a two color You got Navy All two different shades of Navy. I guess I technically a two color or three color He's a shortstop. He's good at baseball Yeah, I agree with Taylor that cart stinks dude next up two of ten Adrian Beltray four color patch auto Eric W with the two spot sweet Beltray four color As a ranger, I've seen we've seen him like everything in this everything except Mariners He doesn't it's like the only team he doesn't he's there for what four and a half years Five years on that and next up is a five of five rookie patch auto Alec Thomas Eric W with the five spots That purple black purple and white redemption Dinos you autograph patch card this can be random to everybody This is not a one-of-one. This will be random to everybody at the end and it is of Dave Parker Dave Parker again, we don't know a serial number.  I don't know. I'm sorry Vaughn Okay, so Dave Parker redemption random to everybody here Yeah, no parallel none that so we don't know who it's going to Go ten times here Whoever's up top Guess the card One two three four five six seven eight nine and ten Go to Eric W. It's an Eric W kind of evening apparently Now I'll do it everybody moving on to our basketball, right?


Okay, for this first activity, I have a pi-10, some water, two nails, and this is just a magnet with a north end and a floater. So let me show you what I'm going to do. First, I'm going to fill up the water in the thing, in the pi-10. And then I can put this on there, like that. Let me stop it from moving. Okay, now I'm going to take the magnet, and you could do this as a demo or students could do this as an activity. And I'm going to rub this with the north end from the head to the tip, just like this, three times. One, two, three. And then I'm going to do the exact same thing to this nail. One, two. Now I'm going to put the magnet off the side. I'm going to put the nail on the little floater so it can spin freely by the stop. Okay, so now I'm going to take, let me move the camera a little bit. So now I'm going to take the tip to the tip and see what happens. Now I'm going to take the tip to the head. Now I'm going to turn this one around. Let's do the head to the tip. Now I'll do the head to the head.