SPEAKER:
And get back to it. So alright, so where we left off is earlier in the day, we got the Nightwatch test running or close to running. Or found out that, hey ChromeDriver can be a pain to set up because it needs to have matching chrome versions. But we walked through setting it up locally, with PHPUnit built-in Server, SQLite and ChromeDriver. Also via DDEV and through Lando, which there's all the configurations in this source project, which I'm going to repaste into the chat in case anybody lost it. So, that was the first part of it. Now, let's get to the fun part where we understand like what is happening. So, if I scroll up in my history, there should be some tests. So, it ran the tests. And that's neat in all, but like what's actually happening? How do we write our own test? So, we dove through this a little bit before, but I'll bring it through again. Inside the core directory, there is, I'm gonna open this ahead of time. There's the test directory, inside of its Drupal. And then we have the Nightwatch directory.
There's a handful of things in here, tests are, whoa! My screen went weird. This test directory are the PHP unit tests for Drupal core that don't belong to any modules. So, we want to look inside Nightwatch. Actually, that's the unit test directory. So, we wanna look at Nightwatch. And inside of Nightwatch, we have the assertions commands, pages in the test directory along with Global's and nightwatch.conf.js This configuration file is what, you know, just like PHP unit has phpunit.xml Nightwatch has this file. So, all those environment variables that we were configuring. This is where they're read in. So, the search directory, by default, it looks in the current directory, you know, ignore directories. Here we go the source output folder, the commands path, so commands path looks for any Nightwatch folder that has a commands directory, or assertions, or pages. And these are all part of the nightwatch documentation. We will go through a bit of these with the Quicklink module. And also one of the tests modules I've added in here the test settings.
This is where the Selenium port and selenium host. Now remember, Selenium was like a standalone project, but it became an open standard. And that is what is called WebDriver. So, if you see the terms of WebDriver and Selenium use interchangeably, it's because they are WebDriver is the, you know the open standard version of Selenium. And that's where all this gets parsed in in nightwatch reads. So, as it run up that there's the different commands, we'll open this commands file real quick. And one is the Drupal install command. And nightwatch uses this as a node process to run an execution, run the execution of a local command. So, that's what this...execute. There we go, execute synchronously, because you know, JavaScript is asynchronous by default. So, right here, it does this install command, which runs PHP scripts, test site install. That's what this test-site.php is. It's a mini-console application within Drupal. And it installs a base Drupal site for testing. So this test site application, there's a command in here.
We'll pop to it real quick. We wanna look at this test site install. And actually, this test user login is used as well to log a user in. But the main thing here is a site install. sets up an installed version of the site for Nightwatch. Just like Drupal functional tests, do a full site install. So, it is Nightwatch. But instead of calling it directly, like in PHPUnit, it's called an outside script. So, this is great for what we would call like BlackBox testing where with PHP unit, the PHP units running inside of an instance of... I just kind of decided to pop in 'cause local development is relevant to some of my interests. I do a lot of things with Lando. So, let's figure it out hang out here., you know, there a lot to learn. Cool. Thanks for joining. So, this is the script that allows Nightwatch, the Nightwatch test runner to have a Drupal site installed to work against. And one of the... Oops! Close that too fast. The main item here is this option called the setup file. So, what happened, right, when you rushed install site, you get a bare minimum site, you don't get any actions installed, you have to click through and do so.
And this command allows you to pass a setup file. So, think of it as like a bootstrap file. You know, like bootstrap has something to start up not bootstrap the theming library. So, when you install the site, it then executes this script to configure the site. And that's what this Drupal install command does is it will run that, it will pass the simple test user agent cookie and ensure that passes on. If you're not familiar with this, Drupal will read this cookie and this user agent to determine what is the current test database and know that it's working in a test environment. So, that is actually a really crucial piece. So, that's about the innards of that for the inside. Like if we looked at login, oh, there's actually where it does a full login. Here we go. If you do the command, Drupal login as admin, this is another command which runs a script on the server, which is like Drush ULI but as a test site script command, which allows you to log in as user ID one in your tests. And how these are called will pop into tests.
So, let's just look at example tests. So, inside of the test, we have add tags. So, the tags documentation is like grouping your tests, when we were running tests, before we did dash dash tag core. Everything in here is dash core. If you had your own module, you would name it after your module just like your PHP unit tests. And the app before... No, I will actually go to a custom module because I added notes there. Sorry, let me go to this Nightwatch example. So, inside this repo, I actually did add a Nightwatch example test. And I put some notes in there. So let's just go here, since I already wrote a bunch of these notes. This module up on GitHub or anything? It's inside the repo. So, if you go to the project, and you go to web modules, and under modules, there's custom Nightwatch example, test source Nightwatch. This is all already in the repository. And just to reiterate, again, like this Drupal testing workshop that I'm creating inside of custom, I'm gonna be creating a plethora, I want to have at least 50 different modules showing different test cases and uses.
So this will be like my education area for test writing. So, if you do want to be able to reference this later on, it is available. And a lot of this is also documented on Nightwatch JS but we're hitting that weird area where it's documentation of the test framework and documentation of well, it's Drupal using something. And we all know what that's like when you finally hit that point where it's integrated into Drupal. So, tags are how tests are grouped and make it easier to run this, you can run a test directly. Oop! Did not want to do that. As we did previously, you can run a test directly by calling it or via...via a tag. So, in here, we could do tag core, or for this example, we have workshop. So, if I did this command, I don't have everything running, maybe I do, but if I ran that it would run my test here. Let's see. So, it should run by integ workshop, it will find my contrib test. And it should execute "Hello world test!" Found it, it's gonna - I didn't turn it back into headless mode.
So, again here, the test hello word test, test suite, it launched Chrome, you can see here that it's hitting the browser. And it did, oh, hitting the browser, hitting the webserver. And you can see here that it passed a deep strict equal test. When you write a Nightwatch test, you must add this before a statement. When working with the PHP unit tests, we're used to having the setup method predefined for us by all of the base classes. But we don't have class inheritance here. So, all tests must set up the before hook. And in this, they must call that Drupal install command that we looked at, you need to call a Drupal install. Otherwise, if you don't, you won't have a Drupal site, you'll just hit the install page, and the site will crash or the test will fail, not crash. And in here, you'll see that we're passing a custom site install test script. Now, we could reuse the one provided by core. But this sets up our module. So, I have it in here. So, the path matches its modules custom Nightwatch test site install.
This path should always work regardless if you're in a Drupal development repository or in your....in your client work because it matches the root path of the doc root. And I can prove that via the Quicklink module when we pop over to that one. So in here, I have the test site install script. And it does one thing. All these scripts must implement tests set up interface. And this interface defines one thing set up. You know, it's really simple, but it's just that way, when you're implementing it, you know, like, "Oh, I must have a setup command." And all we do is install the module because there's no way to define that inside the test, not like in our PHP unit where you have protected modules. And it's an array of modules to install, you have to write the setup script, which is like a bootstrap that says, OK, Drupal was installed now do things. And anything that you need prepared for your test is done in here. And we'll look at the quick, I guess at the Quicklink module. We'll look at that afterwards because it does a little bit more.
So, Drupal is installed, it calls that script which installs this Nightwatch example module, just like you have to call the before hook, you must also call the after hook to uninstalled Drupal. If we look at the commands on install, calls the script once more and drops the database, it runs the teardown command. And if you don't run this, well, then you're going to have a pre-existing site. And I cannot recall if the test site setup will fail. If there's an existing database, it should. I haven't tested that in a while. So, after that, we can finally start defining our tests. If you've worked with any JavaScript testing frameworks, like just Mocha, I think Chai is one I don't know they're all named, half of them are named after like a cafe...cafe drinks. But essentially, we're just adding it to the object. So, this is our test name. See here, running visit a test page, we have visit a test page. And it is this value is a function. This is the shorthand for anonymous function. If you're not used to IES six, this is equivalent to writing function browser Nightwatch will pass a browser instance to your call back to your closure.
And that has all of the available commands attached. Commands are either provided by Nightwatch JS, or through modules or core itself. So, unfortunately, there isn't a great type hinting for this and automatic completion. So, if you're OK with having to go dig things up, you're gonna have to kind of remember them. Luckily, there aren't too many helpers. So, it's pretty easy to find them because they're all right here. So, what this does is b browser drupal relative URL, so let's look here, what this does is it just ensures that you're going to the test base URL is otherwise like what if you're running it in a subdirectory like drupal ci does so drupal ci has all tests under what is it localhost slash checkout it's something different now because this actually broke drupal commerce with having it be under slash checkout but let's say it's like localhost slash environment dot index PHP. So, this is their base whereas for you know all of us that are running it locally we don't have a subdirectory.
But that command just allows sub-directory support. And then the browser object is documented on nightwatchjs.org under the API reference. So in any API reference, there's the assert, expect page object API commands. All of this can be gone through to find the core items that are available but we'll go to the very bottom or maybe we'll go to document handling sorry to execute. So, execute allows us to run Javascript in the browser that's being tested. So, in this case, we're not testing an element necessarily, we wanna test some data that's on the page. And what we have inside our module we implemented hook page attachments, if you're not familiar with this hook uses a hook to add libraries or drupal settings or HTML head elements that are across every single page or across conditional pages I guess if you have logic in here. But it's meant to be attached to the page, that specific elements. So, in here we're adding drupal settings called Nightwatch test with echo "Hello world!" So, if we were to visit our browser in the console we would do drupal settings we were able to type drupal settings dot Nightwatch test and drupal would return, the console would return an object that looks like this so we wrote a test to make sure that our hook page attachments is properly bubbling this drupal settings data into you know it's actually being attached.
So, in this the execute command takes a function and this first function is executed in the browser. So, we're returning drupal settings which is the global object and then we want the Nightwatch property, the second command allows you to pass extra arguments to the function that's called, yes we do have a dog com joining us today. And then the third parameter is the important one because this is called with the result. So, once this function is called with these parameters the result is passed to a third closure callback. And so, maybe we can do an assert, so the browser object has the Node.js Assert library attached. So, anything that's available in the assert library is available here. I had to go look that up, so if you go to Assert the methods from the base Node.js Assert module are also available. So, anything that you use for testing in node.js is available here. I feel like maybe I was in PHP storm but this did actually autocomplete at one time. It might have been PhpStorm or WebStorm.
But what we're doing here is we're doing a deep strict equal and this sounds weird but there is just equal is deprecated. So, they made everything be strict equal. But the problem was strict equals the objects aren't exactly the same, so we use deep strict equal which just is like it goes and make sure that all the properties match but it's not the same object. So, we're asserting that on our page we have this object called echo "Hello world!" So, with this test, we were able to verify that this javascript document was the javascript settings were on the page. Now, that's one of the benefits of Nightwatch is if we did this in PHPUnit it would be harder. When thinking about just testing elements on the page it's kind of like well what's the benefit of Nightwatch over functional tests. We even had this discussion in the D9 Theme Channel, when you're using functional tests you can just as easily assert content on the page and the dom. You can fire certain commands but it's harder to test some of these scenarios, some of this interaction when writing PHP to talk to WebDriver versus just running Javascript code, as you can technically execute Javascript code in the functional Javascript tests from PHP unit.
But this is much more easy, it's easier. So, that's writing and running a Nightwatch test, before moving on to the next step I wanted to show the Quicklink module. So, this is a module written and maintained by our very own guests Mike Herschel, though we can't see him because we just see his dog staring at somewhere in his backyard. And he was having, Mike I don't quite remember what happened, but like something was wrong, something was broken and we needed to write a test. I was like, "Hey there's this new thing core called Nightwatch, let's try it out." So, we wrote an integration test and the Quicklink module for those who don't know integrates with this library called Quicklink, which is why it's called that. And it will read, it like watches links that are in your viewport and prefetch them, so that way when somebody clicks that link, it's like an instant load. So, it's like having a single page app without having a single-page app. So, we wrote an integration test to verify that the library is loaded.
So, in our test, you know, we tied it as Quicklink and we wrote an install script or a setup script. The setup script does a little bit more than the previous example, it not only installs the module but it modifies the settings and turns on debug mode. Because when this module installs debug mode is turned off. But since we're in a test, we want to flip this on so we can have it be more verbose. So, that's the point of some of these setup scripts is not only to install various modules but allows you to modify certain parts of the state. After this we're gonna move into writing one for the Olivero theme, so you could use this to modify some of the Olivero settings versus having it be done manually in the test. So, our test then goes to a relative URL the login script and if you notice here, we have a custom assertion called Quicklink exists. And that's what this assertion folder is for is to hold custom assertions. You should notice that there's nothing here that tells drupal to find this file, when I looked at that night, when I opened up the Nightwatch configuration, it knows to find this pattern of test source Nightwatch assertions.
And anything in there should be registered as a custom assertion, And we use this to verify that the Quicklink library is valid on the page. So, the assertion is not to write your own assertions are also documented in the API reference or actually, I think it's the developer guide for extending. And custom assertions like it walks through it pretty well, I remember this wasn't too hard. So, you create this expected which is true, like the assertion is that this should return true. This pass, it passes if the return value is strictly equal to true. The value, this is...you can call it a reducer or mutator, whatever you wanna call it just says, "Based on the value object, what's the actual value that's being called to the pass function?" And in this case, it's result dot value. Popping back to the other item quick, whenever you call the execute command, the result has is an object. The result has like the session ID, another property and then value the value property is the result of what was executed.
So, we now have the command, we do this API execute and we check if the Quicklink if the global Quicklink object is a function. And that's a result. So, we return the results and the result that value should be true and it passes if that's true. So, I have a question for you. Yeah. So, I mean could you do something where you're running like the exact command and you just say the global Quicklink is a function and the exact command. But you put that in the actual test as opposed to a mass rotation or...? Yes, we could have done that. I realized that like I didn't know, I don't remember why I went this route when we wrote this. Because we could have easily just done this, what I wrote here is the simpler version that we could have had inside the Quicklink module, basically. So, this line of code inside of this example performs the same operation almost as this assertion. So, this core have been put into the main test instead of being his own standalone assertion. I probably also want to help create an example for people when writing this.
Like I know after all, after we do the Olivero thing, there isn't a command for asserting Drupal settings. So, I'll probably be, I'll be opening a issue for core to add this as a command, as an assertion, like assert Drupal settings, pass a key, and it returns that key value. Because we don't have that. So, for example, if we want to modify this, so here's a tenant of test-driven development, right, we wrote the test, and it passed/ ow we're going to change things and make sure it still passes. So, I could change this to say, to change this to key, so we're gonna pass a parameter of key. And we'll pass the key value, the key parameter as an object, key reference, like, take this key out of the Drupal settings. And we'll pass it as an argument here is a string. So, what we've done here, I'll move some things around to make this easier to read, as we're telling it to execute this function and pass these parameters to it. So, now, we've made this function reusable. And this could be moved into its own assertion or helper method, like a command, get Drupal settings.
So, if I run the test again, once I get I'm gonna make sure it runs endlessly, so it's a little bit faster and quieter. Copy, Paste. So, now, we put the key we want from the Drupal settings into an argument for the function that gets executed. And it should... And report this to Drupal have a command or assertion or some kind of helper for testing the data push to Drupal settings because there isn't one right now. So, it ran. So, it's still passed. That's great. And if I don't do this, I hope somebody else does or reminds me to make it a core issue for this. So, we have that. And these two examples kind of showed interacting with the JavaScript, like the state of the site. If we look here, so Claro has an autocomplete test. So, it goes in and it goes to add-in modules. It sets the value of the search for form API test. It waits for it to be visible. And this is where things were like, well, we can test this with functional tests, like this right here could be done without JavaScript for a lot of it.
Actually. Sorry, not the whole typing part and waiting for it to be visible. So what this does here is it shows that the type to search works on admin modules. And then this whole wait for element to be visible gives it a second to weight. And make sure that it shows up, and then it clicks on the other. So this just sets up and turns on Claro as a default theme, which again, this could be a custom setup script. Like, it doesn't need to click through it, but it does test a few things. Did you say that the functional JavaScript tests can't wait for an element? No, they can, but it would not work. But this helps test... Basically, let me rephrase it. Everything you see here we can do in functional JavaScript tests. There's nothing in this section we do this all the time in Drupal Commerce tests, where it's like assert wait for you know, jQuery to finish wait for the thing to be visible inside of... No, functional webDriver, WebAssert. So, if we, sorry, let me, I'm gonna, no. JS WebAssert, there we go.
So, for example in here, it's very similar to items we have in here where it's assertWeight on AJAX request. We're able to execute, we're the session right here is a Mink. Session Mink is the library. Mink Session that connects to the WebDriver instance ChromeDriver. And that the condition is x is JavaScript code. So we are able to execute JavaScript code via functional JavaScript as well. So everything that we read in this Claro autocomplete test can be done here. And a lot of times has been done, there are core tests for the entity reference autocomplete written in functional JavaScript. So for here, wait for element to be removed, it does a wait for. This is also executing a JavaScript command. Wait for element to be visible. So a lot of these things are possible with the functional JavaScript, where it becomes that and that's where it's like kind of like a hard line to draw. It's like, well, which should I use? And like I said, in the d9-theme, like, Brian Mike and I, we sat a few times.
Like, well, this could be. It's like, well, I don't know, should it? And kind of back and forth, back and forth. But it really is useful when testing the state of your JavaScript. And like I said, you could do it with the PHP code, but it's just more natural and a little bit easier to do here. And that's why this was added, the Admin UI, is it, was it the Admin UI or the JavaScript Modernization Initiative? And they were both like one the same, really needed this. Cuz it made testing so much easier, and it's actually paying benefits now that we're working on the Decoupled Menus Initiative. And (CROSSTALK) Another thing from my perspective is just to think of a JavaScript developer, you know, having to go write their JavaScript in PHP to test their code. It could be much more natural for them to write something in Nightwatch, I think. Yes. So there is that. And that's when where you know, this weight for element to be visible is provided by Nightwatch.JS. If we went to API, wait for, maybe not, it should be.
Let's see, let's search. So, yep. So that's that's given. And you know what? I bet under the hood, it's running the same kind of JavaScript code. So they're very similar, but it is just one like it feels a bit more natural to test JavaScript code with JavaScript than in PHP. You know, Java people do it all the time, though, right. They have Java code that runs Selenium and WebDriver and test JavaScripts. But we yeah, this makes it easier for others to contribute and to do more complex things, which we're about to do one of those complex things. We're going to write a patch for Olivero to test out a feature it has, which I don't have. Let's see, let's very quickly... Go to lb.cm/olivero, if you want. Whoa, what lb dot... Cm/olivero. You're a lifesaver. Not, almost, you almost are. Oh, there we go. I just had to make the screen bigger. So we're gonna write a test. And the Olivero has these awesome, this awesome menu. But wait, there's more. When you scroll, the menu collapses. And what we're gonna write a test for, we're gonna test that, right.
We're gonna test that. When you scroll, that this collapses, and we're gonna test that when the browser window shrinks, we get the mobile menu. So we're gonna do some live coding here. I've only written two Nightwatch tests in my life, then the quick link one, a year and eight months ago. And then two nights ago, I wrote the Hello, World test. So, we'll see what happens. And this, like I said, this repo is not set up for core contribution. But luckily, I should be able to just copy and paste. I can copy and paste it into a branch for Drupal core. So, let's get to it. So, we're gonna create a new test called... Do they want all the tests inside this folder? Cuz this feels weird. Brian and Mike, do you know? I would say like, let's put it in for right now, and let him tell us now. Cuz it feels like more appropriate to actually put it in Olivero. It does test discovery for themes. Put it where Claro puts theirs for right now. Like we can change it later. Cuz Claro only puts has one test.
Well, for now, we will put it here. (LAUGHTER) Because we're just doing an example and trying to teach. Instead of me going down the rabbit hole of like, well, let's bike shed the placement of this test. Let's just get to it. So, we'll call it oliveromenu test.js. So we do our module dot exports. You know, I wanna see, is there a? Yeah, but these are always bad. Sorry, apparently I have way too high of expectations and I expect the world to just be a perfect place all the time. So don't mind me. Alright, let's see, we'll see how well this works. And hopefully it helps autocomplete a few things. So, cuz I don't have this memorized by heart yet, so, let's, we'll do a side-by-side. Can everybody see this OK? Or do I need to enlarge it? Cuz I can enlarge it to you. I can see it, I have a pretty small screen. Alright. So do tags, we're gonna take it's core. But you know what? I like to have lots of tags because I don't wanna run off tour. I want to be able to run core and just the Olivero things.
So, we've got our tags. Let's do a before, and we're gonna do browser. And we'll do browser.drupal install setup file. We're gonna create our setup file. Cuz I don't wanna do all this, this is just ick. i don't wanna click all that stuff. We're writing a test, should be fast. And we'll do, we'll copy this after. Alright, so the setup file we need to create. Let's look at this, this other test. So setup file we'll copy that line. Now, we can close. From here, we can close all that. I think we've got the scaffolding. So inside of core test Drupal test site, test Drupal test site, test site install script. So they have a test site multilingual install script, which pre-install copies over some translations. That's new, I didn't know that. Test site install, we're gonna copy that, we'll call it test site. Oh, you know what? Can you install themes from the command line decently even? Yeah, I guess. Yes. But they manually install it. And I guess I could do that. Well, in the PHP tests, they do something to install.
Here let me try to dig it up. And since I'm not in PhpStorm, I have no idea what anything's called right now. So pardon me. So, I'm used to the Symphony plug-in, which auto-completes a bunch of stuff. So, I don't know Jack Dataly, theme manager. Is it theme manager that installs things? Alright, we'll find out. And I guess we can just do service, and we'll say assert theme installer instance of. I'll clean this up to be our code standards friendly. Actually, I'll just do it now. See change all occurrences to theme manager. So theme manager, whoa, two cursors. So theme manager install. No, it's not theme manager. There you go, that's beautiful. Thank you, saving the day. So theme installer. So it was theme installed. That's the one thing with core that kills me is we have thing underscore and thing period. No, I know like habits change, but I wish like we could like make aliases to some of those. So that way we know what's going on. So, we'll do an assert. The reason why I'm doing an assert here is so that way we get the autocompletion.
Cuz right now, the IntelliSense, IntelliSense whatever they call their like their static analysis inside VS Code, has no idea what this means, like service returns mixed. So, by doing an inline assert, we're telling the interpreter. Now, the command line, the editor interpreter, like what it actually is. So we'll do theme installer. And now see we do install, and it gives us a list of things. Then we'll kind of copy it verbatim, and then we'll get the ConfigFactory. So we do Drupal ConfigFactory, get editable system dot theme. Oh, sorry that's just config. We'll just say config copy. The no, that's not it. Sorry, copy from Zoom, paste in the editor. Alright, so what this should do then for us is we'll have a test site setup script that gets the theme installer, installs Olivero, and sets it as the default theme. So, let's go find this file again in our sidebar. I'm going to copy the relative path and paste that here and drop the WebPrefix. Why is this? Alright. So let's run the test. So we're gonna say on scroll menu collapses to, what do you call that the mobile menu?
We'll say mobile menu. Shit like, we just renamed it in an issue. Call it hamburger button or something, just mobile menu. And I'll change it later. We're gonna say. (CROSSTALK) Can you use a hamburger emoji? Hold on. Let's see if the... I'm tryna do the shortcut of control command spacebar. And now, it's gonna randomly pop up in about three minutes when I start typing. (LAUGHTER) And I can't get my touch bar, just shows zoom. And I can't open the thing. So, yeah, if you paste it (CROSSTALK) (LAUGHTER) Alright, I'm gonna throw it in here, there it is. Alright. Oh. (LAUGHTER) You know. (LAUGHS) Alright, there we go. So what we want to do is we're gonna do some assertions of. So we need to know what state we're working with. So, we have the site header, and it's site header fixable and fixable and JS fixed is what seems to be the trigger. Like, if I delete JS fixed, the menu gets, oh, it does go back. OK, so if I removed this fixable and JS fixable, we get the menu back. You want to do the JS fix, not the fixable.
I know, but just oh, so if I removed, how can I? What are you tryna do right now, just like? I'm just tryna show that we could turn it off. I'm tryna analyze the state to know like what it means if it was fixed, which this is it. So we basically need to assert that when we scroll, JSfix is attached. Is there any way instead of that that we can assert that the button is visible? The button that appears right there. Right now, it goes to, I think it goes from like, yeah, visibility visible and then there's visibility hidden. So we need to assert that, it's like visibility visible right now. Yeah, we can. So let's get to finding. Let's look at the docs. I'm gonna try to like browse the NightWatch docs versus the test. Normally, I just go through all the tests and I poke around till I find what I need. But I know the way that I do things doesn't necessarily work best for everybody. So, let's learn how to browse the NightWatch docs, instead of poking around aimlessly in tons of files as I furiously scroll around.
So, let's go to Developer Guide. No. Writing assertions, sure of finding. What was that? Somebody had a question? No, OK. We're gonna use existing, I click the wrong link. I wanna make sure I use all the things that they have before going on a tangent and using other items. So we'll use browserdot. I know we need to look up this part, it's the Drupal relative URL. So Drupal relative URL. We wanna go to the home page. And actually, isn't there some default content, Mike, that gets added to the home page? Yeah, there is. So we can test for that too. Let me bring that up for you really quick. I'll shoot you a tugboat link in a second here. I'll show you what that looks like. Well, while that goes, I'm going to realize that this doesn't have Sequel light. Oh, and here we go. We'll see who's faster, my computer or tugboat? My bet is tugboat. Does it be great to also assert that you know, we're on the home page, and we have Olivero data? Maybe there's a way we could do that here. So, if I go to Drupal settings, there is nothing.
I'm gonna throw into the chat here. Without like the default state, without content with the standard profile, as soon as I can find my Window here. Somewhere, there it is. Open Chrome. And tugboat was faster than my computer. Alright, so we're gonna assert for this text. Actually, we'll search for this one because it's awesome (CROSSTALK) the Drupal community. Yep, the Olivero is dynamic right there, so that might change. That's like the site name. Oh, OK. So, yep. So we wanna do browser.assert. Oh, contains text. Hey, look at that, great. So the snippets do work. I take it back. I take back any presumed negativity. So let's look for what selector we would want to check. Let's check for block content. So we'll say the CSS selector is block content. There might be multiple block content or yeah, yeah, yeah. You're right. Because that's not the main one. I would use like the ID of the main content or whatever. And that's what you should do. So, if you're a person that's like, I don't like having IDs littered out throughout the code.
Like, this is one reason they are kind of nice, because when you do testing like this, it's great to have it added. So let's turn off prettier for now. Can I? Oh, I don't know. We'll just deal with the error marks. Alright, so we wrote our setup file, and we've got a base test right now. Like, let's just run it to make sure that the hamburger test can get this content to be shown, which verifies that our setup script installed Olivero. So, we tagged it with Olivero, not just color. Cuz I don't wanna run all the other core tests. And we'll see if this runs. No problem. (BACKGROUND CONVERSATION) Alright. Never mind, Brian. (LAUGHTER) I would make the CSS selector something like Olivero content space h2 or if you wanna use just content, ID content add a space h2. So, it's not searching all the text on the page. I thought about that, but I don't know how specific we wanna be for the main content. But you're right, cuz main is literally main of everything. So we could do... That region content would be good and then or that you see that block Olivero content that would be a good one, right.
Cuz that's a standard Drupal block ID. Where it says Olivero is that like, I'm trying to think of where that, that comes from the site name. It might be, let's look. Yeah, it says page title. So we'll just leave that. We're gonna go back to our test real quick though and type error Drupal relative URL is not a function. Well, it should be. So, let's look at our test, cuz that means I probably did something wrong. So example tests. So we've got before. So our test name is wrong, long. So this browser blah-blah-blah. Did I forget? Yep, that's why, thank you. And you know, I guess we could even be more generic. Like here it says assert body or contains text in the body. But I like this specificity being specific here. Specificity, I can't. I am horrible with words and talking. There are certain words that I just cannot say. And I always feel bad whenever I have to do names. Because my pronunciation is deplorable. So, in the future, if I ever have to say your name and I say it horribly, I'm sorry.
Alright, so we've got it running, we should not get any errors now. And if it passes, oh, unmet dependencies. Oh, interesting. So it couldn't be located, but that's because the block module doesn't ex. Wait, unmet dependencies block. This is missing the block module. So just like Kernel tests, we have to enable 5,000 different dependencies. Is there a way you can just install the standard profile? Yep, there is. And I found that minimal is usually enough. (CROSSTALK) Cuz if we look at Drupal install, you'll see here that the install profile is NightWatch testing, which I had no idea that existed. And where our profiles? Profiles NightWatch testing. Minimal profile for running NightWatch tests includes the absolutely required modules only where testing adds page caching. I like having leaner tests, but will Olivero break if we don't have views and block enabled? No, it's not gonna break. And honestly, like that test should still work, like, with the minimal profile. So, we'll try minimal.
Yeah, for the PHP unit functional tests, I've had to use minimal. It probably could be made more efficient, but. I'm gonna double check. I have a tugboat preview for minimal too. I'm just gonna make sure that doesn't... The reason why, just so everybody knows like why that broke is the configuration dependencies. So on install, it must be able to install blocks. And you can see here dependencies. Oh, wait, user account menu. It was the user menu? Well, so that's actually not gonna work on the minimal. That test is gonna fail on the minimal account, because that front page is generated via views, which is not installed. So we need standard, we're just gonna do standard. We're gonna avoid any fanciness. I'm tryna have a lean test, and we're just gonna do it. So that's interesting. It's probably because it's a BlockConfig. And even though, like this is one thing that it has a module dependency on system. But it also needs to technically have one on block, because BlockConfig entities are provided by the block module.
Yeah, the block module provides BlockConfig entities, block content provides content blocks. So that's why that this failed. Is it explicitly said uninstalled these blocks must be installed? But the block module did not exist. Yeah. It might be worth moving those over to optional too. But then, well, we wouldn't be able to test the menu. Because the menu (CROSSTALK) via blocks. So we can use the standard install, hopefully, it doesn't make it take too much longer, you know. One fix would be to have... We would take the module installer. And cuz we would have it install block and views. Yes, yeah. I guess, the fix would just be to add the dependency in there. Or that, well, but themes can't have dependencies. Can they? Yeah, they can now. That's new. But I mean, like, the config would have a dependency, right. I'm not quite sure how that works. You would move it to optional. And once the dependency is available, that like help. Like, once the help module is installed, the optional dependencies will install.
Which is a fun deep dive into the config system if everybody wants to do that later. But our tests, look at the hamburger. We have text, so great. The Olivero theme is installed. It's working. We're start working on the test more. I'm rerun it with the standard profile commented out, to see if the changes to the install script work. So, our next step is, we need to take the header, which we're going to work with the header ID. And believe, I wanna see if there's a way to get the specific element returned and do more scoped inspections, but maybe not. So, let's go to API reference, and I wanna go to assert, page object, API commands, element. So, that would let us get the element. Didn't wanna look at the example test. Page test page, what does this do? Oh, that just gets (UNKNOWN). So, we'll go, and now we gonna do browser. assert. element. We're going to assert that the... We were gonna look at the button. We want to assert this button. Which has (UNKNOWN), so let's look at this API reference.
So, finding elements, we wanna do assert. So, assert attribute contains, contains text. Contains visible, here we go. Is there an invisible? Oh not, that's right. Everything has an optional not (UNKNOWN). So, we want to do browser. assert. not visible. Expect, that doesn't look right. I'm not trusting any of the assertions that this is giving me. So, we want it to be button. that, correct? Button there and now we're gonna see how to do a scroll. So ,let's do scroll, element id clear, element id value. Is there a way to just like, element interaction, unlike actions you'll immediately scroll elements into view, and check that it is intractable? Oh, there we go, move to element. Move the mouse by an offset of the specified elements. So, I guess what will have to do.
STUDENT:
And just gotta be like a scroll down or something, right? 'Cause you don't wanna move the mouse. I'm looking on stack overflow right now. And it says there is no native method to do scrolling. What you should do is get location in view for whatever anchor is gonna pop you down. Yeah sure. That's what this is gonna be. So, what we wanna do, is we're gonna just move down to the body text. So ,we'll just... This should be a contest, so browser that move to elements. But then I guess, what is this? Exocet. Well, it looks like Top Gear off, we want move element moves the mouse, get location in view, I think scrolls the browser that can get location in via. Automatically wait for the element to be present, Elmas not found an error is Using Selector .So, this looks like it's still requires an element, you could use the footer. Oh yeah. So just go all the way down to the footer. Perfect. You should just be able to use like. That safer should be fine. We're going to get even more specific than that.
(LAUGHTER) Why? So, alright, so we're going to do a certain not visible, then move to Element and assert that it is visible. And we should also... this is the menu inside of here. Yeah, and the menu currently, like it's kind of translated, but it's not removed from the DOM, so I don't really know how visible would react. So, I should probably Google that. So, what does that is visible Night watch? Alright, Invesco, how do you duplicate a line of code option down? Because it's not command d. Now, as you just highlighted, I usually like shift command left and it highlights the whole thing. And then I control seeing (INAUDIBLE). Well, we're gonna find out if it's not visible because it shouldn't be, but it is technically. And that would feel that I need to put an I.D. on that, so let's just run the tests. Let's see where we get. That did feel and here so I'm going to go back and say it has to be the shift out down, that's it. Thank you. I was doing(INAUDIBLE). There it is. So, in this and the install script test, just installing the blocking views module didn't seem to do it, so we just installed the standard profile.
Isn't it an intelligent key biding? Should just use intelligent. Alright, so we're gonna rerun this again, and the goal should be we know we got the text to be present. We're going to assert the button is not visible. We're going to scroll down to the footer and make sure that the buttons visible and that the menu is not visible. And one thing I do want to do is be able to view some of this awesome goodness. So, we gonna comment about and run it again in a little bit. Now, all your tests should be highlighted in emojis all the time. That's the only way you communicate if you're gonna work in JavaScript. That's the only way you can talk is in hieroglyphics of emojis. All right, it's just such a bummer because it takes so long when we do the standard install, like I wonder know why this failed. So ,that's the type of thing we could if you leave like that whole like in sound, the blue block and views commented out in there. That's something we could work on. Well, we'll leave it. And that's something they can do.
Not during this training. No such element, OK. Is not visible. So, I bet I know why. So ,I'm actually really glad this film. So, the button is not visible, expected, is not visible, but could not even be located. I think that makes sense because you're trying to raise. I'm not sure that button actually exists until it's scroll down. I don't think it's not visible. I don't even think it's there. Well, it exists in the HTML. So, you should be able to find it there. It's there. So, we're going to now this is why it's nice not to run things heedlessly. We gonna run it and let it launch and see if it hangs enough as it waited five seconds for it to be visible. Alright, so there we go. And if you're really fast. You can open this, but you need you can open the dev tools for the test browser, but you need to pop it out right away because otherwise it changes the viewport and that can screw up things if it kicks into like responsive design and things shift around. Was there a way to parse it?
Yes, but not in it. You have to run like, you know, like pop, like sleep for thirty seconds. You'd have to write something like that, like you'd have to write your own set time out. but even then, that's not blocking. So, I don't remember. I found a way to do it. But since JavaScript is asynchronous, I can't remember what you have to do. Alright, so there's the power. Too slow, does it show up on a standard install without. it'll be the random error. It's not visible, what? I guess we'll just do not exist. So, the element not present, but that's just seems wrong because it is present. Let's see if we're able to hold on, so it should be writing reports and creating screenshots. Thank goodness. So ,every time we ran this, apparently it created tests and so.... it's, if you go up one right there, you had the mobile menu, like the screen shot or the screen with is too narrow. And that's a common bug. Everybody that's worked with Behat, I'm sure, has worked with that where it's like .I want to make sure my pretests that it widens the browser screen.
So, if we do resize window. And we'll change it to one thousand by eight hundred and we'll make that a before. And it'll need to be wider than that may make it easier for I think like that goes away at like twelve hundred pixels or something like that. I was hoping you could like, resize your screen that way. No, Instead you just break JavaScript apparently and(LAUGHTER) you can set it so it changes to fourteen hundred. Alright. So, JavaScript is fun. You can set property and it doesn't reset. So ,we'll rerun it and now we have, so in the reports it is generating screenshots. And the Ximo output, which can be passed as a unit for your C.I. results, there's got to be a way to save the HTML too. So, that way we could see what's happening there. open it in the chrome. There we go. Thank you for finding the way to pause. Too bad there's not a way to make un pause it in viewing, which is one reason that. what we're like wait for user input. And that's one reason a lot of people have become fans of Cyprus, which Cyprus is a truly neat testing sweet.
I think it's too much, but it gives you like it's a full like like electron app that runs chromium and web driver and like gives you like a visual test running system. It's great, but it's like so heavy. It's just so heavy. But it has a lot of like nice user feature. I didn't see it scroll. Because it didn't even find the button to be invisible. So, it can't even assert that the button is not visible because it can't find it. So, that's what we're going to set it to not present. But I just wanted to... So,we gonna change it to not. So, it's just weird because it should be. But you know what? Let's see something real quick that might be true. It set the visibility hidden at this point. And it also has no opacity zero. What's below? You see, it does get set to display none. But that that doesn't display flex, I'm so... But why isn't it? Has it opacity is zero somewhere in there, too, because we animate the opacity or maybe I know we animate the icon has the opacity zero. And let me see, why isn't it showing up?
Go back to the parent item. Display. Check the box for display flex. Well, we just gonna try this, not present, that just feels incorrect, but that's what it's telling us. So, let's run the test again. Because it is weird when I run the query selector in the console, it finds it so it is present. We'll see. So much fun, just working with Dom Stone down some XPath. Not being able to find a button. I wish there should be a way to replicate scrolling down the page with JavaScript, that's not necessarily like a Nightwatch API function. There is. And that's ideally what would wanna be run. I'm assuming that's what it's doing in the background when we say scroll to this element. I still would like to just run JavaScript that says scroll. It's easy. It's just like window that scroll too. Move to element expects method expects for arguments given to. So, this worked element not present worked. I just didn't. And don't forget to change line 23 or no change my 22 to element present. Alright, or can we keep it visible?
I think we can keep it visible because we want to make sure it's not only present but visible. Move to element. Well, that's a slighter X Y.OK. So, expect four or five. How can I expect four elements? The dark say Selector offset, why offset optional callback, that should be fine, but I just saw there's move to. Let's try this. Ship movement master. (INUDIBLE) offset specified the Web by the Web element idea or relative to the current mouse cursor if no element is specified. But the thing is, when you move the mouse, it doesn't scroll it. You're right, what does this say? Well, this says move the mouse as well. What about executing some JavaScript and just doing a window. scroll to. That's what we'll try. I just wanna try this move to real quick .X is up and down, right? No, X is left and right. So, Y is up. OK? I'm the person who gets Lefty Lucy, right?(LAUGHTER).Because you're spinning like it's always it's going left and right, like it doesn't like it's still going in both directions technically.I get very easily confused by my things.
So, what would be the JavaScript I get? So, since this is now loaded, the java... Its window when the browser executes or whatever, but it's a window that scroll to. Type it out in here. So, that way I have it. Window that scroll to. There you go. And then x, y so zero and then say like 400. So, that's exactly what the should that move to should be doing. Because I'm assuming when it says the mouse because it doesn't actually ever click anything but it has to move. I think when it says the mouse that means like what's in the viewport. Now, I think it means the mouse. So, you can just JavaScript. We will shoot hopefully this doesn't, if not will do will execute the JavaScript, it's just when you do that, it's asynchronous. So, then our test weird. I'm afraid to move the mouse. So, yeah, you're right, that didn't. So ,still move to element, let's just try the.... When we execute the order, maybe we can do we'll try that .And we'll do Browser execute and I'll go to the API actual quick too.
So, that way body ARGs and optional callback, so we know that scrolling 400 was enough. And brought us like Middle of the page, let's say it was 200. That's nice, a little bit of a scroll. So, copy that and once they execute. There so, again, for those who don't work with ESX JavaScript a lot, we just created a an anonymous function and since it only does one line, we're just saying return this value. So, it's a nice little one liner array But with the array at the end that you're passing in(INAUDIBLE) There's an empty arguments. So, I'm really excited because I'm pretty sure PHP were getting this and I am so excited for shorthand closure's, I mean, it's still kind of longhand, but it's a lot better than having to constantly type function or static function for my array maps and array filters. So, this ran and I was too busy paying attention to that. So, it looks like it didn't. Is still saying is not cannot be located. When you look at it in the browser at first loads an error page of some sort and then it loads.
Because that happens to with PHP unit because my local(INAUDIBL)and it hits. So, on the first load, it doesn't know that it's the the the simple test user. So ,it actually is hitting the the default database. And then the second time around the simple test, the user agent string and kookiest set and it knows , I'm using this other database prefix. So ,that's one of that. If you were to watch the functional tests and the functional JavaScript test, it will do the same thing on your local if there's an error in your local area like your local site. So, let's try this execute to we're gonna pause. I'm gonna run this pause thing. Because we'll do you pause indefinitely. I'm just baffled. Alright, watch now that we called Browser execute scroll to it's going to work in that .So, let's see. Like your dog turned into three blue dots. No, maybe my phone died. Let me see him. He's still out there. I bet the battery died on my phone. So far, while we wait for this to go, are there any major questions?
About Night watch or curiosities. For setting up these tests. I had a quick question, how did you get it to actually show up in Chrome again? So ,for that Of course, they came back. So, to do that, scroll down to the DOT EMV file. So, this is the big like. Asterisks like if you run this with Dev and Landow, you can't run it this way, like it will always be headless in those environments. But there are the, it's commented out. So, I chrome driver. So, in the chrome driver or the Web driver, chrome arguments, want to pass it, this disabled GPU headless and no sandbox and that hides it in the background. But if you're debugging locally, like on your machine, you can comment that out to receive the full browser experience. But that doesn't work on debt for. No, because it's inside of a container. So, that's one where you could. If you want to do it this way you have to run it locally. That's a the thing. If there's some other like neat tricky way there's not, I mean maybe there is, maybe somebody has one but.
is that it? It doesn't exist. It's not there. What do you mean it's not there? I don't know. I typed in the same thing. Am I on that test site? Is that tugboat example on nine dot to that I had. And is my local on nine dot one?. And did you introduce a backwards compatibility change I mean Look it is now primary button Even the latest head man. So here's a good lesson for everybody. If you're going to write tests for Core.
SPEAKER:
Make sure you're on latest development branch head. So, um, we
STUDENT:
If there was already a test you would have caught that.
SPEAKER:
Yep. Yep. This is already a test
STUDENT:
That's a good point.
SPEAKER:
Alright. So, cancel that. And we're going to get back to here. And we're going to change this to not visible again. I'm gonna copy that assertion right there. Or I guess I can paste it here. And I'm going to copy. Oh, man. So, we're gonna make a to do. And this is for 9.1.x and 9.2.x. It is, fix before patching.
STUDENT:
And believe it or not, that's actually gonna change one more time.
SPEAKER:
That’s not a problem
STUDENT:
But whenever that patch gets committed, we'll fix the test too depending on whatever gets fixed, gets committed first.
SPEAKER:
So, that fixed that problem. But it didn’t scroll. That is the other problem. But let's just at least try this. And let me run it. And I'll read the question. So, if you're on Lando, or DDev, and you remove the chrome driver AGS, environment variables. It will run in the browser, but it's going to yell at you that there's no display attached. So, by running it with, so let me.
STUDENT:
So real quick, I wish I could like show this better, I want to make sure we I can see everything. So, if you were in Lando, and you remove this statement, so wouldn't try to run in a headless mode, it would complain that there is no display attached. I don't know who remembers having to run the XVFB command in Travis CI or whatever it's like, XVB99 and you emulated a display. So, unless you ran this command, it's just going to error out, like it will just not run because chrome or WebDriver. Probably I'm assuming the WebDriver part of it would say sorry, there's no display attached to your system, so it can't render. So, you have to run it in headless and I swear this thing… Expect it, is visible but God not visible because it didn't scroll. Come on. NightwatchJS scroll element into view. Which is gonna go. Alright, we'll just do, we'll do that and we're gonna pause it because no. Did this class change? I guess I could check if MIKE: I don't think it did but I would check it.
SPEAKER:
I guess I could. I have the code right here so I could have checked that from the get go. Veril templates
STUDENT:
This could be in the page
SPEAKER:
Page?
STUDENT:
Under layout, in the new page. Say footer there it is.
SPEAKER:
So that has not changed. So, let's run the test again. Alright, here we go.
STUDENT:
Alright, work work.
SPEAKER:
And I think this block of time goes until three so I really want to land this before then to be considerate of everybody's time. And I would love to just have it be. I just want it to work. I just want to walk out of here and we're like Woo! we wrote, we collectively wrote a test for the Olivero theme to make it help get it stabler for Drupal 9.2. Mike, when is the deadline for getting Olivero stable?
STUDENT:
That is a great question. I just asked yesterday that to Larry Escro who’s a core committer and he says it is either May 17th or May 31st. So, we're going with May 17th`. We have a number of accessibility issues in front of us and the accessibility maintainers are super busy so it's hard to get them to review stuff but that and the testing are two main things that we got to do. There's a couple like technical (INAUDIBLE) stuff that we shouldn't have any problem doing.
SPEAKER:
So, the month of March would be a great time to sprint on all these tests if we can get it running. It crashed out on me and didn't pause.
STUDENT:
Another time it would be great to sprint on these tests is this Saturday.
SPEAKER:
Oh yeah well yeah, this Saturday. Sorry we're getting ready for; I hope everybody now is armed with knowledge on ways to work with Nightwatch and would be comfortable for sprinting on Saturday. I don't remember if I said it or not, I plan on being there but I’m getting my first COVID vaccine on Friday. So, I didn't know I’d be eligible and all of a sudden, they are like hey you're eligible and I was like great. And I almost scheduled it for today without realizing, so I didn't but I picked Friday and I’m hoping that I don't get knocked out of commission because I would love to work on this on Saturday.
STUDENT:
Cool, supposedly the first one isn't too bad but (INAUDIBLE)
SPEAKER:
Well from what I’ve heard is if you've had COVID, the first one is really bad and the second one…
STUDENT:
Cause that's right because you had it.
SPEAKER:
Yep, well I was assumed because it was in March of last year and they wouldn't test me because I wasn’t sick enough. So, I’m waiting to see I hope it's not too bad but what
STUDENT:
It’s crashing, isn't it? Or did it just pass?
SPEAKER:
Well testing if is not visible. Wait it's like it won't even get to this get locate, it's crashed it's like it won't run that line of code. Oh, shoot! Because it's a callable, you have to run it OK that's why…
STUDENT:
You have to pass in a function?
SPEAKER:
Yeah, that would do it.
STUDENT:
And what does the function do?
SPEAKER:
It’s a callback
STUDENT:
Oh, and then you need to throw, makes sense.
SPEAKER:
So now…
STUDENT:
So, let’s have a handle on the a-sync stuff.
SPEAKER:
Yeah, so this asserts this pause. Cancel that log. It looks like it returns result. It's an object a status and the x and y. So, it's always good to read the docs because twice now I let that crash or it didn't even crash. It's just executed and had no callback so it assumed that the test was done, which is silly because there was stuff after it. But it's like after you call that it just considers it, I’m done. Determinant I don't know. There's always time to improve later right now we just want to prove that it works.
STUDENT:
Yeah, get something going.
SPEAKER:
Prove upfront improve later. So fun history Mike, how long has it been since the Olivero theme first came to fruition as a contrib project?
STUDENT:
I actually hold on one second. I’ll tell you when I first like reach out to Larry cause I have that conversation right now when we were actually considering about considering doing it. It’s been over a year.
SPEAKER:
It did scroll. Did it scroll? Cannot read property pause of undefined. Well, oh shoot! So that's one thing too. We don't want to use an anonymous function here…
STUDENT:
OK
SPEAKER:
Because it lost all context
STUDENT:
Yeah, makes sense. So, we first started thinking about working on it on May 13th 2019.
SPEAKER:
Wow! So, like one year. Wait, wait no.
STUDENT:
It's almost two years. In may it'll be two years since when we like started working on it you know. And that includes the design. We didn't start working on the design till like three or four months later and then there was a, I did that proof of concept which was just html and then at Florida Drupal camp 2019, which was like right as, it was like last camp before COVID. We did a sprint there and we actually got the theme kind of working and a little bit
SPEAKER:
Nice.
STUDENT:
And then it's just and then we got to into core for 9.1. And now we're trying to get a stable for 9.2. It's way more work than I thought.
SPEAKER:
Yeah, well, I will help write. Tests are my fun thing. Like, that's what I enjoy doing. If you give me a list of like, Matt, we need this tested.
STUDENT:
I have some stuff. I'll maybe create like a little meta issue. I want to create some tests, because I want to learn how to do it. Cause honestly, I've never written tests before. So, I'm like, really excited to learn about this. I'm excited that I'm learning right now.
SPEAKER:
And we've got a couple existing issues, too, that have, you know, some testing tasks for me. Alright.
STUDENT:
Look it scrolled down.
SPEAKER:
Woo!
STUDENT:
Yay!
SPEAKER:
So we asserted that the menu does its thing when you scroll. So, and then I did the console dot log here, when it moved to the element, you know, maybe this can be optimized.
STUDENT:
So, go into that, go into that page, that HTML.TWIG and let's break something and see what happens. See what fails.
SPEAKER:
If I dropped the footer name?
STUDENT:
No, scroll up and like rename the button or something.
SPEAKER:
The button’s in here?
STUDENT:
Yeah, the button’s right there. Yeah, there it is.
SPEAKER:
Like if we did the breaking change that committed to nav primary button. No, that's not it. I copied what it is. There we go. Wide nav expand.
STUDENT:
Just add like X’s into it. That's what I always do.
SPEAKER:
Well, no, I mean, but this is like, this is going to prove like you change the class. Because what happens most oftentimes people make changes. And then they forget to update tests. And that's what the tests are there for is like, hey, something changed? Did, is this expected changes or not? Which is the whole point of visual regression testing is like, did you mean for this page to look different? You can say yes or no. What was the solution to get the window to scroll down?
STUDENT:
There was, there's a, there's a method called get location and view. And what I was doing, as I was just calling it, but apparently you have to give it a callback function. And then you can do assertions inside the callback for that element. There's that like, move to element view, those things just didn't seem to work. But this does. I wonder if that move to element works? I don't know why but like unformed elements, maybe is what it's more suited for. I'm not too sure. But now the test is gonna hang. And if we wait three more seconds, or none. So, we got the air were testing element nav dot primary button is not visible, and it could not be found. Because we changed the class name in the template.
MIKE:
It’s awesome. Cool. Is there a way that you can just throw a patch up on that Nightwatch issue? I can give you the link to that someone that Brian created.
SPEAKER:
I just dropped the issue and the link in there. There is a existing fork and feature branch on that issue.
STUDENT:
OK, so you can either create a patch and we'll get it up there or something like that, obviously, your patches against 9.1. But like I would honestly like, like work on it. Maybe tomorrow, Saturday morning before?
SPEAKER:
Has anybody here used the new fork stuff yet?
STUDENT:
Me.
SPEAKER:
Okay, so we're gonna run through it. Because this has been my new favorite thing because I am lazy and I don't like to have to tone down code.
STUDENT:
It’s so fast.
SPEAKER:
So, we're going to go to the web IDE inside GitLab. So, we're gonna go to core tests, Drupal. Nightwatch, no test site. So, we're gonna go to test site first. We're going to click here, we're gonna do new file. And what did we name it? We named it… Olivero site install script. We're going to do, create file. So, the web IDE is nice because you can do a bunch of changes at once. Otherwise, we could like do like add one file and a few things like that. So, we'll paste this as is. I'll just add a to do right now. Blank line at the top. What? There's a blank line at the top. Thank you. I recently had an issue with that and it broke our installs on Tugboat but not locally or in production. And I couldn't figure it out why. And it was because of that blank line at the top. Oh, gosh. And it drove me nuts. And thankfully, Tugboat helped me solve the problem. So, what was it like right now we need, standard install for dependencies. Dependencies, figure them out here. So, we'll just add that. I’m sure its missing like.
Yeah, we'll just add that. And now, this saved it in there, right? I think so. So now we'll create the Olivero menu test, inside of tests, new file. So, I guess even if this local repo doesn't have like, if you use my base, or this, like example here., Why is everything added an extra new line at the top? You could copy and paste stuff into here, at least. It's not extremely the right way to do it. But you could like you could work on it in this example, and then copy things over via the Gitlab UI. What's an actually appropriate name for this test before besides the hamburger?
STUDENT:
I think we should. Don't they have like a bunch of like unicorns or something on some of these tests or something like that?
SPEAKER:
There's llamas everywhere, but we'll say,
STUDENT:
Let's just leave some I want some emojis in here.
SPEAKER:
I think Sally would love it.
STUDENT:
Yeah.
SPEAKER:
So, we'll just leave it to one. Yeah, that's very subtle. I like it. Yeah. So, we can remove that to do You may want to include the word hamburger just for accessibility. Leave the emoji. Spell it on. Awesome. Good call There we go. The spacing looks weird. Alright, so now we're going. That's it, right, the test script that we're gonna commit. We're gonna commit to add, many tests. We will commit. And so that was committed, we're going to create the new merge request. We're gonna name the merge request here, because we're going to add more stuff to it. Hit submit. So now that this loading, let's go back to the issue, and we will refresh. And you'll see that it now says there's a merge request. And it's queuing test. And we're getting a live preview on Tugboat. You know, for a Tugboat and a tiny boat, I think that thing does a lot of work. A lot of good work. I don't think the live preview will actually install the theme yet. No but
STUDENT:
So, I, if anyone's interested in that, I created an issue to have Tugboat by default installed the umami profile, because at that point, we get like free content and stuff like that. And I also talked about having each core sub component, being able to specify its own like Tugboat YAML file. So, we could even like do special things, like, you know, install different things like that. But right now, yeah.
SPEAKER:
Does this. Hey, good. So, it’s always good to guess Admin Admin. You know, our test, our merge request only as a test. So, it doesn't do any good logging into here. But so yeah, so that's how you can contribute to core without having to clone Drupal, I guess, like, right. You could grab my demo environment for just like learning how to write tests. And I went to this. There was already an existing branch, I couldn't show you how to create a new branch. But I went to it, I use the Gitlab web IDE and I created a pull request without having to do anything.
STUDENT:
Well, now, now the test should fail, right? Because you used the old CSS class name. You fix that. OK.
SPEAKER:
I fixed it before committing it, so if we look here.
STUDENT:
That’s so awesome.
SPEAKER:
Yep, and scroll live net
STUDENT:
OK So, in terms of from my, from my bath. See ya.
SPEAKER:
Alright, Derrick you have a question? Or somebody was, Yeah, I was just talking about. I hate talking other (INAUDIBLE) Yeah, I just (INAUDIBLE) like how many tests do you think, is a good number of tests? Because there's a big debate about like, how much test coverage you should have for things. Everything should have a test. There's no such thing as too little test coverage. Now there's a point of absurdity. So, what can I show to you? Um, one second, let me. Alright, opening something in code. So, I'm working on a product called brewed up, which is like untapped, but for coffee. So instead of checking into all the beer you drink, you check into all the coffee you drink and how you brewed it. And inside here, I have several different entities like checking coffee roaster, roaster and tag. Like I said, before I do test driven development. So sometimes I write some kind of like stupid frivolous test, but it helps me make sure that basic bugs are fixed. So, like in the coffee roast test, here.
Do I have, so entity test base. I even have it where it says test exists. So, ensures that the entity type definition is discoverable and parsed. For inside a Drupal because I worked on all this code, I wrote all this code before I even installed the Drupal site. So, I will write an absurd amount of basic boilerplate tests to prevent me from having to install Drupal and make sure things are there. So, I guess it depends on how you work. Like if you do test driven development, then you're going to have the right amount of tests. If you don't do test driven development, you're going to have fewer tests, and you may not know what you need to test because your code may not be, you know, like completely abstracted and testable. A good example is my previous live streams for simply test.me. With some of the testing, you know, it's a blend of what's not a waste of time. That’s the best way to put it. You know, test coverage is great. Was it like Martin Fowler is the one who wrote like the book on test driven development.
And then he went and worked at Facebook, and was like in culture shock, because they weren't writing tests. But there is no point to because they were at such a scale that you couldn't test for things like there's no point in wasting time writing the perfect test for just to be like, completely destroyed, because it ran in production and production was unpredictable. So just best, I would just use your best judgment. Like don't spend like a day writing all these tests that may not ensure stability in your platform. Like if it ensures stability, and it makes you develop faster, then yes, you know, like is this code testing necessary? Not entirely but… Sorry, no, it's all good, keep going. Where was I? I have a really good habit of somehow messing up my namespaces, or my annotations, and like this really basic check, would catch if I, you know, if I miss type, the annotation here, or if there was some kind of invalid key in my entity annotation, it would cause the entity type manager to throw an exception when it tried to fetch the definition.
And when you're first writing your code, and first starting a project, that's really beneficial, because running this test takes two seconds. flushing your caches in Drupal and clicking on pages takes a minute. And that's a difference of 58 seconds, and those 58 seconds add up over time. So that's why I'm a big fan of tests, and but only when it's appropriate, and, you know, gives you the most productivity. If that helps. I didn't answer but I hope it helps guide the answer. Yeah, I don't think there's any, you know, solid answer to it but all critical features, I guess. Yeah. Yeah. Like the critical features and just one that you know, like, you know, I believe in, you know, you should be able to deploy six times a day, if not 20 times, like you shouldn't be afraid to deploy. You should be able to deploy on Fridays. You know, Fridays at 5pm walk out and go get, you know, yourself a dinner, whatever beverage and not have to worry because you have test coverage. And that's kind of like your guidance, you know.
Exactly, that's a point that I make in some of my test talks. When you're really when you're really well covered, you're not gonna have any of those times when you pop up in bed in the middle of the night be like, oh my God, this is gonna break. Because you got it although the deploying 20 times a day. For my two big projects right now each of my test suites, like I've got one that has older tests that are all in newer tests that are all in Drupal test rates, running both of those takes over an hour now because there's 6000 steps. But we can do four a day. Yeah, there's you there's within reason. Why did this a new statement? I think it's already running and updated test. Oh, okay. I'm gonna leave it. Yeah, there's that. And also, like, people in Drupal are way too happy to run, drop Drupal cache rebuild, like, I see people doing it first, then config import, then APPDB, then again, and like, Oh, I plan on doing a series about high performance on Drupal deployments. Because you shouldn't be doing that.
You shouldn't even need to run cache rebuild when you deploy Drupal. There’s ways to avoid that. And you can easily speed up your deployments. But that's a whole different topic for a different day. If anybody's interested in that. I would absolutely watch that. And would hope people watch that as well. Everybody's interested in that. Oh, well, I will make time for it. Go online and sell tickets. Maybe we might Drupal camp Asheville talk, because that's coming up this summer.
STUDENT:
I got my second-best camp.
SPEAKER:
Well behind mid camp. Thanks for saying that about my way. Yeah. I mean, Are there any I know we're coming up on time. And I know there's going to be BoFs and other great things happening at the camp. Are there any other questions?
STUDENT:
I'm excited to do work on this. So, thank you, Matt.
SPEAKER:
Cool. Yeah. Anybody who wants to keep this going Saturday, we're going to sprint on tests (INAUDIBLE)
STUDENT:
So, when is it starting? 10 o'clock. 10 to 2 Central time? Yes. I might be. I might be working a little bit earlier in that day. I like to work in the morning. So maybe.
MATT:
Yep. So here give back Saturday 10am to 2pm Central Daylight Time, which I guess everybody in the world finally on daylight savings, right? Europe, their switch? Okay. Because that week is rough trying to figure out the difference. So yeah, 10-2, I'll be there if I'm not too groggy. Or maybe it'll put me in that perfect test writing spot where I won't be hung up on, you know, going down the rabbit hole on bike shedding. And I'll just be loosey doosey, and cranking out tests. But thanks. Thanks, Matt. And I think that the fact that we were able to get a merge request up for this is amazing.
STUDENT:
Yeah.
SPEAKER:
Took longer than I thought. But I'm glad that we got here and I hope everybody learned something. So, thanks for coming. Go enjoy the rest of the conference. I think there's just there's one more there's like a BoF session, and then it's the social stuff. Go on and have fun.
SPEAKERS:
Bye, everybody. Thanks, everybody. Thanks.