 Hello everyone and thanks for coming to hear my talk on this ember add-on that I've been working on in the last few months We all think that integration testing is a good thing and hopefully you're doing it Personally, I like to do maybe 70% of my time writing integration tests and maybe 30% writing unit tests, you know, I Just like to see if my application is working Okay, so The reason that I wrote this add-on is because as I was writing the integration tests exceptions tests for ember applications I was finding that it was quite a repetitive not very Exciting and it's quite predictable and I saw a lot of patterns and there wasn't anything like new intellectually that was doing so I thought it would be maybe a nice idea to have like a recording use for interactions and And I'm seeing if I can play it back through like the q-unit system and I'm sort of like an Excel macro in a sense, but in ember and So The way that my add-ons designed to be worked is like when you get your application If you're not doing TD then basically when if you have an untested application and it's in a happy state and you want to sort of hard-code that Beat into tests you bring my add-on into your application and it would record what's going on and Record things that are changing and stuff of that and generate tests. That's them. That was the ambition and my ambition is to See So I'm going to explain a little bit how it works There's two things going on when it's doing the tests I Have a series of Loops and recursive loops going over the DOM adding limitation observers has anyone used mutation observers before They'll thought these newer browsers they have basically ways to watch For changes in the DOM and if something changes like an attribute or something added or removed fires off an event and you can basically tap into it and extract information and So in this when this Component is added to your app. It basically goes through your application and sets up all these list listeners and things like that and We also as you're interacting with the app click events jQuery focus in events stuff of that it will then generate like code stubs and The DOM mutations will then be injected into there and generate your tests and And yeah, this is combination that does this so as the user is in clicking on the screen we generate some Some like click here fill in this and then there's like a placeholder for changes that will then happen So a synchronously stuff like that and these mutations from my mutation observers will then look for this placeholder and basically Fill in all these bits here. So as you click in things you basically it's basically a lot of string manipulation. It's going on Basically get these bits filled out and then things that change I have some sort of very basic Assertions, you know, like is this visible and stuff like that Eventually, I want to do some like heuristical stuff. Maybe looking at things moving around and things like that But I haven't quite worked out how that's going to work yet There were some complications I will do a live demo by the way There were some complications That I had to think about quite a lot to get this thing to work When things are removed from the DOM, it's quite easy to generate a test for and you just forget about all the Listeners that are set up because they get removed with the garbage collection stuff like that But when I add DOM to the page then It's sort of don't really know how many DOM and the DOM elements that will be inside it and mutation observers The only sort of work at the DOM level that they're observing is you see the DOM and then It's children immediately. So I had to sort of drill down through the DOM and add mutation observers dynamically, which Whenever I go back to look at this call it takes me about an hour to figure out how to change things, you know, and there was some That the admin works okay when you're doing it in your apps But when it was sort of in the actual dummy app and I was testing it then there was some some issues I had to sort of work around so How to use this in your project so basically all is is a little component that you basically Stick in your application HBS file this year and what this is it gives you a little UI the bottom right answer So you swing and as you're doing your stuff with application It's sort of generating the code and then you basically take that code and copy and paste it and then the end-to-end test files like and There's certain things you can add to your DOM that if you don't want it to be recorded like so you have some List of changing stock of change charts and it'll just You know you don't want all this stuff being observed, you know generating a big long-long test Then you can sort of ignore all the stuff in there And then you just basically start interacting with your app. So hopefully I can do a live demo if I can figure out how to switch to my Browser, so first time I've done a presentation of this this Mac, so Oh, the aim of this is to be your test recording coding monkey So here we have basically I've created a dummy app in the the project on and get hub It's just ember CLI test recorder, and this is the The UI here Eventually I want to make this resizable and stuff like that, but I haven't really go around to it I can't seem to see my mouse pointer. Does anyone know how to So this is basically an example of You can imagine I've been clicking on those inputs and things on that screen there and toggling between the routes and stuff like that This is what actually is generated so basically Everything inside here apart from the test block is what's been generated. So For example When they click on a text input And when you finish typing on it it captures the focus out event and generates this stuff here. Can you see that? I was up to small. Okay so what it's done is Generated a friend a copy of the test helpers how they work and if you click on a An amber element that doesn't have an ID it generates a dynamic path to basically reach it So what I was finding a lot when I was writing integration tests is that I hadn't given a lot of things IDs in order to get it to work I had to like go and give them my IDs. So I thought that I'd just be Blazy and generate if there wasn't ID you can just I would just know how to get to it A lot of these things like That appear on the screen or removed from the screen for example if they click on like This button here, which I think was changed in our route or something it would know that this thing disappeared and generate an assertion and then If things were added Then it would basically generate this assertion here. This has been added to your page and Let's just see if this runs on the screen so this So this basically I only did up to 13 different steps But it only captures sort of button clicks and like text inputs, but I'm on my to-do list. There's quite a few things let's get there's a Road map for I want to make this thing more robust. Oh, I want to be able to generate tests for other components like Select two inputs and other things that I used a lot because for some select to input to order to trigger a Selection you have to trigger mouse click here and then do things maybe some date pickers and Things like that, but So far, I don't think anyone's used it in the wild. So hopefully this will inspire you to try it out She's a feeling a bit lazy and want to See this thing records from tests and I could show you some of the code But it's a bit he's about refactoring. So, I don't know So we have a lot of basically We sit this is for example, this here is the Yeah, this quote takes a lot of even for me to figure out how it does again Okay So when when the components are set into the page We basically get a hold of the mutation observer class and depending on various browsers then That's that's the Just to get that there And this is for example recording the code that's to generate the fill-in event. So basically I Attached to any input on the page and on a focus out event I Check to see what type of input is the moment I'm just this is just taking if it's text and then I have some code to generate the path or to get the idea of the component so I can then target it on the playback And then I just basically I'm just generating text text catenation for the click events I'm basically doing a similar thing And then I'm generating the stubs and I'm generating generating placeholders for when the mutations happen after you click on it So the actual mutations happen with these when I create basically this is a recursive Sort of cursive thing I add observer for a DOM element. That's how you create a new mutation observer and You have it as a callback. That's called when things something changes and There's quite a lot of nodes that get returned to that are not like what you're expecting sometimes there's things like white space and like carriage returns and stuff like that are sort of in the DOM and Ignore all this stuff. I have some filters for it So basically get these added nodes and stuff like that and I basically then look over them and generate assertions Like this sort of thing here And then this is a recursive part where It sort of drills down through the DOM to get access to Sort of nested DOM to see changes inside of it. Yeah, this needs a bit of refactor. I'm forgetting a bit of a lot of Yeah, but um, that's that's mostly what's what's going on there, but Yeah, yeah Just using testing. Yeah It's just for a developer to record it's basically a developer trying to record is To generate interrogation tests. It's like just so you can copy and paste this code stick in integration tests. That's it Yeah, that's Was it? I don't know. Is that is that oh really? Everything's an expert from the root So basically as soon as you change something in your markup the selector breaks, and it's not useful anymore All right. Okay, so it seems to Yeah, work like that. So you won't have it in front of you I want I want to use maybe extract all this mutation stuff outside of the embassy ally and then have available for like Protractor testing, but then I would have a habit as a dependency on ember and on so then I could use it because all that imitation stuff You could use it with any Thank you Yeah Well, just to get its parents parents parent up to the ember div Yeah Because you can in the test runner Originally I was gonna look to the head up to the HTML But then in a test runner, it's all relative to like The container it's in so you don't have to worry about what the q-unit devs are about and stuff like that You just do you know this the path that I generated. Ah, here we are Okay, right so Let's just click on this right so hello and Click out of it and So basically Visit here and it's This is got this is got an ID. So it's giving us an ID here, right? Then I click on this thing here Nothing's happened on the screen. There's no mutations or nothing like that. So it's basically and then is stub empty If it's something has changed then I was and there's no code that entered in there Then the test record is not clever enough to hopefully the community will get involved and they'll try it and we'll try and Add things that will record heuristically things are happening in your app I've kind of kept predictable things I'm just going to be nice and gentle with it so this one here is another I've got a root called foo and This one didn't have an ID. So basically to generate the path for the test and There's been a bunch of Dom added here. So basically it's a It's basically said that what's noticed the roots changed here. So it says um It's not that the root name is foo and get current root names of function that I Passed into the component think So the page navigates to full and button click and then this register inputs disappeared So it says this is removed after then you just Write your reason there. I could probably improve that but I haven't quite worked out how to do that yet And there's also like another div that's been added here And shown after you, you know, click on the button. I hope I improve that as well. This is a an in-page button here So if I click on that it's generate this click thing here and then Basically, there's something disappeared. So it's just picked up that I click it again then It's noticed that that's been added So then I click back to the index route And that button also didn't have an ID so it's given us this path and then You know in theory I can just copy and paste this I Can actually click on it and just do that and then go to my tests which you see on my screen All right, I see All right, okay So let's just get rid of all this and this is quite a satisfying when this works And I haven't really done any brute force She's just showing masses of stuff. It's quite a simple application, you know, but I'm At some point. I'm kind of making it more and more Adding more things to it. So. Oh, yeah, so it's basically I don't know if you I don't know if you saw the Little stuff that I done there Can you see it? So you saw it there a bit, right? All right, so Yeah, so that's hopefully it'll be useful and save you some time questions Is exactly the same as you would it's basically all it's just all generated codes. So if something fails then behave exactly the same It's not doing anything special with it. It's just what I'm trying to do is generate tests that you would write yourself Obviously, it's the certain things that it won't you know, it doesn't know exactly what you want to test but it tries to Figure that out and it gives you more probably than you would write and you can just delete the stuff You don't want from the actual code So if you don't like this thing here, or you know You don't care about these inputs and you just you know delete that or You can do something, you know it'll still It'll just not run that test and if you do something bad, you know, just Fail Also, what I want to do is I want to create some like pause pause start buttons and stuff like that so you can It won't just be recording and recording, you know Anymore questions? well, um You can just do it like an MPM install not save it to your package ason so that All it'll do is it'll give you a node module with the file and then you just bring the component into your app and then but you don't commit anything so You don't even tell me what you're using it Something that builds a unique You know because that it looks like at the moment you're kind of just taking the sort of the longest Yeah, exactly And see That's that's a great idea Yeah, that's a great idea Yeah And if we have done the very bare minimum we need to do to generate those selectors and that's the best chance we have Yeah, that's a good idea if you want to do pull requests Great Yeah, I'm thinking of using them in material actually I'm because I'm using angle material and I really love the material I'm thinking of just ditching bootstraps up and then just going to going to material design because it uses fleck box as well Which is if you only care about ever green browsers and flex boxes. I don't know if anyone's used flex flex layouts It's really really nice and what you can really reduce the amount of markup You need to do certain things like position Minimiddle of a page and stuff that's Using Yeah, yeah Is that would that be ember specific or would it be like yeah It seems like it could be Somewhat agnostic. Yeah, so the bit that writes the tests could be Yeah Yeah, but that's kind of a road map I want to go with this thing Have you seen that Apple has copied you for the latest version of Xcode you can New integration testing stuff for Cocoa apps you can hit record and spin up the app and simulate that for Itself in that on OS 10 Click around and it'll do the same thing writing into the test file great except that yours does more because yours observes Notations and then writes those assertions for you. Whereas there's just mostly like Recording of clicks and drags and stuff like that. Yeah Yeah, it's I think we should be automating things that can be automated. You know, there's no point Right, I mean right in the actual application code is something that won't we can do but If it's if it's just playing back, you know, it's get the computer to do it for us Do Well in this case that part kind of hard And I don't really don't practice is not enough time But yeah, this town development is ideal, you know I Mean something like that's reduced Yeah So it's a slightly different Yeah We could love I can you sort of write a test in this add-on and it was an application Yeah, I thought I'd be really nice for protector guys. Yes, that's some I'm there's there's a Angular CLI add-on that's some Development and I'm pinged one of the guys there and I says I'm I'm doing this test score And I like to if you do a testing I want to do it for the angler stuff So but it's really quite right now. It's an intern. It's doing it. So hopefully they'll get back on in that That's actually a good point. Yeah, that's that's that's part of the road. That's part of the road map If somebody if someone asks me what code I'm writing when I say something I'm writing the Integration test that tests the code that the integration test recorder generates So basically that's going to be yeah, I'm going to basically Do that test that was till all that code that was generated. I'll basically copy and paste that into its own Exceptions test and then basically compare that to the string that's generated Because I know if you've got like some levels turned off and it says Roots change to this Because then there's hijacking all of the links on the page To do like the link to I don't I don't know if they're tracking Like Yeah, maybe you could take a message and explain more about that because I don't really know anything about the how that works The rendering performance tabs works in the inspector it can subscribe to The components like start rendering and render right do stuff with that and then I think there's a hook for any time the component is looked up at these various things Yeah That's listening to stuff that's supposed to happen This is the stuff that Maybe you didn't intend to happen because it's listening to the DOM not to how you build it Right, so maybe that would be the difference between one is built in as intended to say did this happen? Yep, it happened. Whereas here you might see something like why is that triggering these three things over here? Yeah, so why don't you just click on that and it just selects all the text And then you just copy and paste it but what the trouble is is trying to make that window um Small enough it doesn't appear and to fear with the actual application you're required to It's not like I could them add a jQuery UI to it make it resizable. I don't they want to blow it off a bit. I was trying to so yeah, I mean I'm open to any cool requests, you know, it's been it's been quite slow developing this over the past few months, but um, hopefully community will start to use it if you uh, I think in theory it would be possible to literally record it to this because he went well have a Server component running within the embassy li server. Yeah client component Send send these things down over the socket as you go and yeah, yeah Seems feasible. Yeah, I mean that could be like a config option Um, I think also something you just don't want to have it. We see the test. It's well. It's running So yeah, but that would be a useful addition to it All right, um any more questions Okay, well, let's hear it beneath us