Loading
Current section: Debugging 4 exercises
solution

Exercise 02 (Solution)

Transcript

00:00 First, let's take a look at the problematic test. This one is about creating a new node, so I authenticate as a user, go to my notes, then fill in the form to create a new note so I provide the note's title and content, I submit that form and expect the note to be created in the UI. Pretty straightforward. Now if I try running this test locally, I will see that it passes. So Playwright is gonna follow these instructions, and let's see what it prints.

00:28 So I can see that the test passed successfully, but I know that it failed on CI and I have a trace to prove it. I have the trace file generated by playwright in the file called trace. Zip and I can use it to travel in time and see what that failed test run looked like on CI. To do that, I will use the npx playwright command, this is the playwright CLI, and use the show trace function and provide a path to my trace. Once I execute this command, I will see a window very similar to the UI mode pop up and already be at the last failed step.

01:01 So here I can use the actions panel to see that okay, it's the clicking on submit that failed. And here on the preview of of the browser, although it's a little small, I can see the submit button is over here, but the test is unable to click it. And it looks like it cannot click it because of this subscription pop up or model window covering it and making that button element inaccessible. I can also verify that by using the pick locator action and trying to select that submit button. I cannot do that because this model window is blocking the interactivity and makes all the elements behind it inaccessible.

01:37 But if that's the case, how come the same test passes locally? Well, let's take a look at that. In another terminal window, I'm going to run the local tests in the UI mode and see what's going on. I will select the test and run it. And I can see that it passed successfully.

02:04 If I scroll to this action of submission, I can see that the element, this submit button, was correctly present on the page and the test was able to interact with it. But the funny thing is that this subscription, this model is never to be shown at all during my local run. So there has to be some factor that makes that model appear on CI but not during my local test run. And I will start by taking a look how that model window is rendered. Here is the React component for that newsletter dialog.

02:31 But by looking at it I cannot see anything that would be causing this issue. So naturally, I wanna go a step higher to the parent component that uses it. This one is nodes. Tsx, and I can spot that this newsletter dialog is rendered conditionally based on this environment variable. So now I wanna check what is the value of that variable.

02:51 In dot environment file, I can search for it and can see that it's set to false during development. So what if it's actually set to a different value on ci? Let's quickly verify this by going to the test file for our environment variables, set this variable to true, and rerunning my test. But because I changed the environment in which my app runs, I need to restart it as well, so I'm gonna stop the existing UI mode run and just launch it again. Now I will run the test and if my assumption is true the same newsletter dialog should appear and block the submit button from being interactive.

03:23 Let's see. I can already see it appearing if I scroll here There we go. The same action now ends because the button is blocked by this model window. That is great. I reproduced the same issue that happened on CI, so it looks like the culprit was the incorrectly configured environment.

03:42 Playwright's test viewer is based on the UI mode and it looks exactly like it except for the list of tests to the left. You can use all of its features to help you debug any failed test, including the timeline, the list of actions, the browser preview, even console and network to see what messages were printed or requests were performed during the remote test run. Unlike the UI mode, the trace that you're viewing is fixed in time, which is great for debugging purposes, but that also means that it won't be reflecting any changes that you make to the test or to the app as you're trying to investigate and fix the issue. And now let me show you how you can configure Playwright to create these trace files for any failed test run on your CI, using GitHub actions as an example. The first thing you need to do is tell Playwright to record the traces of your test runs.

04:28 To do that, go to the Playwright config file, and here where you define the configuration, go to the use object and provide the trace option. This option supports a number of values, you can turn off tracing, enable it for all test, enable it for every retry, use it on first retry, retain on failure which means that every test will record its trace but then Playwright will delete all the traces of the test that have successfully passed, leaving only the failed traces. I can use things for example on first retry which would do it. Now with the trace option configured, Playwright will create these trace snapshots on disk. Now the only thing remaining is to upload those snapshots somewhere so you're able to download them from the failed CI runs.

05:11 To do that, I will head to my GitHub actions and right here after I ran the test, I will add another step named upload artifacts and I will use this upload artifact action, this is one of the default actions that GitHub gives you. Important thing, I will use the if key here and provide always as the condition. Because that makes sense, I want this action to run even if the test failed especially if they failed and by providing if always it will always trigger and I configure this action with the name. This is just a string I chose to name this artifact and then the path which points to the location where Playwright will emit those trace dot zip files. I can even configure the retention days option so the artifacts I upload get erased after a particular amount of time has passed, just to keep my CI resources in check.

06:00 And now that you have both Playwright and GitHub actions configured, all you have to do is whenever you encounter a Fade CI job, you can just scroll to the bottom and find this uploaded artifacts, click on the name to download the Playwright trace files which you can open in your machine and reliably debug. And if you ever want to record a trace of your local test run, then run your tests with the trace option which is the same option from the Playwright config and it accepts the same values. So if I pass on as a value, Playwright will record traces for all the tests that now run. And once the test run completes, you'll be able to find the results in the test results folder. So here I can see the trace file for my Create Nodes test.

06:48 The Trace Viewer could have saved me hundreds of hours spent debugging flaky tests on CI in the past, but now I don't have to waste time anymore. I need to do you.