Test Fixtures | Bondar Academy
Course: Playwright UI Testing with TypeScript
Module: Advanced Tricks and Techniques
Instructor: Artem Bondar
Lesson Summary
In this lesson, we explored the concept of test fixtures in Playwright, which are essential for setting up and tearing down the test environment. Key Concepts Fixtures create preconditions for tests and clean up afterward. They offer more flexibility than traditional test hooks. Fixtures can be defined in the playwright-config.ts file. Creating a Fixture We demonstrated creating a fixture called formLayoutsPage to navigate to the form layout page. This fixture encapsulates the navigation logic, allowing tests to focus on validation steps. Steps to Create a Fixture: Create a new test option type for the fixture. Define the fixture function to include navigation steps. Use the use keyword to activate the fixture. Performance Benefits Using fixtures significantly improved test execution time. For example, a test with a fixture ran in 2.5 seconds , compared to 4.5 seconds without it. Advanced Fixture Usage Fixtures can be set to initialize automatically by passing auto: true . Dependencies can be established between fixtures for better management. Execution sequence matters: commands before the use block run as setup, while those after serve as teardown. In summary, fixtures are powerful tools in Playwright that enhance test organization and efficiency by managing setup and teardown processes effectively.
Video Transcript
In this lesson, we will talk about test fixtures. So fixtures is a very important concept of the Playwright architecture overall that you need to understand. Fixtures are very useful to create a setup or the precondition for your test, and also fixture can be used to tear down or clean up the test environment after the test is completed. So behavior is similar to test hooks, but gives you way more flexibility for configuration. So in this lesson, we will talk about this. Let's get into it. In one of our previous lessons, we already created a fixture, which was a global SQA URL. Yeah, it looks very simple. It's just an empty placeholder that we used inside of the playwright-config.ts, but technically, this is a fixture. We extended a test object with the new capabilities, and when we use this fixture inside of the test, the global SQA URL was initialized as a precondition for running the test. And to better demonstrate the capabilities, let me create a new test, and I call it test with fixtures.spec.ts. Just for the convenience, I'll take the code from the usePageObjects page and remove some of the stuff that we don't need for the demonstration. So I will remove the very first test. Also, I remove portion of this test, keeping only these steps when we navigate to the form layout page and filling out two of the forms, submit using the grid form and submit inline form. So first of all, let's run this test to see that it is working. All right, test is working fine. So as I have mentioned before, fixtures are very useful to create the environment in advance for our test. So looking in this test, what we have? We need to navigate to the home page, and technically, to validate just these two steps, we also need to be on the form layout page. So we can tell that navigate to the home page and navigate to the form layout page is a precondition for our environment and only these two steps related to the actual test. So technically, we can replace before each hook and this step with a fixture, which will prepare the test environment for us, and the test itself will only execute the steps that related to validation. So let's do this. And our first step will be to create the fixture that will be responsible to navigate to the form layout page. So we're going back to the test options over here, and I create a new test option type. Form layouts page and type will be a string. It will be a simple fixture as well. Then I will create this fixture inside of this object. Form layout page, colon, and then add a function of what this fixture will do. So I will call this function sync. In this fixture, I will need a page fixture as well. And the second method called use, I will talk about later why do we need it for. And create a function. Then inside of the function, I want to put all the tests that are needed to navigate to the form layout page. These are the steps. Click on the forms menu, and click on the forms layout menu, and we will be navigated to the form layouts page. Then in order to activate this feature, we need to use a keyword use. And inside, we need to provide the argument of the string, and in our example, it can be just a simple empty string because we will not use this value for anything else. Well, all right, the fixture was created. Now question, how to use this fixture? Let's go back to our test and look at the import. Right now, we're importing a test fixture from the PlayWrite library, but we want to import, instead of PlayWrite library, we want to import from our newly created test options here. Now this test method will use extended version of the test object that includes our fixture. And then we need to pass a newly created fixture as the argument inside of our test, which is form layouts page. That's it. And now what we can do, we can delete this step, and we can delete before each. It's not needed anymore. Those two steps are handled by our fixture. Now let's run this test. All right, you can see it worked, but did you notice how fast our test was executed? So let me demonstrate you one more time. So I go to use page objects test. I'll comment these two steps, which are similar, right? And I will execute this test with a normal flow, with having a before each hook, with navigating to the forms layout page, and let's see how long does it take. Form layout page, filling out the form, test is done. Duration is 4.5 seconds. Now going back to our modify test with a fixture and running this one more time. Test is passed, and it took only 2.5 seconds. Much, much faster. This is a very, very fast test, and it's a very, very, very, very, very, very, very, very much faster. This happened because our forms layout fixture was initialized before test even kicked in and browser was open. So Playwright began processing this request even before browser was loaded and prepared the environment for us. In this case, what's only left is to execute these two steps. So you notice probably that we triggered this forms layout page fixture, but we didn't use it, right? So how we can run this fixture automatically? Well, there is a way. If you put this fixture into the array like this, you can pass the second argument, which is in options, auto true. By providing auto true, you are saying that forms layout fixture should be automatically initialized as a very, very first thing when we run the test. So we can make this fixture run even before each or before all hook as a very first thing. So we can now remove this fixture from the test itself, run it again. And it works as well and as fast as before. So we can remove these two steps from the test. All right, what else can we do? For our test, we need an instance of page manager because page manager is responsible for access to our page objects and accessing different methods. Why not making a fixture to handle this for us instead? So let's do this as well. So we create a second fixture and I call it page manager. I need to create a new instance over here, page manager, and import it from here, page manager of the type page manager. So new page manager is created and we need to create a new function, a sync. We also need a page fixture. We also need use and we simply copy this step from the test inside of our fixture. And then we type await use pm and something is wrong with use. Okay, it doesn't like typing because, okay, the import didn't work here. So let's make the import correctly. All right, now everything looks fine. Page manager was imported correctly. It has correct type and we have a page manager over here and we don't have any issues. Now we can use this page manager fixture instead of the default page fixture of the playwright, and we can do that by replacing it right here and we can delete it from the test completely. We have a red squigglies over here, so we're replacing pm with page manager and page manager and we can remove this import from here. That's it. So let's run this test one more time. Yeah, and it's working perfectly fine. So now we have the page playwright to our custom page manager fixture, which is responsible right now for building the page manager object that will responsible for all of our objects. And one more thing, you can also set up a dependency between a fixtures. For example, right now, this fixture we configure to automatically load for any environment and for any test. But if you want to use this fixture only in case a page manager fixture is working, you can create a dependency between the fixtures. So let me remove this setting that I used before. And here I will add forms layout page fixture as the fixture dependency for the page manager fixture. Now what's going to happen, page manager fixture will trigger forms layout page to initialize and the page manager will be initialized and the instance of the page manager will be passed into our test. And this will work as well. All right, you see test is working and it is super fast. Also, what is important to know is the sequence of the execution commands inside of the fixture method. All methods and commands that you run before the use block will be executed as a precondition before running the test and setting up your environment. And everything that you put after the use block will work as a tear down, something that have to be executed after the test is completed. For example, if I type here something like console.log tear down and run this test one more time, you can see tear down message is printed. And if you have noticed, it happened after the test was completed. So also the sequence of the execution when you trigger to run the test. First thing will be initialize this step, then will be initialize page manager, then the test will execute all the steps related to that, then page manager will be tear down and then forms layout fixture will be tear down as well and this message will be printed to the console. So this is the sequence of the execution. All right, guys, so let's quickly summarize what we did in this lesson. Fixture is very powerful tool in the playwright to set up the environment. You can create a custom fixtures extending the base test object, then your fixtures will act as a setup and tear down methods for your test setting up the environment. You can then pass your fixtures inside of the test and use them inside of the test. You can create as many fixtures as you want. You can manage dependencies between of the fixtures and group them meaningfully based on the logic of your application. All right, that's it, guys, and see you in the next lesson.