 Yeah, it's good to be at a duplicon where there's no pressure before release. It is different, a totally different experience, actually. All right, so, hi to my session. I'm gonna talk about testing JavaScript. There we go. So I'm wondering here who in the room tests their stuff, what they built for their clients, what they built for modules, what they built, there we go, so it's pretty much everyone. So you are well, no? Well, maybe you should do as well. Some, okay, that's a good idea already. Yeah, okay, I see. What kind of tools do you use there? Who is aware of simple tests? Like, a little bit less. Yeah, who used something like B-Head for their client stuff? Okay, there we go, 50%, it's good. Yeah, and I'm wondering why do other people not do it? But, yeah, well, it seems to be that you, at least, don't have to be convinced about it, that's good. So a few words about myself. I'm Daniel Wiener, not Wiener. And I'm a duper core contributor since a while. I work mainly with chapter three and the tech one. And in general, I'm a curious person, so I really like to learn something new. All right, so I have to admit something, we are ignorant. We think we are actually good developers or we are good site builders or something and the stuff we actually build works, but I would assume it's actually not the case. We change something and then something else in some other system somewhere breaks. So we need testing in order to actually know that stuff is working. That's not only the case for our Drupal, ordinary site building or something, but it's also true for our JavaScript. These days, people build much richer UIs using JavaScript. It's coming, like a lingua franca, kind of like Latin. It used to be in ordinary language, JavaScript these days is everywhere. It's not only on the front end, it's on the back end. It's used even for CLI scripts. So it's in general really good to know how you can test your JavaScript. So here's some quotes you certainly saw. It worked when I tested it. It has a couple of dimensions to this quote. It not only has this dimension of your computer or the way how you set up stuff, it also has the dimension of that there are different browsers involved. Maybe some JavaScript works in one browser, but then in IE, I don't know. It's not bitching about IE, it's just an example. Because Edge is actually pretty good. Different browsers might behave differently. Maybe we use some custom APIs from some browsers and you wanna know whether stuff works. Another thing which is really important these days is mobile browsers or mobile phones versus notebooks. The fact that our viewport, the size of the screen, changes totally has an effect in the way how stuff works. For example, buttons could be not accessible or buttons could be too big or stuff like that. Small things, but small things for us in quote because they are easy to fix, but it's really making a difference. And it's stuff which breaks all the time because mobile phones, for example, is hard. I would assume. Yeah, there's the other thing, it worked last month. So yeah, we, right? I mean, we have some kind of system somewhere, it works. We'd manually tested it and then like, you know, you tweak this little setting somewhere and then like your whole thing explodes. I don't know, your shopping cart on your site is at some point cached. And I don't know, you cannot add any items anymore because there's some caching. For example, just come up with some random example. So yeah, we also want to ensure that there are no requests introduced. That's called regression testing. Of course, we also want that for our core JavaScript, for example, in order to ensure that this continues to work and especially because we need some kind of flexibility in order to innovate. Because when we know that stuff is working, we can change something. Otherwise, we don't change it because we don't want to risk anything. There are a couple of more problems. I would like to stress out, the second one, new members come into the community. If you are new into the system and you don't know how it works, it can be pretty hard. Drupal is a beast, it is so big and it's getting bigger and bigger. I mean, after you listen to the Drees note, like there was no like simple thing in there. It got like, I mean, preview seems to be like the simplest one of his suggestions, actually. So in order to keep up with that, we need some way to enable new people to also do something. And one way is to basically document the system using tests. So if someone new comes in, they can see, okay, this specific thing on Drupal works like that because the tests kind of describe how it's supposed to work and then they can make changes because they know the tests are still working. So here's like my theory about testing. Is that I couldn't center that thing? I'm sorry for that. But yeah, but it's an SCG, so yeah. So here are three types of testing. Well, like, sorry, well, some kind of types of testing you can do. Let's start at the top, end-to-end, slash functional, slash regression, whatever testing. There are many words for everything. End-to-end testing describes the idea to have an entire site test something like clicking on a link, logging in, posting a comment and ensuring that the comment appears. This is really like what, and it tests a lot of things, but on the other hand, it has the disadvantage that it doesn't really help to know where the problem is. When something breaks, like you don't know which subsystem might have the problem because it's involving every subsystem. So if you go further down the stack, let's say to integration testing, then you'll have a smaller scope in which you know maybe where the bug could be. So what is integration testing? Integration testing is testing how several units or components or whatever of your system work together. In Drupal, this would be, for example, you create some content via the API, save the content and ensure that some kind of, I don't know, some view, for example, returns them as a result. And the bottom is our unit tests. Unit tests is the idea or the art of testing just a specific thing, just that thing and just for itself. And in an ideal world, we would have kind of a pyramid where we have a lot of unit tests which also fail if we introduce a bug. Then like fewer integration tests and even fewer end-to-end tests in order to not have maintenance costs for our tests. So here's a state of testing in Drupal 8.1. We have unit tests. You see the unit test case. I'm wondering whether ever, what's called laser pointer, but I don't have one anyway. So there's unit test case which is basically PHP-based unit testing. It provides you some helper methods to deal with Drupal, I don't know, set up some configuration or something. You should certainly check it out, but there is nothing for JavaScript so far. Then there are integration tests. We call them kernel tests because our system, when it boots up, there's a thing called kernel which is kind of like a Linux kernel. It starts Drupal and kernel tests allow you to really easy like create stuff via the API. But if you think about JavaScript, there could be like a similarity where you have like HTML already on your site and JavaScript running and you just click around but you don't have an actual site underneath. Just testing all the JavaScript together but without an actual site. There's though so far nothing in Drupal itself to support you to do that. And then there was end-to-end testing. There it looks a little bit better. We have that three different system actually, or it's kind of two. So we have browser test space that's, so let's start with simple test that still exists from Drupal seven and six. That's still the thing you should use if you don't want to risk anything. And then there's browser test space which is doing the same. It installs it, Drupal. You can create content there doing HTTP request, I don't know, submitting forms and then checking the output. But it's based upon PHP unit rather than simple test which enables cool stuff like integration with Jenkins out of the box or using your IDE in order to execute those tests which is really cool and other kind of stuff. And finally, there's JavaScript test base which is a way to test JavaScript using phantom.js inside like a PHP unit base test. I will show some examples later how you can do that. Yeah, here's a quick overview of other kind of end-to-end technologies. There's a thing called Behat. A lot of you already know about it. It is a tool to define how your website should work in a language of your client. It allows your client to speak in their domain language what they want. So for example, if you are a bank, you maybe have a different language than the usual Drupal people. They don't talk about entities, I guess. They rather talk about, I don't know, accounts and transfers and money or something like that. You should certainly check it out for like sites for custom sites for custom projects. It's often used together with Selenium. Selenium is basically a way to control browsers. So you can start up a Firefox instance and then test your site inside this Firefox instance. So you can actually open up the Firefox and see how the browser behaves. So you can actually watch a user doing something which is pretty good for debugging purposes, actually. Then there's Casper.js. Once you have like more and more JavaScript on your site, you realize that it's hard to test. So Beard is PHP based. So if you do a lot of JavaScript stuff, then it's hard to communicate between the PHP and the JavaScript in order to test something. And Casper.js solves that by being JavaScript first. So you basically already, you are in the language of JavaScript already. And they can also like go inside, click stuff, submit forms and stuff like that. And then finally we have now in Drupal, browser test base and JavaScript test base to do this kind of testing. And it's a new feature of 8.1, which is another cool thing that we can innovate actually now between major releases. So yeah, I will show you an example of how browser test base works. So you can apply it on your own projects or content models or something or core patches. It is Newsense to Blade. It has terminal support and PHP storm support and it's based upon PHP unit. Let's just have a look at an example. So you start with adding a file to the, so here's a module for example, and there's like a test directory and you have a source directory and then a functional directory. And inside there you place your tests. So for example, example test dot PHP, you define a class which extends this browser test base. You say, okay, which modules do I want to have? In this case, the examples module, which really exists. And then you can define your test. Here in this test, we create a user, logs it in and we log it in. Then we go to a specific page, test slash page, and check whether we get a 200 back. Really simple test, nothing fancy is going on here. And then finally we check whether some text appears on that page. The interesting thing is that you can write it like that and then execute it via PHP storm directly without leaving like the context of doing something. You don't have to go to the simple test UI in Drupal for example, so you don't, you cannot distract yourself that easy anymore. Yeah, there's a couple of things you can do in those tests in the setup method. You can create like content or configuration. You need for the test, it's similar to simple test. You can duplicate stuff to, which basically is a get request to click on a link or something. You can click on a link actually. You can submit forms and you can check a couple of things like are there a couple of elements, CSS. So you can use CSS in order to check on your site whether something appears. So for example, this means that the view has three elements or three results. You can also check that form elements exist in yada yada yada. It's just now we'll do this web asset here, which we've created has, I don't know, 50 or something helper methods for you. And we also extend it in Drupal so there's a lot of things there. The cool thing is because a browser test base is based upon Mink. Mink is a browser abstraction layer. So you can basically communicate with Mink and it can deal with either a PHP-based browser. So like a fake browser or like Phantom.js which is a headless browser which runs pretty quickly or you can even communicate with Selenium so a real browser which is really nice because we can run our tests already in all browsers if we want to, if we set up it correctly on the test board. So how do you run actual tests? You start with copying phpunit.xml.dist. It's a file in Drupal to phpunit.xml and then you adapt three lines. It's at the top of the file. The first one is the base URL. So where's your actual Drupal site? The second one, the database, so the database credentials. And the final one is a directory where Drupal puts some verbose output so that some logings for each page you visited. So you can then afterwards see which HTML was on those pages. And once you have that, you can start running those tests and yeah, don't worry about it anymore. Let's have a look at how JavaScript test base works. JavaScript test base is also using Mink so it's basically really just using a different backend for Mink and that's it which is really cool because it's really helpful. Phantom.js itself is our backend in that way. It's kind of a browser but without any visual representation. It's running in the background like in your console or in your terminal but it still allows you for example to take screenshots of what actually happens and you can also attach a debugger and check what your JavaScript is doing which is good. So let's have a look at a JavaScript test. The interesting thing it looks really the same. Instead of putting it into the functional directory we put it into functional JavaScript. So again we put it into test source functional JavaScript and then the filename test.php. We say which modules we want this time to by node. This is an example of typical itself. We log in a user, we go to a certain page. We click on a link. Here we click on a link and then we check whether it's visible or not. So you probably know the toolbar in Drupal where you can see like a menu on the left side and you click on there and then it disappears and that's what we check here. So this is kind of working as expected. The browser in the background executes that kind of operation. So the clicking and then we do asset element not visible so that checks whether the element is there and then it communicates with the browser again and checks what's going on. So let's have a look how this actually works. So here's an example. So we start phantom.js using this command. Don't be scared, you just need to copy it once and it's documented on a change record. It's documented in a readme inside Drupal itself. So don't be worried. Yeah, there you could actually specify a different window size if you want to emulate a mobile browser. So you start that and then in the second screen at the bottom we start at some point all the tests we have in Drupal at some point. So it starts, so you need to specify dash c core which it's just configuration. You just type in that command and don't worry about it. And here at the top we see what's going on. Let's quickly stop. So what you see here at the top are the commands phantom.js gets. So here you see the command clear cookies and reset. So what happens is that we have a phantom.js instance and we have like the PHP and the PHP installs a Drupal site does something and uninstalls the Drupal site. But in the meantime the browser still stays there and in order to not cause any data problems or like data which is still in the client we need to for example remove all the cookies. We need to remove like local storage and all the information which is statically stored in the browser. And by that we communicate with phantom.js using those commands. And at some point you see a little bit more going on. Let's see, it should happen in a while. Yeah, that's where we actually send like HTTP requests and like clicking links and stuff like that. And yeah, and then at the end you see that the tests so we have three tests in this example and it takes 22 seconds which is eight seconds per test which is okayish but does it scale? That's the question. Drupal has 10,000 of tests. If you would calculate that, that could be easily ours. So there we go. Here's the summary of what we saw is this is the command you need to run them. Yeah, this is the output then and you can specify a couple of things to PHP unit. You can either provide like a file name. So this is like a full file name to a test file and with that you run just a specific test file or just a specific test but you can also run them all. So you can specify for example a directory and then it tests all tests inside that directory. Oh, good question. So we run it as web server user because for example we write some files like when you save a file or something. We want to ensure that the actual site is then also able to read those files. Yeah, it's basically what the test port is also doing. Yeah, does it make sense for you? It's definitely a web server's mind user. Yeah, exactly. That's why you don't never have that kind of problem. But otherwise like if for example the test like creates the file directory, files directory and then in the actual site upload a file then this actual site need to be able to write to that directory. So it's easiest to just run the tests as the web user. So here's a, yeah. Can we move on there? Oh yeah, sure. Is there a teardown method? Oh yeah, totally. There's a teardown method you can implement in order to clean up stuff like on the file system or something. That's totally possible. Yeah. The database too. So we in Drupal we implement the idea to install Drupal, do our stuff and uninstall or and then drop the database basically. So that's lower but it's also removing like hassle from developers. Yeah. Whether you want to do that. I mean for Drupal it totally makes sense because we have hundreds of tests. So in case they would interfere they would certainly interfere at some point for custom projects it might not make sense for specific use cases. But we handle that automatically but because it's based upon PHP unit or like on PHP class hierarchy you can override that behavior and maybe import always the same database from some database dump if you really want to. Yeah, you're welcome. Yeah, just ask. So here's a question. Why do we actually use Phantom.js and why do we not use like an actual browser like Firefox? And the reason is actually quite simple. It's a headless browser so it doesn't actually have to do a lot of things as a normal browser so it's like much faster like two times faster or something that then leads to less resources on the test spot for example. Potentially it may be though it has some disadvantages for example because it's headless and because you don't have an actual browser it is harder to debug because you don't see what's going on or not that easy. When we would use Selenium for example and an actual browser that could be easier. So maybe it's up to discussion whether we want to keep Phantom.js actually and especially the way how we implemented it. Yeah, another in general problem with end-to-end testing so that's all end-to-end testing what we saw so far is that it's way too slow. It's super boring like if you want five tests and you need a minute then you are certainly on Twitter. Like there's no way around that. So yeah, another problem is that it tests too much. So if you test the entire system you don't know where the problem is. If you just test a specific thing and that fails you know the problem is in that specific thing. It's also error prone. For example we saw before that we used like CSS selectors so what happens if you change CSS selectors? Boom, the test break. And the last point, the feedback cycle is way too slow. Like in Drupal Core we have like thousands of tests and they need, I think currently it's like just 20 minutes but we are using like an infinite fast hardware and I think 19 or is it 15? I don't know, parallel processes in order to run them all. How many? 32. Oh, I'm sorry. It's even more. Because it was distracting people. And it's... No, like why is it crumbling? Because it costs money. Well, yeah, Drupal's money in a way it could be, I don't know, it could be invested in something else. I don't know how much it actually is but like just imagine if we would actually, so we have a test suite which is using a lot of unit testing, if like, I don't know how many unit tests we have but in case that would be like simple tests or like browser test base as well that could easily like, I don't know, times five in money and time. So, yeah. Yeah, I mean the solution to that is to use unit testing which, so what is unit testing? Unit testing is to just test a specific system instead of everything. That basically means you would not install the site but you would rather load just a specific JavaScript file, execute a function and check the output. So yeah, unit testing is you give it some input and you expect some output or you give it some input and you expect some behavior. The thing with behavior here is that JavaScript is asynchronous so you don't really have output. You rather have like side effects going on or like promises. So here's an example of some really simplified JavaScript unit testing because it's actually not using asynchronous code or something. That's a small library for to do TXT, to do TXT is like a textual format of writing your to-dos. So he, oh, I didn't changed it. All right, it's a way to specify something you should do. So you give it a title, you give it some tags and some projects and you can say when should it be finished and is it finished or not. So the X specifies whether it's finished or not and that's just it. You write it into a text file and be done with it but there are clients for everything. So here's an example of how to write a test for that. So this is using a certain way to define the tests. It's called Maka, I will talk about that later in a little bit but basically the idea is really similar. You set up something in this case a to-do parser and then you check that. So you set up a to-do parser and parse the string hello and you check the result which is a to-do object and in this case I check whether the text of a to-do object is hello. It's using a library called Chai. Chai is an assertion library for JavaScript because obviously in JavaScript there's a library for everything. So even if you have a test framework you still need an assertion framework. So yeah, when you do that and if you run the tests you get and you don't have any code yet you get a wet output then you write some code in order to fix that and you write your to-do parser. In this case it's the simplest implementation which parses our tests which is just returning the entire string as our text. You run it again and it parses and then like in an ideal world you would then continue with writing the other test. So in this case I'm specifying a priority. The cool thing is in this syntax you can have like a human-descriptable name for what do you test in this case. Here you specify a priority and a text and we check whether there's a priority in the result and then you continue and then you fix it and then you write another test and by that you get this kind of loop. So wet means you have a failing test, you fix the failing test and then you can re-factor and improve things. And the cool thing like when you have that kind of test afterwards when you want to introduce a new feature you make it wet again, you make it write a new test, get it green again and re-factor. That's the ideal world of unit testing. And the cool thing is that it's really a nice way to develop because you never leave the scope of your current work. You can just run the tests, they are immediate feedback, they give you like immediate like, I don't know. A minute, no, that's not one millisecond but like below 100 milliseconds. So you never get distracted and you can still focus a lot on working what you actually want to achieve. Yeah, so if we as the Drupal community would like to test our JavaScript, there are all the possibilities. So there are a couple of tools we could leverage. There's first a thing called testing framework. You could think of a testing framework kind of like PHP unit. So there's Q unit, it currently has 3,000 downloads a week. So I would not really recommend it because it's not that. Yeah, I try to came up with the numbers in order to justify why we want something. And then there's Jasmine, and Jasmine is like a testing framework which also allows you to run those tests in the browser, 190K. Then there's Mocha, which is a Node.js based testing. 700,000. Tape is a really simple alternative. All the other ones are pretty complex. Tape is pretty simple. Then there are test runners. So test runners takes a testing framework and run them somewhere. Well, intern is also a testing framework but intern has just like 4,000 downloads but it's advertised as the hot new shit. It's interesting because it says it can run on CLI, on browsers, it can run on browser stack, which is a shared, it's a way to run like a cloud environment tests in all the browsers, all the mobile phones and everything at the same time. So maybe intern is actually interesting. There's also Karma, which has 350,000 downloads. Karma is also a way to run Jasmine, Mocha, Tape and Q&A tests inside your browser in whatever browser you want. So I actually think we should go with Mocha and Karma. So Mocha basically has a testing framework and then Karma in order to actually run our tests in the browser. Another, a couple of other libraries you actually need is Chai and Xenon. You see the amount of downloads are pretty much the same because they are basically required. Chai is a assertion library, which allows you to check that a specific thing was actually done, I will show you an example later and there's Xenon, which is a mocking framework. Yeah, whatever. Here's Chai is also just like why. They have three different notations to define you to check whether actually something happens. So there's the assertion one, which is like the classical one. So assert equal, hello, as that the to-do text is equal to hello. Classical one, then there's a should notation, which is to-do.tix, text should equal hello. They provide magic that like every JavaScript object behaves or has a should function. That's pretty crazy. And then there's the expect notation, which is also expect that a certain variable to equal hello. I don't, I don't know, I don't get the point. Because assert is the shortest. And like, okay, the thing is the should notation is more human friendly to read, or the expect notation. Oh, yeah, that's a good point because you cannot override the behavior of another object. Good point, interesting, interesting. Okay, so you just went with assert. I went with expect. Ah, okay, that's true. So why did you went with expect? Why did you went with expect rather than assert? Okay, fair. So yeah, it is, I mean, like you can certainly use the metrics of less code, but there are other metrics. Like the readability aspect is not that unimportant. Also, when you have expect notation, you can, yeah, like the test runners can also output real actual English because like two equal, they can convert that to a nicer output. But yeah, it's, yeah, JavaScript, I don't know. So one problem we have in Drupal is that we mostly interact with the DOM. We don't have like crazy libraries, which I don't know, calculate something crazy, I don't know, a React route or something, but we rather always integrate, we always interact with the real world. So pure unit testing is maybe a little bit too ambitious for Drupal itself. So I would actually propose we use some kind of integration testing for our JavaScript, which means we need some kind of way to set up our JavaScript. So for example, we could have some HTML files which provides some initial output of Drupal together with even CSS files and then load our JavaScript in there and test it. And test it. So for example, it would be like a front page with some content and then we could execute quick edit on that, is it called quick edit? I think so. So yeah, so I would actually propose to go with like integration test first before we have any libraries. In general, I think we should apply some criterias to the decisions we make, which is, I mean, one criteria is feature richness and flexibility. Drupal is really complex and that means that we potentially need flexibility where other people don't need it. And that simplicity, yeah, you want it to be easy and also easy to understand and best practices, we don't want to alienate people in Drupal. We want to teach them best practices because Drupal is not everything. Actually, I think Drupal is doing very much. So yeah, here's a couple of decisions and questions we could argue about now. Like do we want a real browser? Do we want to test our stuff in real browsers or do we want to continue to use just front-end JS? Do we want to go with source labs or browser stack? They are both like external services, which allow you to run the things in different environments. They are both having an open source free model, so we could probably use it or at least try to use it. We could also experiment with using BDD or a B-Head and not write our code to test stuff. And obviously the question is, which test runner and framework we want to use. Yeah, and there are a couple of issues and you can get involved with this. Yeah, thank you. Yeah, please ask and discuss. And there are sprints on Friday. And yeah, there's also a feedback slide. For any instance, it's a lot easier for people coming in to contribute tests, continue to add a new test as opposed to an actual assert or expect syntax, which I think, you know, even if you use a lot, it can be a real pain to write your test in that syntax. So I would really like to see us, you know, to be sent that we're doing integration test, go use Kirk and that's the language of writing those tests. Yeah, that's a good point. So, now I'm going to have to disagree with you. Well, one could disagree with you. Gherkin works really well in case you have a domain in which your Gherkin text can be written. I'm not sure whether Drupal has a domain or whether Drupal is actually way too flexible to have like a good domain, but yeah, maybe I'm totally wrong about that point. Yeah, anyone else? Yeah, yeah, Gherkin is basically the language. Gherkin is the idea to use human readable test, the text to... Yeah, it's a QCumber and Behead, so QCumber is basically the Ruby framework to test stuff using the Gherkin language. That's the origin of the Gherkin language and Behead is basically a PHP implementation of Gherkin plus the testing. Exactly, exactly, yeah. Which is the idea to not define like expected output, but rather describe your system. Yeah, John? Some of the JavaScript that have like behaviors that are basically just sort of integrating the jQuery library and... Yeah, the thing is you don't actually, yeah. Yeah, I think the fundamental problem is that you don't actually have that much logic in your code. You rather just integrate existing libraries together, which is why I think we should have integration tests rather than unit tests. I don't know like the ideal way to write those integration tests. There's like a way where you can actually like create some fake HTML and then run your JavaScript on that, or we could actually have real HTML. When we have real HTML and CSS on there, we could maybe even have visual regression because we already have those fixtures. Yeah, there's stuff to explore there, of course. Yeah? Can you go to the microphone? Because it's recorded. So when you use an actual browser, then it's pretty easy because you just open up the developer toolbar and click on pause. And yeah, when you use Phantom.js, you can, there's this additional parameter. I don't know, it's something dashboard. So it opens up a debugging port and then you can go to your browser and then with that port on your local host and then you can go in and you basically have the developer toolbar available and then it loads up the initial JavaScript of Phantom.js and then you can put a break point there and then from there, it just loads all the files you have and then you can continuously debug through your JavaScript. It's absolutely cool. Yeah, there's good documentation about that on the Phantom.js page. Oh yeah, totally. You can load any kind of library you want. So it's not only for unit testing, it's also for integration testing. Yeah. I feel like Cascade had run the tests on that library too. Oh, that is what you're saying. I'm pretty sure you can configure a comma to do that as well, but I'm not sure whether I get the point of it because those open source projects already test their stuff. It makes sense because it asks if it's working, data, or it's not working. Oh, that's interesting. Well, but I would assume that they are tests one all the time. I don't think they add regressions in some minor versions, but they rather just don't catch it. Okay. So I think you should just have enough tests for your actual site or library or something to ensure that when Jaguar is broken, you also see it. Oh yeah. Thank you. You're welcome. Yeah. It seems that those are gonna be often out of date or out of sync with what people's actually producing. Is there some way we should basically would strap people to generate the extrusion and kind of run the tests for some way to keep that in sync? Yeah, we could do that. Or we actually say it's okay to not keep them up to date because we have the stable theme. And if we generate our HTML with a stable theme, we are supposed to not change the HTML with a stable theme. So given that, we would ensure that our stable code always works, that code is working with our stable. Maybe we need to have both pictures. Actually, we should do that because we shouldn't rely on the HTML output, but rather have data attributes to select stuff rather than CSS classes. We are going there. I'm not sure whether we are completely there, but anyone else? Cool. Yeah, Swints and feedback. Thank you.