Trace test execution Playwright Python
Debugging plays a major role in automation. Once the automation is run, we have to make sure all the tests are passing according to our expectations. If some tests fail, we have to check why they have failed. Is it because automation issue or a functional issue?
To decide whether it’s an automation or a functional issue, we should debug the test case. We can use the below debugging methods to find where it went wrong.
- Using screenshots to analyze the last step
- Watching the execution video (Playwright can record video also)
- Viewing Execution Trace.
To view the trace of the execution, first, we have to record the exhibition. Let’s learn how to record the trace of the exhibition.
Record the Trace of execution:
What is the trace:
When you perform manual test execution, you observe the behavior of the browser and how it reacts. You may also check the screenshots, network calls, and error messages in the developer tools console.
Similarly, the trace is zip file containing screenshots, the test execution flow, network calls, and console logs, essentially capturing the state of the browser during the test execution.
Record the trace from the test:
You can generate a trace from the test file, for that you should start the browser with context. Normally we open the page from a browser, but to enable tracing, we should create context from the browser and then the page from the context.
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
After Opening the context, write the step to start the trace from the context context.tracing.start()
. Also, provide the required parameter, and set screenshots, snapshots, and sources to True.
context.tracing.start(title="Shopping", screenshots=True,
snapshots=True, sources=True)
Then open the page and perform the action that you to be traced, when you feel the trace is enough, you can stop the trace using context.tracing.stop()
, which will generate the trace-name.zip file in the specified path/location.
context.tracing.stop(path="/trace/shopping-trace.zip")
The complete code to record the trace with the program
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
context.tracing.start(title="Shopping", screenshots=True,
snapshots=True, sources=True)
page = context.new_page()
page.goto("https://demo.testercoder.com")
page.locator("#username").fill("testuser")
page.locator("#password").fill("testpassword")
page.locator("#login-button").click()
page.locator("[data-product-id='1']").click()
context.tracing.stop(path="./trace/shopping-trace.zip")
Play Tracing of execution
Now we have created the tracing and we have to debug the test to see why it failed, for that we have to run the playwright command playwright show-trace
.
Note: if you think what happens if I unzip, nothing, all the files and screenshots will be there inside.
playwright show-trace filepath
# actual
playwright show-trace ./trace/shopping-trace.zip
The moment you press enter you will see a browser opening with the playwright logo on the taskbar(red and green masks).
Major sections/tabs on trace viewer:
The browser that opened is called Trace Viewer. This contains a few section tabs that help you to debug the test.
- Title: This is the value you provided on the script
- Timeline: Shows what happened at a given time
- Actions: These are steps that were executed, you click them to see details
- Meta Data: Contains browser details like size, OS, browser name, and a few other details (rarely used)
- Pick Locator: This lets you choose an element on the screenshot and show you the XPath for that element you chose
- Action: The screenshot of the current step
- Before: Screenshot of the previous step
- After: Screenshot of the next step
- Call: Show locator and how much time it took for the step and logs of the playwright for performing that step.
- Console: Shows if there is any output on the developer console, this will show if some error is happening on loading of the pages
- Network: Show you all the networks that happened during the step, also you can view the response details from the server
- Source: Show you the actual code (python program) and highlight which step this is
Recording of Trace in real-time
I hope you understand what is the concept behind trace now. Let’s use it in real-time. Use Python code, that is the same as the one we used earlier. Change the locator from "#login-button"
to "#login-item"
. Now there is no such locator and the test should fail because the playwright cannot find the element, then the trace should be captured, right?
Try running it, not once but multiple times. Nothing will happen, just the test fails. Why the trace file is not getting updated, it is not updating because before writing the file, the program faces the error and exits the program, so it never reaches the line context.tracing.stop()
.
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
context.tracing.start(title="Shopping", screenshots=True,
snapshots=True, sources=True)
page = context.new_page()
page.goto("https://demo.testercoder.com")
page.locator("#username").fill("testuser")
page.locator("#password").fill("testpassword")
page.locator("#login-item").click() # <--- changed locator
page.locator("[data-product-id='1']").click()
context.tracing.stop(path="./trace/shopping-trace.zip")
How to record the trace in Python playwright in real-time?
Recording a trace with plain Python or just writing a pytest test will not be sufficient. This is where we have to use the pytest fixtures.
If you have not read the pytest fixture then in simple words, it works both as a setup and tear-down block. So the setup block will run before executing the test, and the teardown block will execute after running the test, the teardown does not care whether the test is passed or failed.
yield
is command returns the control from fixture to test and gets back the control to next line after the test execution.
The fixture functions must be denoted with @pytest.fixture
. Now take the example of the below program, which is a modification of the above program. Here we set the trace in the fixture before the yield
command, then stop the trace after yield
.
The fixture must be called from the test. Here the fixture name is page
, I kept it as a page so that we have uniformity.
from playwright.sync_api import sync_playwright
@pytest.fixture
def page():
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
context.tracing.start(title="Shopping", screenshots=True,
snapshots=True, sources=True)
page = context.new_page()
yield page
context.tracing.stop(path="./trace/shopping-trace.zip")
def test_demo_login(page):
page.goto("https://demo.testercoder.com")
page.locator("#username").fill("testuser")
page.locator("#password").fill("testpassword")
page.locator("#login-item").click(timeout=5000)
page.locator("[data-product-id='1']").click()
For a more detailed version of the fixtures, visit Fixture in pytest playwright
Record the Trace using Pytest
You can record the trace using the command line if you are using pytest. Run pytest --tracing on
. This will record the trace file named trace.pwtrace.zip
in your test-results
directory.
Note: This method did not work for me, when I created the test-results directory, the execution deleted it.
pytest --tracing on
# or
pytest filenameToRun --tracing on
Options for tracing are:
- on: Record trace for each test
- off: Do not record trace. (default)
- retain-on-failure: Record trace for each test, but remove all traces from successful test runs.
Posts You Might Like
- Why playwright is better than selenium webdriver, is it?
- Handle dropdowns in Playwright Python
- Open the browser and Close in Playwright Python
- Handle checkbox in Playwright Python
- Handle IFrames in Playwright Python
- Element Operations in Playwright Python
- Page level commands in Playwright Python
- Element State with Playwright Python