 I guess we'll go and get started. I want to thank all of you guys for coming out. This is arguably one of the worst time slots. So it's right before the end of everything. It comes right next to right after lunch and then first thing in the morning after all the parties. So I appreciate you guys, you know, coming here and listening to what we have to talk about or what I have to talk about about Cyprus. So before we get started though, they asked me to do a slide about the speaker. I didn't really understand what that meant. So I tried. I've been drupal-ing. I first drupaled. I'm not sure the right way to say it. Since Drupal 4, and this is my eighth Drupal con. So I made this cool thing. Look at that. Little things, they pop up. So I worked like 30, 45 minutes on that. Hope everybody liked it. Sometimes I just watch it to make myself smile. So anyway, I was not planning, despite having been at eight Drupal cons, I was not planning to speak here. What happened was Dan from Savagrub, who's back in the corner, he actually submitted two talks. One was on PDFs and the other one was on Cyprus and got both talks were accepted. So when they realized that he was giving both talks, they said that's a problem. You cannot give two talks. So Dan asked me and I graciously accepted. So I threw together this wonderful presentation, which is gonna start off with some slides, some general talk about testing, and then move into the dangerous world of live demos. So yeah, let's see. When I was preparing for our talk or this talk here, I was trying to think of the best way to present it. Should I focus on specific use cases or just very general? And so I took a step back and I thought like Drupal's kind of in a very formative time right now where you've got kind of the idea of decoupled. That term I should say is floating around where you've got the front end separate from the back end and then you've also got another term that's floating around DevOps. And so the community is really embracing both and Cyprus kind of plays into both of those. So like I said, with the decoupling, we're talking about developing the front end separate from the back end. This talk is actually on the front end track, I believe. And so this would be building your back end in Drupal and your front end right using one of these shiny new JavaScript frameworks, React, Angular, Vue. And then on the other side, the other sort of main idea that I was thinking of was around DevOps. And so what I mean by that is really automating the steps in the software development life cycle. The goal of being more efficient and being faster. So if we look at the software development life cycle, it looks kind of like this. It probably isn't 100% accurate, but you get the idea. You start on the left with research, you do a bunch of things, and then at the end of it, you land with your deployment. And in today's world, that deployment is more often than not gonna be automated. And so this automation is sort of pushed towards a more automated world with the needs to release code more frequently, oftentimes multiple times per day, really pushes everything to kind of move at that accelerated pace. However, if you're moving really fast, but you're deploying garbage, that's probably not a good thing. So what do we do to ensure a high level of reliability before we deploy code? And that's this guy right here, testing. So testing is super, super important. And given the title of this talk and given the fact that you guys are here, you probably all know the importance of testing, I would guess. And as time goes on, I think we're learning that the traditional methods and ways that people have tested with very long sort of QA cycles isn't really helping us get to the right any faster. So logically, we're trying to automate that testing process as well. So I guess of the people that are here, like who is currently testing what they do development wise? And this can be automated because that's cool, or it can be manual, you know, you deploy, you figure you should check the production site to make sure nothing blew up. That's technically kind of a little bit of testing. It's maybe not in this order, but it's testing. So can you do your hands again? Cool. And then how many are doing like automated testing? Awesome. Barely. That's a yes, it's a binary, you know. But yeah, so, you know, I think the idea of automated testing sounds so amazing. And I think everybody that didn't raise their hand or the one that's kind of, you know, halfway almost testing, you know, they might not be doing it for kind of several reasons, right? And I think kind of it comes down to the existing tool set and the existing ways of doing automated testing. They feel broken in that, you know, are the existing tool sets are slow, inefficient, difficult and outdated, right? So even though they're automated, they still run fairly slowly. You've got to sometimes spin up entire like environments and instances to kind of drive these things. They're very difficult to set up and configure. So you've got, you know, all these sort of very isolated, really neat tools that are really good at doing certain bits of automated testing, but to get them all running together in a way that's actually gonna allow you to just write some tests and, you know, take care of that thing that was over there, the little testing triangle, you know, it's difficult. And then what makes it even worse is that once you get all these like fragile pieces put together and you write some really cool tests, you often realize that they're flaky and they're inconsistent. You're writing a test, it passes locally, you, you, you know, push it and it fails and see eye and you don't know why. It's the same test, it's the same everything, right? Why is it failing? So, you know, I would argue that the reason this exists or this sort of problem exists is that the tools that are used for automated testing, you know, were built ages ago, right? Where you would do everything server side and then you'd get a DOM and you could look at it and say yes or no, this passes or fails, right? But, you know, the whole world of, you know, decoupled things, that doesn't work because so much is actually happening on the client side. You've got an API that's serving up some data and then you've got the client that's actually consuming it and, you know, doing stuff and things with that. So, I guess, you know, this sort of pain resonates with developers, not just in the Dribble community, not just in, you know, a specific part of, you know, the development world, it's every developer that's ever tried to write an automated test for the web, you know, they run into this. So, you know, we kind of at Cyprus set out to develop a tool that solves this. So, you get up and running very quickly with just being able to kind of download an app, which is our test runner. And you can download that directly or install it via NPM if you're using one of those shiny new JavaScript frameworks. And go through a streamlined onboarding process where, within the first five minutes, you're writing your first passing test. So, you're not dealing with all those, like, fragile pieces that you're trying to put together and make sure that it actually, you know, works. You're just focusing on what you need to be focusing on, and that's the writing of tests and, you know, running them consistently. And so, the test runner is, it's free and open source, which is really neat. And then that's great and everything because you got this really cool GUI that, you know, we'll look at to really build these tests, interact with your web app. But then when you want to, you know, make it a part of your CI, CD pipeline, you add a couple of lines to a config file and you're set to go. And that data then, you know, gets pushed to a dashboard where you can see, you can gain insight into a, into your builds that are running in CI. So, it's not just you do it locally, you push it, you see what happens, you come back to it, it's a, the feedback loop is a lot shorter. You iterate a lot faster. So, that's kind of like what Cyprus is, right? What, where we came from, why we're doing, what we're doing. So, now I'm just gonna go right into a demo because I think that that's probably a good thing to do. And then I'm gonna do this out of order because I don't wanna forget and it was another thing I was supposed to do, but I've got a couple more slides about the contribution sprints tomorrow and then the feedback slide. So, I just wanna make sure I show these so I can check that box, check both boxes. But yeah, so we'll go into the demo and then hopefully I'll remember to come back to this. Let's see here. So yeah, like I mentioned, getting started, super easy. You can go to the Cyprus website and solve the NPM or just download it now. Once it's downloaded, when you open it up and add your project to it, you're actually going to get this example spec file which basically tests sort of a dummy app using every sort of command and API that Cyprus has available. So you actually can kind of see how stuff is implemented. In addition to that, the docs are pretty phenomenal. There's a lot of work that's gone into this that describes not just the specific APIs and whatnot, but just also like how you might want to test and different sort of core concepts, guides, that sort of thing. So definitely check that out. So yeah, if we look at, like after you add the project, you're going to get a Cyprus folder here and then this integration folder, you see that example spec file, but we want to just add a new file. I'm just calling it Drupal. Oops, cool. So for the purpose of what we're going to be testing and everything, I just set up a very vanilla Drupalate site. So I decided not to tackle the whole decoupled thing because I didn't want to introduce more concepts of like front end, back end. I thought that it would be good just to start with very vanilla, like, you know, how we're dealing with the front end. And then if you go in more detail into the docs and whatnot, you can see some of the advantages and I'll try to point them out as we're going through this of how this, specifically how certain of our commands specifically sort of apply to, you know, just the front end world and whatnot. So yeah, basically, you know, we want it to say that the site should load, right? And to do that, we just use side visits and just type little URL, Drupal.duxl, save it, go back to this, you see that it's recognized that you've got a new spec file in there and you click on it, it launches your browser and it starts running your test. And so there we go, we wrote our first passing test which is pretty neat, it loads. So, well, thanks for coming, speedy. So yeah, so the really neat thing about Cyprus is that you've got the ability to not just see your app, right, but you can like interact with it and you've got like full access to your Chrome Dev tools, right? And the other thing that's probably important to mention is that your app that's running here, it's scaled, right? So you can see right now it's at 45%, we've got, it's at, you know, that's like the resolution that it's displaying at. But it shows you kind of what you would see there. So I think one of the important things about being able to interact with it is like, you know, if you wanted to inspect an element, you've got like your normal sort of playground of like what you're used to working with when you're, you know, building front ends. And then as I mentioned, like the resolution bit is pretty cool. So, you know, we're on, what is, I don't know what resolution this is, but it's not very big, right? But if we wanted to say simulate like a different screen size or whatever, like my actual screen size, it's like a MacBook, we could do, I think it's a view port and then MacBook 15. And so now it's just gonna rerun the test and you'll see that, you know, it's changed the resolution, it's scaled, it kind of looks, you know, similar, or not similar, but you know, you can still work with it. And then you can also give it sort of arbitrary amount. So if you want to just be like tiny or something, do that, and there you go. And so again, you can, you know, fully sort of interact with it. So the other cool thing is like on the right hand side of the screen, you see all the commands that are running. And it's great that that ran super neat, but what's even neater is when you start interacting with it. So if you hover over it, it restores the DOM to the state at that time. You can click on it to pin it and now I can interact with the DOM as it was when that command was run. The other neat thing is at the bottom here, you see additional output about what the command actually did. So this one was pretty boring. It visited, there weren't any redirects, there weren't any cookies, it was very, you know, vanilla. But if you had a redirect or if you had some cookies being set, it would all kind of be in your face there so that it's not, you know, hidden away. And then we've got, you know, again, just additional information, 400, 800, that's just what it is. And then so I think there was, I was gonna do this also where if you look at, you know, Drupal.org, right? And it doesn't look good at 400 pixels wide, just put that out there. But who's that small anymore? So anyway, if you look at this, you also see information. So for example, like they have a redirect, right? So it says that, you know, I requested the www.drupal.org and it redirected me to the HTTPS, so over SSL. So that's a cool bit of information. And then also, this is one of those areas where it's really neat when you're dealing with like a decoupled app situation is the amount of insight you get into XHR requests. So you're able to see, you know, what was done, the method, the URL, the status that it returned, how long it took, I mean, all this information, the request, the response, there's a ton of really good information that you can do to kind of iterate through, you know, how you're dealing with the response that's coming back. So I mean, this is all about, you know, speeding up your development, which is super neat. All right, so let's go back to our little test site. And I'm sure we wanna do other things, like test the site kind of as like an anonymous user. So we'll just set like a context of anonymous function. And then we're gonna throw this stuff up here. And as you start writing more tests, you start to notice that like, hey, you know, I'm doing this like visit a lot between tests. So there's probably a better way to do that. And there is. And so if you guys are familiar, like Cypress is built on some of the most common tools, which is why, you know, the API feels very natural. And you'll see when we start doing like assertions, it just, it feels familiar because you've used tools that kind of are the underlying engine to this. So we will do a before each. And this is where we'll just do the visit. So I actually, I set the base URL of our project in the Cypress.json, which basically just makes it, it tells the app where to start. So with that in place, we can actually just tell it to just go, you know, to slash. And it will know that, you know, we're trying to do that. So that's gonna save a lot of time. It's gonna look, you're gonna be able to make your tests a lot more readable. So that's neat. Let's see. So there, site loads. It's got nothing in it. It's fine. But let's, let's do something else. Let's actually do an assertion. So we're gonna say site has correct title, right? And this again will be a beautiful function. And what we wanna do is we're gonna use the Cy.title command. And so what this does is it returns, it yields the title. And so we can look at the command when we run it. Or actually, I guess we could do that right now. We can see that, you know, this was the command that was ran and this is, this is what it yielded. So we wanna make, we wanna say like this should include or contain whatever the word will say welcome. So you run that and I can't spell. So yeah, there we go. We've got two passing tests, huh? Isn't that great? I'm excited. So yeah, that's super neat. But then you can start going into more than just looking at what you can interact or rather the title, that's great. But what about like what an anonymous user might actually do? They might do a search, right? So in order to do that search, they're gonna probably put something into this text box, right? So how, how, how could we find this? Like we could, you know, inspect element and try to pick out, you know, oh my, we've got some choices. We can use the data to select and use ID, the name. We can do all this, or we've got this fancy thing that we call the selector playground. And so it kind of gives you that same sort of inspect element feel. But what happens is like when you click on it, it tells you the command that you would use to interact with that element. So we're just gonna copy that to the clipboard and oops, I guess I need to, so, can search function. So if we, you know, run that. And again, like when you save a test, it automatically runs it. I mean, you're talking about like just everything you can do to help people move faster, this does. So yeah, there we go. We've now selected that, but we wanna do something with it, right? Probably wanna type something in it. So we're gonna use the type command and we're gonna search for a little page that I added here. So just hello world, save that. It's gonna run, gonna see it types it. So like that's neat, right? But like what if you wanted it to go faster or even more fun, slower? Cause it's just too fast. You can do that. It actually slows down the typing. So you can modify the delay in typing. So like this is useful if you're doing some sort of, you know, XHR that's like querying for something and you need to control that time. There's a lot of things, a lot of commands around here that allow you to really, I mean control time by setting the clock and doing really neat things. We're not gonna get into that cause that's like a lot more technical, but it's a possibility. So okay, there we go, we got that. So after you type it in, you wanna maybe click this or you know, you can type enter or whatever. I like to type enter just cause it's easy. I'm also gonna set the delay to zero cause it's speedy testing with Cypress. It's not slow testing with Cypress. So you can do, you can just type it in like enter, right? And it recognizes that as, you know, something that you're doing. So boom, there we go. It searched for, you know, hello world. It found it. It looks excited. Good for it. And that's cool, but that doesn't really help us. We probably need like an assertion here. So let's do, let's see. Let's use the selector playground again. There we go. So search results that makes it easy. So I get search results. And we're gonna say should contain hello save. And there we go. It did it. So again, you can click into every command that it runs. And you can see all that is doing. It's getting this element. It's typing into it, submitting a form. Console's gonna show you data around that form submission. It's gonna tell you that the page loaded. It's also gonna tell you that the URL changed cause you might wanna do something about that. You might wanna know about that. And then last but not least, you know, we are getting the search results and asserting that the results, the result that we expected is there. So that's super neat. Another, you know, something that you might wanna do is like can search, but get like no results, right? Cause that's a decent use case. Function. And so here we're going to essentially do the same thing as I'm gonna cheat. Just copy this. Actually, I'm gonna do this instead. Hello world. And then we're gonna do the side I get. And I don't think we've actually done a click yet. So let's actually click on the support or not the support, the search button. So you can see, I said this is speedy testing, but like if you have to wait one and a half seconds, that's kind of not, that's not speedy enough. So we're gonna speed it up a little bit more by doing an only on that test. And so now we just saved 50% of the time there, which is pretty neat. So it drives you right to that particular test and shows you what's going on. So we're gonna use a selector to find that button. It's the edit submit. And this one means that it matched one element. So there are certain cases where you might have elements that are gonna match the same selector, whether it's the ID or a class or whatever it is. And this allows you to gain some insight to it. And there's actually some additional context that gets provided in the command do Hickey on the left-hand side here. When you do, when it does match multiple, multiple selectors, I don't think we're gonna, hopefully we don't experience that. So yeah, we're gonna get that wonderful thing. And then we're gonna click on it. So essentially doing kind of the same thing, right? But it's clicking. The click command is very versatile, right? It knows if what you're trying to click on is not visible. You can tell it to click in certain areas, like within that element. So like, has anybody ever experienced something where like you have to like be in a specific spot and click on it, otherwise it doesn't recognize your click? This is one way you can kind of test for that. All right, so what are we doing? We're doing no results, right? So then we're gonna take this, no results. And then we are going to, let's just run that. And as I mentioned, like one of the things was like the URL changing. And so when I was talking about this presentation with Dan, he was like, you know, why don't you show like a web form, you know, kind of going through a process and having it, you know, bounce you to a different place depending on what you put into it. I was like, that's a great idea. Sounds like a lot of work. So I kind of like, you know, I'm gonna meet you in the middle here, Dan. And I'm gonna just show off the awesomeness of what is PSI URL. So it is a command that essentially gets your URL. And so here, if we do that, you can click on it, see what it gives us, right? And we know that it should say that, right? So you can do like should contain this. So there, we know that, you know, somebody searched, it took him to the right URL. That's super fancy. And then obviously we probably do want to, you know, make sure that, you know, search results or rather that the way I did it before was just showing, I guess, how you can use the body. So I get, and this is like the sloppiest way to do it. I do not recommend doing this. But basically you get the entire body, right? And then you look in there and you're saying, I think something should contain your search, search, yielded, that was a fun word. No results, period, period's very important. So there we go. We've got another passing test. So that's kind of, you know, very basic interacting with a, you know, with a site, non-authenticated. But let's, let's, you know, talk about maybe an authenticated user and kind of what that would look like. So we're gonna go down here, do another context of authenticated function, do, do, and we're gonna say it in here. We're just gonna cheat, do side visit, user, user, get rid of my only, they're sneaky. And I'm gonna add the only here so we can speed things up a little bit. Okay, so another important thing to mention, you guys might already know this depending on what kind of testing tools you're using, but you know, we have, the before each is only gonna be kind of applied there. So we're kind of, you know, fresh slate here. And so we can use the selector, do Hickey again, select your playground. I'm sure they don't appreciate me calling it a do Hickey. Spent a lot of time working on that. Apologize, Chris. So we're gonna type admin, and then, you know, the same thing goes where you can like actually, like I mentioned, you can do enter, you can do tab, you can do backspace, you can do all those kind of things, but I'm just gonna use the playground again and, or the do Hickey, whichever. And we're gonna type into that and the password, anybody wanna guess? Hello, hello. It's close, it's close. So if we do that, all right, that's cool. And then we're gonna go and we're gonna do the enter because that's always fun. So we save it, runs it, logs in. You'll notice one of the slowest parts here is Drupal, just thinking about like, do I wanna let you log in? And it said yes. So here we are, but maybe we want to wanna know a little bit more about, you know, or confirm a cert that we've logged in and the content is what we expect it to be. So here we're just gonna, you know, we've got an H1 tag that's got admin in it. So let's go ahead and do one of our favorite assertions. Get H, not high, it's funny. Should contain admin, save that, run it, and whew, there we are. We are now logged in and every time you run this test, it logs in. So if you can probably imagine, you know, if you're running a bunch of tests as an authenticated user, you don't actually, I should say, when you're running tests as an authenticated, any kind of user, you don't want to persist state between these tests because that's like garbage that you're dragging along. That's like a skeleton in the closet that might jump out and attack you at some point. So Cyprus resets the state whenever you, you know, run each test. There are ways to, I guess, interact directly with cookies to interact directly with local storage. So you can kind of speed that stuff up a little bit. But one of the things, I kind of got a little sidetrack there, but what I was trying to, where I'm going with this is, you know, on the login side of things, what we want to do is log in before every test. But instead of, you know, having our, this like four lines, it's a lot of lines. Really, I guess it's only three lines. Three lines of code in every test, we can actually write a custom command. And so this is a way that you can extend Cyprus to really do everything that you need it to do, that you might need it to do frequently. And again, to keep your tests and your spec files super clean. So we're just gonna do Cyprus, commands. And quick question, who, any TypeScript fans in the room? Got one. All right, the world will catch up to you, I promise. So if you are not a TypeScript fan, you should be, because it's really cool. But there are typings for Cyprus. So if you're using like BS code or any, you know, IDE that supports that, you get a lot of like context around everything that you're typing. So it'll basically say like, okay, you just type get, this is how you use it. You want to read the docs, here's a link to the docs. It's kind of information overload, but sometimes it's awesome, because again, you're not having a balance between applications to get stuff done. All right, so we're gonna add a command. We're gonna get really creative and call this login. It's gonna be a function, because that's what it is. And we're gonna drop our stuff in here, right? So I can save that. And actually, instead of having all this stuff, we're just gonna now do Cy.login. So if we come over here, we can see that it ran. It ran really fast, we gotta start it over again. Isn't that super neat? I thought that was super neat. Maybe it's just me. So here, you know, you've got the ability to, you know, run, do a lot, really. Like you can not just create your own commands. You can create child commands. You can override existing commands. So if you don't like the way that we're implementing something, by all means. Go ahead, you know, do it a different way. And like I mentioned, Cypress is open source. So if it's not just some really particular thing that you're kind of weird about anyway, and it's something that the rest of the community would enjoy, pull requests are always welcome. So yeah, that was, I guess, you know, what I wanted to show you guys in the demo. Outside of the demo, I wanted to kind of give you some, you know, next steps. Like if you're interested in getting involved with the Cypress community or just testing, you know, your app. Like I mentioned, the website's super neat. I mentioned the docs. Support is really cool. So we are super active in Gitter. Anybody here active in any sort of Gitter channels? Nope, it's really cool. So it's, you will be, trust me. So look at this. Look at all these words. So many words. Yeah. So if, you know, if you're getting started and you need, you know, help getting started, this is probably a really great place to start for, actually no, starting the docs, right? But if you need that sort of human interaction, Gitter's gonna be a great place to do it. So Valerie, she's actually an intern. So she's here just pointing someone to an issue that already exists, awkward. And then Stack Overflow, also another really cool place. So, you know, Cypress entered a, it's public beta back in October. And like, I mean, it's kind of amazing the amount of people that have started to adopt it. You know, definitely, you know, follow Cypress on Twitter. You know, check it out, all the good stuff. And then I wanted to show you kind of the docs and the API. So like I mentioned, that Kitchen Sync sort of example spec that gets pre-populated into your project, it is, it shows you everything, but then more detail you've got here with really every command. And I mean, it's like, it's a lot, a lot of words. So like, side-out visit, right? Seems so simple, but we've got a lot of words talking about how it is simple, but also how it can be extended. So you can override time-outs, which is again, something that I really didn't get into. But like one of the reasons that your more sort of traditional tools that are built on top of, you know, Selenium or WebDriver, the things that they struggle with are, you know, seeing what's going on within your application. So, Selenium, it is basically outside of the browser. And it, you know, sends a command, flashes a light, sees what's going on. You know, tells you, okay, cool, yes, no. Cyprus is architected completely differently. So it's not built on Selenium, it's built like from the ground up and runs within the browser. And because of that, it knows everything your app has done, everything your app will do, and can intelligently not be flaky. So it knows that, hey, there's an XHR that hasn't come back yet, I should probably wait on it. And then it sits there and waits until the time-out, right, which can be adjusted. But that gives you two things. It gives you one less flake, but then it also gives you faster tests. So if you look at a lot of Selenium code or WebDriver code, you're gonna see a lot of waits. Somebody's like, oh, let me do this request, and then I'm gonna wait five seconds because it might take five seconds. But if it's coming back in like, you know, 500 milliseconds, then you're wasting four and a half seconds, and that doesn't sound like a lot until you start thinking about how many times you're gonna run that test, not just locally, but in continuous integration, everywhere, right? So that's a huge benefit. So again, sort of sidetracked, but you've got wonderful docs here. We've got in the examples different recipes for the ways that people are attacking certain sort of use cases. Single sign-on is another really unique one because the way that that works, and we basically use what's called side-out request to send a request directly to that endpoint with the credentials it needs, receives it back, does all the tokenization fanciness and allows you to kind of get around having to actually interact with a form, which again is another way to sort of speed things up. Stubbing, again, if you've got like a back-end, we have some users that actually build their front-end without having a back-end and can use how they've mocked out the back-end as essentially a spec for the people that develop in the back-end. So super neat, super cool. Let's see, we've got best practices. Tutorial videos, very neat. So if you're really wanting to sink your teeth in, definitely check out the videos. It kind of walks you through everything, which is super cool. And then we've got our media stuff, which is all there. So you can see what other people have written or spoken about Cyprus, which is pretty cool. And then we've got our roadmap. So some of the most commonly requested features are on our roadmap. So if anybody noticed, and if you didn't, I'm gonna point it out, when you are running Cyprus, it actually, it's launching Chrome, right? So what other browsers do you support? Right now we are supporting all your flavors of Chrome, so Chrome, Chromium, Canary, even Electron. And Firefox will be dropping shortly, followed by Safari and then Edge, and then we'll have a thought about IE. Oh wait, we just did. So what's basically gonna happen is when you have more browsers that are available, they're gonna be available to see via this dropdown. And then super neat. One thing I didn't touch on, which I really need to, is probably the dashboard. So this is like when you're running it in CI, like being able to kind of see what's going on. So I'm gonna actually cheat and go back here, delete this project ID. It's gonna yell at me, because there's a comma. Try it again, try it again. What'd I do wrong now? Anyhow, it likes me now, so we're good. So basically whenever you get started with a project, there's a runs tab. It's gonna say you have no recorded runs because it hasn't recorded any runs. You click set up, you give it a name. Drupal, who's gonna own it? Me, it's gonna be public. Set up a project, and it gives you this command. So this is essentially, if you're getting started in CI and stuff, we've got a whole guide on that. Again, lots of really good words. And then it shows you kind of essentially what the command that's gonna run. So if you guys are using like Circle for example, let's see if I can find it. But you can see it's super simple. You're essentially installing Cypress and you're running it. So if I did that, for example here, so this is essentially like we're pretending like I'm CI, but I'm not, we're just pretending. So it's gonna go and it's gonna give you this beautiful warning, which apparently is bug and electron, so there's an open issue. It's gonna run all your tests. It's gonna give you this nice little should log in. Oh, because we have that only in there, right? But it'll show you the number of tests that ran, the one that passed, the ones that failed. Records of video, super neat. It's gonna upload those assets. And then when you come back to this runs tab, you see that, bam, here we ran this three seconds ago. You know, Hi Sierra, very, I'm sure that's common in the CI world. Click on it and it takes you to the dashboard, which I guess you need to log into. Tell you what I'm gonna do. So yeah, there we go, we got Drupal. And you can go into the run. You can see kind of that same console output, which, you know, if you're running it in headless CI, you typically don't have access to or whatever. If you had failures, they'd be here. You'd watch a video of the whole run. You know, if you've got some free time, just browse through the passing runs. I don't know why you'd do that. And then I did, right back here, the doc route, I was playing around with it earlier, just to kind of show like the different states. So here you've got like a failure. When you click on it, you see kind of the stack trace of what that failure was. And I think this is because there was one additional test that I didn't actually do in the talk, where I basically added something to a menu. I checked a checkbox and adjusted the order and that kind of thing. So it shows you the stack trace. It shows you the error. It didn't check it because it's not visible. So again, we talked about how it's intelligent. It knows what it can and cannot do as an actual user of the site. And then it gives you the video. One of the neat things about the videos that you're gonna have in the dashboard is that they use key frames to know exactly when things happen. So like if you've got a 60 minute build and you've got a failure at like 45 minutes and 33 seconds, it's gonna jump you right to that point when you hit play on this. And you see it like started here, just to show you kind of that failure. And it can again, help you kind of pinpoint that. Also it's gonna take a screenshot. You can take arbitrary screenshots if you want, just for funsies. If you go to like, you know, where you did it only here. So after you start that, you can do like screenshot. And we'll call it logged in. Save that. And then if we ran that test in Cyprus, it's actually just gonna, let's see here. It's gonna tell you that it took a screenshot. And then if we look back in the file system, we'll see screenshots logged in. And this is where it was. Trying to think if there's anything else I wanted to cover. I guess not. Yeah. So I'm gonna do this. I'm gonna remember to come back to this and remind you guys about the contribution sprints. Very important. Tomorrow community needs you. And then surveys. If this is about me, hopefully you guys are gonna say good things. Cause I'd say good things about you and best audience ever, except the people that left. So yeah, thank you guys so much. I do have a couple of actually several shirts and stickers if anybody wants. You're more than welcome to come up and grab them. Nikki from Sivagroup was kind enough to fold and organize. They came in a big like circle, like a bundle and she made them not that. So we got small, medium, large, extra large. Very good stuff. So yeah, thank you guys so much. Any questions? Yeah. Yeah. You wanna come up to the mic? I think they wanna hear you. Okay. For archival purposes. Is there a way to examine the headers of what's coming back? Is there a way? Yes. You can, you have complete control over everything. That's, so Cyprus sits as a proxy in between everything. And by doing that, it gives you the ability to have complete control. Thanks. Yep, yep. Is that your question too? The second hand? Awesome. Well, thank you guys so much. Come get shirts. Oh, question. How does Cyprus handle visual regression testing? Visual regression testing. How might you solve for it? Yep. It's a tool. Absolutely. So let's see. Let me go back to this bad boy. We've got road map. So there are a lot of ways that people are kind of combining tools to get it done. So if you like, go on our, let's see if I can find it real quick, screenshot diffing. So here's like the issue, 495, very popular one. But there are some folks that have put together some libraries to kind of make it easy. It's not quite perfect, but it will be a feature of the dashboard. So actually taking two images and laying them over each other and telling what the difference is. Yeah. Like that, that's not the hard part, right? The hard part is honestly managing, well, the hard part is one, making sure that that screenshot is being taken at the exact same time. You know, the cursor isn't blinking. So that's kind of the hard part. The really hard part is managing. Right, things change. You're moving updates to your UI. How do you say, hey, this is actually intentional. Exactly. This is a huge regression. And so that whole like interface is really the hard part to say like, you know, these are your masters and this didn't match your master, what needs to happen. So it's in the road map, it's coming. There are some tools to kind of get you kind of halfway there until they're ready. You know the XKCD on competing standards. Yeah. That's what we're trying to avoid is like throwing another tool at it and you're like, oh, it doesn't quite do this and then go to the next one. Exactly. So that's one of the things that we believe with like Cyprus is that the, you know, by just doing the baseline testing stuff so well that like everything is just incrementally gonna add on that, right? So on the road map, you know, we've got a spec load balancing. So that's actually about to drop here in a couple of weeks. That's like spec parallelization as well as third party integrations. So like this is something that you're kind of getting for free. You've invested all of this, like the really expensive part of testing is investing the time and actually developing the test, right? So you've invested all of this time and actually developing, you know, these tests. Like we're giving you all of these things for free. So like if your tests take, you know, an hour to run, the parallelization will help, you know, orchestrate that with your CI and, you know, run them efficiently. But the same thing goes for like screenshot diffing, the analytic side of things. Just it's something that you're gonna inherit by having used the, you know, the test runner. Very cool, thanks. Thank you. T-shirts. This is extra large and this is small over there.