 So, welcome everyone to this workshop which is Builder Responsive TypeScript WDIO Framework by Varuna Srivastav and Vim Sillis. We are glad they can join us today and this particular workshop is sponsored by Saucelabs so we would like to thank Saucelabs for that and without further delay over to you Vim and Varuna. Thanks Shrita. Hi all. Hope you all are doing well. So, I am Varuna Srivastav. I have been a Lead Quality Analyst at ThoughtWorks. So, today in this 90 minute session you would see how we are going to build a responsive web driver IO or framework using our TypeScript. End of 90 minutes you would have your own framework, a basic structure of an end-to-end test framework with a TypeScript and web driver IO. So, before we go and deep dive into the session, may I have a quick thumbs up of how many four of you folks have worked on JavaScript before. Cool. So, you would see why are we moving from JavaScript to TypeScript or what had helped us using a TypeScript. Over to you Vim. Okay. Well, yeah, my name is Vim Sillis. I'm a senior solution to our detected Saucelabs and let me just start by going to the agenda about what we're going to discuss today. Like you already saw in the introduction slide, we're going to build our own automation framework with TypeScript and web drive IO. But to build it, we first want to start with exploring a bit more of the dependencies that are needed to build that framework. And we will start with the basics and then from the basics in the end go to web drive IO TypeScript and then we will provide you the demonstration for this workshop. But basically to start, we need to know our environment. And in this case, we're going to start with Node.js. Node.js is kind of like the environment we're going to use to run all our test cases on. So, Node.js, let me first take a look at it, what it's not. And this is kind of like something that we see a lot if we ask people and ask them, okay, what is Node.js? Nine out of 10 times people say it's a programming language and no, it's not. It's not a programming language. Basically, you use JavaScript together with Node.js to do something. What is Node.js then? Well, Node.js, as you can see here, is an open source cross-platform runtime environment for JavaScript outside of your browser based on Chrome's V8 engine. And basically it gives you more opportunities to work, for example, with the file system on your machine or on your CI pipeline. It gives you the options to work with the network, with the operating system. There are a lot of core modules and you can find them also in the documentation that will help you develop the stuff that you want to do. It's not only for testing, there's much more that you can do with Node.js. And just to give you a brief history also about Node.js, it was founded also in 2019. It introduced a lot of innovating thinking and approaches for using a JavaScript service site development because normally, JavaScript is only available for your browser. But with Node.js, you've got that runtime environment to also run JavaScript outside of your browser. And to do that, browsers got better and better from 2009. And then the V8 engine from Chrome came. And that's a very, very powerful engine. And that engine is used within Node.js. And if we would then look also at how it evolved then in 2010, they developed Express, basically giving you the opportunity to host a simple website with a web server on your machine. 2011, sorry, MPM1 was released. And I will dive a little bit later into what MPM is. And you can also see it kind of like the large companies like LinkedIn, Uber, they started adopting Node.js. Between 2012 and 2014, we got a lot of improvements. And in 2015, we saw that the Node.js Foundation was born. They supported the latest versions of JavaScript. They gave the possibility to create private modules. I will also dive into that later on. And like the competitor of MPM, package manager, which was called Yarn was also born. It was created by Facebook and some other companies. And basically what it also provided was a way to have the same packages of a module on the same versions between all developers. And I will dive into that later on. And last but not least, from 2016 till now, it evolved enormously. It went really sky high. Why? Well, basically with Node.js, you can do whatever you want. You can build APIs with it, for example. But you can also build very complex websites. And you might know all these logos like React or Angular or Vue. Node.js gives you the opportunity to do all those complex stuff. But it's not only for websites. You can even create mobile applications with JavaScript together with Node.js. Take, for example, a product which is called Ionic or React Native, giving you the opportunity to use JavaScript and to build a hybrid application or even a native application. Basically, it compiles to native SDKs. And last but not least, we can even build desktop applications. For people who know Appium, they also might know Appium desktop. Appium desktop was built with Electron. And Electron is also based on Chromium, using Node.js, using JavaScript, and being able to build something which you can use on OS X, on your Macs. You can use it on Linux or even on your Windows machine. But building all these things with JavaScript also means that you need to test it and preferably with JavaScript. And before we dive into the details about JavaScript, let's first take a look at the biggest difference between Java and JavaScript. Well, one of the biggest things, and I think this is really obvious, is the syntax. And with the syntax, I mean the way you write code, not only if you build an API, but also if you need to write something, some test cases. There's also a difference in the way everything is typed. Java is strongly typed language, so if you have a variable, it should be declared first before using it. But with JavaScript, you can just declare it whatever location in your page that they're used. But there's also a difference here. And this is something that also for Runa, I will mention when we're talking about TypeScript, but keep this in the back of your mind. Before you need to use Java, you need to compile it. You will get some errors if something went wrong and you cannot use it. But with JavaScript, it's client-side interpreted. You just run it and it will break at the line where you have your wrong code. So that's also a difference. But with also a very important difference is synchronous versus asynchronous behavior. And this is very important, this is a very important principle to understand. So let's dive a little bit more into that. If we have synchronous behavior, then we're talking about handle one blocking request in a single thread. And let me try to explain this with a simple example. If he would go to a restaurant and hopefully during the current pandemic, you have the opportunity sometimes to do it, but let's go to a restaurant where we have a waiter. We're sitting at table one and that waiter will go to our table. He will ask and he will take our order. And when we're talking about a synchronous process, he will go to the kitchen, he will give his order or our order to the chef. The chef will prepare the meal, but the waiter will still wait until the chef is done. When he's done, he will get back to my table. And then he will go back to, for example, a witness table. So she needs to wait before I get my food. This is basically how it works in a synchronous world. And I will also show you later on with a code example. Then we also have the asynchronous world. And this is basically how JavaScript and also Node.js work. They can handle multiple non-blocking requests on a single threat. So let's get back to a restaurant. This is a different restaurant. Again, I'm sitting at table one, Karuna at table two. The waiter is coming to me. He takes my order. He goes to the kitchen, but because this is asynchronous, the chef can already prepare the meal and the waiter can now also ask what Karuna wants to eat. And in this case, we can eat maybe even at the same time. So if we now look at that, you might also have heard of promises. And this is something which you will see in the asynchronous world. And promise is an object, as you can read here, that can return three different states. It can return a state which is called pending. It can return a state which is called fulfilled. And it can return a state which is called rejected. And see this, as you are doing a call to an API, that API is retrieving data from the database. Sometimes you just need to wait. In that case, the asynchronous call will give you back the status pending. If you get an answer back, it will give you back the status fulfilled with the answer. And if it went wrong, you will get back the rejected status. So if we would look at asynchronous code, and if we would look at promises, I've got a code example here. And as you can see, we have a function. And that function will put something in the console, but it will wait the amount of time that we tell it to wait. In this case, we say for the first line, wait three seconds, then do the console log of the first line. The second line will be console log of the second line. Then the third, again, we have a wait, but this time only two seconds. And then we have a fourth line, and then we need to print it. In a synchronous world, it will print it like this. So if you would do this, for example, in Java, all lines will be executed after each other. But in an asynchronous world, you will have something like this. And just take a look at what's happening now. Because we will now print line two, line four, then line three, which was waiting for two seconds, and then we're printing line one. And this is how it works with asynchronous code. It will execute all the calls and will only resolve when the time is done, when they need to print the results. So if we go back also to asynchronous code and would also look at Java and also for testing, then you might have an example like this, where you would say retrieve some text from an element. And in Java, this is just synchronous. It will wait for the text, and when it has the text, it will give it back to you, and you can print it. But when we're talking about JavaScript, and in the Node.js world, and especially if we're using Selenium or Appium, we need to resolve our promise. In this case, we're using asynchronous code, we would say driver dot find element by ID, for example, then retrieve the text. And when we have the text, then we can log it. And there are multiple ways and also advantages for doing this, because you can also now retrieve all types, all text of multiple elements, put them in a promise all, as we call it. And it will just print the result when all promises are executed. So all executions will be done at the same time. And when the slowest one returns, it will print the results. To kind of like get back to the behavior of asynchronous world, the JavaScript world introduced something which was called async await. And with async await, you can tell a line of code to do a blocking stop, retrieve the result, and then being able to print it. With async await, you can create the same behavior almost as the synchronous world. So hopefully you now got an idea between what synchronous and asynchronous is, and also one of the biggest differences between, for example, Java, which is the synchronous world, and JavaScript, which is the asynchronous world. Now let's take a look at NPM. You might have heard of NPM. And to give you a little bit of an idea of what NPM can do, it can do three things. First of all, NPM is the website. You can go to the website, you can find multiple things there. And as you can see here already, you've got products, you've got pricing, documentation, community. And in one of the first slides, I mentioned that NPM provides packages, and it also provides private modules. If you pay for NPM, it's all open source, which you can use, but if you pay for it as an organization, you can host your private code on their side, your private packages, and then we'll go back to packages in a few seconds. The second thing of NPM is that it's a command line interface. As you can see here, if you downloaded Node.js, you will get NPM for free, and you can do all kinds of things in your terminal. And last but not least, this is kind of like the most important part that maybe a lot of people also know NPM about. It's a registry where you can store all your packages. So you now might be wondering, what is a package? Well, a package is basically a project or a collection of JavaScript files. And all those collections kind of like that package will be described in a package JSON. And you can see a package JSON here. And in the package JSON, you can find what a package can do. In this case, we're looking at multiple Cucumber HTML reporter. It's a reporter module for Cucumber output for Cucumber JSON files. And it uses some dependencies. Those are the dependencies that are needed if we want to use the module. And we have some dev dependencies, as we call it. And those are the modules that are needed to develop that application. So now that we know a little bit more about the road, WebDriver.io is driving on Node.js, NPM, and also the packages, let's take a look at WebDriver.io itself. So WebDriver.io is based on the WebDriver protocol. So what does that mean? Well, basically, the WebDriver protocol is this. It's a remote control interface that enables introspection and control of the user agents. Translated, it's an interface to control, for example, browser drivers. And basically, yeah, the agents can be any technology, but yeah, we're here at Selenium conference. So let's just take the drivers itself as an example. And if you take a closer look also to the protocol, you can also see a list of API endpoints. And this enables a certain action to be carried out in the browser, for example, navigating to a URL or clicking on a link, clicking on an item. And this is implemented in the so-called browser drivers. You've got Chrome driver, you've got Gecko driver, you've got Safari driver, all types of drivers. And if you would then go back, how does it work? Well, we've got an element we want to select. You can use Selenium or you can use WebDriver.io to communicate or with the driver or with Appium or through a Selenium grid that will communicate with the drivers and then you can interact with your browsers and your devices. Official W3 standard for browser automation has also some advantages. It enables also the automation of all browsers and ensures that every command does the same for every browser. There's also a small disadvantage, as we might know in contrast to tools like, for example, Cypress. Only those functions can be defined in a WebDriver protocol that really work in all browsers. And if you would look at tools like Cypress or Tescafe, they add extra stuff that currently the current version of Selenium cannot do. And here you also see Selenium and WebDriver.io mentioned. And just to mention the difference between them, they both use the same protocol. So that's basically equal. But Selenium, you need to build your own framework. And with WebDriver.io, you will get a complete framework. And this will bring us to some of the key features also of WebDriver.io. One of the things, and this is also what we're going to do during the workshop, it's very easy to set up. As you can see here, there's just a command line interface where you can kind of like say what you want to do, and it can start downloading everything for you, and you've got your project already set up. Then, like I mentioned before, in the Node.js environment, everything is async. But the beauty of WebDriver.io is that you can choose both modes. You can choose async, as you can see here, but you can also choose the synchronous mode. And then WebDriver.io will do everything automatically for you. So if you're now used to a Java framework and you need to use something in JavaScript, I think WebDriver.io will be the best way and the easiest way to transfer all your test cases to JavaScript, because it's just synchronous. You can just enable this. Then what's also very awesome of WebDriver.io. They are very easy to integrate with whatever package you can find. They've got a specific Apptium service, which will start the Apptium server automatically for you if you've downloaded it. It got a visual regression testing service and also reporters. And we're going to dive also into a lear reporter during this workshop. What's also awesome is they've got multi-remote. And if you would just go back to the basics of a automation framework, you would have your test, you would have a test file that will communicate with the browser, and then you will have a result. But they also have multi-remote. This is not the same as running something in parallel, but this is made for test cases who need to communicate with each other. In this case, we've got a test file. And in a test file, we, for example, have, let's say, we want to test WhatsApp and we want to communicate between each other in the same test case. Multi-remote can do that. Multi-remote can give you the option to communicate between Chrome, for example, and a device. They can communicate with each other and in the end it will succeed or will fail. That's the awesomeness of multi-remote. Also, if you want to know more about WebDriver.io, there are tons of online tutorials. So easy for you also or enough possibilities for you to learn how to use WebDriver.io. Secondly, what we also have is that we have a large online community. We have around 5,000 people in our Gitter channel. And in the Gitter channel, if you ask a question, not enough time, between 15 minutes you would have or a response or maybe even an answer. And then WebDriver.io, yeah, this is sponsored by Salelabs, but WebDriver.io itself is not sponsored by Salelabs. It's not owned by Salelabs. It's an open source project and it's available free of charge in GitHub and MPI. The project itself belongs to the OpenJS Foundation and this is a non-profit organization that takes care of the sustainability and development of large open source projects and support the projects in many areas. Take a look, for example, at Node.js, ESLint, Webpack and Express.js. They also belong to that OpenJS Foundation. But enough about this. How do you start it? How do you start with WebDriver.io? We're going to dive into that later on, but just to give you an overview, we've got three different tastes. We've got the very hot one where you need to do everything yourself. The bare metal mode, as we call it, we've got a medium one. The standalone, but the most used version is the test runner. The test runner will just give you a configuration file where you can adjust a few things and it will do everything for you. Start a driver, stop a driver. You can also choose from different frameworks. You can choose Maka, Jasmine or Cucumber. Like I said before, there are a lot of plugins and extensions and you can easily create it yourself. You can create your own reporter, you can create your own service. Also, the option to create custom commands. You would say if there's an action you do repeatedly in your framework, you can just attach it to the browser or the driver command. In this case, we have a delete user function and we can just create that once and reuse that function multiple times, so preventing double code. Also, you've got the option with different ways to select elements. As you can see here, you can do it based on CSS, on X path, on link text. A lot of options, even options to interact with react itself. We even got support for the Shadow DOM. Last but not least, we also have the option to interact with elements, native elements together with Appium. I think a lot of options where WebDriver.io can help you build up your framework. That's basically what we're going to do now. But before we dive into that, we're going to look into TypeScript. So Faruna, stage is yours. Yeah, thanks, Wim. Yeah, so what is TypeScript and what it is all about and why should we use it? It's a type superset of JavaScript that compiles to a JavaScript. So it's not a brand new programming language. It adds a new features to a JavaScript which makes your JavaScript code easier and more powerful. It's a strongly typed, object-oriented, compile-based language designed at Microsofts and it is both a language and a set of two. So if you would see this slide here, it's more on adding a static typing to a JavaScript. So once you have a type, you can build a great tool around it, like a statement completion, code navigation, refactoring becomes very easier. So if I have to save in one line, a TypeScript starts with JavaScript and ends with a JavaScript. It adopts the basic building blocks of your program from JavaScript. Hence, you will need to know a JavaScript to use a TypeScript. So if we go to the next one here, TypeScript gets converted to a JavaScript. So TypeScript compiler transpiles for .ts to .js. Then the question comes here, how could TypeScript build a new feature if it does compile to a JavaScript? It compiles to a JS for corons and in addition to this, as a name implies, TypeScript adds an important feature type. So as a developer, when I'm building something, I'm more leaning towards getting the error when I'm writing a code than the error when it comes and deployed. So the journey of TypeScript, it started all in. So maybe we could go to the next slide please. Yeah. So initially, people were hesitant of using a TypeScript. It's since the slowness of the compiler. But since 2014, we could see a lot of improvements in the build. And the current version which was just launched in August 2020, version 4.0. So there are great features in this version, but two of my favorite ones are short assignment operators. So you would have seen that A plus A equals to A plus B. But in TypeScript, you could have A plus equals to B. So it has also introduced a three new operators, it's and, or, and then a label or operator. The other one is that we have a significance to improvements in build using the command hyphen hyphen no. So if we compare a JavaScript with a TypeScript, there are multiple differences which we could see in the next slides. So JavaScript is prepared to use in our small coding projects. We may be able to go to the next one please. And TypeScript is an object oriented language, which makes the code more consistent. It is cleaner. It's more simpler. You could remove a duplicates. It is more reusable code in your large enterprise. So the three major differences which I have picked up is more based on what we are going to do during our workshop. So whether as a developer or as a QL, do you want to have an error at a compile time versus a runtime? We would see examples of whether how the strongly typed language helps us when we are writing a set of codes. If TypeScript does support a module's generate and interface, which we don't have a support in a JavaScript. So if you are coming from a Java word, it would be easy for you to go and start using a TypeScript. So as you could see here in this example, one of the methods is on the base test, a cert item added again is not there. And what TypeScript gives you an error, then and there itself. So I don't have to worry about once my code has been compiled. So this property does not exist in my type and I could just use few shortcuts come on and get this added if you want to add this property. The next one is more on the type. Like how static and how strong the type is. So if you see the right hand side, the first example ABC.js. So here the intent is more on I'm going to add a two number 999 and my intent is to get an output as 80. But since it's a JS, it's going to concatenate these two strings. So it's taking nine digit as a string. And even though 99 is a higher number, my intent was not to get a 99. So it's a technical error. It's and it's a logical mistake in a group. But if you see the next example, add.js, we do have a defined a tag over a number. So now here, if I give up nine as a string, I would get that error before itself calling the ad function. There also comes the feature like people keep asking, we could do some work around in JavaScript. Yes, you could mitigate this. Well, before calling an ad function, you could have a logic like if num is equals to integer, or if you could provide those. But those extra line of codes and adding it to a simple function, you could imagine when you have a bigger functions like that, how, how many extra lines of code you need to add it on top of it as a developer, as a QA, you need to write those unit tests, like whether nine and nine should give me an output as what I'm expecting as 18, not a 99. So to get rid of that, we do have a mitigation strategy here, and that's where the tag strip comes into a picture. The next one, the feature of type strip, what is is more on the interface. So as in Java, you have your set of interface, so you don't have your class function being overloaded. So if you could see in this example, a username and a password is my element. And on top of that, what operation I'm performing, I'm adding a logging information. And in a login page class, I'm just using those information and those constructives. So type strip also helps to make abstract your properties and methods in your interface. So how let's get started. How would we get started with this workshop? If you could clone, please this repository, and then get to clone the master branch of it, we do have a multiple branches as we go during a demo. So, and we will walk you through all all the steps during our evening, how you could get started. Only prerequisite is to get the node being installed in your machine. So if you want, you could get started now. The most important thing to know here about while we get started is a TS conflict. So what is TS conflict? It's a type script conflict file. It's a directory that indicates a root of JavaScript or a type script. So you could have a jsconfig.json also, and you could have a tsconfig.json too based on what you want to use it. So it starts with an overview of every flag and then moves to a root attribute in json, the compiler options. The two most important thing which I want to highlight here is the target, which is my at my script and the types. So you would see during a demo that we would have those types like nodes, web driver, are you seeing and what are the test framework you are using. So once you are running during a workshop, it will ask to define the types. The next one is more on the type inference which you should be aware of. So here mostly I have added a list of cities. It's more on the Indian cities with three letters, but here comes a question also that I could add a list to a city code also. No, whenever you are adding a list of elements to a city code, it would give you an error then and there only you could know that. So your type inference is the key here that even though those city codes are valid in your list, it will always accept your city name. So let's quickly get started. So we have divided a demo in the four parts. The very first one will start with a master. Chapter one is to quick a setup of your whole package. Then we'll write a basic test. We will refactor these tests using a page update pattern and then at last we would integrate our running test for a live report. So let's get started. I'll share my screen pretty quick here. I hope you folks would have got the link of the repository. Right. So let's see, we'll go to a read me and what is the very first thing we have. So I already have a node being installed here. So let's see what version I have. So it's node hyphen B you do. You would be able to see the version. Same with an npm, npm hyphen B, which should be able to see the version. So now let's get started. The very first command what I'm going to run it npm init hyphen Y, Y, Y because I wanted to be added a default for my whole. So this will generate a package.json or dependencies. So if you're coming from a Java word and if you want to compare this file, it is pretty equivalent to your build or gradle in your gradle or your pom.html in your maverick. And if you want your customized one, you can just remove hyphen. But I'm giving it a basic. So let's read and it will quickly create a package.json. So if I go back to my code base now, I should have a package.json. The most important part here in the package.json is here is the place where you could specify your test, what kind of test you want to run, what is your category of the test. And now let's start adding some of the dependencies. So we'll add all the dependency in one group and then we can get started. So I'm going to install a type script, a web driver IO command line interface, a search library list, chai and mocha. You could also use your inbuilt web driver IO assertions, but my preferred one is a chai, so I'm installing that. Hope I'm still audible. So we are installing a type script, how are we installing a TS node here, and the web driver IO command line interface. Once this installation is done, we would create our web driver IO point fit project. So as Vim was also pointing in the presentation, that how with few clicks of commands, you should have your project being ready. It takes a little bit of time, so let's see it should be done. We should be done in a minute. Yeah, so we are good to go here. Now let's create our web driver IO. NPS is my web driver IO executable. So currently what we are doing here is I'm going to get this located at my local machine, or going forward you can integrate with a source lab, source browser stack, whichever you or you could use any of those frameworks mocha, jess, main cook umber. Amota is the most used one. So let's go with Amota here. We are using a sync mode on a web driver IO commands. And where are your tests located? So I want to look, locate my test in a test.js, but let's I would like to change the extension here as we would be using a piece, right? Do you want to web driver IO to auto generate some test file? Yes, let's auto generate some of the test files and see how the entire project structure looks. Do you want to use page objects? Yes, our third chapter is around the page object. So let's see. And where are your pages located? So even the page objects pages would be located in the same location. Only thing what I'm going to make it from JS to TS. We are using a tag strip compiler here. And for by the call, let's use a spec as a reporter. And in chapter four, we will integrate with an older reporter. Do you want to add here? We are using a phone driver. So what is the base here? So as for this workshop, we are using planning to use Amazon.in. You could use any of your base URL, whichever you feel like. And now we should be just ready in couple of seconds to get our first project. So before this project, after this project, you would see that you are still looking for a tag strip. So the most important thing here is the TS config.json, so which we would install next. You would see that if you want to run this, you would get that. So you could see your config file installed. And to have a sub tag strip support, please add the following packages to your tags list. So and you could run this using nps, web driver IO run web driver IO.conf.js. Cool. So let's go to our readme and initiate this file is created. And now we want to add these in my TS config.json. So let's go back to our repository. We do have your TS config.json. Under compiler options, we would see your types. So please see your types here. Yep. Here we go. And then let's add the type here. With me. Okay. So now let's run this test. So it's one of the spec files. And we will look into the structure of what it has created. So it's initiating a new session. So if you don't want logs, we could also disable these logs. So currently the log level is info, but if you don't want, we could make it a silent. We will do that. So here you could see that few commands and without writing a set of code, you have your basic setup project being ready. Right. So yeah, let's go and see what our structure of the project is. So if you go here under test, we have a specs. And under specs, we have an example test of TS. Right. And what it is doing, it is having a log in. And we do have some of the page objects. So this was our chapter one basic setup with our test gets running. So now let's go with an R example of how mix and dot in and start adding some of the tests. So what the use case we are looking for here today is we are looking for a use case of having adding an item to the card. So should and this is what my chapter is. So if you want, you could clone the chapter. We want to add an item to the card. Now let's remove the unused inputs if we don't have those. What we want to do here is we want to first open the browser. Let's maximize whenever we are opening a browser. And then let's browse it out. What URL we want to use. So we would use that base URL, whatever we had given it during our project creation. So HTTP, Poland, www.Pamelson. And what do we want to do here? We want to search an item and add to cards. So let's go to the website of Amazon. And let's go to the homepage. And suppose I want to search for a book. So let's inspect this element. So it's easy for us as it is an ID. We could quickly use it in our code page. So as it is ID, we can have it hash. So we have a locator. Now what do we want? We want to set a value to this. And what value we are looking for here is suppose you have, you're looking for a book. So let's make this as a variable. Let the title equals to book. And then let's set that value. What value we want to set here? We want to set item. And on top of it, we are also performing here a enter keyword. So let's also enter that. Once we have added this item, I should go to my search search result page. So before that, let's quickly run this test and see where we are. So if we want to run here, let's run here. Yes. So we have entered an item to the part. All good. So now on search result page, suppose I want to search the first book and Vim wants to select search the end book. So we need to identify the locator in that manner that anyone can do and search for any of those. So let's inspect this element. So we could see here, this is my product image, but we are looking for something on the, so let's put that here, something on the index, like first index or a second index. So let's see what we have on top of it and if we could get some of the index here. So yeah, we do have here dip data index one, which is my dip. So now tomorrow your test, anyone can pass it and you could add a data index and based on that data index, you could make it working. So this one is what I'm going to copy here, then data if an index equals to one. Right. So we got the image, we have a hold of image and under that we have an enter and then we have the data. So let's put this element in our code base and try to picture it. So we have put that element here and let's assign this as a variable and what we want, we want to click this element. So let's click this element. So we have already clicked our selected element. Now let's see what it happens when we click this element. So when we click this element, it opens in a new tab. So my current browser handle is still on the 0th one. So we want to switch to a new window to perform the next operation. And for that, what we will do here is we will do browser dot switch to window and then browser dot get window handles. So window handle starts from the index 0. So the first index is where my current locator is. So now we have, we are already on the item page and I would like to add this item to my card. So let's pretty quickly inspect this element, what it is, and then we can go to it. So input add to card. So now you could just add this item to the card. And since it was an ID, it was easy call for us and then dot get. So now your item has been added to card. Let's run this test and see where we are. So yeah, your item is added to card. So this is what our chapter two is. In the next chapter, we are going to introduce a page object for this card. So you would have already seen that we have interacted with a multiple pages from home page to search results page to an item page. So let's write us some pseudopode. What do we want to do here? Like from a page object item. So we know that we were on home page. And then on home page, what we did? We search for an item. So pseudopode helps me to visualize what all pages I need and what all we could have in our script. So let's have a data search for then the next one, what was it? We went to a search results page, then we had a set of item. And there what we did? We navigated, navigate to item. So now item, I'm going to navigate it by an index. So yeah, it's navigate to item. So once you are there navigated to item, what it is the next one is your item page where you are adding that item to the card. So you have these operations. So before searching what else do you need? You need to open the open page. So there is also one working here, home page of open. So we could now get started incorporating this in our page object. So let's create some of those pages under the page object. So we don't need these. So let's delete these. You all would have heard around the base page. So base page is where we will keep our headers, footers, all on base URL. So right now if you see we have a home page dot open. And for this test we are opening, but it could be for other tests also where we want to have the main base URL. So let's put those and that base URL if you go and see here if we search webriver.io.conf.js and if I type a base URL here, we could see it is configured to Amazon.in what we have given it during creation of the repository. So let's create some pages here. So the very first page which if I go back to my pseudocode it turns like a home page, right? And let's let's say it's my home page and we would need a base page for my UI. So let's also create a base page. If I go back here, this is what my base page dot .js looks like. So now we will introduce a interface here. So if we go back to a test class here, what do we need? A home page dot open. So before introducing our interface, let's extend my home page class to a base page. Class home page extends to a base page, right? And now let's do the export of this class new home page. And now let's also implement this home page. So let's implement this as the I home page and you would see what all we need to add it here. For now, I'm just creating our interface and keeping it for that. So now let's go back to our base page dot yes. And what do we, so since in home page we have already introduced here, so let's create a constructor here and pretty quick reformat it and go back to your base page dot yes. And what would be needed here is in a base page dot yes, we want to have a open method which takes a path as a string and in that we will keep what do we, in our test class, we have our, this is what we are looking for. So let's put here home page dot open. So this is my test suite or describe and it is my test. So we would need it before each test. So let's put a before here and this would be my setup method. And under this setup what I want, I want to call a home page dot open and with that I want to give a path which is already being defined in my web driver iodo.com.js. So let's go back to this and then here what do I need to do here browser dot maximize window and browser dot url is null path. So we have a very basic setup of the page dotted pattern being ready. So we could get rid of these two lines from the code and we could run this test to see where we are. So yeah, it has initiated the open method and the searchers still are previous in the base structure. So you could quickly and easily migrate to your page object by that. So now what is, so we have already incorporated this suitable. So let's see what we want to do. So we want to search for an item. So what do we have is home page dot search for some item, right? So let's go back to my home page class and define what do we want. So we need a search search key bar which would be my web driver iodo element. And now as soon as I have added this you could see that in typescript the home page class is giving me an error here. It is asking me for the implementation of this method. So now let's go back and then what method I need is search for. So let's again go to my home page dot ps and put that search for. Search for is my method which takes a key or you could put a index or let's see what it I think it will let's see what we want to put it here. So we want to search for an item here. So this is a key which is a string and all we could just return this as a one. Now we need to implement these two methods in my home. So we can just have implement all members. Yeah. So let's do this. We have search key bar will return the locator here. And this is what my I'll get the locator from my test class and then we want to search here. So we will put it here. This dot search key bar dot we want to set a value here. So let's put key plus again we need to enter key and then let's create a variable out of it and we can make it a search keyword. This dot search key bar dot set value of search. And now let's get the locators from here. We'll go back to our homepage at this little and now if I go back to my desk class I don't need this. I would still need this item. Well, let's do quickly back here. And then what we could do here now I want to search for so home page dot sorry search for this item. We want to search for an item book. So we have implemented this part of it right now if we go back here we could just run the test after we are making the let's run the test and the next step would be to select that item and go to the package. Cool. So now let's go back again to our test class and what do we want here. Now we want us to navigate to with something. So let's put this search results page. So we don't have a search results page yet. So let's create that. Right. So results page of deals at this class as search results page and let's implement this class again with an interface. We still don't have that interface will create it now create an interface and then let's let's put this one before new one search results page. So let's go back to our test class. So what do we need here? We need to navigate to an item. So let's put this method in our interface navigate to item and since we are providing a this as an index so this would be my number right and as soon as I add there it will say to implement this in my class. So let's implement that in our class implement all members navigate to item. So let's again go back to so what is there in this method we want to click that element. So let's copy this locator here go to navigate this method and then get this as a variable. We want to pass this index. We don't want to hard code here the index. So let's pass that index and how would we pass it here? This is the data index and we want to put it under this one dollar. We could see a dollar and then the index. Now if I go to function last I need to change this. So we do have an element here. Now we want we want to do we want to click this element as we did before and then let's go back to our homepage. So we are good with these two lines here as we have already navigated to search results page dot navigate to. So let's put this point of time let's put our index as two right instead of one whatever we did to test whether our function is working or not and we can get rid of these two lines here. And yeah so what we have here is download or switch window. So we could put the same thing in my navigate to after. If I go back here yeah so if I go back to my example class now we know that we are on homepage we search for an item we are on search results page and then we navigated to item index two and let's pretty quick run this test before implementing the last page. So yeah we are searching here and again going back and so let's do for our last page here. What do we want here is item page dot add to dot. So if we go back and see here we don't have yet an item page. So let's create an item page here as item page and let's do this for default or new item page and then let's implement this. So if we go back to our class what do we need here we want to add an item to cart and how would we add that item to cart we should have some locator also. So we would need a method add item to cart and we would need one element right add to cart button right. So we could add that item to cart. So if you put again see that item page is looking for that method so let's do that add to cart button and let's return here the locator. Then what next is my add item to cart method. So all good with my test class here and let's implement this method. So what do we want here base dot add to cart button dot we are performing an option click here. So you don't have to wait for an element here as in whatever are you you do have a default date. So we'll go back to a test class and get the locator from there and put in in my template and we are done on this. So we have already selected item two and two. So this sort of would help me to visualize what I want to do. It's completely a personal choice. So we feel to add whatever you feel like doing it. And now let's run this test. There is one more thing here in the base page. So I've seen people also overpopulate the base page. So the thumb rule word should keep for any of the framework whichever you are designing from the best practices that base page line should not be more than 200 lines. If it is more than 200 lines start dividing your pages into a different components like a login or a shipping card or a different component. Yeah. So here we are going with our chapter three where we have incorporated a page of reference. So what our chapter four says is to introduce the reporting. So before that introducing a reporting here to an allure. Let's go and see what we have in current reporters. So if I search for your reporters here we should have a spec. So let's add the allure here in our report. And then let's and then also let's make the log level to a silent house being too much of information here now whenever we are running a test. If we need to do well we will again come back to the load level. We'll come back and change it. So yeah. So how would we integrate here? So if you go back to your review you should see this npm install web driver IO allure report. So once we install this reporter we will run the test again and we will see how the report looks like. Yeah. So it's installed. The next one is our allure command line interface to run and generate our reports. Now let's do generate. So we are generating a report and output here. So before generating a report let's run the test and then generate a report. Yep. So our test is already run. And now let's generate. So npm allure generate. So these instructions have been mentioned here in review. If you go down here under reporting section that how could you generate a report and how could you open that report. Yeah. So we could see that report successfully generated to allure report. Let's go and see here. Yeah. We already have here. Now we want to open this. So yeah. Now I'll do it open. Yeah. So we could see here that this is what my application here is and what it is doing here for a suit level. It is adding an item to the top. So this reporting helps like to also for you to visualize which all items or locators are taking time or sometimes it happens on your application. That capability or the locators are not present in. So you could get those and you have a history here also. And you could also see how many times those elements have been done. We have a quick graph here also. You could see this would like you could share this with your product owners and all who want to see the health of your system what it is all around. So you could also specify your reports based on your test use category. So right now I have only my web application but going forward you have multiple categories you could see which area of your application has took a longer part or which area needs some more attention from the test schools. Yeah. So that's all I had for the demo. So thanks for Runa also for this awesome presentation. I think we had a lot of questions also during this session. I answered them so you would not be disturbed giving kind of like your presentation. I think we've got some time now already if people have some questions for Runa or for me or about WebDriver.io or about types please ask them. Yeah thank you so much women Varuna for the session. Let's take the questions one by one if okay. So Vim did you take a did you have a chance to look at the Q&A section? Yes. Yes I answered all the questions except the last one. The last one we got in was how can one add learn and contribute for this project and I think then that Avraham means WebDriver.io. The project if you want to help also for WebDriver.io if you would go to the website of WebDriver.io and you would go to the homepage you will also find some information. Let me get it. It's not published yet. It will be published I think in a few days. There are also open office hours for WebDriver.io where you can like get more information on how to contribute to WebDriver.io. Just if you're on Twitter watch WebDriver.io the handle on Twitter and we will post if there is another open office session where you can kind of like learn how to contribute also to the project. We also have a list of good first picks if you would go to the GitHub channel on the GitHub project also from WebDriver.io. All issues that might be easy to fix with a PR with a pool request can easily be seen by looking at the label good first pick. So there are multiple ways also to contribute to WebDriver.io and make the product even better than it is currently. Okay I think there's a lot of appreciation and good feedback from the audience and I don't think we have any other questions really. Yeah we have all the likes popping up. So I just say that thank you once again Wim and Varuna for this fantastic practical hands-on. I think it was it was flawless.