Alright, so welcome guys. It's good to have you here on a Saturday morning, especially. So that's thanks for coming here. Hopefully we'll make the most of this session and then hopefully we all will learn something today. So that's good. So just briefly get to know each other type of stuff. So how many of you, so let's start with me, right? So I'm Chinmay Naik. I have been working with Equal Express for all three years now and worked with mostly enterprise projects, recently working on some products that we are working with and in terms of technology, I don't really, I mean, I don't want to start there because it's just, as we said, we work on the idea of technology. So my aim or the thing that I want to accomplish is getting simple and clear solutions to the client. So whichever technology you use, it doesn't matter, right? As long as we use the right tools with the right job. So that's probably me. What about you guys? How many of you are working or have worked with JavaScript, for example? So yeah, almost all of you, I guess. So that's good. And anyone who's worked with Node.js? Okay, couple of you guys. So that's nice. So what we did, right? A few months back we had this project in our company, internal project, which we implemented in Node.js and then we wanted to write automated tests for that so that we don't have to test it manually. So do you guys know what is automated testing and what is automated end-to-end testing for applications? So what is that? Can you give me an example of and why that matters or something? Why do we care about that? Anyway, so we would like this to be interactive session, right? So it's not that I talk and then you guys just listen and do the workshop. It's all interactive. Even I want to learn from you guys, your work experience, your past, right? So what do you think are, like why should we write automated tests? If I change anything, any functionality, it should not create the existing functionality. So that, you know, automatically before I manually go ahead and test it so that if the build gets trained, I will come to know. So it's early feedback, right? I get very early, very fast feedback. So that's one. What else can you think of? Is there anything else that you can think of? Yeah, so you have confidence, right? Again, he's touching the same point. So it's very good. So we have confidence on in our product. Whatever we do, I am sure that this works. At least it doesn't break in these main areas, main workflows that I have, right? So that's that's good. So quickly. So these are the things that I felt are the real value for, for using automated testing. One is the confidence I get. I can change anything in my application and then just make sure that the tests, I mean, if I have enough coverage and enough tests, I make any change in the existing code also. I am confident that if my test pass, everything works nicely and clearly. So that's that's a confidence that I get and I try to, I can ship early. I can ship often. I can refactor fearlessly because of because of the confidence that I have in the test, right? There is a lot of business value in acceptance test. So it so I'm specifically talking about acceptance test now and not the unit or the small level test that we use for technical benefit and everyday work, right? Those are essential to those are very vital and we use that every day. The real value for the customers, however, is comes from acceptance test. Like if you had a product and you have thousand unit tests which cover all the product, but if you look at it, if all of your units work, is that, does that give you confidence? You can, I can always, there's always a workflow that you can do and it kind of breaks the application, but the units still pass because they are what they are just thinking about the isolating the parts. So units are really, okay, everything else is constant. I'm working on this, this small module, does that work? Given all the external state is same or given I don't care about external state is my module or is my small unit that I'm testing works and that's a very vital test to have. It's not, there's no negative thing about that. It's just a, it's just very technology focus or it's just very implementation or it helps us not to the business really if you look at it, right? Whereas the acceptance test or the end to end test, they help the business and they have this business value that if these workflow work which are like 80% of my workflows for my application, then I can say for sure that this application will work end to end and there won't be any surprises there. So that's the value for business and the best part I think I like about acceptance test like hardly or not many of us get to work on or get to create software from scratch. So that's, and we have to live with the existing code, existing applications that you have to just add few functionalities just to here and there and then add some stuff here and there, right? So we, I think we spend almost 80% of time reading the code then writing the code generally even in your own code, right? Even if it's from scratch project you would still, if you wanted to add some functionalities to something you would have to read through where to go about which class to change, what method to add or something like that, right? So it's all about making it better, making it more readable in the end for us. So that works for legacy apps also, like acceptance test, you can write for legacy apps also. So that's probably the best part which I feel is for the acceptance test that most of the applications if they are already running and we have had bugs there, we have had surprises in the production and which we wanted to eliminate that you could start with acceptance test. You could also start with unit test but probably in unit test you, I don't know if you guys have had to write very small unit level test for already existing application, how easy or how difficult or what was your experience like? But for me, I think my experience was it mostly it's difficult to write very nice and clean, clear unit test that really adds value to the code. I mean you can always write unit test and get it passing but if that doesn't really give you confidence, it doesn't really assert something that's really the business, it's a bit difficult to and it's a bit flaky also there's no point in writing that. So whereas acceptance test here shine really and then because you don't worry about the application how it's implemented, it's like a black box to you. So you worry about how do I interact, what if I have a user, how would I click this button and then what would I do, what would I get back on the screen or so that's the end to end thing. You ignore the small bits as to this class sets the variable over there and then is that variable set properly and all that stuff. You don't worry about these small, small things. You worry about the application engine. So that's a good thing for the legacy. So what we'll be covering today is Cache per JS, it's a framework for writing acceptance test in JavaScript. So brief about Node because it's, I think it deserves a mention here. So what do you think, I mean what for the guys who have used Node, did they really find an advantage or what kind of applications did you use Node for big data processes? Yes, okay. Right, so event driven. So what to really note it's a JavaScript on the server. So if you know JavaScript you kind of already know what Node is in a sense. You have a basic idea of the sentence. There's nothing, no new major syntax to learn really. It's JavaScript. So the main feature or the main trifling thing in the Node is really it's event driven and non-blocking. So what do we mean by event driven and non-blocking? In typical in Java or any of the language, any of the C-sharp Java or probably some of the other over languages we program like this. We say okay, where? We could say okay, we want to get data from database. I want to fetch customers and then once I fetch the customers, I want to find out the orders that they have placed. So I say customers, I have a SQL query which goes to database, gets the customers and from there I get all the orders for each of the customers. So if you look at one request from application, from a user, so browser, if I click show my orders on my application what that file, that file is a web request and the web server possibly creates a thread for that or uses a thread from the thread pool and it then assigns that request and response to that thread. That's how typical web stuff works. So what you do there is you have the thread has to go and fetch the data, fetch the values from the database. Now while, I mean we all know IO is very slow. IO is the bottleneck in computing, not CPU processes. IO is the bottleneck. So it goes and fetches the data but while the IO and the disk are working, the thread can't do anything. It's just sitting there and waiting for the data to come back. It is kind of blocked or it's sleeping or waiting for the IO to complete. So once the IO is complete, so we are losing CPU cycles, we are losing the thread. We could have used that same thread for something else, for some CPU processes or something which we can't do now because it's blocked for that IO and then once that IO gets completed, once you have the data, you come back, that thread resumes and then it does the next operation. Again if that's a blocking operation you again block. So you kind of, if you have a very networked application or if you are talking to many services or many databases if you are getting a fetching data from multiple services via network probably you would have a lot of blocking IO. So a non-blocking IO or event driven is exactly what, how does it solve that problem? What it does is there is in node especially, there is an event loop. So you have something like a thread, a single thread that's running in the background. So it's like UI thread and any of us if we have interacted with any of the UI or GUI applications in our desktops, let's say, you know it, even click on some button, while the action is performed you can still move your mouse and click another button and see what's going on here and there. So how they handle that? So they have this something called as event loop which runs as a single thread in the back end which just, what it does, it just dispatches the event. So all it does is okay I've got an event for getting the data from database, fine. It spawns a new or it asks the IO to do that and then it comes back again and says okay I'll execute the next operation in line and then if that's again a blocking operation I instruct or I use IO or let IO handle that and then I come back and do the next operation.  So it's a single thread event loop and the real biggest difference in node and simple javascript is really you don't have a DOM. In javascript you pretty much always are on a browser and you always have a DOM, right? You interact with DOM elements, you say okay I want this selector, you use multiple selectors to use a query or any other lab result and you work with that, right? So since it runs on the server and not on the browser you don't have a DOM. That's one of the changes. So what we'll be covering today is mainly Casper.js. So what is that? So that's a scripting and navigation testing utility for phantom and slimmer. So if you went to Casper.js website or few... So in automated testing there are multiple ways, right? You can have full browser tests like I can create in Selenium or WebDriver if you've used or if you've used automated tests using that, you would actually spawn up a new Firefox or whatever Chrome instance and then you would actually see the application see that the button is getting clicked, see there's something added in the text box and then the form is submitted and things like that, right? You can actually say it's not headless. So the Casper.js and the phantom especially is phantom and slimmer.js. Slimmer is not totally headless but phantom.js is for WebKit. So WebKit and Gecko are these browser engines, right? These that power the browsers. The browsers, your Chrome, your Firefox, your Safari they use a browser engine to actually understand and render the contents on the browser window, right? So phantom is a headless WebKit. So you can have a headless test. So what is a headless test? You run a test and that doesn't spawn the browser but actually it kind of has a non-gui browser internally so that's where we call it headless. There's no head and therefore you will see that these names are all have to do with a ghost or something like that. So Casper is a ghost, phantom and there's a lot of related tools and utilities. They all have the same theme of being headless. So that's that. So there's nothing much there in the slides. Let's just quickly dive in and see what we have to do and see what we can do today. So any feedback, any questions you have, just shout and stop me and we can just discuss quickly, yeah? So when you say Casper.js is a utility that we'll be studying here, that kind of has really nothing to do with Node in a sense. But why I wanted to mention Node is since we are anyway talking about JavaScript and we are writing it on server side or as a separate kind of for command-line utility, I thought I would talk about Node as well. So it's a Node agent. So yes, so event loop and everything, that's Node stuff, Node related stuff. Casper.js has kind of really nothing to do with what Node is or how Node works. So let's quickly see. So actually I, as I said, we are not really planning for a proper workshop. But let's say we have, we're at 10.50 now and we probably have, I'm planning to limit this to 12, 12.30 maximum. Is that fine or right? So what we can do is, I'm thinking we can actually do a workshop and you guys can actually code along with me. So do you guys, if you're interested obviously, if it's fine, you just want to look at it, then it's fine as well. So you can, side by side, you can set up Casper.js. It's just if you have NPM and Node, it's very easy to have to get Casper.js. You just say NPM minus G install Casper.js and you would get it. And what we can do now is let's try to, let's try to write a proper end-to-end test, application test for a simple app. So let's say, let's try that. So what I have is I, we'll be working on this to-do application. We were initially thinking of using a proper big application probably because of the time domain, time constraint. Yes, please do. So you can also go and have a look at this app. It's, I'll probably not use mic now. If it's fine, I'll try to be loud here and it will just be very difficult for me to type and use mic. So all you need- So all you have to do is Google for to-do MVC Angular and you would get it. Actually you could use any app, but I started with Angular so probably, so we can use that. It doesn't really matter which app it is. So let's just find out. So it's to-do MVC. Okay, one quick thing. If people are interested in the internet, the Wi-Fi password and username are here. All of you see that? So you can just search for to-do MVC and go to AngularJS and this is what you get. So what I have done here is, so what we want to do, let's say let's understand the app first before we can start writing the tests. And we don't know anything about Casper, let's say. We're just starting. So we'll learn as and by finding, by figuring out stuff. But we know the aim that we want to do. We want to write tests for this. So what is this application? It's a simple to-do list, right? So what you can do is you can add to-dos. Let's say I can add it to-do and it could be something like this. And then I can say, okay, that's done and this is remaining, let's say. So I can and then probably I can say, okay, this all can be done. Or this is a very simple to-do list today. All of us are probably familiar with that. And then you could remove items from a to-do list. And once you're done with all the items, let's say I'm done with phantom also. So I say, okay, I'm going to remove this. So clear all the computer items. So that's going to run back to normal. So very simple domain. There's nothing big or new to learn here as far as the domain is concerned. So let's start by, so what do you think? What do you think we can test here? What is the application behavior? And what all features does this application have? Let's just quickly discuss about that so that we know what we can try to write. Or what is the test that you can write, automated test for this application? What can you test for this app? Right. So you should basically be able to add to-do items and see that the to-dos are added. That's the one. So that's very simple one, the small one. So that's good. So let's say I'm able to add something like this. And that gets added. That's the behavior. What else could be the behavior? Right. So again, I can mark the to-do is completed. I can also remove to-do if I wanted to. So these are the small, small bits that we have in the application. This is a very, very minimalistic and very simple and dumb example that we're taking. But again, that's for a purpose. Because we don't want to complicate the domain and then it just becomes difficult to write test. And this is kind of a legacy app for us. We haven't written this code. I mean it's some guy who has open source repository and those guys have written this code and they have the app in life. And what we want to do is we want to make sure that this works. That's our goal, let's say. So how do we start? So let's say let me just go and show you what what Casper is and how. So if you go to Casper's home page, you would see that it's a navigation flipping and testing utility for phantom and slimmer. So what all it can provide? It provides features like, maybe can you guys see that? You can do all sort of navigation stuff. You can click buttons, links. You can fill up text boxes. You can select radio buttons. You can fill up forms and submit forms. You can upload files. You can take screenshot of a particular page if you wanted to. Those are all the capabilities that are provided thanks to phantom. So and then if you look at it right, you can download resources and this is for writing functional test suits and web scrapping really. If you wanted to scrap a few web pages and find out the formal element or whatever you wanted to do that, probably this you could use some something like this. So let's start with a very let's start right. We want to know. We know what we want to test. Where is that? So this is the admin screen. So we know what we want to test. So we want to let's say test first that so this is where I'm going to be coding. Can you guys see this? Is that visible back there? Okay cool. So that font is good. So what I have is a simple, so I have installed Caspid.js. Let me show you that. So I have is that is that visible here? So I have Caspid.js installed and if I say help, it gives me the options and what it is and the docs and all that. It's a basic command line utility that that you can start with and so let's say first for very starters right let's say to start with what we want to test is this to-do app that we have. There is a heading called to-dos so I want to check that there is a heading for to-dos. There should be a heading called to-dos in there. This is like a application logo or the main thing for me for the application to find out what this application is. So let's say I want to test this is there indeed. So how do I do that? So the way is for writing test any test you say okay Caspid so there is a Caspid instance available here in the script it could be just any script. So what I have created is just let's say I create a spec file. So I delete this file so I've created a brand new spec.js file and I start writing. So let's just figure out there is a Caspid instance that's there and I can say I want to start a test so let's say I start okay Caspid.test.begin I start a test and I want to give a name to the test what this test is. So let's say I'm testing the to-dos functionality so I want to make sure that the header is there so I say okay the to-dos header is found and then what I do is function and then I start the test so okay it's very difficult for me to so let me do this function and all I do is let's say so what we know right we want to go to this application URL we want to open this URL and once that URL is open we want to make sure that there is a title there is a to-dos header here something like that so that's what we want to do so since we don't know anything about this application we'll have to figure out how first of all how to open this URL using Caspid that's the first thing probably how do I open a particular URL using Caspid.js in Caspid.js before I can assert something so what you can do is say Caspid on start and this is all there is a good and nice documentation for that and that's one of the reasons actually we chose Caspid.js way back at that time we wanted to write something the acceptance has been JavaScript the other libraries they were all very low level either low level or they had very it was just very hard to figure out how to get along and what to do and what not to do so as far as very nice documentation and it's the even user community is nice you have you get a lot of answers on Stackoutflow or Google if you search for so it's a fairly nice library I would say so let's start so we wanted to open this URL so I can give this URL complete URL I would say let me that's better so I have this URL maybe I can take this URL into app URL separate app here so let's say I say I have URL equal to that and I just pass it over here and then once that URL is open I can say I want to say function so this is like a if you look at it this this follows the same syntax in JavaScript you fire a JAX request and typically have a okay dollar dot whatever a JAX jQuery a JAX and then you have these callbacks success and error callbacks so that's very similar here you have your opening a URL and once that URL is open you can say call this function for me that's what you're saying over here once that URL is done you call this function for me so in a way that's where I was talking about non blocking if I were to print something here that would be printed before that URL before that function gets executed typically because it's over a network call and that usually takes time right so far with me you guys or should I is that fine this is space fine right so the aim is to check the to-do header is found in a particular so that's the goal that we have right let's not for a dimension bubble so we are opening this URL and once that URL is open I want to now somehow be able to assert that the title is there so I want to now actually find out in the DOM that the to-dos there's somewhere to-dos is written somewhere so we'll find out where that is so let's go to html and let's find out where is this in the DOM so if you inspect this element you would find that it's in the heading rightfully so so you would say okay there is a heading h1 called to-dos so I want to make sure that it is to-dos that is written over here nothing nothing if I change it to sample this will become sample but that my assertion should be it should be to-do right I want it to be a to-do because this is a to-do application so what I would do I want to find out let's say using xpath have you heard about xpath do you know what that is so very basically I mean it's a very simple terms xpath is a method that you can use to find elements in xml tree so x is for xml path is for finding things in the xml you traverse a path to reach somewhere right that's a very basic one minute introduction of xpath I think so the way you would write xpath is let's say we want to find out an element using xpath so let's say we what I want to do in Chrome you can actually search for xpath so let me mention that is that visible or right so there is a variable called $x in Chrome console you can write an xpath there and if it's found the element will be highlighted so this we know as a heading right h1 which contains the text called to-dos so let's say we find it that way so the way since that's what writing xpath is is really this you say so these are we are searching in the root of the document from the root of the document and what we want to find is h1 h1 that has text the text in h1 should be equal to to-dos right so if you look at this h1 it found this h1 and if I hover over here it highlights this h1 for me so I know that this h1 so that's xpath and valid xpath so yes so then I can copy this xpath so this is how I would test whether the xpath that I'm checking works fine on Chrome or even in Firefox there is a firebug if you're using firebug there is a firepath tool that you can use and find out the xpath so what the xpath and now I say so I somehow want to know how in Casper can find out a particular element and assert that the element text is something like that I want that and this is visible in the UI the element is visible in the UI so I want that so let's say where xpath or header xpath header hpath is equal to that and so the way you would do that so Casper has the function and so let's find out maybe in the documentation let's find out so I have opened the Casper documentation the Casper module so there are multiple modules here you have a Casper module you have utils module you have mouse module because so most of the functions are typically available in the Casper module and some of the utility functions are there in the utils module we can see what functions are there and if you wanted to click on let's say some pixel 435 by 220 with the mouse you could do that using mouse functionality there is a mouse module so if you were to click on some particular element there is a if you can locate that element by xpath you can click using xpath or if you wanted extra mouse functionality drag and drop and something like that you would have to go to mouse module which probably won't be able to cover today but let's find out how do I is there a way to make sure that the element is seen on the web page is there something called as visible so let's say okay then visible to yes so this probably is something that we can look for that's too bad visible so there is a visible I can say even is there a way to assert that something is visible let's find that out okay so in the documentation let me check so all the assertions related things are in the test module so if I were to go in the test module there is a assert that some element is visible or some element has some text or some element has is there are various conditions you can assert on so for starters let's just again that's one module that you are trying to use over here and then you can assert visible and then I am saying I want to make sure that the this whatever I have xpath right this xpath is the element with that xpath is visible in the DOM so the syntax again is you can say I have type of xpath and the path actual path so I say path is equal to header xpath and then if that element is visible I can give a nice text that the to-dos header is visible so I have this this is the front of it so this is what I have in the test and I think that's there is an assertion and we are going to a URL and checking that something is available so that's probably a complete test although it's a very simple and very basic test but it's still complete so again there is some so one thing that we learned while we were using Casper and we had to figure out the syntax and that that was a challenge for I think a week or two but then after that after two weeks we got used to it and then we just got the figuring out the APIs so we just said probably there is an API and then we just wrote assert something and actually check there was an API for that so it's very intuitive once you get the hang of it and once you know how the modules and how the API has been structured right so so let's say let's run this so again the syntax to run is there is you can say Casper.run and once that's done you could say my tests are done so I say Casper.test.done so again bear with me for the syntax thing here we can cover this later so that's my test case that's my complete test case and let's just try running this and see if this really works or makes sense so let's say the way to run this test you say Casper.js I have installed Casper.js and then the test I want to test the file name so it says peg.js so it's running this test called toDoHeader is found and then toDoHeader has visited it says okay that's correct that's done so awesome but then I mean every time a test passes first time I get a very I get a strange feeling probably is that really done is that something that's really running and because you can't see it right it's headless I want a nice feedback I want something feedback to see whether it's actually there right so let's say what we can do we can first of all let's make it fail let's just change this to do is to XORZ something that we definitely don't exist on that web page and let's just see it running and see if it fails it should definitely fail now if everything is working fine so let's see somehow this is strange am I connected to internet yes it's again fetching the data from internet problem that's taking so much time so that's that and then so let it run let it out maybe the internet that's very slow so while we talked about feedback I want to see whether that web page is actually loaded although we are in headless mode is there a way to really see that page so yes there is you can actually capture the screenshot of a page even you are in headless mode so you don't have a DOM or you don't have a page but you would still like to see a feedback get a feedback right so you can capture it fail right it fail for that Xpath was incorrect so there was no header to do header is visible is fail that's the question that is failed are you guys with me are you guys still following along cool so let's change that to to do and we know it's passes but what I want is I want a feedback I want I want to see that page in some way just doesn't give me confidence right if you have never worked with headless browser before headless mode before this is something that we failed I want to see something is there a way to see the action there so there is a utility you can capture screenshot using Casper so what you can do is you can say Casper. then again I'll explain the API quickly so once so what I'm saying is once the start is done then once this complete so this is maybe so let's just write it down and then I explain what what's strange about the API and why that API right so so there is a you can do you can do function and I can say Casper. capture and I say okay image.png so I want to capture the screenshot in an image.png of that web page once that web page is loaded I want to see that the page is actually indeed loaded right that's what I want to see so that's the way you would do and let's just see if it works again so let's see this should pass because I've changed the to-dos proper to-dos and this passes and we said okay image.png we wanted some image to be we were expecting image so let's see if there is an image so yes there is so let's say open this image so if you look at it there is an image so this is the web page it was able to get that web page and find that to-dos here so it is actually indeed loading the web page and here is what you can see right so are you guys with me but if you look at the web page right have a look at the web page what does it look like the one that you are testing if I were to go in a normal if I were to zoom this is how it would look like but if I were to have it on default zoom this is what it looks like so again so again this page is probably responsive in a sense that if I zoom it enough so it probably understand that probably the user is viewing it in mobile browser or tablet or something it's responsive it tries to detect the screen view and then based on that it adjust itself it hides the unnecessary elements so that you can just focus on the important content here so that's what this is doing but if I wanted to have it on if I wanted to have a desktop viewport in a sense I wanted to know Casper should run using a particular viewport as if I am running it in micro, more firefox or safari I wanted to do that so there is a way again you can set the viewport in Casper so let's go back to the script again and these are the config options that Casper has actually talk about what the then functionality and then feature but if we just cover this first so you can do Casper.options.viewport size so you can say okay what's the width width is I want 1024 and height I want it's a 760 so I am just setting the viewport globally so that it affects all the tests or all the things in the script we just set on the Casper global object so now if I were to run this this should work and this should tell me if I am running the test again so it should find out let's open the image and see for ourselves how the web page is due to the viewport it understood that this is the viewport so it kind of instructed the headless mode to have to set that user agent or set that viewport size so that the JS on the page doesn't hide the elements so you can see this is complete web page that you can see as is so it's a screenshot right so this is kind of gives me feedback as to this is indeed loading in the browser and this is working fine great so we want to now talk about what is that there so let's quickly talk about what this syntax and the syntax stuff so in node right I mentioned sometime back the JavaScript the node language in a sense the node platform is even driven so anytime you write some line of code if that is a sync call or that has to wait for block it has to wait for I or some other thing to fulfill that call what it does it just runs that separately and then proceeds with the execution so if I were to let's say if I were to ignore this then and if I were to capture the screenshot for example let's say if I were to do that what would happen is this would start and this statement would run this is a single statement right and this call is a function which is a kind of a call back call once that function is done you call this drop for me please that's what I'm saying so this app URL is it's a ctp call so it's definitely going to take some time it's going to go over network fetch that actually to page and then load it on the client side so that's that's going to definitely take some time in milliseconds or microseconds whatever that is and but the node what is going to do is it's on node of Casper again or the it's again phantom.js so what they will do so it's not going to be blocked by this so this statement would continue and even before you have this page you are saying to capture the screenshot you're asking it to capture the screenshot but the page loading is started it's not completed the page I have instructed the page to load that's going to take some time but I'm not waiting for that to load I'm saying okay I want the screenshot so it will take I don't know weird I've never tried this let's try that maybe let's see what kind of screenshot does it do we get yeah we would typically get a empty or whatever blank screen right so let's say we open the image yeah this looks like blank screen so that's the most important thing one has to keep in mind when writing code in Node.js or on the server side that every statement that you can write if it's a sync or if it's going to take time you have to write callback or you have to write promises to make your code nice and clean because again if your program heavily in JavaScript you would know that callbacks can definitely go nested and you would have a typical pyramid of callback or callback hell as it is called you would have those problems so in order to keep your code clean you would need some sort of way to handle that callbacks nicely and probably promises is a nice and good way to handle that so that's what this Casper.then is what it is saying is so in this case again here it starts fetching the HTTP page and then immediately it calls this method but then here it knows okay Casper.then so it has to so what this then is so Casper has these then and so you have to write kind of every function in the Casper.then not every but you would see an exception there later later let's say so you are writing this in a Casper.then just so to instruct Casper or the underlying structure to say that once that above call is complete then only I want to call this so what this does is once your entire statement in a sense you want to callback also is complete once this statement or this promise is fulfilled now I am talking about promises but once that is fulfilled and that's done once it returns a value and it's complete then only call this function and similarly then only run the test and that's how you are kind of wrapping it inside the dense and the promise chain repeating that promise chain in a way so far yeah yeah yeah okay so let's so is that the Casper intelligence which makes it run up to then yeah so Casper.then so the question is what is Casper.then and how is it different from Casper.then in a sense that's the question so really Casper.run is I haven't gone into detail and found out in the API how it's implemented but what it instructs Casper is now the tests are now there is no more promises and the promise chain is going to be complete so this is where you actually start running the yes so it's this is where once once you have Casper.run this is where actually it executes the test so if you look at it right these are just so this is where it actually starts execution and you have to have all the dense and all the promises and all the assertion everything before that so that's what this instructs Casper.then inside the then inside the then block there are some except we can we can talk about that later yeah but yeah generally you would have that if I need to I mean something what happens is every task to come up or the compatibility issues with the browser version set up I mean sometimes yeah so this the question is about browser compatibility and how Casper enters that so how to set up the browser version for a specific test if it are sometime it is so yes so that's a how to set a proper browser version and how to deal browser compatible things in Casper so the thing is this is not the area where Casper is intended to work with so this is really what you're saying is Casper is headless so there is no browser in a sense you can't have you can't really have if you wanted to have browser compatible test and you were to write functional test for checking browser compatibility probably you should not use Casper that's not the aim of the library it doesn't do that there is there's no way to set okay Firefox version is that and then run that because it runs on webkit which is a browser engine and because phantom uses webkit so so there is no way to set browsers there's no browsers it just uses what's provided by webkit API internally so for browser compatibility to test probably Casper is not a solution you don't want to write tests using Casper in that case so yes cool cool so that's a question is there only xpath here right so there is no there is a CSS 3 selectors you can use any CSS selectors we can try that also let's try that jQuery selectors jQuery selectors okay yeah so you can inject jQuery in Casper so Casper you can you can say once the page is loaded I want the jQuery to load so there is a client scripts module in Casper with which you can load jQuery and then use jQuery as if as is you know in inbuilt in the in the Casper test you could do that or if it's a simple selector for example xpath was one way we thought of generally people generally xpaths are very slow and at least slow compared to id lookups or direct CSS lookups they're very slow so as far as possible we should use CSS 3 lookups or the direct hash id lookups using jQuery or even using selectors CSS 3 selectors so we could try that let's see if there is a way to select this element this element using CSS 3 selector is there a way so we can check that I have a selector tester here so let's see if I just okay so there is a way I can just select h1 any h1 and pop this one h1 I think here in this document so we are saved so if I just select h1 here that should that should fetch the same element and I should be able to assert that's the same thing right so that's possible so you can use either CSS 3 or xpath selector some of the functions in casper are not compatible with CSS 3 xpath selectors so CSS 3 is generally applicable everywhere you always have CSS 3 selectors if not xpath there are some functions where xpath selectors don't work because phantom which casper uses internally doesn't support that so you have this file uploading one feature that we figured out was file upload upload a file using that and I wanted to select which where is the file upload box and I wanted to click okay this is where I want to go and upload this file on this button and something like that there is no way to select that button that box using xpath selector because phantom internally doesn't have that capability so basically casper you use it either with phantom or js which is replicate or slimer js which is get how does this help me in case I want to test it with ie is there a plugin that can cache for a long way okay so that so about ie the famous yeah so finally I have one use or prediction that we wrote headless for we wanted headless we really didn't care about how the UI looks we were not very particular about in ie this should exactly have the same look and feel as in firefox same on other browsers we were not really we did not really care about that what we care about was wherever it is displayed am I able to click it and am I able to go through as a business flow yes did not therefore I am not very I cannot really judge and tell you what is there a way to that way to do that so frankly I don't know I mean in casper is there a way to add plugins but I'm hoping there should be there will be probably if it's not already there similarly again when I when we started looking there was very experimental support for slimmer jazz or get go when we use that now if I look at it is there is a proper nice setup and there's things are working smoothly there so probably the next phase on their cards the maintenance card probably maybe should be ie or that compatibility but again if you look at it right the aim is not to really have browser compatibility the aim is of this library so this is probably where I would not use casper if I were to really make sure that website looks proper on ie and this and all of these that is not what I want to do my my aim if that's your aim as as so again this comes up with digression but I think it's okay when when to really use this and when to not use that's that's the main question that we all face and that's a big choice that we have to make right once you make a framework choice you cannot live with it and you have to support it and you have to get along with even with drawbacks so so for that I think Casper where I would use or what I have learned from and what mistakes when we know we made while we while we were using that what we've learned from the mistake is I think I would use it for to start with small to know to automating end to end test for small applications to start with and see how it fairs for me exactly for that like we had a very small application which which had a couple of functionalities some credit operations and some reporting and some just calls and some network services and just in that internal in the application and we wanted to test each of those components and all of that whether an uploading form and submitting forms and things like that so I would use it for cases where it's it's it's it's where I don't really care about what browser and how it looks and and the compatibility issues that's that's probably one phase one for me that's that's one criteria major criteria because it's all headless and I don't have access to the actual I can't see the browser it's headless so that's that's limits your choice and it's very specific targeted to very specific things then the reason I would use is it once you get the hang of it we took took us two weeks to really understand how it goes and what's the apn to explore and and figure out how to write as and once that I think we we wrote the test for that application entire application in three three again total three weeks we have in three weeks we had the complete test suit which was running for that application and that considering and we again we did not choose to automate all and all the workflows we were we were automatically only 80% of the common workflows that are business that that were possible in that application so again what you need to automate and what you want to automate that's again a drive for choosing the framework I would say does that kind of answer your question I'm digressing a lot no it's sort of less probably we could also say that since Casper gives you the confidence with web feed and yes you can at least use it eliminate this yeah yeah I would do that from what I said I did a little bit of preparation before coming here there is an automation tool for IE as well called trident.js my internet is not working there is a like phantom is for web feed apparently there is a js but IE as well called trident that was an experimental project but I don't know how much the development is happening on that apparently there was a time when people were using it to automate IE tests so people could look it up yeah right so that's what happened trident.js from the experience I can tell that even you had different browsers and you are displaying something right even if you take the same app to different browsers there would be even a pixel gap so I mean okay so we have a project called this is the project so the difficulty is about the 3pt standard right so on different browsers when you have seen the same 3pt you would expect to see in the same way right so even they couldn't find out a very good way so they did a hard part like taking a snapshot and comparing the pixel by pixel I mean they did a very much image processing programming rather than writing any test cases for a specific browser so if you want to verify a look and feel I think there is no hard and fast tool that this will yeah I think exactly hitting the same point I have something to add so the real game I think what we have used acceptance tests for in general is to not do exploratory testing I mean automated testing does not and cannot right now at least get rid of manual testing I mean if you say I have automated tests that test everything in my application and you wanted to ship I would still do some exploratory testing before I would still do UAT I would still figure out some scenarios manually myself just to get and find out the bugs related to you know your IE or Firefox or browse compatibility there is so many variables and so many things going on and since we are still not standardized on HTML even HTML and also on the browser engines and we are still so that's probably the reason we can't really have we can't really get rid of manual testing even if you have 100% automated tests and that's the stage right now probably in future if we get to more standardized web that's probably when we would be able to have that more confidence there that if my automated tests run and if I have 100% of them covered I can just ship the product so that's probably for the future but for now we have to do some manual testing and exploratory testing looking from single page web applications from HTML and mobile apps from your experience do you think CasperJS can fit in there when a complex single page web application a lot of components which are running from there and here so do you think there also CasperJS can fit in there yes so the question is should I use Casper for single page apps and very high UI rich component apps what I would do is I would I would try it out for one case because what I have seen in UI apps or in very high concentrated or rich UI apps is you have mostly all the logic right business also on UI and also the presentation centric logic if you use Angular right this app uses Angular so there is a lot of things like if you look at it right if I just add something there is a lot of classes that are changed and it's very dynamically so it just modifies the HTML dynamically and the problem could be if you have enough if you have a way to nicely select the DOM elements and assert there that would be okay but but this is probably not a good example but if you do something if you do some action here that reflects a lot of other components right you have kind of an event and that so many listeners for that event if I check something here it is updating this item it is updating this item it is adding this item so it is doing three things at once so to verify this and to really locate these elements and find out we will see it becomes complex a bit so what I would do to start with is I would try to write a one test and see see the feedback from the test get the feedback from the test is that test readable that's probably the first feedback does that really make sense is that maintainable in a sense if I just change some HTML element or if I just change something is my test breaking up even though application functionality should not be breaking that's one feedback that I learned from the test and then I will choose whether to go with any framework to start with any framework what we do is we always do a spike we always try to try it out once we don't we don't make a decision okay let's go with this I think this Angular is good so let's just go with Angular that's not the way we should do in general application development you should be able to try it out and learn from your mistakes and learn from your past experience also saying okay I have used Angular for that kind of application but this is probably different ballgame altogether would this framework or would this choice so it's coming back to using the right tool for the right job right for the job at hand so it's again is learning from mistakes learning from and trying out some things and learning from that so again there is no silver and direct answer to that there's no black and white answer would I definitely use it would I not use it it all depends kind of bottom line is like as per this it's not good for more of like down the limits are being created again I don't want to give that impression because I have not tried that so again if you are getting that impression then but as long as somehow you have to look at that down the limits it should be in the page but what happens normally in complex cloud web apps which you have seen we conditionally rent there are some kind of blogs okay so they only access HTML they create it when the process comes by but that is true for any any framework is out there which tests it all like Selenium sometimes you just hide it and sometimes you don't create it so if it is hidden you can still test it but it is not there at all it's just the logic is the back end is controlling front end somehow so in that case so there is a way to check that also there is a way to check assert element exists assert the expat selector exists so that check and check your there are checks for that yes there is a way to do that also you requested some resource and you wanted to wait for that resource to be available and then you wanted to do something with that so I have seen good examples when people what they have done is they have yeah so maybe less I think it's a good point to go through the high level API what these what are available in Casper so you have a lot of them related to let's say this is one that we looked at capture the screen shot this is you can click any button or link or anything with the selector again everything takes a selector if it doesn't make sense right so everything takes a selector there then you can you can get the entire page source code and do if you wanted to pass that or do something in that you can download resources there is way to evaluate on the fly so that's one which we will be touching that if we get there so you can evaluate some function on the DOM to do something when the page loads I can ask it to run some function there on the DOM it's like going to Chrome console and then running the function there it's just like that you can evaluate it directly on the fly on the DOM then you can check for elements that exist on the DOM you can even do forward and backward with the URLs you can auto refresh the page you can do all those small things so these are really not the capabilities of Casper but they are of phantom so Casper is why we use Casper you can use phantom also the reason we wanted to explore Casper was phantom we found out that it's kind of low level API and then you have to deal with HTML page it's a very low level API and this Casper provides a very high level and exactly that's what they do they say that it's a high level API kind of on top of phantom JS so that's the benefit that you get that you worry about the business flow and not worry about low level HTML and low level code you work with high level languages you can get HTML, you can get title there's so many APIs, you can wait for selectors wait for resource, you can work with popups with frames, iframes so there is good support for that and that all comes from phantom if you know something is possible in phantom, probably that's possible in Casper because it doesn't do any magic on top of that and I think we haven't had a case to really go to phantom to do something the existing Casper APIs that we had that are there, they were sufficient for our needs but I think I'm sure if there is a way if there is a need to go to phantom there is definitely a way to go to phantom and then actually do ask phantom instance, inner instance to do something for you if there is no API for that in Casper although we haven't had chance, we haven't had the requirement to do that because the Casper API itself is nice and good it suits 80% of our needs so that's that, you had something to say? okay so I think let's take a time check, we are 11.45 so we'll spend another half an hour if it's fine, is that fine? are you guys following along and is it nice and clear for you? because we haven't really covered anything we just, I wanted to cover so much but this is just basic stuff that we have covered we would take another page where it has a little more variety in terms of the elements input elements that it has so what do you want to do? okay is that okay if I demo that? we've had that application that we root tests for they had those elements, some of the elements video boxes, text boxes, text areas and this and we can cover that or for now I can just give you a way to so there is a fill URL or fill API, you can fill a form that's how you would fill a form in Casper there is a simple way to just if each of these is given a name you would just say this and that and if there was no name what you would do is you could also select this by by selectors so you could say okay I can search by input with name is equal to that and then fill the value so there could be any other selector over here, I could select by ID I could select by whatever because typically the newer forms that we typically do there is no I mean if it's all client side we don't need to have the names or IDs so there could be different selectors that we can use over here we can take it afterwards, I think it's fine so what could be the so this is one test, what we have done is we have tested that the to-do header is found but that's just very static or simple test we want to now be able to say if I can add to-do or not I should be able to add a to-do and see the to-do is added I should be able to do that, so let's do does that mean that only one instance of browser is possible simultaneously if we have the run one because I'm just using the Casper to do very good right, right, so what I could do is you could, so yeah it's just one instance here right now, what I could do is I could spin up a new Casper instance, so if I had two tests I could run Casper whatever, Casper JS test one and then similarly I could do Casper JS test two and I could run them in parallel, it's just one command you can run commands in parallel, so there's a way to do that and I'm typically running a test, so yeah, you would want to parallelize that if you wanted to again, we had around again from experience, we had around I think 8 or 9 tests or 10 tests if I'm not wrong, 10 or 11 tests but each test had there were some tests which had a lot of assertions a lot of setup and a lot of interactions with the element we were actually using this for survey creation and testing the survey creation application so we had an application where we could create a survey with multiple questions and then each person the individual would take a survey and then we wanted to verify the survey report that is generated is nice and clear so that was our test, so we had a lot of setup to do create a survey with multiple questions for 5 users or 3 users, the 3 users were taking the survey in the test as part of setup and once that entire data is set up, we were actually verifying the report generation works properly or not, so that we had such tests and I think the average, I mean I don't have the benchmarks right now on the slide, but the average duration for that was in seconds, it ran in less than a minute for us, so that was not a problem but because it's bit headless right, that's the thing if your application is slow then that's a different story but the test would work properly and again if you are told it's a problem you can always parallelize using basic, parallelizing that we just discussed and if that's not sufficient then probably you would have to figure out what different ways to do that so now again coming back to the application, what we are trying to test is I can add a to-do, I should be able to add CasperJS or whatever to-do and I should be able to see that to-do there that's kind of giving me a proper nice valid test just checking the sample text, that's just forky-dose I think, so let's try that, so that is my text editor so what we could do, we could write a different new test for this or we could let's say do it in the same test again up to us so let's say we do that in the same test or we do it over here before we capture this screenshot, so let's say we do this now once you've verified that the header is there now we want to add the to-dos and then verify the to-do can be added so maybe I'll rename the test now the to-dos something like that once that header check is done, I want to do casper.den some function and this is where I want to actually add a to-do, so I want to be able to somehow go to this webpage and click on this or select this text box, I should be able to type in something and say enter, because that's the only way to add that if there was a button to add I would have clicked add or I would have hit enter, both would have worked fine but here there is just one way to add which is to go in the text box and hit enter so let's see whether we can do that so there is a way, so let's say so first we want to select the select the text box and type in the keys type in some text so again the api, if you google or if you go to casper website there is an api for that that's called send keys, you can send keys in some selector and then that would be there so I can say what you want to find out is I want to first find out what this what this element is, so that where I can where can I add the input so this looks like an input input text box, which there is an id there so that's good, so I can use the css3 or whatever id selector simply, so let me copy this todo id, new todo and let me say yeah, so so I can say this.send keys again the syntax is you pass in the id selector so I say that's my selector and what are the keys that I want to pass in so this is where I am I am actually adding the text in that text box as if I am typing the text in the text box and now I want to submit that, so there is the only way to submit that is to hit enter so is there a way to hit enter so again after googling I found out there is an api or there is casper as this so we are again hitting some key, so again this has to be send keys and there is a way to model enter and that is via again casper's inbuilt event, so I am saying again hash to loose, I want to insert there and there is, so these are a couple of objects that casper gives us and then you can look for methods or internal structures there if you wanted to so there is casper.page there is not event.key.enter so that is the enter key that you can press there using that, so there is enter key probably there is escape key also I haven't needed that but there is enter and escape keys there so if I do that then this kind of simulates the action of typing in something and then hitting enter so that essentially adds it to the to do right so let's say if we can if this works let's just see and then again let's for starters right let's do let's just do this and take a screenshot we are not really verifying anything we just want to take a feedback as to does it really work because I am still in exploration mode I don't know whether how to write and what to do I am still in exploration mode so I am going to run this test and then open the file you would see that the casper.js is added there, so and the to do is added one item is left and the web app has taken care of the functionality so now we have seen that it works there is a way to add a to do now I want to verify that and that's a verification part so how do I verify that so so the way is if you look at this page now let's say if we try this let's try this one let's say test and so it kind of adds a new list element or list here it is adding a list here right and and if there is nothing there is no list so list is empty initially to start with and when I add something in the to do a list is created or I don't know whether it's created or it's already there but it's empty I need to figure that out but what I can see the list is added and list contains one item there so what we can do so what we want to do is I want to be able to select to whatever this list in some way and check that the size of the list is one for starters let's do that let's say we do that for starters like if there is one more element then there would be there would be a list with size 2 there would be 2 li elements in the list so let's say I want to do that first for starters so as usual I am going to say casper.then and once that is done I am going to say you have to execute this function and what do we execute there is so some way I should be able to find out that list and and then verify that the contents or the size of the list is one so there are multiple ways I want to demonstrate one way wherein we can create a reusable function so if you look at this application in more detail right you have this list over here if you go to active you would see the same list over here and if I say let me do couple of more items here and let me so these are the items that I have and I have one item that is done right so I have to do 4 items but I have 2 items that I still have to do the other 2 are done and completed so there is one list over here if you go to active menu or active function that function and you see another list of active items and another list with completed items so what I am thinking is probably since I want to later test the active and completed and that functionality also is there a way I can get the list in general like is there a way to get the list so that that is reusable that code is reusable so what I want is something like that we just talked about sometime which is evaluate I want to evaluate some function some x path selector something that will give me that will give me the list that I am looking for so so let me write the function that I want to be evaluated which is I want to be able to get the to-dos get whatever to-dos I have these are the to-dos or these are the to-dos or these are the to-dos whatever to-dos I have I want to get those to-dos so let's write that function that I want to get a to-do so how would that look like so so let's say I am writing a function get to-dos and I want to return all the elements that match a particular selector so what's the way to select this to-dos list so there is the application so let's say we right click on here and inspect the element and find out what is there really in the so I will have to do it this way just bear with me for some time let's say I am inspecting this element just so that it fits into the screen so there is this li there is another li so these are the list elements here and there is this to-dos list there is this to-dos list so and when I have one to-dos in that I would have one list item in there there would be two to-dos there would be two list items so this is the list where it actually dynamically angular in the application dynamically appends the items list items there in that list so that's what I am looking for here but what I am looking for is not the to-do list the ul elements but the li elements in that if I just say hash to-do list it's going to give me the ul it's not the ul but the actual list items in that so the way I could do that is I would say if this selector works for that so let's say we say hash to-do list it selected that list for me and if I say li it selected all the li's for me so that's what I want I want all the list items and I want to make sure that there is just one when I add just one to-dos and there are two when I add two to-dos and there are n when I add n to-dos so this is what I want to have this is what is going to give me the to-do list so going back I am going to say document dot so this is where I am accessing what I am going to do with this get to-do function I am going to run or evaluate this function I am going to ask Casper to evaluate this function for me in the DOM when Casper loads the page and it comes to this part it is going to say okay in the document right now that you have evaluate this function for me and you get whatever that function returns to but dynamically evaluating the code there and this is just to demonstrate again this is just one function we could have we are again doing basic selection over here we could have actually done some function that does some more manipulations or does some more logic than just queries using a query selector right so this is just to demonstrate there is one way to do this we could have also done it using XPath previously or even CSS selector if you wanted to but that is just another way that I want to show you so that this is more powerful or useful if you wanted to do some more things instead of just selecting some things if you wanted to do some more once you select I wanted just the third element just the fifth element whatever you had some logic to return evaluate probably is one way you can use so we are going to say document.query selector and I am going to say I want all the elements that match this pattern so these are all my to-dos really right these are all my to-dos each individual to-dos these are the list items and I am going to say now okay so that is just one so that is the reusable function but how do I use it here how do I evaluate that function so I can say casper.evaluate for me and then I am going to say evaluate this gate to-dos and that is going to return me all to-dos right these are all the to-dos that I get from that function all the list items and now I can say casper.test.assert that so what I want to assert is the size is one for now just for starting with right once I want to do the size should be one I can go and verify each of the the text of the to-dos also that indeed when I add casper.js the to-dos is actually casper.js and not something else I could verify that also but for starters let's say we just verify we have a very linear linear assertion here just to check the size of the list here so I am going to say all to-dos.length has to be one it has to be one and if that is the case then so this is the assertion message that you want to see in the test if you look at the test let me enable the debug mode so that I can show you that so this is one message that will be displayed when the test passes or when the test fails you will know exactly which assertion failed so this is just a meaningful message that you can give so that in case a test breaks you see it breaking you see what not failed you can really find out exactly what failed so I am saying when I add one to-dos only one to-dos is something like that that's what I am testing here so let's say we will run that and again as usual we will capture the screenshot just for our confidence and just to see if the things are nice working nicely so these are the messages that I was talking about when something passes you see that that message is displayed over here and then you can see which assertion failed or which assertion completed successfully and as usual we can open image.png and see that the to-dos is added which was indeed the case because that was so now we have verified that we usually verify that but now we have an assertion that verifies that really so far so good so what else could we do let's say we can add one more to-dos and make sure that there is sizes too or what I want to if you look at this application what it does let's say clear all of that if you look at these you have no message before already you have nothing there when I add let's say something it not only adds the item there but it also gives you some statistics as to okay you have one item added one item left and if I have one more item if you notice that if I add one more item it automatically does this two items left so there is a way to pluralize there is a way it nicely handles the pluralization there I think thanks to angular is doing that but you will see that I want to also verify that this count is correct let's say that this count is indeed one when I add one item there should be only one item there and one count should be shown properly if I wanted to verify that how can we verify that so again as usual we will have to locate this element and find out where this element is and add that so let's say we locate that element find out where that element is let's say I go and find this element okay so where is that element so there is a span for two count and there is this two there is this two here and there is there is this can you guys see there is this two over here so I want to verify that the number is one or not the number is two also so again it's again same CSS three selectors and CSS selectors so let's just quickly do it what I would do is I would say again I want I want to get the text text this text to text so what there are couple of APIs I mean there is couple of ways of getting the actual HTML content of a particular element so when I say h1 it gives me the content of that we just check for to-dos sometime back we just said h1 and then we got the content the text with the text so there is one more way we can do that just for the sake of showing different APIs and displaying that otherwise there are other simple ways to do this also so what I want is there is a way to get HTML HTML content from the DOM because it's a DOM and then you can get the entire HTML content there so what you can do is you can say this .gethtml and you would be able to pass in the selector again which is the selector that you want you can say what we have is we have this to-do count and so what we want is this but I don't want to use strong because strong there is and I don't want to use this ng binding class again because it's not generic enough and so I need a good way to locate this two elements over here so maybe I could say to-do count and strong so I could use a cs3 selector which says which says something like so I am going to say hash to-do count so it selects the complete thing for me and I am going to say let's say just that so just select that two over here and then it gives me the content of that so so that's what I am going to do over here that's this xpath that I will use again if I were developing this application or probably again this is something to learn from the test or make your HTML structured in a way if you call it that way so this is a very flaky lookup if you look at it if I would call it very flaky lookup if I just change the HTML tomorrow that's the test is going to break but my functionality doesn't break so this is where there is a do it pragmatically here and avoid too many of such lookups or too many of such UI coupled look selectors and locations otherwise your test will be so tightly coupled to your UI that even if the functionality changes if your only UI changes your test would break and they would break for no reason just because that selector if I change it instead of strong if I use something else that that test will break for no reason even though the functionality works properly so that's one lesson learned from writing good acceptance test you don't want to be coupled too much to UI if you're coupled too much to UI and the way the HTML is rendered the way the particular class is used because UI developers if they are working on this they would just change the HTML tomorrow if they find a better way if they would just add a new class and then all your test would break and they would not know why that test broke because if they try that app manually the functionality works but it's just a test very tightly coupled to UI and it's a flaky test so avoid such lookups wherever possible in case of legacy or in case of such apps like we don't have control over that so this is where you have to find a control you have to find a sweet spot and you might just say okay I don't want to verify the strict assertions I just am okay with linear assertions I'm okay with just verifying that the to-do size list you know this size is one that's fine for me for now so that's where the pragmatic pragmatism comes in and you say I don't want to verify each and every element each every you know text box or the selectors I just want to verify broadly whether this works or not just to give me confidence and just avoid very tightly very tight coupling and flaky test so this is where I'm going to get the to here all I have to do is to say casper.test.assert it has to be to and this to I could say equal equals or I could even do assert equals to equal on that and to do it was one to do right so you could give the same message to this and this should still work and should still pass and now we can add one more to do now it's very simple now we know how to add it to do just sending these keys sending these keys again with let's say new input so let's say we add one more to do and see that two to-dos are added let's verify that now it's very simple I can kind of just copy paste this and then say in the new to-do I want to now add let's say phantom bits and again I'm just going to say hit enter there so that that to-do gets added so far so good so following along so that test was complete also here and we have not changed anything this is a strict assertion that we have and so there's no change in the you are here now we've changed we have added one more to do so let's check let's check how that looks like for now so let's just run the test again we haven't we are not verifying anything right now we're just adding adding one more to do so there is some syntax error which line wait okay there's a problem here can you forward to the error message that you're helping with the line? yes that's a good point let me check if I if there is error message so no it can't tell you it doesn't tell me line number but if I enable my debug board probably it should let me check let's come back to that yeah let's do that so let's here open the emergency yes we have two to do items here right we have the two items it's very simple that's what we just did way back talking about debugging and talking about good error message so that's important and we initially spent some we had hard time in gas person time back until we discovered there is a way to nicely debug html also and there is a nice log that difference and it's again very simple you just take as per dot options again I am doing this globally over here you could do this not globally you could do this for only one test or something like that but just put this paper I am doing this globally so I can say as per dot option dot log level and I can say info or debug for example and I can also say as per dot options for you know verbose I want verbose logs something and if I run the test again so it tells you how what it is doing so it's starting the phantom js run time and then it kind of fetches the so if I can you guys still see this so it is trying to request this html page and got a response of 200 and then ran the two headers is visible because as the first test that we had we were just checking for the header pattern and then we are what are we doing so text anonymous so I think you can give step names also which will be which will be visible here I think which we haven't done or need to check that so so it tells you which and how many steps I think what it does is anytime you have casper dot then and casper dot then and chaining of that that counted as one step so that's what it is 4 of 6 5 of 6 and 6 of 6 that's what it's doing and then capture save to blah blah blah the screen shot so those are the logs so that's that what else can we verify I mean we are just adding functionality maybe what we can do is we can we can verify that the tools can be checked let's say for starters again so there is a way to check all the tools and there is a way to check one to do also you can just check one to do and there is a way to check all the tools also so let's say for simplicity we will do this one I think I tried with this but the locators and there is an array and then you have to do some jugglery to find out this element only this element because there are no good selectors for that so let's just do all all elements so there is a way to so this is it's an id called toggle all so there is an id for this button over here and when I click that it toggles the to-dos or it checks all the to-dos or unchecks all the to-dos depending on the status so let's say we have added two and then we want to toggle we wanted to check all the to-dos so how would that work what we want to verify is when I add two to-dos and I click here all the to-dos should be checked and probably the assertion would be there is a zero here so there is no items left probably that's probably how would I how I would assert that actually the checked word and probably also I could assert that I think if you look at this if you look at the JS it must be adding some class or something to this element over here so that you get a stripe through font what you get is a stripe through font and that's what so it must be adding a class there if you look at yeah can I just to be honest can you guys see where is the class added complicated yeah I think it's a so how does it okay so this is where it is adding the class okay so it is adding for all the list items that makes sense and because we are checking all the to-dos so we could also verify in here that the class I think we can verify maybe but it's up to us as to how we assert and what we want to do is we want to limit or we want to limit the UI coupling as much as possible let's just do it with this the zero items here maybe for now so what I want to do is I want to click here which is a toggle there was a toggle class let me inspect this element again so there is this toggle all and if I click on toggle all it should work right so let me go to console and I can I can verify that dollar or yeah it's just a simple idea lookups on a problem I can just do it so this is where we'll do it let's say we have added two to-dos now we want to check all the to-dos so we want to say as per dot then this is where we're going to check all the to-dos so what we what we did here we clicked on this element right whatever the idea was we looked up this element and we clicked on that element now there is is there a way to click we want a way to click on a particular element based on selector so we have that we can just say this dot click and again you will find in the API that this takes a selector which we can pass so we can pass hash because that toggle all I guess toggle all let me verify that that's exactly so let me verify it is toggle all yes it is toggle all id so I'm finding my idea and just click on this element that's toggle all so again as usual I would not write any assertions first I would just get a feedback and see if this is indeed happening and I would run the test and maybe we can just disable disable logs and open the image and open the image and the to-dos are checked so that is working so my selector is working and the to-dos are being checked but now I do verify that there is zero items left here so again I could do it in the same lookup selector and then verify the assert equals is equal to zero so fair simple it fairly easy so let's copy paste data session where are we verifying this yeah so let's say this one then and I say it has to be zero right to do count it's short something like that what is I think do you want to cover I mean we can go on and we can cover more tasks we can cover okay when I click on active only active to-dos should be shown when I click on an active only inactive to-dos should be shown and when I clear completed all the to-dos should go away and then the size of the list should be empty or this should be empty the to-dos list so we can go and implement and do all of that maybe I think what I would like to do is what do you guys think should we stop here because it's it's not adding much value I feel it's just plain same thing doing over and over again so what we can do probably right now is just discuss about anything that you might have I mean it don't be related to I think we have we have around 15 minutes if Mayank if I'm not wrong for lunch so to let time let's have a discussion about any topic that you might have not necessarily related to Casper or not necessarily to testing or anything it could be anything in general if you have learned something by using some tool share that so let's let's have it as a platform and let's discuss about things that that we work on and then our learnings or problems that we face every day right so I have a question regarding Casper so we just had a demo here and we tried to take a look at Casper so we started in some really seconds and now you see your results in about 5 seconds so when we are getting more and more tests it will definitely take time assume that if I want to make it automatic so in short my first question is how to make a bigger test I can make multiple tests and I want to do all of them gradually how can easily you know I can generate a report on top of that I'm not more interested in what are the past and understand what can fit and definitely maybe everything so that's good so what I can tell you from my experience about the reports let's start with the reports first Casper we we had Casper J's test running in our Jenkins box and we were just printing we were just happy with the so we had the info logs were both logs in Casper and we were happy with that we did not have any problems there anything something fails we even know what selection failed and what selector fails and we even had this screenshot captioning mechanism and we would add that screenshot to the build so that we immediately know if I just all have to do is any test that fails I just have to click on the screenshot to see the page where it failed and probably I know okay I probably missed something there and we just go and fix that so that's from that we that's of that was sufficient for us whereas if you're typically interested in the the output or the test report generation I think Casper has X unit type of so you can you can generate test reports where is that you can generate test reports yeah but you can generate test reports minor using a command line argument saying you can export it into X unit format so that is compatible with your so it's very similar to the report that you get right this test file this test passed this test failed and if you click on some test you would see what failed in that test so it gives a nice tabular view of view of that I haven't tried that myself but I've seen that there is a API and there is a way to export the reports in X unit format which is mostly compatible with the CI servers so that's that and as far as the is Casper really fast or will it make my test really slow as I grow over time so again so probably why it is taking time is because of couple of reasons right now we are correcting to internet and then fetching that page from the internet that would be one typically on the CI server what you would do you would deploy the application in the same local environment so you would not have this network calls but you would have the network if the application makes networks call for other services you would have that so that could slow so that's the application slowing the test down that could be one or is the Casper itself that is slow or the phantom that is slow so I mean if I am right maybe you can correct me so in this building system we just look at one page and after that we do strata parts in the same way so when we execute the first test is it gets completed in really seconds probably but currently I can see that it is taking 5 seconds to send a valid to that so we just included 6 or 7 steps yeah true true so I can't explain that behavior but what I can show you is yes I can show you so what I can show you is so we have this application that is running and let me see if I have Casper test test so we have this one spec with couple of 10 of whatever 10-15 tests and this was the report generation that I just mentioned there was a survey creation tool and there was a report generation let me see if this is still running and how much time it takes so this is pretty ok I think let's just verify my I think 20-30 seconds probably again this is again off my local so I have 30 there are not 30 tests there are 30 assertions that I have but some of them are very complex assertions which which require us to do lot of setup data also this runs in 22 seconds so frankly for us we haven't done heavy acceptance testing we haven't used Casper for a big project wherein we have thousands of tests and we automated all of that we haven't tried that but for what we have tried we did not have any problems and I think what we've written that's a sizeable amount of test if I were to run again I can't compare and I don't want to compare if I run this same thing in Selenium with a browser it's the browser that slows everything down so Casper being headless is very fast compared to Selenium because it's browser based so you shouldn't have any performance problems in case you are worried about that you could always group your tests this is what we could do you could always group your tests the slow running and the fast running test so you could always do if I have a big application which I wanted to test right what I could do is I could have sanity tests which are grouped in one file and I would run that file first so that I just want to verify that entire functionality basic functionality of entire app works and then I go crazy in every feature and then I automate that feature and then I check that feature in depth that okay when I add it to do I should see it to do and all that related to to do if I have something related to the other part of the page I just check have a sanity test that the basic heading is shown which is displayed there is a form that I can see and some basic very basic stuff which is very fast which doesn't need any interaction so I could do that you could segregate your tests into fast running and slow running test and run the fast running test before you run the slow running test so in Casper you can give multiple script we just said one script right spec.js you could pass in multiple files and it would run those files one by one I think I mean you just pass in multiple files just like in the next command line you just pass in multiple files and it would run that so shouldn't be a problem and there are always simple ways to get around that problem is by running multiple Casper instances because each spins up its own separate thing right so it's not a problem yes I have something to add to this on this which is that when there is some optimization that you can do what you say hold true very much in addition to that what you can do is sort of look at your testing strategy and see what kind of tests need to be at the UI level and what can we level down and what can we push down to the lower levels and integration and unit test and to know more about this if you can google on youtube search on youtube about inverting the test pyramid there was a talk about this in another make up called tech jamming valley about few weeks ago where the title of the talk is inverting the test pyramid where exactly these topics are touched upon how do you that is more of a strategy rather than whether to use rather than not to optimize Casper it is about the strategy of how do you test your whole application and ensure that everything works so now should everything be UI testing should everything be integration testing or should you do only unit testing is a call that you take and if you want to know more about exactly how that happens you can look for that you know inverting the test pyramid on youtube that will give you a little more input from a strategy perspective in addition to making Casper yes very tight list idea I have one more question sir no no no problem so you know because we were writing everything in javascript and the biggest time consuming thing which I observed is finding the x path and everything so I am very about you know we have data and we can simply code it what it and you know we can play it this help us quickly help us finding the x path and everything so definitely probably your real projects are even we are seeing the observed testing so is there any quick way and any shortcuts so resurrection is one tool which I think it is a Chrome plugin or something like that which records the tests and creates a Casper script file so what I could do I could just run resurrection I don't have it installed how do you spend something like that yeah so this is one tool in Chrome that you can use for recording you use record and script so you would it would record whatever action you do and then when you stop the script it would produce output which is Casper compatible script file that you can just reuse later one learning that we had from any I mean you would even notice that yourself if you were to do and table enough in testing that any of the record tools they are they are not very perfect and what they selectors they do they are very UI specific typically they say okay slash HTML body slash div slash h1 slash something is equal to that but that's very UI specific this is very UI centric and it's very bound to fail again and you would have time and nightmares in debugging why fail and then re-creating the test script and the code that they generate is very messy and very crappy to be honest and it's just a pain to work with so that's but again if you were to look for Xpath they are probably good tools even in Chrome you can just right click and create get the Xpath I don't have that plugin installed but there is a way you can get the Xpath of a particular thing and then helps you finding Xpaths and that selectors so that's it so when we talk about Casper JS you know we always say that sand does and so you can then you know like why doesn't it execute and you know it's not everything so it is pretty faster compared to Selenium is there any other difference to observe like to highlight here comparing Selenium or any other advantage of using Casper okay so yeah good question so when would I use Selenium and not use Casper or vice versa again it comes back to since that's what I have experienced with probably that's and it has worked well for us that time so we had this application that I just showed you in the 2030 test we had this application in Node.js and it was all JavaScript style so it was very easy for us and it was very quick for us that we find something that's in JavaScript so that it just gives us a momentum and no new tool needs to be installed and you know Java virtual machine and all of that stuff and and this is very easy to start just take npm and install Casper.js and then bam and you start running the script if you know the API there's no jar to be downloaded there's no profile to be created for Firefox or there's no setup much of the setup in world so for quick running things that's what we tried for that approach and that's what we we felt the value was added for us so probably that and again we had all JavaScript so that again kind of had a decision going for JavaScript framework for acceptance testing yeah okay so again now my knowledge there is a bit limited I think as in we haven't really tried it for a heavy application which I think which is what we are going to do now I mean we I'm working on a project right now which which has heavy which does a lot of network calls and which is data from multiple sources so so and we have currently not had any acceptances for that for now we are fine with basic UI testing and basic sanity testing by basic manual testing are fine with that so we want to now write test for that so I I'm thinking should maybe we maybe Casper will fit there and then I'll have some more learning in terms of using it for a bigger application so so to speak so not what I can't tell you from my experience because I don't have but what I can tell you in terms of as even the other application even the other test frameworks they have the same mechanism which this has so I'm guessing there should not be any big big worry or big problem there as long as you your choices made properly as long as you care only about the functionality and not care about whether it looks fine on this whether it looks fine on that and you can again always separate that and you can always write your acceptance test in Casper for functionality for making it fast and headless and you can do the sanity testing there and if you want a big proper tests for browser compatibility and for the other issues you can always go with other go to other tools and so it's you can always mix and match the tools and use the tool that it is intended for so that's yes so that's yeah so that's when you can always maintain that in the same repository and have set up differently but yeah there is some over it there yes yes yeah right right yeah yes that's one so again that's that's where we usually pair on on everything that we do in equals right so so that there is no dependency and we get to learn from other person so that's that's one of the things that we follow as part of our process and we again maybe I want to point out here that the acceptance that we wrote right this this was not written by QAs specifically we were involved actively and we wrote it and we treat this as a normal code base we treat this treat this as a proper code that we have to maintain and work with so we try to strive to keep it clean maintainable readable and we try to learn from the the feedback from the code right what it says if it if the tests are just becoming messy probably there's something to be learned there and and probably as what Sela said I think maybe should we should we automate this you know drive this from UI drive this from simple unit test will that suffice so these are the questions that you have to ask as a team and take feedback from when you when you code actively in in any product assume that you know I write a test case let's take this example right so in this test case we already ended to go home to lose I have a separate test JavaScript file which takes on from there so my question will be if I have to separate file which you know the background is creating a base for the second one right so and if I execute in a group will it maintain my state or will it execute you know right so again that comes back to writing tests so what I would do is I would write a test that's so every test should set up its own data so tests should not depend on external environment to set up the data you can use setup and tear down methods Casper also has that there is a way you can do global setup for every so let's say there was some some web page that you wanted to do some image that you wanted to download before you can proceed with the test you could do that in setup for example there is a way to do that in Casper every framework like logging in the website yeah logging in the website so you could do that you could do that as part of setup or every test can do that so you could extract that out into functionality which is exactly what we had done our tests where if you imagine they had to create the survey people had to log in and fill the survey admin had to log in later and check the survey so there was all this setup so we had extracted it nicely into small small methods and small small reusable snippets that we can use for other tests also so every test kind of was setting up its own data and was very clean and readable in that way