 Welcome everybody to the session doing wonders with a web driver by Satashan, we are glad they could join us today without any further delay. Over to you Satashan. Thanks a lot for the awesome introduction. So before going into the session I would really like to thank the people who really wanted to attend this session. So considering Saturday evening instead of spending time with the loud ones, you guys planned to attend this session so it's really great and I'm really thankful for you guys. So the session which today I'm going to host us are doing wonders with a web driver. By seeing the title you may all wonder like what's the wonder that's going to delay with the web driver, right? So the main reason why I chose this topic is like so currently if you see like a lot of automation tools are getting introduced and people now start showing interest to learn these tools. But the problem is that like the fundamentals of understanding what the tool list and what purpose the tool going to store, right? So if you take any fresher who recently started working with any automation tool, the first thing they think is like these automation tools are only meant for testing but that's not true, right? So to understand the tool, we first understand what problem it's going to solve. Later we should try to learn other aspects of the tool, right? So to get a better understanding and to try to teach the freshers like how the tool can be fictionally used, I came up with some of the fun things which can be done using a web driver and I will be showcasing those demos in this upcoming session. So without further ado, I will start the session. So this is the code that if you open the Selenium home page, this will be the first thing you will see. And for me, this is so true that Selenium automated browser. That's it. What you do with the power ended up to you. So this is so true, right? So Selenium has nothing specific to do with testing. So it's just a tool that automates the browser. So what we are going to do with this tool is completely subjective for the user who is going to use it. So, yeah. So hi. So I'm Suleshan Selvaraj. I'm currently working as a SDAT at Jumio in Bangalore. So I have around 8 years of experience in automation and I'm so passionate about learning new automation tools, technology and love building frameworks around the tools. So if you have any questions or something, you can reach me through LinkedIn or through my GitHub. These are my handles. So yeah. Okay. The first thing which I would like to showcase is like, I think like, at least once in your lifetime, you might have played this game in Google Chrome when the internet is down, right? So like during the pandemic time when I was very active in LinkedIn, I saw a lot of posts around several engineers trying to play this game automatically using some AML or using Arduino and all. So then later I got a thought. So like this game is running inside a browser and Selenium can automate the browser. So why not we use Selenium to automate the game. So I got very interested to automate this and I came up with a simple like around handle line solution to automate this game purely using Selenium. So I will quickly show a demo of it. So for this I use Selenium with Java and just the Chrome browser, nothing else, no fancy library or anything. So let me run this program for you. So you may all think I might be playing. So it's not the script is automatically playing the game now. So like still the algorithm needs to be like hard coded because as the game progresses, the speed of the like dynamo will already get increased. So it's kind of like a simple mathematical calculation on like determining when the jump needs to be made. So I will not dig much deep inside the technical aspect, but I can like give you an overview on how I actually automated it. So before that I will go ahead and put my internet in offline. Okay, so this is the page we are trying to automate here. So if you inspect it, all you will get is a simple canvas element Okay, so this is the canvas element inside which the game is completely rendered. So there is no way we can inspect the individual elements like this dyno or whatever the obstacle is going up. So we need some other way to determine where the dyno is, where the obstacle is, what's the game speed everything right. So to get this, if you open the console and if you type for this run now, you will get a function like this. And there is another object called instance, which holds the complete context of the game here. So if you inspect here, you can see so like instance.obstacles. So this will give the list of obstacles as the game progresses. Okay, so you will get all the information like what is the position, what type of obstacle it is, same applicable for the dyno as well. So this object holds where the dyno's position is, what's the game speed, so all this information will be obtained from the DRets. So now it's just a matter of having a while loop and keep on determining what's the question of this dyno and what's the question of the obstacle and calculating the optimal distance and just with this spacebar. So that's a very simple thing which we need to do to automate this game. So I will just include the source code as part of the presentation and you can also give it a try and you can optimize it so that we can reach like a high score right. So this is one thing which I wanted to share with you all. So going next, so this is another project which I did which I did to like play songs using online piano. So since childhood days I was like very fond to music and I wanted to learn music but unfortunately I couldn't able to. But recently when I try to like play this online piano I tried really hard and I couldn't able to succeed. Then I really got an idea like why not I should like automate this piano using Selenium and I written like a simple script again this is going to be around like 100 line script just to play a few songs in the online piano. So I will again show a demo. So if you can you can guess what song I'm going to play. So for this again I'm using Java with Selenium here. So this is going to be song number two. So next is going to be song number three. So yeah, so I hope you all can guess the second and third song, right? Okay, the second one is the Game of Thrones theme and the last one is the coffee dance like the meme that got like really famous during the COVID time. So that's the third song. So coming to the next project. So this is also like another project which I did to solve online that based Rubik's Cube. So the algorithm it's like we use a different library which will give us the like list of steps to solve the Rubik's Cube that's something which I haven't done. So the code part which is like how are we going to like automate the UI like because this is one of the complex HTML structure I have seen in my entire career. So I wanted to really automate this so like I took it upon a challenge and I completed it. I will also quickly show a demo of it. So I have done this using Node.js and Selenium in JavaScript. So initially like the website has the shuffle functionality. So it will just randomly shuffle the Cube. So once the shuffle is complete like we will pre-solving the cube using the script. So now the shuffling has been completed. So you can also see the steps like what we are performing. Like it will take like 5-1 minutes. So I will like stop it because it will take a long time. So this is like kind of a demonstration how we need to handle the HTML elements. So if you take this, like I would like you all to like go to the site and try to see how the HTML is structured and try to write a simple script just to move a row or column because this is like kind of a complex thing to automate. So with just the HTML you cannot automate this. You also need some information from this cube object. So this tells like which cube is facing forward and what are the colors, how you need to switch. So all this information is available in this cube object. So with this information you all can also try to automate this as well. So I will again share the source code in my PowerPoint presentation. You all can take a look. So the next thing would be so SpaceX docked the simulator. So like recently like last year I guess the SpaceX has launched a new capsule which has a HTML and CSS based user interface which is used to dock the capsule to the ISS simulator. So this is the site which Spaces has recently launched to see how the interface looks and user can like actually try it out and they can dock the shuttle to the space station. So even if you try it manually it's really hard for you to manually dock it because there are like lot of things to be considered simultaneously to achieve this. So as you can see now I am like performing some action but if you don't perform any action it will automatically move its position because there is no gravity in space right. So I tried to automate considering all the different aspects and finally I was able to successfully dock it with the international space station. So this is kind of a very long script and it took around like 10 to 15 minutes for the automation to get completed. So I cannot be able to show a complete demo but I can like quickly run you through a video which I have already recorded. So everything is happening through the script. So this is also one of the complex of a page to be automated. So I recommend you all to give it a try and see like if you are able to automate this. So this is one of the projects which I wanted to show all. So moving on to next handling HTML canvas is one of the toughest challenges in automation. So especially like there are some applications where you want to validate the signatures which is written in the HTML canvas right. So like I wanted to come up with a solution where like let's say have a signature as an image file. Why not use that image file and draw the same signature in the canvas using the HTML. So with that in that I created a simple library which uses Serenium to read an image and using that image and draw it in the HTML canvas. So for that also like I don't have the setup currently in my machine but I can show you a quick demo. So this is the one here. So what we're going to do here is so we're going to try to draw the same image, the same image isn't like without the colors just the outline on to HTML canvas. So this is a web page which has a canvas and has the ability to draw. So the entire sketching thing is purely done using Serenium's action class. So no fancy libraries. So this is going to be how the output is going to look. So the underlying algorithm here is like so for any given image we will convert that image and find the outline using some ML algorithm. So from this outline we can easily find out where are the white pixels resides and based on the white pixels part we were just using the action class and we will plot the dots in the HTML canvas. So that's the underlying technique which I have followed. So that's one thing. Okay so moving now like we have seen some of the cool projects using WebDriver. WebDriver is already great but still there are like a few gaps which WebDriver currently doesn't support. So to fill those gaps like I have also written a few libraries to overcome those limitations and make WebDriver great again. So that's the thing which we are going to see in this upcoming session. So the first library which I would like to introduce is called a SpyDriver. So if you all attended the previous sessions about APM plugins you might have got an idea like how the plugin works and what are all the APM plugin functionalities. So one of the key functionalities of the APM plugin is like you can able to modify the existing behavior of a method. So in case like there is a find element method you have the ability to modify the functionality of the find element. Either perform something before the find element method is called or perform something after the find element method is called. So currently WebDriver lacks this functionality. I will not say lack because we already have a class called even driven WebDriver. But if you are going to use the even driven WebDriver you cannot typecast it to the original base WebDriver. Let's say you are going to create WebDriver for a Chrome driver. You cannot typecast back into Chrome driver when you use the even driven WebDriver. So what I did is like I created a new utility called SpyDriver. You can register a listener and listen for all the method calls made on a WebDriver element. So if you are going to let's say you got called a method called driver.get you can perform certain action before the driver.get execute and perform certain action after the driver.get method has been executed. So I can like walk you through some examples and real time use cases. Okay. So first let's consider a simple automation script. What this script will do is it will just open the Selenium home page and it will move to the download section and it will just find the latest version and it will print it out. So now I will just run this function. Okay. So if I print it out, read out one dot one for one dot finite. So this is how the normal test would look like. But now what I wanted is like I wanted to log all the action that has been performed in the same test. Okay. So if I want to log actions currently so for each and every method I have to go and I have to say okay logger.log navigated to home page. Again for each and every step I have to go and add a log step. So instead of doing it what we can do is like we can use this leverage the functionality of the SpyDriver. So it's very simple. We just create a SpyDriver for whatever web driver we're going to create. So in this case we can use Chrome driver. But this supports all web driver. You can use SpyDriver or remote web driver, whatever web driver you want you can use it. After that you want to add a listener. So listener is something which the SpyDriver will use to notify us. So whenever some event happens on this driver object this listener will be called using the SpyDriver. So I will explain about this listener later. So once this listener has been registered we want to obtain this SpyDriver because this driver will be spied with the SpyDriver and it will create proxy object. So using which we are going to continue our automation now. So now I will quickly run this and I will show how the logs will be printed. So this is the same code which I have executed before. I haven't modified anything else. So if you can see, now you can tell right. So before driver.it is called with the parameter this. So before driver.findElement is called with byLinkTest as the parameter downloads. So after that we are clicking on the element with LinkTest downloads and we are finding an element with some x path and we are getting the text of that particular element and we are printing. So this is how the logs are generated. Now I will show how the logic for printing the logs is written. So this is a listener class which implements the SpyDriver listener. So there is an interface which defines what are all the callback methods that is supported by the SpyDriver. There are like two different types of events. One is for driver events and one other is for element events. So all method calls that happens on a web driver will be called for driver command executor and all actions that are executed on an element will be received by the element command executor. So there are two aspects there. Before driver command executed and after driver command executor. So this is before executing any command on the driver this method will be called and after the command has been executed you can use this callback to perform the action here. So this is kind of a simple use case where you will be adding the logs. But using this library you can use like a lot more functionality to an existing automation test. So there are like few other things which I have created using this library which I will show in the next slides. So this is SpyDriver. So the next one is VAL-XSR. So currently if you use a Selenium for your automation test, so mocking the API request is one of the toughest job to do now. So if you want to mock any API request in the browser either you have to go for any like proxies like browser mob or something like that to mock the API response. But the problem is like if the setup is going to be in local it's okay it's very simple we just create a proxy attaching it to the driver and we will be executing it. But if you want to execute in like a distributed system or if you want to execute the test in some remote environment or using browser stuff or something the setup is kind of like a pain here. So to overcome those things I have created again a simple utility it's very lightweight it doesn't use any proxies internally to mock any API request or response and to get all API logs. So there is some scenarios where like you also need to capture the API request made by the browser for better debugging. Sometimes during automation script there might be some APIs that may be randomly failing and it will be really hard for us to debug it. So using VAL-XSR you will be able to completely get the list of API calls made by the browser along with its request body, response body, headers, everything. So I will just quickly show a demo of this as well. So for that I have a sample application ready for testing here. So initially like when you load this application we have two different tables. One is for users and another one is for posts. So both the... I will refresh it again. So if you see the data is getting loaded from these both endpoints. The one is for users and you will get list of different users and one is for posts, for different posts. So let's say if it's going to be a static list it is very easy you will just like hard code the data whatever going to come from the back end and you will just validate it. But if it's going to be different data you don't have to always like try to get the latest data. Because for testing the UI you just need some mock data. If you want to test this table all you need is like some mock data to be populated here. So using VAL-XSR now I will like show a demo how that table entries can be mocked here. Okay. So first what we don't need to do is like same like how we created object for a SpyDriver. We will create a new object for VAL-XSR and we will just pass whatever the driver we are going to use. So again you can use any web driver like Firefox or like Safari or remote web driver whatever the web driver you are going to use. You just need to pass to it. And from the VAL-XSR you will get the mock driver. So using this driver we are going to like perform all our operations in the test here. So again this is kind of a simple page object we are going to the login page Okay. Okay it's here. So you got a driver object here. So this is just a simple page object you will just pass the whatever driver you got to here. Now what I have done is I have already stored the list of dummy users to this JSON file which is present under the resources folder you see. Like I just like replaced it with my name for all the 10 entries there. Now if we go to on small test okay. So what we are going to do is we are going to read the JSON file and we are going to store that result as a list of user object here. And now we need to add a mock. So adding a mock is as simple as like this. So VAL-XSR.mock you need to add a mock here. So whenever an API call is made for the same point when a get call is made to the same point you need to have a mock response with this body. That's it. We don't have to do any other configuration. So whenever a get call made to the same point just respond it with this mock body here. So that's it. Now you go to the URL you go to the dashboard and you see that the name should be displayed at the version. Let's quickly run this example. Okay. So now we can see. So if I go to dashboard still see solution I will go to a different page and I will come back to users. Still you will see the mock response here. So not just walking you can like now currently we have just mocked the body right. Similarly you can also mock status code. So if you see this methods you can like update the body. So let's say if there are scenarios where like you want to check whether the load indicator for any API call is displayed or not. So sometimes the API response might be very soon. So to test the loading functionality you want to delay the response of the API right. So you can add a delay here. So let's say whenever the user's API is made delay it by let's say 30 seconds. So if we run this so see because the user's API call is not fulfilled for 30 seconds right. That's why you're seeing this loading indicator. So even if you go to post and come back it will still load because we have made that API to respond only after 30 seconds. So like there are a lot other things you can do with this. So not just the response you can also mock the request body. So let's say previously we saw how to mock a response body. Similarly we can also mock whenever a request is made you can also update the request body itself. So here in this example what we can do is whenever a post request is made we can update the body. So let's say in the way you enter a valid username and password you can forcefully update the username and password while making the API call. So this way you can easily test a lot of negative scenarios or like error scenarios. So sometimes your application will behave differently when the API error happens right. So you can easily mock those scenarios using this library. So one other thing is like you can also get all the logs made from the application right. So for that you can simply use log. So get accessor logs. So this will return a list of accessor logs. So from that accessor log you can get all this information like at what time the API call has been initiated and when the API call gets completed complete request information. What method it is what is the URL, what is the request body what are all the headers it has and if you take the response you can get what is the response status and what is the URL, what is the headers and what is the response body. So you will get all this information. So this is also one thing which you can achieve using the Vavaxas here. So yeah that sits for the Vavaxas here. The one other thing is like I wanted to really share with communities like this auto weight plugin. So if you take any modern JavaScript based automation tools the first thing which they are telling is like under Selenium our tool is going to automatically wait for all the development commands. So you don't have to explicitly manage the development weights right. So somehow I wanted to overcome the limitations which Selenium has. That is like automatically wait for an element before performing an interaction eliminating the use of weights. So this weight plugin is really handy when you wanted to write a quick automation script considering you don't want to add any weight statements. So I will also show a quick demo of it. So here let's take a scenario where like I wanted to go to Amazon search for a one plus and I wanted to click the first search link and I need to add the card button and I need to go to the card page. So this is what I wanted to automate. But typically if you are using if you have ever used Selenium before you know that this won't work right because definitely there will be some delay before each and every action. So after entering the search term there will be some delay for the results to be up here. So you need to add some certain weight statements. So this is how the original test looks. So if you use Selenium so you need to wait for the search box you need to wait for the search results and then you need to wait for each every element to click right. So what I have done is it's a very simple plugin so it's called Selenium weight plugin. So what you will do is like you create a Selenium weight plugin and you can pass any driver here. So again it is going to be Chrome driver or Firefox driver whatever driver it is going to be and it requires some options what are all the important options like default waiting. So how long does it automatically wait for an element. So here I will have given 30 seconds so you can ignore these parameters for now. So we have told the plugin to wait for 30 seconds before each element interaction is performed right. So now I'm getting the driver and I'm not at all adding any weight statements there. What are I going to do? I can just simply run the test and it will work. Navigated to wwwm was on in type value 1 a plus sorry for that. I was just doing some experiment and I forgot to do so see that it's got passed. I haven't added any single weight statement so now let's see what happens for the same test if I remove that weight plugin. I will just remove everything and I will just give a normal driver and let's see what happens. So see it got failed because because you cannot able to find this button here because the test didn't wait for this button to appear. So this is really very handy if you want to write a quick simple Selenium automation script without spending much time on adding those unnecessary weight statements. So this also has a lot of other features as well. So let's say if you are using any page object model and you don't want this plugin to wait for certain methods, certain steps under that specific page object method, you can use this ignore weight function so this annotation so what this ignore weight annotation will do is like, so whenever a test is getting run, this particular plugin will check whether that particular web driver command is running under ignore weight annotation. If ignore weight annotation is present it will just not wait for any interaction it will just pass the control over to the Selenium itself. If the ignore weight annotation is not present, then it will wait for each and every interaction before making any interaction on the development. So that's one functionality which this library can offer you. So again this is open source, I have given the link for this report in my power point as well. So you guys can it's kind of in very early stage because only very few are using in my current organization, so you all can give it a try and report any issues so that we can make this plugin even more stable and the community can use it right. So having said that, I have came to the end of this session now so thanks a lot for patiently listening my entire presentation and being here. Yeah, I will now hand over to the moderators. Yeah. There are three questions. Okay. What is the key difference between WebDriver EventListener and SpyDriver since WebDriver EventListener also has capabilities of printing before and after logs without adding manual logs. Okay, so one of the main key difference is like so WebDriver EventListener it's kind of individual class so unless like let's say if you take a Chrome driver Chrome driver implements like extents or remote WebDriver and it implements the WebDriver interface so that typecasting can be done so even if you go on to type like downcast to WebDriver you can do it. Again you can downcast to Chrome driver that is possible but if you are going to create WebDriver EventListener you cannot typecast it back to Chrome driver or you cannot typecast it back to remote WebDriver but in case of SpyDriver that is possible so you create an object for Chrome driver you can cast it to any object that Chrome driver has right so you can cast it back to remote WebDriver and call any methods that is available in the remote WebDriver but in case of WebDriver EventListener you cannot cast it back to remote WebDriver or something or the other so that's the key difference between the SpyDriver and the remote WebDriver. The next question is will HXR work for HTTPS? Yeah it will work for both HTTPS and HTTPS as well Okay and can we iterate, ignore, wait with new kumbh? Yeah it works so it's a normal Java annotation you just need to annotate, ignore, wait for any Java methods and it should work it doesn't matter whether you use kumbh or test engine or any test framework The next question is can we wonderful to see SpyDriver and autowheat plugins can we extend them to use for mobile drivers as well? Yeah currently SpyDriver do have support for APM as well but still it's not completely tested so if you can use it and if you can provide a suggestion I'm happy to help you and the last question is any plugins for Shadow DOM element in future? I haven't had any plans for that but if there is a necessity then we can surely work on it Okay so your answer Q&A session Thank you so much Sudarshan Bye, thanks all