 Hey there, Polycasters. Rob here. A lot of you have written in asking if we could do a series on unit testing. So today on the show, I want to show you how to get Web Component Tester set up for your project. And also going to demonstrate how you can write your first couple of unit tests. Let's check it out. To get started, we're going to need to install the Web Component Tester test runner. The Polymer team has created this test runner because we want to make sure that when you're testing your elements, you're doing so in a real browser. So that's kind of the benefit of Web Component Tester. To get it set up, we can just run npm install dash g Web Component Tester. And that's going to go out and install all the things. And then we need an element to actually test. And instead of having to set this up myself, what I'm going to do is go ahead and clone a project that we've created called seed element. A seed element is just sort of a boilerplate element, which you can use to sort of as a starting point, if you will, for any sort of element that you're writing. The nice thing about it is that it already has a test directory with some dummy unit tests set up. So once we've got that pulled down, we can just run the Web Component Tester command, which is just WCT. And that's going to try and kick off our test runner. Now, if this is your first time running Web Component Tester, there is a possibility that you'll see something like this, where all your tests fail. And it says that Selenium's Safari driver was not working just then. So what we're using under the hood to actually control all the browsers is this program called Selenium. For Safari, you've got to install an extra piece of software to make sure that it works. And you can see that there's a little URL inside of this error message. So if we go and open up that URL, up here at the top, there is a link to a piece of software that we can download. It's just a little jar file, so it's a little Java thing. And it tells you then to unzip the file. And if you're not familiar with jars, they're actually secretly just like zip files. So once you've got it downloaded, you can just change the extension from jar to dot zip. And then double click on it, and that will let you unzip it. And then inside of here, inside of this directory, we're going to be looking for this thing called safari driver dot safari extz. So we'll navigate a few of these directories, bury it in here somewhere. And there we go. All right, so we're going to open this up, double click on it. And that'll actually boot up Safari. And it'll say, hey, do you want to install this web driver extension? Heck yeah. And now we should be able to control Safari using Selenium. So make sure you close Safari and everything like that. And then we can go back to our terminal. We can try again. We'll run Bower install, make sure we've got all our components set up. That's good. And then we'll run web component tester. And what you should see after a moment or two is yes, green tests. OK, so all the tests that came with seed element are now passing. So let's go take a look at those tests. Over inside of seed element in the test directory, there are two files, index HTML and basic test HTML. Index HTML is where we can create our suite of tests. So all of the individual tests that we want to run in one big group. And to do that, what we're going to do is we're going to set up an HTML file. We're going to include web components like JS. We're going to include this browser JS file up here in the head as well. That is the JavaScript that's being used to control the different browsers. And then we've got a script tag down here, which calls the web component tester loadsweets method. And there we can pass in an array of files that we want to kick off. And each one of those files is a document that contains some unit tests. So we've got basic test.html. And then there's another copy of basic test.html, but this time with a little query string for DOM equal shadow. And what we're doing here is we're saying that we want to test it first under polyfill. And then the second time we run basic test, we want to turn native shadow DOM on. And so for browsers that do have support for native shadow DOM, like Chrome and Opera, that's going to kick that off. And that way we can verify both the polyfill and the native shadow DOM version of our element is working. So let's take a look at basic test.html. So inside basic test.html, up at the top, we're also going to include web components like JS and browser JS. And that's because we could just open this file standalone by itself if we wanted to. Then we're going to import seed element. It's how seed element is already set up. But when you switch to your own element, you can replace this with your own markup. Below that, you'll see that the actual seed element tag is just sitting there in the body. And then underneath that, we have a script tag which contains our unit tests. So we're selecting the seed element. We're grabbing a reference to it. And then we have this suite method. And that's how we kind of create a context for our test. So we're saying, hey, we're going to create a bucket full of unit tests right here. And you can see there's a bunch of test methods inside of here. They're all asserting different things. So what I'm going to do is take this first test up here that says the author's name is Dmitri Glaskov. And I'm going to change it so that it says the author's name is Dmitri with a bunch of z's at the end, Glaskov. And this should break things. So let's see. Let's go ahead and we'll give that a shot. Switch over to our console and run web component tester. And yes, we do see a whole bunch of errors. It was expecting the name to be Dmitri Glaskov. Instead, I got Dmitri with a bunch of z's, Glaskov. So we can go back. And we can just delete those z's, run it again. And now we can verify basically that, yes, these tests are working when we modify them. Things break, right? So everything is happening as we expect it to. So the seed element is great, but there's also a lot going on inside of here. The next thing I want to do is just kind of clean it all out, create my own element. And that way I can demonstrate how you can write your unit tests from scratch. So now that I've kind of cleaned things up a little bit, I deleted a lot of the stuff that was already inside of seed element. It's useful as an example, but I want to create my own element here. So I changed the name to weight button. And the element that I've now morphed seed element into, basically, it's just this little button. And when you click on it, it displays a paper spinner. Pretty simple. So that's the behavior that we're going to test. So looking at my element's definition, you can see inside of the template, I just have a paper spinner whose active state is bound to an is-waiting variable. And then I've got a button which has a on-tap listener which is listening, which is going to execute a weight method. So let's go down and look at our source here. And you can see that is-waiting is just a regular old Boolean that starts l off as false. And the weight method is going to do two things. It's going to fire an event called waiting that passes along a little bit of data. And it's also going to set is-waiting to true. And that's going to cause our spinner to display. So these are the two behaviors that we're going to be testing in our unit test. And I realize this is not traditional test-driven development where you write the test first and then you implement the behavior. That is one way to do things, but this is just the way that I happen to do things today. Either one is totally valid. But I'm going to be, you know, I wrote my behavior first and then I'm going to write some tests for it. So over in my basic test HTML file, you'll notice that instead of just putting the element in the document here, I've actually put it inside of this thing called test fixture. And test fixture is a really neat feature of Web Component Tester. And what it does is it takes whatever is inside of its template and it stamps out a brand new instance of that content for each unit test. And so what this does is it ensures that each unit test gets a completely clean slate version of the element. And that way, if a previous unit test had maybe modified the element in some way, you're not accidentally sharing state between your tests and perhaps confusing them and causing things to appear broken when really they shouldn't be. So this way, we're just creating a brand new fixture each time and each test gets its own instance of the tag. Now to use the test fixture, I'm going to create a reference for my element. And then I'm going to call this setup method. And setup is going to run before each unit test. And so inside of setup, I'm just going to say that my L equals and I'll call the fixture method to grab all the content out of that template. Cool. So now I've got it stamping out a brand new instance of my tag. The next thing I want to do is just write a really basic unit test. So I'll call the test method. And in this test, I'm going to say that when the user clicks on the button inside of the element, we want to see if iswaiting gets set to true. Now I need a way to poke around inside of this element to actually click on that button because it lives inside of the local DOM or the shadow DOM, however you want to refer to it. So I'm going to use Polymer's API for the DOM. I'm going to grab my elements dot root property. So that'll actually let me get access to that shadow root. And then I can query a selector around inside of there and call click. So I'm kind of poking around inside of there, but I know what I'm doing in this case. I really need to click that button, and I can't quite do that from the outside. So I've got to pierce the shadow DOM to do that. Now once that's done, I'm going to assert that the iswaiting property matches true. So far, so good. This looks correct. Let's switch over to Web Component Tester, fire it up. After a second, do, do, do, do, do. Yes. OK, we see that our tests are passing both for. You'll notice that it says two tests are passed. So both the Polyfill browser and the native shadow DOM version were passing. Cool. All right, now that was a synchronous test. Let's try an asynchronous test. So sometimes you'll have some action that takes a certain amount of time. It could be just the next frame. It could be 1,000 milliseconds, whatever. And in those cases, you need a way to signal to the testing library, which in this case, Web Component Tester under the hood is just using mocha. So you need a way to signal to mocha, hey, my test is finally finished, and now you can move on to the next test. And to do that, mocha actually gives you this little method called done, which you can call whenever you've got an async test. So what I'm going to do is inside of this next test, I'm going to be listening for the event that my element fires. And you'll see that in the function to kick off my test, I've passed a done argument. And that's actually a little signal to mocha that, hey, this is going to be an async test. And then inside of that test, I've just added an event listener to my element. I'm listening for its waiting event. And then I'm asserting that the detail message that comes from the event equals time for some meditation. And after all of that is finished, I finally just call done. And that will allow the system to wrap up the unit test and move on to the next one if there is one. And just like the previous test, I'm going to use Polymer's DOM API to actually click the button that's inside of my element. All right. Let's give this one a shot. So we're on Web Component Tester. And it fires up all our browsers. And yes, we're done. All right, so now you've got your first couple of tests passing, but there's a lot more that I want to cover on this topic. So leave me some comments down below. Let me know what you want me to cover next. Also, if you have questions, you can ping me on a social network of your choosing at hashtag Ask Polymer. As always, thank you so much for watching. And I'll see you next time.