 So that's gonna be our agenda. Is that all good? All right, cool. So how many people are using end-to-end of functional testing? Have two arms? Good. So what is actually functional testing is and what's the, what actually the problem we have with why do we need functional testing and end-to-end testing is the reason for it is we don't need to hire people to test, click and test. We actually wanna get as close as possible to the user without getting the user into the room and testing it. Don't get me wrong, it's not a replacement for the user, but how we can get most of the job done and get the repetitive task out of the way. To obviously simulate the user and use some sort of a tool for it. And in implementation of end-to-end you'll find two definitions, which is one is a test runner and another is browser-automated tool. So that's where Nightwatch just kicks in. It is actually our test runner. So tool that controls the test, it's written in JavaScript and it's just basically your NPM dependency. So if you ever use NPM dependency you just go type NPM install Nightwatch and you have Nightwatch on your machine. So the development been on and off, but it's open source, it's on GitHub, you can contribute to it. It's actually quite a nice guide once you go in and click on special API references and developers guide. So let's just without further ado go rather than going into much theory, let's write a test. Anyone wrote a Nightwatch test before? Good. So we're gonna do that. And actually I was thinking what to test should we install Drupal website and do that? I was like nah, we already have one Drupal Camp Singapore. And I mean the simplest test we can do is actually go to the page. So our requirements is to have the title, right? Of the conference Drupal Camp Singapore. Let's go to the page, let's just check if we can load the URL and see the title. Simple. So Nightwatch tests are pretty simple. If you use JavaScript before, so you just do module export, then you define a number of functions. Here there are two before each and after. Can anyone tell me two more? Judging by this. There's after each, there's before. The difference is before and after runs only once. Before each and after each, obviously run before each test and after each test. So after we will start the way, we'll say browser and browser variable for Nightwatch is your client. So how to control your browser, you supply browser space and you send it. Woo. I hope it's only one slide that does that. Otherwise we're in trouble. I think the resolution is wrong. Yeah. But for the browser, we'll just say which URL we want to go to. I may, that's better. So everyone can see that still. Do you want to move closer? Because I was expecting a resolution would be just a bit bigger. Sorry for that. But we chain command. So here we supply, let's see how we'll go further. We'll supply the URL, which is DrupalCam.sg. And then the second command we're gonna use is wait for element visible. And can't remove this. There you go. Maybe a bit better this way. And then we say, okay, let's wait until the body element is actually there. So this is, we put that in before each. So it means as many tests as we're gonna put in, every time it's gonna run, it's gonna go to URL, type in URL and wait for the element body. And here are our first tests we're gonna put in. So you just put the body of the function. So you supply, you tell what's the name of the function. In this case, it's a first Drupal Singapore test. And then we'll write our test. So we wanted to test the title. So there's a number of commands called assert. So we're gonna assert the title and it's gonna be a Drupal Camp Singapore 2018. Any questions so far? Pretty simple. So let's run it. Let's pray to the gods of the live demo. So what's happening here is I'm actually conducting the service. So outsource partial stuff to the service in the cloud. So it goes there and the service actually, the test is on my machine. So now it was still sits here. So there were two assertions as you saw. So two assertions. First one is element body is visible after 900 milliseconds and the second one testing the page title equals Drupal Camp Singapore 2018. If you look back at our code, so we can see that the first assertion came from wait for element body, right? So it actually came in from before each and the second one came from when we actually assert the title. So let's actually see what happened when we executed the test. So the first thing we did was actually calling night watch, right? Then we supplied the configuration file which we're gonna talk a little bit later about and then we provided the test file. That's all we did. I wrap it up in NPM run command but that's pretty much it. And of course the output we already kind of look at it before but as I said, the wait for element visible body was going into the first assertion and the second assertion was actually checking that the title is correct. All right, so let's see how it actually all runs together, how we pull all together. And depending on your setup or your project, if it's a personal one, you might run it on your local machine. If it's something a bit more experimental you might try something else. So at the moment we have my laptop and our night, our cold night watch is sitting there. That's pretty much simple. And what night watch is actually, it uses WS3 foundation web driver API. It performs command and assertion on a DOM element of your HTML page. That's all it does. It also have some cloud service support, continuous integration support where you can connect it to the services which we're gonna look at right now. It also provides querying by CSS and by XPath and we will have a bit of time and then we're gonna look how it actually works. What's the difference between CSS and XPath if you haven't seen it before? And it's easy to extend so it's easy to write your own command, easy to write your own tests. So let's see where we're at the moment. So we actually know we have a test runner, it's in our machine, but as we said before for automated testing we need two things. We need a test runner and a browser automation tool. So what actually automated the browser? There's this thing called Selenium and it's free to use and download. It's not open source though. It's a web testing frameworks and it runs on Java. You can use it standalone and decouple. We're gonna look at it in a second and it provides a great artifacts for testing. Apart from the logs it also can provide your screenshots. It also available as a Docker image which is quite handy these days because your Ops team probably would, if you ask for them they would install it much faster just to experiment with if you don't have control over what you install and what services you are using. So again, I'll see it's on our laptop but here's our Selenium server which runs on Java and our night watch talks to Selenium and says here's my test, run with it and then send me the answer back. Did it fail, did it pass? What happened? So when we look inside what actually Selenium does it talks to drivers. So it talks to different browser drivers. So it can talk to Firefox, it can talk to Safari, it can talk to Chrome, it can talk to Edge and there are different browsers provided for different tools. Sometimes as a part of the Selenium team writes them, sometimes I think Google writes Chrome browser. I'm not sure about Edge if it's Microsoft or Selenium team. So any question about that setup? The machine which is a development machine and the web driver is it also on the same machine? Good question and that's what we're gonna look at. You actually have three choices. So you can have it locally, everything, what we just look at all three parts sitting on your machine. You can use cloud services and you can use containers and with containers means you can either put it in the cloud and connect it or you can leave it on your machine and run containers on your local machine. So three ways to set it up, local stuff. You install Java, you install Selenium, you install browser and then you install your browser driver and then you try to make make up about a month of time and try to make it all work together. So I'm just joking but it takes a while to actually get it all up and running on your local machine. There are good guides there but there is no quick way to do it. I find like it's a good way to find out how it all works but it means you need to install every browser and the driver for each browser driver that talks to Selenium and then make sure the Selenium is running and not hang, open the ports up and then configure Nightwatch to talk to you locally. I've done that before. The good thing about this setup, if you set it up and run it, the browser will open up and you'll see the actually all the clicks it would be automated on your machine. There are links provided to blog posts where you can see the video how it's done on your local machine. So this is the advantage of this setup. It's also cheap. I mean, not time-wise cheap but cheap in terms of you don't need to pay for any cloud services. And as I said, it's all executables. So the second one, cloud services. It's the one that I just showed you. So all I had on my machine was Nightwatch. The rest of the stuff I just outsourced. The most two popular cloud services are browser stack and source labs. Anyone use browser stack before, source labs? So second, actually the most useful part how those services started is manual testing. So you would go to source labs, you would select I want Windows machine with IE6 running or Windows XP with IE6. You would go, they spin up machine and you could actually manually click in the web interface and test your browser. And then they, as a kind of guess second generation of their services, they roll out the automated stuff. That's what they charge more money for. Starts from about $100 a month. Free trials, two week trial for source labs. I think two week trial for browser stack. Very similar pricing. Yeah, so and they set up Selenium for you, drivers, virtual machines. All you care about is just providing the correct settings file by the API key that they give you. So that's how it works. So again, Nightwatch sits on our local machine and in the cloud we have all the Selenium setup. So here's our source labs, here's our browser stack. And that's what happened. So I just ran a command, Nightwatch send it according to the configuration file, got the answers back. Whatever happened in the cloud, stay in the cloud. In fact, we have results. To prove that, I would go to my source lab account and nine minutes ago, we just executed the test. In fact, you probably didn't know, but it ran on Windows 7 on Firefox 61. And if you still didn't believe me, you can actually play it. That was the test really. We just checked that it is a title, took 10 seconds. Any questions about the cloud setup? Let's move on. And you of course can roll out your implementation of this stack and not pay $100 to source labs or browser stack and pay $100 to AWS, Google Cloud, DigitalOcean or your preferred cloud provider. But it means again, you need to have a look after your setup. So if you have Ops team or if you have people interested in it, so there are options. And the last but not least is a container and Docker service. The good thing about the containers is you can either run them in the cloud or locally. So if you spin off the machine in the AWS, you can spin off Selenium server using the container in about five seconds after it downloads. So depending on your browser speed. And the good thing about the container setup thanks to Selenium, you can have all of it being wrapped up in a single container or you can have Hub as they call it for Selenium and nodes as a separate containers and make them talk to each other. So this setup is usually good for a big enterprise production apps where you need multiple nodes, lots of browsers. I'm still using that. In fact, the only thing I'm using, it's called node stand alone. So Selenium node stand alone. I think that's what it's called Selenium stand alone Chrome. Sorry, Selenium stand alone Chrome. And it basically wraps up Chrome browser, Chrome driver, Selenium in one container. And you can, using your tool of choice, either Circle CI, my preferences, GitLab CI, you can wrap it up and just using one command. If you're not familiar with Docker, don't worry about it. But if you are, that's all you need to write to be able to have a container up and running, three lines. And two of them actually define its name. And one of them define where to grab container. That sits on a Docker hub right here. So Selenium provided and the one I was talking about is the Selenium stand alone Chrome container. Again, if you don't know about much about containers or the operation stuff, don't worry, I'm not gonna go deeper than that. This is just something for you to research if you're interested. So any questions about the container set up, cloud set up or local set up for your tests? All good? Okay, so here's some links to actually do those containers. So you can see the first one is a hub. So just Selenium, second one is stand alone Chrome. So it's a Selenium and a Chrome. And another one is just node Chrome. So you can have hub and Chrome. You can also have Firefox and other browsers as well. And actually the configuration file, remember the one we provided? There you define a few things. Again, we're not gonna go just a lot of lines and every blog post you go about night which would talk about it. So all we're gonna say it defines test location. So we're a test city. It also defines your extra commands. If you wrote any extra commands, it would define you at the local machine where the driver is sitting. And it actually can be in JSON and JS file. This is I found out just recently. The good thing about JavaScript file configuration is that you can use the environment variables. So you won't commit your API key from a source labs, for example. You can provide as a variable. I don't think you can do it for JSON file. Okay, so how is Night word JS relevant in Drupal? And has anyone used any other tools that available in Drupal at the moment? Phantom JS, yep. Web driver, did you use a web driver? Yep. So before 8.5, so before March, April this year, there was simple test in PHP unit. It means if you wanna write a test for Drupal just using core, you would need to know PHP. The Phantom JS was used. Phantom JS is another one of those drivers. Like we look at the Chrome driver and Firefox driver. Phantom JS was one of the first one appeared and it was made basically to emulate any browser. So it was like a very tiny, teeny browser engine and lots of people used it before browser companies decided now we need to put our engines there so people can test with them. So as a result, it's minimally maintained and apparently it's crashing a lot on Drupal CI. So when you submit a patch for Drupal core and you see this red or green things that's when Drupal CI runs and if you wrote any of the front end tests it might crash just because Phantom JS just becomes more and more unstable. So first there was a decision for 8.5 to actually bring the Chrome driver. Chrome driver is what Selenium is using to control all this stuff. So it's like W3C standard for talking to a browser and terminating the browser. The problem is with the current latest live version of Drupal is most of the tests are still using Phantom JS. Obviously they're gonna crash and show me how many front end developers know PHP. Like that's another big issue. Especially PHP and then you can try to teach them PHP which is fine. Then you show them PHP unit and they're gonna run away from you. That's my experience. So as of 5th of September this year the night watch gonna be in a core. And what you can do you can actually go and install Drupal 8.6 core. I did. Here it is. So if you go to the actual core and you go to tests Drupal. Look what we got here. You got night watch. And they even wrote some commands like Drupal install, Drupal log and end and Drupal relative URLs. So there's already a start point there. So if you're thinking about contributing to Drupal have a look in this folder and they read a bit of the commutation there. So it's interesting. It's all written ES6 as well, which is good. All of my tests still running like old school JavaScript. But yeah, this is how it looks at the moment in Drupal 6 core. So comes 5th of September it's gonna be up and stable. So you can actually put it in your, if you read the documentation you can put it in your module file, your theme file and start putting the night watch scripts like the one we wrote before straight. Right, any questions about Drupal 8? Good. So should we write more tests? Yes, let's do that. So let's see, like for example how about we'll check if the get ticket button is there. So let's do that. I already wrote some tests but I'm gonna, can everyone see that? Probably not, right? Is it fine? What did it do? Doesn't assume, does it? Let me do it this way. So that's the function we wrote, right? So let's see what night watch can do for us to actually make it testable the click button. So we not only need to test the button we probably need to click on it, right? So let's write Drupal Camp Singapore by button text. Everyone's happy with the name? Sure, okay. Just let me know. Cause, you know, the artifacts like test logs they're important. So when you manager look at it they don't see some gibberish they actually see, ooh, we have a buy button and it is working. There is another talk I did in one of the Drupal cons. You can check it out. It's more focused on managers and how to sell testing to managers. And it's all about night watch as well. So I'll provide the links there. Anyway, so let's go to actually Drupal Camp Singapore website. Here we go. Let's see. What's there? So this is the usual thing I would do for testing to actually go and expect. Ooh, I got a div with buy ticket. Whoa. So copy that. I got buy ticket clone and buy ticket. Seems like it's the only class so it's fine. So it's buy ticket and then there is directly a tag. There, right? So what I'll do, sorry for jumping too much. So what I'll do, I'll go browser, wait for element visible. So I'll just copy that. And then I'll go and say, oh, please now it's green. Excellent. So let's wait for element visible and then we have a command called click. So we're gonna click on it and provide the same thing. Great. So and then another page should appear. So maybe we should do exactly the same as we did in the before test. So we're gonna do that. And here's our test. So we're gonna go to, so this file called to more tests. I'm gonna replace all the previous tests, except the first one because it works here. So here's our second test, buy button test. And let's run it. So we're going into our cloud. Waiting and waiting and waiting. Who wrote tests for Selenium before? Like using web driver. How long did it take you to write? What did you use just direct Selenium test in JavaScript? Yeah, so how long would it usually take you to write? Well, the test, yeah, for your project, for example. Okay. So you didn't have any issues where you would spend maybe 50% of the time coding and then 50% of the time writing test. Fair enough. We're actually having an issue. So it says buy ticket not visible. I waited for 10 seconds. That's what we have in configuration. So any ideas. It's always good to test it. Yourself, but if we'll test it ourselves that's what we just did, right? So we went to the browser. We checked it all, the button is there but we can't see it. Maybe we should go cause Selenium records it all. Sorry, so slept. Anyone noticed stuff before? Who's gonna be first to notice stuff? Who said it? Well done. So it's actually using mobile button, completely different button. Cause we didn't provide the, you know render it in 1080p on the latest Chrome browser. We provided some Asian window system and the mobile menu is there. And if you actually go and have a look, so inspect mobile menu, you can see class toggler here. But if you look at get tickets, it actually uses buy ticket clone. It hides the other button and the test actually succeeded. So the test was correct. We just provided the wrong thing. So if we'll update our test with here at the moment. I mean, you would actually go and put the normal browser in and your test should succeed but because we have time restrictions and all that, it's a good idea to put this selector in a variable as well. And maybe let's see what's happened when we click get tickets and maybe instead of that, let's see what title is gonna appear. So it goes to Eventbrite and it gets this title. So I'm gonna paste this title. So our test gonna look like that, right? So wait for element visible, click and assert the title and see if that's gonna work for our current setup. So a few things you'll see when you're doing the test for Nightwish. For example, you'll never see it's telling you about clicking. So the click kind of silent. So you can extend Nightwish test with your own commands. And the two commands I was using on all projects pretty much, one of them called log and another is click log. So all log does is logs stuff for you like to the screen. So while the test is still running, I'll show you the log command. So first the configuration file that I said we don't need to look at. Here it is. And here, apart from the source folder for the scripts, we would also have a, it's actually couldn't connect to Selenium. Might have a connection problem. So we are going to connect to Selenium. So we also have a custom path for the commands. And at the moment here, it says that miscellaneous command. So if we go to this particular folder, we can see there are two functions, log and click log. I wrote them, the log is pretty simple. It just returns console log with a blue information thing, really. A quick question, previously the test was failed because people mentioned it's because of the mobile. Is it means that the night watch is actually? No, it means that source less setup by default uses Firefox on Windows 7. That's all it means. If you would use it locally or in, for example, Chrome setup, Chrome would use the latest version of Chrome. I'm not sure about the resolution because I actually ran into those issues two days ago when the resolution was by default small or maybe it's just a browser that converts menu into mobile. Yes, yep. So the configuration file here, it's a default environment. So you can set up default environment, Chrome 64, Chrome 64 at 100 pixels, Android mobile, and you can go on and on and on and on. By the way, don't write this access key. I still need it. Yeah, so default is just a default environment, but you can set up the environments, the one you specifically want to target and provide the either. So for example, if you're gonna run it locally, you're gonna have different nodes. So for Firefox and for Safari and for the Chrome and for Edge, you would send it to a different executables, which you're gonna define. So for example, these are settings for defining the Chrome driver, Edge driver and Chrome driver. Yeah, but yeah, so you would set up some things and there are blog posts again, how to set up resolutions as well. And I saw a few people trying to change the resolution in the same test, but I think it's a bit hacky in my perspective. But apparently it's possible as well with the Selenium. Okay, so a few more things. So again, log and a click log just uses log and uses different format of the test, which I copied from one of the core Nightwish stuff. And all it does is basically says clicking something, right? So if we would test those two things, so click log here instead of click and maybe just log to see what log does. Say hello, triple camp. Okay, let's run it, see what's gonna happen. And you saw before the connection, the previous time it failed, the connection with Selenium couldn't be established. So it might be connectivity issues, but you occasionally would get those on the local setup as well. So Selenium is a bit like they working on it heavily. And yeah, you might find yourself in a very interesting situation where it might end session before finishing all the tests. So you need to get a bit of a trickery in configuration on the way you finish in your sessions. So it depends on the setup as well. So you can see it says hello, Drupal can Singapore and output and then it actually, instead of click, we use my function which overrides click, click log and says clicking.byticketclone.a. So you can actually extend your commands and that's exactly what they did in Drupal core. So again, if you look at the web core tests, Nightwatch commands, you can now jump in and as an expert, have a look what they didn't have done. It's quite interesting. They're not massive, so you can actually go on search. So any questions about extending and writing your own commands for Nightwatch? All good. Right, let's wrap it up. So as I said before, you can expand the Nightwatch not only with commands, but with the other services as well. There is a great pause from previous next from last week, I think. So they actually use a service called ashexie to extend the Nightwatch and the past accessibility testing using the repo Nightwatch accessibility. So the link is there or if you type accessibility Nightwatch there's only one post on that from previous next. Have a look at them. But you can actually use other services with Nightwatch. It's quite an active development as well. So this is the accessibility testing tool I never used to do for myself. So I'll just give it to you if in case you would need accessibility services, accessibility testing. And I would really, really, really again advise you to go in and contribute to the documentation test. If you don't know what to contribute, try to develop something and see what's like in documentation. And then just go to documentation, click edit and place the header, for example, extended Nightwatch for Drupal Core, TBA. So for people who actively contribute to the documentation that's a good sign what people needed. And because now you cannot leave the comments in the documentation, just communicate some other way. I know the documentation for Drupal 8 is not up to scratch in development one as well. It's getting there. I'm contributing on migration and planning to contribute to the Nightwatch. So if you think of something, I don't know, do it on Twitter, but do it on Drupal.org as well. Because we need your input as well. We need to know what people need, what they're lacking in the current documentation. So here where it is, just type testing in Drupal 8. And one of the links below would be types of testing in Drupal 8 and Night, which is one of those. A few tips to wrap it up. So for automated testing, I would recommend spend up to 30% while I ask the question about the writing test directly for Selenium. I had a project where we would spend up to 50% of the time because it would just ridiculously slow to actually debug the test. So make sure your time box yourself but also don't fall in a trap where are we gonna do test later? That's like number one answer, I think from all the managers I've been talking to. I will do it later, it's not important. Make sure you spend at least 10%. So between 10 and 20 is very good. If you can't stretch it up to 30, if your budget allows it to, and if your project needs it, so it's not one of project you know which you released and dropped it, but something that's gonna live for two plus years, definitely spend more than 20% on testing. Doesn't matter which one. But people ask me, do we need to do the full coverage? How long is it gonna take to actually cover the whole project? You don't need the whole project coverage. I had 10 tests and when Drupal 8.4 was released. So jQuery was updated to jQuery 3. It broke, dropped down menus for Bootstrap 3 theme. What else was there? The views broke. There was some relationship issue in views and there was something else. So three bugs I detected within just by changing the version of Drupal and sending it to my CI. So yeah, it's not 100% coverage. It's actually the crucial bits of your project that you really need to concentrate on and test. Even if you're just trying to create the node, as simple as that might give you enough insight. So jQuery version changes, your tests were failing, but how was that? How tests was failing? Because you identified how was your opening? No, no, I would go and click and wait for the menu to appear and because drop-down functionality was broken, the menu would never appear and tests would be broken. So do... Sorry. So in order to make your menu appearing, so you do the same thing, like every time you go to buy what was the part of it. So once you get something broken, which was working before, you start looking at what you actually updated. And yeah, so and then just trying to figure out what's actually was broken, what's not. Yeah, so that's pretty much how we did it, but we found three bugs before even updating to a Drupal 8.4. So any more questions about that? No? Okay, so we're gonna conclude, but before that I'm gonna jump on one of my projects, just an example. It's not the biggest one, the biggest amount of tests, but I'll just show you the setup. So tests. So here's the test, right? So they correlate directly to a user storage and if you look at the videos I would provide the links for, you'll see the tests correlate directly to a user storage. So for example, this one, as an anonymous user I want to see homepage with the header and footer as on the current SOQ website. When go to this particular URL, so very simple task, but then they go deeper and deeper and deeper and then we start logging in as a separate users and creating by just a, so this is number of tests actually, they're half of them are empty. I just asked my team to do that because they weren't priority, I would spend too much time on actual tasks, but half of them are still operating. So when I go to my GitLab account for this particular project, I can look at my CI and part of the CI is actually installing the Drupal at the moment it's all linked together. So get independence installing Drupal and running tests, but you can see I can go and see which tests are running which tests. And also some of them are quite big. As a content admin, I want to be able to add file, title, description, text when I'm creating, editing, new document media item, right? So it correlates to the story. So now I can grab the title, can go to my project manager and say, here's all the tests I actually wrote tests for. Any questions about tests and running in GitLab CI or other CI? All right, let's wrap it up then. So in the conclusion, again, to do an automated testing, we need two things, we need test runner and a browser automation tool and a test runner called, thank you, and the browser automation tool called, excellent. So, and why do we need them? So they're JavaScript based. Again, try to, if you want to get rid of all your front vendors, teach them PHP. And if you still got half, teach them PHP unit. Or just give them night watch and the error can write the actual tests in JavaScript. Night watch open source and free, you can contribute to it. Will be in Drupal 8.6 core and additional services available like source labs and browser stack. So as I said before, why do we need it? Discover bugs early, test upgrades early. And by upgrades, I don't mean just night watch upgrades and Drupal upgrades. Don't forget you have PHP 7.1 to 7.2 updates. Or if you're still running 5.6, the time is a pressure now to move on to seven. That's all can be done using a night watch test as well, making sure just like what I do, I change the containers, send it off to the cloud, get a report if it's actually doable for me to upgrade to 7.2. Maybe Drupal isn't working. Maybe PHP isn't working. Maybe my SQL isn't working. Something might be broken. So this setup will allow you to actually do that and test it. And again, you get awesome artifacts, text report and coverage. You can set up Selenium to do screenshots for you or you can outsource it to those cloud tools. Again, cloud tools also record your video of your tests. Any final questions? Yep. So we went very crazy on one of the first projects we were running in. It would take 40 minutes. So I'll, oh, might actually get some here. Yeah. So just an example of a pipeline. So you get the idea. So we went very crazy. So apart from the tests, which were here, you can see Selenium 3.7, we would also have LinkedIn and Drupal installation and then checking the Composer and Drupal security updates. Which again, the longest part would be running the actual tests and it would take up to 40 minutes. So you go push your code in. So eventually we decided, okay, don't run over the whole code base. We divide the core tests. I would take on average 10 minutes. It's a good time to like maximum good time to run core tests. If you're getting over 10 minutes on overall pipeline, cut something down. Another thing is this project would have three massive workflows. Where document would go into 20 different stages, shifted between six different user roles. So it was a big project to test. And because we were writing tests as stories, eventually lots of tests became duplicates of each other. So the first test would go and check if the author can send it to an owner. And the second test would go owner to send it to a manager. But because we made tests independent, it would go create a document, send it to an owner, login as an owner, owner would send it to a manager. And eventually it's snowballed. So then we would just say, oh, why don't we kind of write a document function, send this document to this stage and then test what you need. So refactoring is a big thing. Again, once you hit 10 minute mark on your CI, review your stuff, see if you can wrap it up, cut some stuff in by using specific commands. So for example, hashtag run all tests would run the whole 40 minutes of CI, but without this hashtag, it would just run, you know, five core tests like that it can log in, it can create a document and maybe can do something else. Yeah, that's what we did. It kind of optimized it, but yeah, it was still like full on release, just testing would take about 40 minutes. So yeah. And especially if you have juniors, all juniors do is, sorry, all right. See it and twiddle the thumbs. Sorry for the sound effects. Any more questions? That's it then. Thank you very much. Test more, test often. I'm gonna be sending the slides and yeah, so you can go through all the links and the videos as well. The slides of the Lachigo and Closing stuff happening in the...