Check out a free preview of the full Complete Intro to React, v9 course
The "Browser Tests" Lesson is part of the full, Complete Intro to React, v9 course featured in this preview video. Here's what you'd learn in this lesson:
Brian explores the experimental support in Vitest for browser testing. These tests use Playwright to carry out browser-based interactions in real-browser instances. A naming convention is used on the test files to indicate which tests can be run in the browser and which will use Happy DOM in the Node environment.
Transcript from the "Browser Tests" Lesson
[00:00:00]
>> Brian Holt: Let's do some experimental stuff, experimental browser stuff that's actually probably even more dangerous. So everything that I just taught you, 100% of it, applicable today, go forth to your companies and use everything that I just taught you about vitest. This is all tried and true science so far, I'm gonna show you what's what's coming next.
[00:00:21]
And I almost taught this to you as the way to go, no matter what, but it's just not stable enough for me to recommend yet, so I'm not going to. But it's soon, the answer is, soon this will be stable enough for you to do, so I want you to know about it.
[00:00:35]
So, come into your project and we're gonna do nmp install-D at vitest/browser at 2.1.3 we're gonna need playwright, which is a Microsoft thing. If you've heard of Puppeteer, this is kind of the spiritual successor to Puppeteer, it's literally the same person, Pavel. He created Puppeteer at Google, and then Microsoft stole them, and then he created playwright at Microsoft, so he was just kinda continuing on the line of work.
[00:01:10]
The test-browser-react, and you can see how experimental this is, it's 0.0, 0.1, experimental and not done yet. So I'll also say like, this one is, in particular, liable to be broken by the time that you run this because they'll probably have changed this several times, so you might need to debug this a little bit.
[00:01:37]
>> Brian Holt: Okay, so we have that, we now have to go and create a vitest.config file. So we're gonna create a new file, we're gonna call it vitest.config.js, we're gonna import, define workspace, define workspace from vitest.config.js. We're kinda hacking around a little bit there, you can leave the .js, it doesn't have to be there either way.
[00:02:15]
Workspaces is actually for monorepos, so if you have like, seven packages in one repo, you can define different vitest workspaces for each one of them, that's the point of define workspace. But we're gonna use it to define a happy-dom environment for our old tests and a playwright environment for our new tests cuz I don't want to rewrite our old tests if there's still good, right?
[00:02:40]
And I just want to write new test in our browser way, so we're gonna export default define workspace and it's gonna be an array. And you're basically, two different config files here, so the first one we're gonna make sure you have extends ./vitet.config.js, and test. So basically, this is saying bring everything in from this file here, my vite file, and I'm going to just overwrite the test part of it, and we're gonna say include,
>> Brian Holt: We only wanna test files that have,
>> Brian Holt: .node.test.js or jsx, let's see the one of those, okay?
[00:03:44]
These ones are all going to be run in the happy-dom environment. So we're gonna say name,
>> Brian Holt: Call them happy-dom, and environment, we're going to set to be happy-dom.
>> Brian Holt: So basically, all of our existing tests we wanna run in happy-dom, and we're gonna have to go rename all of them to have .node in the title.
[00:04:11]
That's why I said later that the name of this one's gonna get even more ridiculous cuz it's gonna have to be contact.lazy.node.test .jsx.
>> Brian Holt: It's both absurd, but I also, I can't really do anything about it, It does have to kinda be that way. So that's fine, and then we're gonna have a new one, we're gonna write new tests with, and that is going to be extends I guess we don't need the quotes, extends, same thing, vite config.js, test, okay?
[00:04:54]
And this one has a little bit more involved setup, it's gonna have some setup files. This is just things that get run before your test get run and we're gonna put vitest browser react. we're gonna make sure that that gets run before our test get run, we're going to include anything that we include browser in the test.
[00:05:13]
So, the other thing instead of doing .node or .browser we could have just put them in separate directories that would have been fine as well, that's totally up to you. I think this just made me laugh, and so I kept doing it, chaos driven development, if you will, name we're gonna call this browser.
[00:05:35]
The reason why we're putting the name here is so that when we're looking at our test, it'll it'll actually give you a little label, it says this was run in the browser. This was run in happy-dom, and it makes it easy to tell at a glance, browser, and we're gonna say provider, provider.
[00:05:53]
And your two choices are playwright, which I strongly suggest you go with, I think you can also use web driver, which is Selenium, same thing. Enabled true and name, here you can put what browser you would like to test in. I'm gonna test in Firefox but feel free to put Chromium can go there or WebKit if you're on Mac OS.
[00:06:23]
But if you want to test in Chrome, you put Chromium here, I think you can put Edge there, maybe? Don't quote me on that one, anyway, Firefox, that's what I'm putting there, all right? So let's go rename these so that they have node .node contact.node, nope, not there.
[00:06:50]
It sucks, but unfortunately, the order is important, node, so contact.lazy.node.test.jsx.
>> Brian Holt: And pizza of the day, I'm gonna put this.
>> Brian Holt: And those are all of our node tests.
>> Brian Holt: And if I remember correctly, yeah, so cart one this actually, that can be run in the browser because playwright already does snapshot testing.
[00:07:28]
So, this actually will run in either one of them, and so we might as well just throw this into our browser environment. So rather than cart.node, we're gonna do cart.browser, these other ones actually depend on the fact that we're in happy-dom, and they could be rewritten to work with the browser.
[00:07:47]
I just don't want to make you do that because I don't think that's a useful exercise for you right now. But we are gonna create another pizza test, so we're gonna create pizza.browser.
>> Brian Holt: And we're gonna do that.
>> Brian Holt: So, all right, let's go write our test, so in pizza.browser.test.jsx, import render from, and we're gonna get it from vitest-browser-react, so this library aims to mimic testing library.
[00:08:27]
So we actually don't need testing library at all in the browser-based environment, because vitest-browser-react does all of the things that testing library would do for us, it aims to be mostly API compliant. So, if you have questions about it, just go look at the testing library docs, it's usually the same thing, okay?
[00:08:49]
Expect and test from vitest, import Pizza from src/Pizza, capital P, Pizza. Okay, we're gonna test alt text renders on image, and so we're gonna test the same thing, but we're gonna do in a browser-based environment, the test is gonna end up looking pretty similar. Const name = My favorite pizza, const src = our nice looking picture there pick some photo/200 and const screen = render.
[00:09:44]
Pizza name = name, src = src,
>> Brian Holt: And it's not src, it's image, sorry. Image = source and description = cool browser stuff. Close your tag there, and we're gonna say const image = await screen.get by role.
>> Brian Holt: And the matches end up looking a little bit different we have to use this expect element thing.
[00:10:25]
Or say const or await, expect element image to be in the document.
>> Brian Holt: So we expect it to render an image at all, right? Let's just make two of these here, I'm gonna say to have attribute
>> Brian Holt: Src, src and to have attribute alt name. So, if you're looking at this, its like, this looks pretty similar, right?
[00:11:08]
And not totally the same, just to put them side by side, just for a second.
>> Brian Holt: See the screen here, screen here, and this one you're just able to just do these synchronous checks, right? Cuz it's just really reading text out of a document, this is the whole browser, this is actually going into Firefox, grabbing this out of the downloads.
[00:11:36]
We have to await stuff, cuz it is, it's truly asynchronous, it's really in a browser. I think you're gonna have to do something like NPX playwright install if you've never run playwright before, let's just, I'm gonna run it and see what happens. I've done this before, so it might, yeah, I think it's just gonna exit for me, for the rest of you, it's probably gonna say like, do you wanna install 300 megs of stuff, is that working for people, okay, cool.
[00:12:02]
That was from memory, so I just was worried I was giving you the wrong command. What it's doing, it's gonna actually install mini versions of Firefox, mini versions of Chromium and a mini version of WebKit.
>> Brian Holt: Okay, so now you should be able to run npm run test and it should pop up a browser or it should fail miserably.
[00:12:27]
>> Brian Holt: Fail to load config.
>> Speaker 2: All right, I have one question that we maybe skipped a step a little bit earlier, but there was a step to remove things from the v.config.js.
>> Brian Holt: Yeah, you're absolutely right.
>> Speaker 2: I tried messing around with that, but I'm still getting that error, personally right now, so I don't.
[00:12:42]
>> Brian Holt: Okay, no, you're right, you do have to delete this stuff out of your configure because we put it in our vitest stuff. So, I had called this vitest.config.workspace, which technically is a valid thing to call it, but it's only for one project I was explaining to you earlier.
[00:13:00]
We're technically abusing a tool to make define it for multiple projects, so we can take care of a browser-based environment and a node-based environment. And in the docs, they recognize like, we already have that for workspaces, so we're doing it that way. But the big thing here is make sure it's vitest.workspace.js, and that'll fix our problem here.
[00:13:27]
>> Brian Holt: It's kinda silly to me that that's not the same thing, but I don't know, I'm not the one writing the open source software. All right, so you do all this, and notice that I'm popped up, I have another window here from Nightly, so this is actually downloading Firefox Nightly to run this, right?
[00:13:44]
That's why it's called Nightly. I have an error here in my test, but let's go figure out what's going on with that, failed to resolve report src/pizza. So I'm in pizza.browser.test.jsx, pizza from src/pizza, it seems like that should be correct, so yes, that dot slash, that was no source there.
[00:14:08]
And now we have a test running in our browser, which is kind of cool, right?
>> Brian Holt: So this should be able to refresh and notice this should feel familiar, right, the same UI, right? But there's actually something kind of cool about this, if you come into your browser tests, I will say that this breaks constantly and it's like, it will freeze, and so it's just a good refresh usually does it.
[00:14:36]
Yeah, so stuff like this, so you can actually see the component being rendered on the page, you're gonna include the CSS and all stuff and make it look really nice. We're not doing that stuff, and I'm not super worried about it at the moment, that's too bad that the image is not working, but the image should work there as well.
[00:14:54]
Pizza.jsx, did I misspell it?
>> Brian Holt: Photos, picsum.photos.
>> Brian Holt: And then now if we go back to our UI here, or this one, yeah, and then you can see that it actually renders out the image as well. Kinda ends up being like a little bit of a storybook, kinda thing where you can kinda like show off all of your components in an individual kind of way using tests, which is kinda cool as well.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops