Test a Demo Login with Playwright
Design manual login tests and automate SauceDemo checks with Playwright.
Introduction
30 Second Summary
A login screen has two jobs. It lets the right person in while keeping blocked users out.
In this project, you will test the SauceDemo login flow manually in Google Chrome. You will turn those requirements into a Playwright Test regression suite whose HTML report exposes a controlled URL mismatch.
What You'll Build
You'll open one QA evidence pack that traces each login requirement from a manual result through a visible browser run to a final report showing both checks passing.
By the end of this project, you'll have:
- A requirement-linked manual test record that shows each login scenario's steps, expected result, observed result, and pass status.
- A visible browser run that signs in as the standard user before reaching the inventory page.
- A controlled failure report that pinpoints the wrong expected URL before your repaired suite proves both login requirements pass.
- An optional Secret Mission: data-driven negative coverage that generates separate checks for locked and invalid users.
Are there any prerequisites?
This project requires Windows 11 or later, internet access, plus permission to install software.
Visual Studio Code and Google Chrome are already part of your starting setup.
Before We Start
A clear quality question keeps every test focused. Commit to checking that valid SauceDemo credentials reach inventory while blocked credentials stay out. Repeatable regression checks protect both requirements.
Set Up the Windows Test Workspace
Your SauceDemo quality questions are clear. A repeatable browser check now needs a local toolchain that runs the same way each time.
In this step, you install Node.js v24.21.0 LTS as the supported JavaScript runtime. You then pin Playwright Test 1.62.1 inside a local project with its matching Chromium browser binary.
In this step, get ready to:
- Install Node.js v24.21.0 LTS with npm on Windows.
- Create the saucedemo-qa folder with its pinned Playwright Test dependency.
- Install Playwright Chromium and verify both tool versions.
Install Node.js
Node.js runs the JavaScript tools behind your automated tests. Its Windows installer also installs npm for managing the project's dependency.
- Press the Windows key to open Windows search.
- Type Visual Studio Code and press Enter to open it.
- Select View from the Visual Studio Code menu bar.
- Select Terminal to open the integrated terminal.
- Check the current Node.js version by running this command:
node --version
What Does This Check Do?
The --version option asks node to print the installed runtime version. The result tells you whether the required release is already available.
✔️ I see the required version
Great. The pinned Node.js runtime is already available in your Visual Studio Code terminal.
Your output should read v24.21.0.
ⓧ I see another version
This project uses an exact Node.js release so everyone works with the same runtime. The official Windows installer brings your machine onto that pinned version.
- Select Start in Windows.
- Select Settings.
- Select System.
- Select About.
- Read the System type value under Device specifications.
The System type identifies the MSI file that matches your processor.
- Open the official Node.js release directory in Chrome.
- Download node-v24.21.0-x64.msi for an x64-based processor.
- Download node-v24.21.0-arm64.msi for an ARM-based processor.
- Run the downloaded MSI installer.
- Keep the standard installer options.
- Close Visual Studio Code after the installation finishes.
The installer updates the command path used by Windows. A freshly opened Visual Studio Code process can inherit that update.
- Press the Windows key to open Windows search.
- Type Visual Studio Code and press Enter to reopen it.
- Select View from the menu bar.
- Select Terminal to open a fresh integrated terminal.
- Verify the installed Node.js version by running this command:
node --version
What Does This Check Do?
The fresh terminal reads the updated Windows command path. The version result confirms that it finds the newly installed runtime.
You should see v24.21.0 in the terminal.
ⓧ Command not found
The missing command confirms that Node.js still needs to be installed. The official Windows MSI includes both Node.js and npm.
- Select Start in Windows.
- Select Settings.
- Select System.
- Select About.
- Read the System type value under Device specifications.
The System type identifies the MSI file that matches your processor.
- Open the official Node.js release directory in Chrome.
- Download node-v24.21.0-x64.msi for an x64-based processor.
- Download node-v24.21.0-arm64.msi for an ARM-based processor.
- Run the downloaded MSI installer.
- Keep the standard installer options.
- Close Visual Studio Code after the installation finishes.
The installer updates the command path used by Windows. A freshly opened Visual Studio Code process can inherit that update.
- Press the Windows key to open Windows search.
- Type Visual Studio Code and press Enter to reopen it.
- Select View from the menu bar.
- Select Terminal to open a fresh integrated terminal.
- Verify the installed Node.js version by running this command:
node --version
What Does This Check Do?
The fresh terminal reads the updated Windows command path. The version result confirms that it finds the newly installed runtime.
You should see v24.21.0 in the terminal.
Still Missing the Expected Node.js Version?
Confirm that you closed every Visual Studio Code window after the MSI finished. Existing terminal sessions keep the older Windows command path.
Run the installer matching the System type shown in Windows. An installer for another processor architecture cannot provide the required runtime.
Ask for help with the installation: help me troubleshoot why Node.js v24.21.0 is unavailable in my reopened VS Code terminal
Create the Pinned Project
The package.json file records the exact testing dependency for this workspace. Pinning the version keeps later test runs consistent.
- Select File from the Visual Studio Code menu bar.
- Select Open Folder....
- Select your Desktop location.
- Select New Folder.
- Enter saucedemo-qa as the folder name.
- Select Select Folder to open it in Visual Studio Code.
- Select Yes, I trust the authors if the Workspace Trust prompt appears.
You should see saucedemo-qa at the top of the Explorer sidebar. Visual Studio Code now treats this folder as your workspace.
- Select New File in the Explorer sidebar.
- Enter package.json as the file name.
The Explorer should now list package.json. Its editor tab is ready for the project manifest.
- Add the pinned project manifest by pasting this code into package.json:
{
"name": "saucedemo-qa",
"version": "1.0.0",
"private": true,
"devDependencies": {
"@playwright/test": "1.62.1"
}
}
What Does This File Do?
- The name value identifies the local project.
- The private value prevents accidental publication as an npm package.
- The devDependencies section pins @playwright/test to version 1.62.1.
- Press Ctrl+S to save package.json.
- Install the pinned project dependency by running this command in the integrated terminal:
npm install
What Does This Command Do?
The npm command reads package.json. The install action downloads the pinned development dependency and creates the project's lockfile.
The terminal should complete without an installation error. The Explorer should show the npm-generated lockfile beside package.json.
Did the Dependency Installation Fail?
Confirm that the terminal is running inside the open saucedemo-qa workspace. Visual Studio Code starts its integrated terminal from the folder shown at the top of the Explorer.
Check that package.json matches the supplied JSON exactly. A missing quote or comma prevents npm from reading the manifest.
Ask for help with the install: help me diagnose my npm install failure in the saucedemo-qa workspace
✔️ Awesome, I've got everything!
That dependency is now locked to the project. Make sure package.json is saved before continuing.
ⓧ I'd like to double check the full code
Compare your complete package.json file with this reference.
{
"name": "saucedemo-qa",
"version": "1.0.0",
"private": true,
"devDependencies": {
"@playwright/test": "1.62.1"
}
}
What Should Match?
Every property and value should match this file exactly. The dependency version must remain pinned to 1.62.1.
Install Chromium and Verify
Playwright Test provides the runner and assertions. The matching browser binary gives those tests a real browser to control.
Expect the browser download to take a few minutes on some connections. Keep the terminal open while the installation completes.
- Install Playwright Chromium with its operating-system dependencies by running this command:
npx playwright install --with-deps chromium
What Does This Command Do?
- The npx command runs the Playwright CLI installed in this project.
- The install action downloads the selected browser binary.
- The --with-deps option installs the operating-system dependencies needed by chromium.
The terminal should finish without an installation error. Playwright Chromium is then available to the tests in this workspace.
Did the Browser Installation Stop?
Keep the internet connection active until the download completes. Restart the command if a temporary network interruption stops it.
Confirm that the integrated terminal still belongs to the saucedemo-qa workspace. The local Playwright CLI comes from that folder's installed dependency.
Ask for help with the browser installation: help me troubleshoot why Playwright Chromium did not install
Before you run the final checks, what two version results do you expect from your pinned workspace?
- Verify the Node.js runtime and local Playwright CLI by running these commands:
node --version
npx playwright --version
What Do These Checks Prove?
The first line confirms that Windows can find the installed Node.js runtime. The second line confirms that npx can find the Playwright CLI pinned inside this project.
You should see v24.21.0 followed by Version 1.62.1. Your Windows browser-automation workspace is ready.
Your pinned runtime, test framework, project lockfile, and browser binary are in place. Next, you will turn the SauceDemo login requirements into manual test evidence before automating them.
Create and Run Manual Login Tests
Your Windows test workspace is ready. The SauceDemo login requirements now need evidence from the application itself.
Automation is valuable after expected behavior is explicit. In this step, you will turn each requirement into a manual test case before recording what the browser shows.
In this step, get ready to:
- Connect each login requirement to its own manual test case.
- Execute the positive login case in Google Chrome.
- Execute the negative login case with blocked credentials.
Build the manual test record
A test case turns a requirement into repeatable steps with a defined outcome. This structure makes the final status traceable to the behavior you observed.
The expected result defines success before execution. The actual result captures what happened during execution.
- Create a new file named TEST-CASES.md inside the open saucedemo-qa folder using the Visual Studio Code file sidebar.
- Add the requirements with the empty results table by pasting this content into TEST-CASES.md:
# SauceDemo Login Test Cases
## Requirements
- R1: A standard user with valid credentials reaches the inventory page.
- R2: A locked user does not reach the inventory page.
| ID | Requirement | Scenario | Steps | Expected result | Actual result | Status |
| --- | --- | --- | --- | --- | --- | --- |
How Is the Record Structured?
- R1 defines the successful behavior for a standard user.
- R2 defines the blocked behavior for a locked user.
- The table keeps the planned outcome separate from the observed outcome.
- The status shows whether the observation satisfies its requirement.
- Save TEST-CASES.md.
- Confirm that the file shows R1 above R2.
- Confirm that the table has seven columns with no result rows yet.
Does the Table Look Misaligned?
Check that every table row begins with a vertical bar. Check that each row also ends with a vertical bar.
Use the full-file comparison near the end of this step if a column is missing. You can also ask for help fixing the Markdown table.
Execute the positive login case
A positive test case uses valid input to confirm the required success path. The destination URL gives you visible evidence that the login reached inventory.
- Press the Windows key to open the Windows search bar.
- Type Google Chrome to find the browser.
- Press Enter to open Google Chrome.
- Navigate to https://www.saucedemo.com using the address bar.
- Enter standard_user in the username field.
- Enter secret_sauce in the password field.
Before you submit the form, predict whether the address bar will end with /inventory.html.
- Select Login.
You should see the inventory page after the valid login completes.
- Confirm that the address bar shows https://www.saucedemo.com/inventory.html.
- Switch back to Visual Studio Code.
- Place your cursor below the table separator row in TEST-CASES.md.
- Record the positive result by adding this row:
| TC-01 | R1 | Valid standard-user login | Open SauceDemo, enter `standard_user` and `secret_sauce`, then select Login. | The inventory page opens at `https://www.saucedemo.com/inventory.html`. | The inventory page opened at `https://www.saucedemo.com/inventory.html`. | Pass |
What Does This Result Prove?
TC-01 connects the valid login steps to R1. Its actual URL matches the expected inventory URL.
The matching outcomes justify the Pass status.
- Save TEST-CASES.md.
- Confirm that TC-01 shows R1 with a Pass status.
Good progress. Your first requirement now has browser evidence tied to a recorded passing result.
Did the Inventory Page Stay Closed?
- Check that the username is spelled standard_user.
- Check that the password is spelled secret_sauce.
- Reload the login page after confirming your internet connection.
If the valid login still fails, ask for help diagnosing the manual login result.
Execute the negative login case
A negative test case confirms that blocked input cannot reach protected content. This case passes when the locked user stays outside inventory.
- Switch back to Google Chrome.
- Return to https://www.saucedemo.com using the address bar.
- Enter locked_out_user in the username field.
- Enter secret_sauce in the password field.
Before you submit the form, predict whether the locked user will reach the same inventory URL as the standard user.
- Select Login.
The inventory page should stay closed. This observed block satisfies R2.
- Confirm that the address bar does not show https://www.saucedemo.com/inventory.html.
- Switch back to Visual Studio Code.
- Place your cursor below the TC-01 row in TEST-CASES.md.
- Record the negative result by adding this row:
| TC-02 | R2 | Locked-user login | Open SauceDemo, enter `locked_out_user` and `secret_sauce`, then select Login. | The inventory page does not load. | The inventory page did not load. | Pass |
Why Does a Blocked Login Pass?
TC-02 expects the locked user to remain outside inventory. The observed result matches that requirement.
A negative case earns a Pass when the application rejects the blocked input as required.
Before you inspect the finished record, predict whether both cases can pass even though only TC-01 reaches inventory.
- Save TEST-CASES.md.
- Confirm that TC-01 records https://www.saucedemo.com/inventory.html as its actual destination.
- Confirm that TC-02 records that the inventory page did not load.
- Confirm that both rows show Pass in the status column.
That is your manual QA evidence complete. Both requirements now have a repeatable procedure with a matching observed result.
Did the Locked User Reach Inventory?
- Return to the SauceDemo login page before repeating TC-02.
- Check that the username is spelled locked_out_user.
- Confirm that you did not reuse standard_user from TC-01.
If the locked user still reaches inventory, ask for help separating the two browser sessions.
✔️ Awesome, I've got everything!
Your TEST-CASES.md file now records two passing manual login cases. Save the file before continuing.
ⓧ I'd like to double check the full code
Compare your completed manual test record with this file.
# SauceDemo Login Test Cases
## Requirements
- R1: A standard user with valid credentials reaches the inventory page.
- R2: A locked user does not reach the inventory page.
| ID | Requirement | Scenario | Steps | Expected result | Actual result | Status |
| --- | --- | --- | --- | --- | --- | --- |
| TC-01 | R1 | Valid standard-user login | Open SauceDemo, enter `standard_user` and `secret_sauce`, then select Login. | The inventory page opens at `https://www.saucedemo.com/inventory.html`. | The inventory page opened at `https://www.saucedemo.com/inventory.html`. | Pass |
| TC-02 | R2 | Locked-user login | Open SauceDemo, enter `locked_out_user` and `secret_sauce`, then select Login. | The inventory page does not load. | The inventory page did not load. | Pass |
Your existing package.json should remain unchanged.
{
"name": "saucedemo-qa",
"version": "1.0.0",
"private": true,
"devDependencies": {
"@playwright/test": "1.62.1"
}
}
Your manual evidence now defines the behavior that automation must protect. Next, you will translate the successful login case into a browser test with a controlled failing expectation.
Automate and Inspect a Designed Failure
Your manual test record now proves that a standard SauceDemo user reaches inventory. That evidence gives the automated check a clear requirement to protect.
A trustworthy test report must separate a test's expected result from the browser's observed state. A controlled mismatch makes that difference visible.
You will use Playwright Test to encode the positive login flow. You will then inspect the resulting failure through a headed browser run and an HTML report.
In this step, get ready to:
- Configure a focused Playwright suite with an HTML reporter.
- Automate the standard-user login behavior from TC-01.
- Capture a controlled URL mismatch as test evidence.
Configure the HTML report
The configuration tells Playwright where your tests live. It also keeps the HTML report closed until you request it.
- Create playwright.config.ts beside package.json using the file icon with a plus sign in the Explorer sidebar.
- Add the configuration by pasting this code into playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
reporter: [['html', { open: 'never' }]],
});
What Does This Configuration Do?
- The defineConfig() helper defines the settings Playwright uses for every test run.
- The testDir setting points Playwright to the tests folder.
- The reporter setting creates an HTML report without opening it automatically.
- Save playwright.config.ts.
- Confirm that the Explorer sidebar lists playwright.config.ts beside package.json.
Cannot Find the Configuration File?
- Check that playwright.config.ts sits directly inside saucedemo-qa.
- Check that the filename ends with .ts.
Help me check why Playwright cannot find my configuration file.
Translate the positive login case
The manual steps in TC-01 become browser actions through locators. The expected destination becomes a retrying assertion that decides whether the test passes.
- Create a tests folder inside saucedemo-qa using the folder icon with a plus sign in the Explorer sidebar.
The Explorer sidebar now shows an empty tests folder inside your project.
- Create login.spec.ts inside tests using the file icon with a plus sign.
- Add the positive login test by pasting this code into tests/login.spec.ts:
import { test, expect } from '@playwright/test';
const LOGIN_URL = 'https://www.saucedemo.com';
const PRODUCTS_URL = 'https://www.saucedemo.com/products.html';
const PASSWORD = 'secret_sauce';
test('standard user can sign in', async ({ page }) => {
await page.goto(LOGIN_URL);
await page.locator('#user-name').fill('standard_user');
await page.locator('#password').fill(PASSWORD);
await page.locator('.btn_action').click();
await expect(page).toHaveURL(PRODUCTS_URL);
});
What Does This Test Do?
- The LOGIN_URL, PRODUCTS_URL, and PASSWORD constants keep the test data separate from the browser actions.
- The page fixture gives the test a fresh browser page.
- The #user-name, #password, and .btn_action locators reproduce the interactions from TC-01.
- The toHaveURL() assertion checks whether the resulting browser destination matches PRODUCTS_URL.
- Save tests/login.spec.ts.
Run and inspect the designed failure
Your automated path now reproduces the same login actions as TC-01. The URL assertion determines whether Playwright records those actions as a pass or failure.
Before you run the test, do you expect the automated destination to agree with the destination recorded in TC-01?
- Run the test with a visible Chromium window by running:
npx playwright test --headed
You will see Chromium perform the standard-user login. The terminal then reports one failed test because the expected URL differs from the browser's observed URL.
This Failure Is Deliberate
The browser completed the login interaction. The assertion compared that result with the controlled PRODUCTS_URL expectation.
This gives you a focused failure to diagnose through the report. Leave the test code unchanged for the rest of this step.
Did Chromium Fail to Reach the Assertion?
- Confirm that your internet connection can load https://www.saucedemo.com in Chrome.
- Compare the three locators in tests/login.spec.ts with the code above.
- Return to the browser installation check from setup if Chromium never opens.
Help me diagnose why my headed Playwright test does not reach the URL assertion.
The terminal summary confirms that an assertion failed. The HTML report preserves the expected and observed values so you can diagnose the cause.
- Open the latest HTML report by running:
npx playwright show-report
Your browser opens the latest Playwright report with one failed test result.
Did the Report Stay Closed?
- Return to the VS Code terminal from earlier.
- Confirm that the headed test run finished before requesting its report.
Help me open the HTML report from my latest Playwright test run.
- Open the failed standard user can sign in result in the browser report.
- Locate the URL assertion comparison in the failed result.
- Compare the expected destination with the observed destination.
You should see https://www.saucedemo.com/products.html as the expected destination. You should see https://www.saucedemo.com/inventory.html as the observed destination.
What Does the Report Prove?
The login actions reached the inventory page described by TC-01. The failure points to the destination stored in PRODUCTS_URL.
You now have evidence that the browser followed the requirement while the test oracle carried a conflicting expectation.
✔️ Awesome, I've got everything!
Your manual evidence and automated failure artifacts are in place. The report now exposes the controlled URL mismatch.
ⓧ I'd like to double check the full code
Compare each project file with the complete state below.
TEST-CASES.md.
# SauceDemo Login Test Cases
## Requirements
- R1: A standard user with valid credentials reaches the inventory page.
- R2: A locked user does not reach the inventory page.
| ID | Requirement | Scenario | Steps | Expected result | Actual result | Status |
| --- | --- | --- | --- | --- | --- | --- |
| TC-01 | R1 | Valid standard-user login | Open SauceDemo, enter `standard_user` and `secret_sauce`, then select Login. | The inventory page opens at `https://www.saucedemo.com/inventory.html`. | The inventory page opened at `https://www.saucedemo.com/inventory.html`. | Pass |
| TC-02 | R2 | Locked-user login | Open SauceDemo, enter `locked_out_user` and `secret_sauce`, then select Login. | The inventory page does not load. | The inventory page did not load. | Pass |
package.json.
{
"name": "saucedemo-qa",
"version": "1.0.0",
"private": true,
"devDependencies": {
"@playwright/test": "1.62.1"
}
}
playwright.config.ts.
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
reporter: [['html', { open: 'never' }]],
});
tests/login.spec.ts.
import { test, expect } from '@playwright/test';
const LOGIN_URL = 'https://www.saucedemo.com';
const PRODUCTS_URL = 'https://www.saucedemo.com/products.html';
const PASSWORD = 'secret_sauce';
test('standard user can sign in', async ({ page }) => {
await page.goto(LOGIN_URL);
await page.locator('#user-name').fill('standard_user');
await page.locator('#password').fill(PASSWORD);
await page.locator('.btn_action').click();
await expect(page).toHaveURL(PRODUCTS_URL);
});
You have turned TC-01 into a repeatable browser test and used its report to isolate a faulty expectation. Next, you will repair the test oracle and add locked-user regression coverage.
Repair and Run the Regression Suite
Your designed failure proved that Playwright Test can expose a mismatch in a browser check. The SauceDemo report traced the failure to the incorrect products URL.
A test oracle is the expected result that decides whether observed behavior passes. This step aligns that oracle with your manual evidence.
You will also add a negative regression test for the locked user. Together, the two tests protect both login requirements.
In this step, get ready to:
- Replace the incorrect destination with the inventory URL.
- Add a regression test for the locked user.
- Compare the automated report with the manual test record.
Correct the test oracle
The failed assertion already supplied the diagnosis. Your positive manual case identifies the inventory page as the correct destination.
- In tests/login.spec.ts, find the constant named PRODUCTS_URL.
- Replace that constant with this corrected line:
const INVENTORY_URL = 'https://www.saucedemo.com/inventory.html';
Why does this repair the oracle?
The INVENTORY_URL constant names the destination required by TC-01. Its value matches the result you observed manually.
- Find the assertion that checks PRODUCTS_URL near the bottom of the test.
- Replace that assertion with this line:
await expect(page).toHaveURL(INVENTORY_URL);
What does the corrected assertion prove?
The toHaveURL(INVENTORY_URL) assertion checks the browser against the corrected oracle. Playwright retries this check while the page finishes navigating.
- Save tests/login.spec.ts.
- Predict whether the positive test passes with the corrected oracle.
- Rerun the positive test in a visible browser by running this command:
npx playwright test --headed
What does this command check?
Playwright Test runs the configured suite. The --headed option keeps the browser visible while the login interaction runs.
You will see the standard user reach the inventory page. The terminal finishes with one passing test.
Does the positive test still fail?
- Check that the constant is named INVENTORY_URL in both locations.
- Check that the URL ends with /inventory.html.
- Confirm that your computer still has internet access to SauceDemo.
Help me diagnose the remaining Playwright failure.
Add the locked-user regression
The positive test protects successful login behavior. The negative test protects the boundary that keeps blocked credentials away from inventory.
Playwright's web-first assertions repeatedly check the page until each condition passes or times out. This makes the test resilient to normal browser timing.
- In tests/login.spec.ts, place your cursor below the standard-user test.
- Add the locked-user regression by pasting this code:
test('locked user cannot reach inventory', async ({ page }) => {
await page.goto(LOGIN_URL);
await page.locator('#user-name').fill('locked_out_user');
await page.locator('#password').fill(PASSWORD);
await page.locator('.btn_action').click();
await expect(page).not.toHaveURL(INVENTORY_URL);
await expect(page.locator('#user-name')).toBeVisible();
});
What does this test protect?
- The test submits locked_out_user with the shared demo password.
- The not.toHaveURL(INVENTORY_URL) assertion confirms that inventory stays inaccessible.
- The toBeVisible() assertion confirms that the username field remains on the page.
- Save tests/login.spec.ts.
- Predict the two browser outcomes that the headed run should demonstrate.
- Run both regression tests in a visible browser by running this command:
npx playwright test --headed
What does this run prove?
The suite now exercises both sides of the login requirement. One test reaches inventory while the other remains outside it.
You will see the successful login followed by the blocked login path. The terminal finishes with two passing tests.
Is the locked-user test failing?
- Check that the username is exactly locked_out_user.
- Check that the URL assertion includes not before toHaveURL(INVENTORY_URL).
- Check that the final locator uses #user-name.
Help me debug the locked-user regression test.
✔️ Awesome, I've got everything!
Your tests/login.spec.ts file is saved. Both login tests now pass.
ⓧ I'd like to double check the full code
Compare your complete tests/login.spec.ts file with this version.
import { test, expect } from '@playwright/test';
const LOGIN_URL = 'https://www.saucedemo.com';
const INVENTORY_URL = 'https://www.saucedemo.com/inventory.html';
const PASSWORD = 'secret_sauce';
test('standard user can sign in', async ({ page }) => {
await page.goto(LOGIN_URL);
await page.locator('#user-name').fill('standard_user');
await page.locator('#password').fill(PASSWORD);
await page.locator('.btn_action').click();
await expect(page).toHaveURL(INVENTORY_URL);
});
test('locked user cannot reach inventory', async ({ page }) => {
await page.goto(LOGIN_URL);
await page.locator('#user-name').fill('locked_out_user');
await page.locator('#password').fill(PASSWORD);
await page.locator('.btn_action').click();
await expect(page).not.toHaveURL(INVENTORY_URL);
await expect(page.locator('#user-name')).toBeVisible();
});
How should this file read?
The constants hold the shared login values. The two tests reuse those values to protect the successful and blocked login paths.
Review the final evidence
An HTML report turns the latest run into evidence you can inspect. The final report should support the same two requirements recorded in TEST-CASES.md.
- Predict whether the automated report agrees with both manual test rows.
- Open the latest HTML report from the Visual Studio Code integrated terminal by running this command:
npx playwright show-report
What does this command open?
Playwright opens the latest HTML test report in your browser. The report keeps each test result separate so you can inspect its status.
- Confirm that the report lists two passing test results.
- Return to TEST-CASES.md from earlier.
- Compare the standard-user report entry with TC-01.
- Compare the locked-user report entry with TC-02.
You will find one passing result for the standard user. You will also find one passing result for the locked user.
Report does not open?
- Confirm that the headed test run finished before you open the report.
- Use the report address printed in the terminal if the browser does not open automatically.
Help me open or inspect my latest Playwright HTML report.
You closed the evidence loop. The manual record now matches the automated regression suite.
Secret mission
Make Negative Coverage Data-Driven
Your negative test protects one blocked credential set today. Refactor it into a data-driven suite that checks locked and invalid users without duplicating the login behavior.
Clean Up Your Resources
Clean Up Your Resources
Everything created for this project stays on your computer, so there are no ongoing costs. Decide whether to keep the local workspace, pause your current session, or delete the workspace entirely.
Resources you used:
- Local saucedemo-qa project folder containing every project file.
Keep everything running
No action is needed. Choose this if you want to keep refining the test suite.
- Keep the saucedemo-qa folder in its current location.
- Leave the latest HTML report available as evidence of the three passing tests.
- Return to the project whenever you want to add more regression cases.
Pause - I'll come back to this later
Pause your current session to free any active local process while preserving every project file.
- Switch back to the Visual Studio Code integrated terminal from earlier.
- Press Ctrl+C if the terminal is still occupied by the HTML report.
- Close the HTML report tab in Google Chrome.
- Leave the saucedemo-qa folder untouched for your next session.
Delete - I don't want to use this again
Deleting the folder is permanent, but it affects only this local workspace. No cloud account or paid resource is connected to it.
- Switch back to the Visual Studio Code integrated terminal from earlier.
- Press Ctrl+C if the terminal is still occupied by the HTML report.
- Right-click saucedemo-qa in the Visual Studio Code Explorer sidebar.
- Choose the context-menu option that shows the folder in File Explorer.
- Close Visual Studio Code.
- Select saucedemo-qa in File Explorer.
- Press Shift+Delete to remove the folder permanently.
- Confirm the deletion when Windows asks.
Your local QA workspace is now cleared. You should no longer see saucedemo-qa in File Explorer.
Nice Work!
Nice Work!
You did it! Your SauceDemo QA evidence pack now combines manual test records with a passing Playwright Test regression suite.
You've learned how to:
- Build a requirement-linked manual test record in Google Chrome for successful plus blocked login behavior.
- Automate the successful login flow with Playwright locators plus web-first assertions.
- Repair a faulty test oracle after diagnosing an intentional expected-versus-actual URL mismatch in an HTML report.
- Complete the Secret Mission by converting blocked-login coverage into data-driven tests for locked users plus invalid usernames.
Ready to quiz yourself?