 Welcome everyone to the session smart locator strategy for react applications by Sudarshan Selvaraj. So we are glad Sudarshan can join us today. Hey, thanks a lot for the quick introduction. So and I welcome everyone for the session and I hope all are doing well and good. So in the session like we'll be covering like few important things that everyone should know for automating ideas applications right. And I will also try to keep things very simple. So rather than providing with a lot of information. So we will just like go through the very basic information that are that are required for automating react applications. And before going to the session like just a word about myself. So I am Sudarshan Selvaraj and I'm working as a lead as debt in Gojek. And I have around eight years of experience in QB space. And I have worked extensively on a UI automation tools like Selenium, APM and couple of others. And you can follow me on LinkedIn and Twitter. I like often post all things later to testing and also develop a lot of other tools that enables all QB some is gets to make their life easier. So do check this out. So keeping things aside like let's just start with the session. So first like I just want to make it like what are the things that you will be covering as part of the session. So the first thing is like so I always encourage you and I have been doing this myself for the entire career is whenever I'm going to start with testing or automating any application. The first things I will do is like so try to understand the application under the test better or text like that has been used what type of framework that is being used. So what are the challenges that we might face if we start automating the applications. So understanding of the application will give a better visibility on things that needs to be taken care of before and we start testing it. And also we could also get additional information like what are the other tools and technologies that can be implemented to make our life easier right. So on that sense, since this is going to be a application. So we want to understand a very basic things like what are your component is how the real component works. So that will give a better understanding of how that can be tested as part of our automation. So that will be the first thing we'll be covering. So next thing is like so what are the challenges that we might face in automating such components. So in terms of automation like what are the real time challenges and how we can overcome it. So the last part is like how are we going to use the react web driver and leveraging all its capabilities to overcome the issues that we are facing. Cool. So being said that what is a react component right. So in recent days like most of the single page applications have been created using frameworks like react angler and view right. So all these things looks very crazy and sounds very hard to understand right. Hey what is react what it is doing. But if you break things into a smaller chunks then it will give up meaning and sense like hey this is what the application is doing. So in case of react everything is a component at the end of the day. When you say a component so it is just a piece of code or a function or a class that resembles a ui element. So for example let's take Amazon so when you search for any product you will get list of search items right. So under the search items each item is internally a component. So it has some functionality associated to it. It has some HTML attached to it. So that is a basic of a component right. So with each individual component you will just add it up and build it as a whole application. So it's a chunk of data which is collectively used to build a page or an application. So that is what a react component is. And as I said a single component can hold several other components inside. So same like how HTML is rendered right. So you have a parent component and each parent component has any number of child components to it. So similarly in react you have a component and the component can reuse any existing components inside it. And the key things which we need to get is like so each component consists of two information. The first information is called as a prop and the next one is called as state. So this sounds crazy but a prop is nothing but so Java word or a JavaScript. Consider a function as a component and a function can accept a parameter right. So those parameters are nothing but the properties. So when you render a component in a webpage you can give some properties to it. So for example in YouTube there are like a video thumbnails that are being rendered right. So that is a component and that component expects few properties like what is the thumbnail URL what should be the video description and what are all the other properties for that video like how many likes how many dislikes all those are the properties for that particular thumbnail component. And the next one is called as a state. State is nothing but a private variable for the component itself. So each component has to maintain some state right. So for example in YouTube if you hover on a video type it will automatically starts playing it. There are like other action items like you can delete it or you can hover it to show some information. So all those things are called as state which is applicable only for that particular component instance. So these are all the three main things that we will be covering today. So let's take an example of a simple react component here. So as you see on the left side like we have a counter application where I'm clicking the plus icon. The counter value gets implemented and I'm clicking the minus the value is between decremented very simple as that. And if you look at the component code here, so we just have a function with some name which accepts some parameters and it returns a HTML element. So this entirely is called as a component and the name of the function is the component name itself. So for this component the name is counter and what is the property? It accepts the property called maximum value and it is going to be number and it is optional value. So if you provide a maximum value the counter will stop at this maximum. If not it will go endlessly. And we have state here. The state is the internal property of the counter which it maintains. So whenever we incremented we will increment the state variable. So this is nothing but a local variable to this counter. This variable cannot be accessed outside of this component. This is only specific to this particular component. And if you take a look at the HTML here, so we just have icon here. Again this icon is another component. So as I said a single component can composed with several other components here. So we have icon component and we are passing a property to it. So this icon component has a property called name and we are passing what is the name of this icon. And onclick is going to be another property. We are passing a callback reference here. So whenever we click on this, this method gets executed and we are updating the state here. So same goes with the decrement icon. We have icon component and we have provided a property to it and on clicking we will just decrement it. And we have a simple heading element which will just display the counter. So what React does is whenever this component is rendered in the UI, it will render this particular HTML over there. And whenever there is a change in the state variable, it will just re-renders this particular element. Rather than re-rendering the entire DOM, it will just re-renders the element which associated to a state to it. So this is all together called as a React component. So now we know what a component is. Now let's see when we mount this component to the HTML and we open the bit page, let's see how the DOM looks like. So for the same application. So if we open it in the browser, we check the DOM. So we don't have any information of the component here. It's just a bunch of HTML elements with some random class names, some properties are sent away. If you take a look at it, so I'm just highlighting the plus icon. If you check at the DOM, there is no meaningful information that we could get whether this icon is plus or minus. Because the same properties are there for the minus icon as well. So this is a very simple application. So you could just simply go ahead with, okay, I will just use XPath and find the first SVG. So that is going to be the plus icon. We could go ahead. But what in the future if the product or requirement is going to be swap the icons. I want the minus icon first and the plus icon next. What happens? Our automation test eventually will break and we need to come again and we need to fix this. But still it is okay. Just two icons you could fix it. But think of a very complex application where you have a simple component can have like 10 icons. 10 different icons for denoting different things. How are we going to automate those things? So that is going to become a problematic thing. So that is where we will be using the React WebDriver and see how effectively we could find these elements. So this is a general HTML DOM. But in ReactJS, the library internally uses a concept called virtual DOM. Okay. So what a virtual DOM is, it is nothing but an in-memory representation of the HTML DOM itself. So this is nothing but an XML document where we have a tag and internally it has all the subchains, everything. So React what it does is it will just maintain these hierarchy in form of an object. So it knows an object with a key called okay. I have an element with a tag named do and that do as an internal array of children. And if you go inside the cheat children, it might have internally like a number of children. And with all the properties, it will maintain an object. So what React gives the capability is we could able to go and inspect that object. So for that, there is an extension called the React DevTools. You could just install in the Chrome and we could visualize the same DOM in virtual DOM way. Okay. So in my browser, I just installed the DevTools and I just activated it. So now if I inspect the same application, I can get the information about the component itself. So see, I have the parent counter component and I can see what property it has. So I have provided a maximum value of 100. And there you can see I can have a component called icon. So that component internally has a component called mdr. So this is nothing but the name of the icon itself. So if you go below, we have another component called icon that internally has icon called fa-. Now we will go and inspect how that icon component looks like. So now I'm just highlighting the plus icon. So there is this icon component. And in the property section, you could see there is a name attached to it. So if you remember in the previous slide, so we have an icon here, we have provided a name to it. So this is a property, right? So the same property is reflected here as well. So now what the way we think this can be make use of these information to find this element. So rather than relying on the pure normal expertise as a way, can we somehow make use of these information and we try to find the elements from the array. So that's the key idea behind the React web drivers. So now let's see what this React web driver does and what it is. So it is not alternative to a Chrome driver or Firefox driver, rather than it is going to be a simple utility library. That can be used along with our existing drivers and make life easy with the capabilities it's going to provide. And it is currently only available for Java, but we are also working on releasing it for other Selenium writings as well. So just look for the GitHub repo to get updated with the latest releases and all. And the final thing is that it is completely open sourced and it is free for use in any project or any companies. So that's the main things we wanted to share. So now we saw what it is, how to use it. So it's very straightforward. So this is the repository. So it has complete documentation which you can refer to. And this can be easily plugged into any of the existing automation frameworks. So in case if you're going to use Maven, just add this as a dependency. And in case of Gradle, just add it to your build.gradle file. And this will input the library for you. So I have already set up a sample automation project with the library already added. And I have done some very basic setup, right? So you're opening a Chrome driver and creating some instances. So I also have the sample, the JS-based application. So we just send us some user information, like our name, email, the agenda. So if it's going to be admin user, a small batch will be shown. And what country this user is from. A very, very simple and straightforward application. Now let's inspect and see how this application looks like. So now if someone wants you to automate this, so first thing we will do is like, we will go and inspect the UI stack, right? Okay, so we have a card element here. So this is going to be the card element. So let's see how the user name looks like. Okay, so user name has some meaningful value in its class name. We could use some expert to find a class that contains username and we could find username. This is fine. Let's see how we can go with the email ID. So this is just a div and there is another div. There is no meaningful class name attached to it, no ID, but it has an email to it. Okay, so how about these icons? So again, it is a div. It has a bunch of divs to it. A simple SVG, no additional information. Same for other also, no information. And it's same here, but it's just a span. But even though if it's going to be a span, like we don't know what icon it is, right? So for India also, the icon is going to be the same. The properties are the same. And for US also, it's going to be a span, the same role, same class name, same styles. So how are we going to differentiate it, right? So to find these elements, so React WebDriver provides a new locator type called bi-react component. So we already know that Selenium has its own inbuilt, like locators, like ID, class name, CSS, right? So using this React WebDriver, it exposes a new locator called bi-react component. You can find a component by its name. So this is just a plain name, right? So for example, we used a component called counter. You're just passing the component name. And if you use it with find element, it will return the first counter. And if you use it with find elements, it will return all the elements that has a counter to it. If not, if you want to further filter out this counter, okay, we could do it. How? I need to find a component with counter that has a props called maximum value and it has a value as 100. So let's say I have 10 counter values that has been rendered on the same page, but I'm only interested with the counter whose maximum value is 100. Same applicable for state. So I want to find a counter, but the count should be 10 on it. I'm only interested on the counter with the value 10 assigned to it. Or else you could mix all these things into a single locator. I want a counter that has a maximum value of 100 and its count should be 10. So using this, like you could find any React components on the webpage, you know, so just with a single thing. And also it is relatively fast because this rather than finding the element in the original DOM, it will go get the virtual DOM object from the React, parses it and from the virtual DOM, it will identify the respective DOM from the node itself. So let's now see these things in a quick action. So as I said, like I have this demo project already set up and you don't have to do any initialization. So it will just open the application. Now what we could do is let's try and find how many user cards, how many users are displayed in the page. So to do that, we need to find what is the component name of the card itself. So now let's go through this and let's inspect the card. And if you come to the components, so it has this, so we have a component called user card here. So if you check it, user card, it holds a property called user and it has some additional information, whether it is admin or not, what's the country, email ID, gender, so all this information are here. So let's use this component name and let's try to find out how many user cards are there. So let's do all users. Let's do find elements and instead of using the default locators, we will just go with byreact.component and we will just say component name and we will just talk to it. So there should be 10 users. Okay, this is good. Now let's, what we want to do is let's try to grab the email ID of each user. Okay, how we could do is again like let's go here and inspect. So let's inspect this element. Let's go to this components tab. So we could see there is a component called email. So let's make use of it. So list of again the element, email. So component of email. Now let's do, let's print it out all the text of the email elements. Okay, so we just got all the email elements. Okay, this is good. So we could get all the email IDs and all the users, right? But the use cases, I want to get the email ID of the first user. So I need to validate it in that way. That is also possible. So we could change the locators as well. So let's take all users and I'm only interested in getting the email of the first user. So let's get the first user. Again, let's do a final element. Let's use the same component and let's do the text. So we don't need this. So we got this email ID. Let's go and check if that is correct. Okay. The first user's email ID is this. Cool. So now what let's do is, let's try to filter out these users. So rather than getting all the users, I'm just interested in the admin users alone. So if you check the DOM, so admin users will be denoted by this badge icon. And if you check the user properties here in the user card, so it has a user, and we have a value called admin as true. So let's filter only the admin users. So here we have all users. Now let's go users. We'll say driver dot find elements. The component. And the component name is user card. But I was only interested in the user card with a property called admin proof. So just add a property called props. And the property is going to be user. And under the user, I'm just only interested in the key called admin. And the value should be true. So now let's print out all user size. And what is the count of all users? So I'm going to copy it. So since user itself is a JSON property or to that particular component, so the property should also be in a JSON format. So I guess we should pass it this way then. So our property called user, yeah, this should be the property tax. So if you see here, so we have like 10 users, all of them, we are having three admin users. So same way, you could just filter out the users with a country India or you could specifically gender and so let's go with gender and do a window. So we are still working on like improvising the way how we will pass in all these filters. So currently we just made keep it as a very simple string, but these things will be improvised where like you could pass in as a JSON object therapy or a map with key value pass. So those things will be improved in future versions. So now what you can see is like we have 10 users out of it. We have four main users. So you could like apply any values here, right? Based on the properties available, you can just filter it out based on that. So this is the first thing. The next is, so we want to validate whether this admin batch is displayed for admin users or not. How we could do that? So let's inspect it. In the DOM, no unique information that is there to check whether this is present or not. So let's again make use of the scope here. So just a plain SVG element. Let's go to the component. Now I can see there is an icon. So there is a component called admin batch. So that simply tells it whether this admin batch is available or not. So let's take this component name. So I have all the admin users, right? So we could do the users.stream for each admin. What I need to do. Admin.findElement by.byReact.component. The component should be admin batch. It is displayed or not. It's to a simplest. So we cannot locate an admin batch. Okay. So we have changed it to mail, right? So we should change it back to admin. So we can search for mail. So there are like a few mails who are not admin, right? So for those things, like we will get element.findException. So for admin users, it should be true. So we want this. Cool. So we have true for all the admin users. This is very simple, right? So and also the chances of these component names changing is very minimal, you know? So no one just goes and say, hey, I don't want this to be a user card. I want to change it to user fancy card. That's not going to happen. Even if that's going to happen. So we have a support for well card finding, you know? So rather than giving the component name entirely, you can just search with some wild card characters like this. Let's also see example of that. So let me first pull up the source code. Okay. So here it is the component name called user card. So what I'm going to change it is like, I will change it to new user card. Now if I refresh and go to the new row. So now if you check the name of the component has changed to new user card. So for this scenarios, what you could simply do was just add a star and then perfect. So it matches a user card. And it just ignores what are the previous value test. So let's do it for the same name. And that's it. No, any additional changes required. Same result with very minimal change, right? So this is as far as identifying the elements. It also has another capability. What that capability is. I don't want to use this by the component. So I will just use a normal locator that is being provided with Selenium. It's okay. But what I'm interested is I want to get the properties and state of the element some way. So let's say I have a user. I want to find the idea of this user, but the idea is not displayed in the UI. Or what else? Is there any other information that is not in the UI? But it is there in the properties or state. I want to extract it. So for example, whenever we click on any of the user, it has the internal state called selected. Okay. So if we go here, let's select someone. We can inspect here. So we have a user card. And if you go to the state, there is a state called selected. I want to check whether element is selected or not. Or I want to get the idea of this user, what country this user belongs to. See, in case of website, it is not displayed in the UI. But I am interested in finding what the user's website is. So that is where this React web driver comes with another functionality where it is displayed. So first I have created an instance of this React web driver just passing in the driver object. And now what I can do is, so I will find all the users. And for all users, I will just like loop through it. And I will try to get the properties of this user. How am I going to get? I will do this dot React web driver. And I want to get a React component for the found web element. I will just pass in the web element. And I will say, get its property. See, it will just pull in all this information, whether the user is admin, country, image, agenda, everything. What if I don't want all this information? I just interested in getting the, maybe website. I could just pass in here, I just want the props user dot website. Cool. It just returns the, all the website family. So this is for property. But what if I want to get the state? So let's do all users dot, get of zero dot click. So that the first and second users state will become selected to true. Now, instead of getting the prop, let's try to get the state. So you just click on the first element. Okay. So still it is showing first. Okay. Let's try to do this. Something I made yesterday broken. So basically like how we've got the props, right? The same way, you could also able to get the state from these elements. So this user is a generic web element. This is not something which we found using a React component. You can also use any locator here. So you could say, hey, if I find all the locators by CSS, and you could pass the same element to this information, to this component, and it will return all the state and properties of this. So yeah. So this is pretty much which I wanted to showcase it to the community. And I hope like you all can start using it. And I agreed like still there are like few improvements that needs to be done, but we're actually working on it and we will be publishing new versions and new bindings for other programming languages as well. So just start using it. And in case if you face any issues, like just feel free to create a new one in the GitHub and you will be fixing it as soon as possible. So yeah. That being said, like I just opened the ties for the, any questions and answers that needs to come in. Okay. The first question is from Anna. So this work for a react-based application as well. It's like, so I haven't like explored in those friends, like we just like tested it with the basic React apps and it works well. We will also try to evaluate that and like, we will like keep you posted on that. So yeah, the same similar question, like can we use this with the APM as well? So if you're, if you want to test it, the web-based application in the views, then this will definitely work. So yeah, for APM web-based applications. Will this work with React elements inside a Shadow DOM? Okay. So this has nothing to do anything with the Shadow DOM. So like, in case if you're going to use Selenium, like you need to switch the context and then if you start locating it, it should work. So Shadow DOM is something similar to how the iPhone works, right? So it has nothing specific to do with the Shadow DOM. Okay. That's all the questions we have. So thanks Darshan for joining and sharing with your experience with us today. Okay. Thanks a lot for being a great host.