 Hi, everyone. Quickly, my name is Nate. I work at a search for targeting company in the city called Magnetic. We're hiring, so come talk to me afterward. That's my shameless plug. So let's talk about third-party JavaScripts. All of you kind of know the general concept. You've seen the like button, the Twitter widget, Google Analytics, OLARC, tons of advertisements. But if you actually inspect the DOM on tons of pages, you can see it's polluted. There's so much going on. There's all these advertisements in the console, outputting all of that. And we're a little bit crazy, so let's take a look at maybe how a JavaScript could work, one of these third-party JavaScripts. So generally, they have kind of two parts. You have your embed code. So if any of you have used Google Analytics before, you have that little code. You give it to the client. They put that on their site. And usually it loads something more substantial, which is all the logic. So that's how we're going to refer to things. And the embed code usually looks something like this. So we're going to go ahead and create a little embed code. And you can see this is just going to load a JavaScript from our third party. And some things to think about are, obviously, you want this to be small. You don't want to give your client this huge embed code. And the logic code, of course, is like the meat, right? It's like, what do we actually want the code to do? And most of the time, this is the place where you have to deal with sort of the biggest problem, which is the same origin policy. So in general, though, we're not going to talk about that today. Pretend our logic JavaScript looks something like this. So I think everyone can understand what this is. But basically, we're just going to create a text node. And we're going to append it to the body of the page. Very amazing. So how do we go about testing this? We have this embed code. And it's going to load this other JavaScript. And ultimately, the way we want to test it is on the client page. We give it to the client. And we know for 100% sure it's going to work on their page. We also know that it's kind of the wild west out there. Any code we give to the client who knows what they're actually going to do with it. But as a reasonable idea, we set up our own test page. If you're in Rails, you create some view, and you put the embed code in there. And we create some tests. So if you guys are familiar with Capybara, we create a test that's like, visit my test page and expect it to have content, because that's what our embed code was supposed to do. And you can test all your features. And you feel good at the end of the day. Your tests pass. You test every single feature. 100% code coverage. You start drinking a beer. And you start drinking a few more beers. And I like to think, after about four beers, I'm peeking. It's my Balmer Plateau, if you will. And I kind of have this feeling, though, that I tested all the features. But if I give this to a client, is it actually going to work? If they put it on their page and follow my install instructions, I don't have that confidence, normally, that I would. And that's kind of a scary feeling. Especially if you're kind of in the situation, if you're a startup or something like that, and you say, I wonder if I give it to my client tomorrow, and it's going to break their page. And we spend all this time recruiting these clients. They're really hard to come by and convince. And salespeople are going to yell at you if you break the page. So you kind of have that pit in your stomach that's like, my JavaScript, it's great. It works. But anyone I give it to at any point, it could break. So maybe you have an idea that says, let's go to this client page, and let's open the Chrome Developer Console. Click on the Console tab, and copy and paste our developer JavaScript in there, or embed JavaScript. So theoretically, that should embed our JavaScript on the page, and we can kind of debug. And when we do that, it doesn't work. We get some syntax errors, we get something. Something's going wrong. All we know is that our JavaScript really isn't working on this page. And if the client puts it on tomorrow, it's going to break. Even though all of our tests pass, when we set up our test page, everything was amazing. And the biggest issue underlying all of this is that with most testing, you don't have to test the environment, the environment's an assumption. So when you're dealing with third party JavaScripts though, that's something you have to completely think about. You can have library clashes. So if your JavaScript uses one version of jQuery and the client uses another version of jQuery on the same page, either they're going to break you or you're going to break them. And there's tons of other crazy things you have to worry about. Part of dealing with this is just having a better design. It's dealing with all these scope issues, and there's actually libraries to help you with that, specifically Lightning.js and other ones. But that's not what we actually care about. We can always try to write better code and handle all this stuff. But what we really want is some sense of confidence that if I give this to a client, we know almost for a fact, assuming they don't screw anything else up, that it's going to work. And just testing in our isolated test page just doesn't give me that confidence as a developer. So it would be great if there was a way that we could almost simulate putting the JavaScript on the page directly without having the client have to actually do that for us. So essentially, we have our one test that we run that visits our test page and expects the page to have the proper output. What we'd actually like to do for our test to look like this, we visit the client page. And we can verify that our thing is actually working on the client page itself. So this is Butters, my dog. And he says he knows how to do this. And he told me how to do this, too. And here's the trick. The idea is, what if we put a proxy server between our browser that's being driven by Capubara and the outside world? And any time that we receive a request for our client page, we listen for the response through the proxy server and inject our JavaScript directly back into the page. So this is a technique that you could think about using. So kind of said again, if you guys missed that, we have our browser, our proxy server, and the client site. And we're going to intercept the response, which is going to be an HTML document. And we're going to embed our JavaScript directly in there. So let's write a proxy server real quick. How do we do this in Ruby? There's many different proxy servers, but you can do this pretty quickly with WebRick. And you can see here, if we look at the code, if we read our JavaScript and then take a look at this block here, it's really simple to do. We just listen for this response. We make sure that the content type is HTML, and that it's from our host. And then when we get that response, we just add our script into the body. And what this is going to allow us to do, again, is to put that JavaScript right into the page and almost trick the browser. We can go to the client site.com, and it's going to look like the JavaScript is actually running on that page. So it's kind of exciting. So here's how you'd actually do it if you wanted to point your browser directly to it. For a lot of you who've used Kevibar, you can register a custom driver. And we can point our driver directly at the proxy that we just started that I just showed you. And one thing to look out for if you're ever attempting this is to make sure that you're not accepting anything that's zipped. Because if you try to add JavaScript to something that's zipped, it's not going to be nice. And of course, Kevibar is great that you can also test IE with this technique. And finally, in our spec, if you wanted this to run before your suite to start up the browser automatically, you could set that up before the suite and after the suite. So great. I mean, we basically solved the problem that we set out to do, which is we want to simulate the JavaScript actually running on the page. And our test passed now. We can go directly to the client's site. It looks like there's a JavaScript on the page. And we're happy. Another side effect of this is basically if you ever are doing demos to any clients and you wanted to show them their JavaScript running on that page of their site without having them to do an integration, then you could easily demo this. Set up a proxy server, inject some stuff into the page and show them how amazing their page could look with your JavaScript on it. You can also do this with phantom.js. There's a bunch of easy ways to do it. But it's kind of the new hotness these days. So it has a couple methods, inject.js, if you want to just inject your JavaScript directly. Also, it makes it a little bit easier to listen for responses and requests. And finally, if you think about the anatomy that we first started, there's the embed and then there's the logic. And like I said, most of the time, you don't have to test the environment. But in this case, you do. And when you're testing the embed, you need to look at things like, what happens if my API goes down? Is it going to break the client page? What's going to happen? What happens if the client installs my embed code in the head versus the body versus who knows where? What happens if they load me dynamically? What happens if I'm a JavaScript inside of a JavaScript inside of a JavaScript? And finally, when you're looking at the testing the logic, you're going to look for things like library conflicts. Are they using JSON? Library conflicts? Are they using jQuery? And you're using jQuery? And especially testing for performance is huge. So I hope this technique, you guys can go try it. I'll throw up this code on GitHub. But the main technique here is, and the main thing to take away is that you want to simulate things as live as possible when you're developing third-party JavaScript. And hopefully this helps you discover new test cases and new scenarios that you didn't think about in your environment. That's it. Thanks.