- Description
- How to build, run the app, run tests and view the test results
- Playwright configuration
- Fixtures
A proper description of what a Playwright fixture is can be found on the official docs. For the purpose of this code demo, you can think of fixtures as a way to provide, or even automatically apply, behaviour to your tests.
The fixtures used in this code demo are all declared on the app-fixtures.ts file.
Important
Required dependencies:
- Node. Tested working with
v20.10.0
. If you need to have different versions of node installed it's recommended that you use Node Version Manager to install and swap between node versions. - npm@latest: package manager used on the demos. Tested working on
10.2.5
. - VS Code is recommended as a code editor but you can use whatever you prefer.
- Clone the repo.
- Using your favorite shell go to
/demos/fixtures
. - Install the required npm packages with:
npm install
- Install the playwright browsers with:
npx playwright install
- Run the tests with:
This will start the app and run the playwright tests against it.
npm test
- After running the tests you can view test results with:
npm run test:show-report
- If you just want to run the app execute the command:
Once the command finishes the app should open in your default browser at http://127.0.0.1:4200/.
npm start
Note
When you run the tests in this fixtures demo with npm test
you will have 8 tests that pass, 1 test that is skipped and 9 that fail. This is intentional as the tests are meant to show the fixtures in action. For more information see the comments at example.spec.ts.
The majority of the content of the playwright.config.ts file is what you get by default after adding Playwright to your project with npm init playwright@latest
.
The main changes are:
- Declared a few variables at the start that are reused throughout the playwright configuration.
- Updated the
reporter
array. In addition to using the default html reporter, we've added the built-in list reporter. - Defined a baseURL so that we can use relative URLs when doing page navigations on the tests.
- Configured the
webServer
block to run the Angular app locally so that the tests can be executed against it. If you're not testing an Angular app that's fine, you just need to adjust thewebServer.command
so that it launches your app and set thewebServer.url
to the url your app will be running at. For more information see the webServer docs.
Note
The _isRunningOnCI
variable used on the playwright.config.ts
changes the value of some options when running tests on CI. To set the _isRunningOnCI
variable to true
you must set the environment variable CI
to true
before running the tests. For more information regarding using Playwright on a CI environment see Playwright docs on Continuous Integration.
Furthermore, we have created:
- a playwright.cli-options.ts file: to represent Playwright CLI options we care about.
- a playwright.env-vars.ts file: to represent environment variables we care about.
Note
You don't have to create the playwright.cli-options.ts
or the playwright.env-vars.ts
file. You can have all of this on the playwright.config.ts
. Code structure is up to you.
Note
Depending on your playwright.config.ts
, make sure you update your .gitignore
to exclude any directory used by test results, report results, etc. Scroll to the end of this demo's .gitignore to see an example.
Playwright let's you emulate a real device such as a mobile phone or tablet. This means you can control things like a Locale & Timezone, however if you need to control the value of the Time/Date then there's nothing built-in to Playwright to help you do that.
Setting the value of Time/Date is very useful when you need to take a screenshot or assert on values that contain Time/Date information. It's also important if your app has time based actions such as "press a button and after X amount of time some action occurs". To be able to implement reliable tests on these scenarios you need to be able to control Time/Date.
The setDate fixture is an automatic fixture that shows how you can use the Page.addInitScript function to control the values returned by JavaScript's Date constructor and the Date.now
function. See set-date.ts file.
The setDate test at example.spec.ts shows this fixture at work by allowing reliable asserts on a text field that is based on the current Date and on the screenshot.
Note
This fixture is based on this comment from the microsoft/playwright [Feature] Time/Date emulation via e.g. a clock() primitive #6347 GitHub issue.
The issue contains other solutions such as the one from this comment which uses Sinon.JS fake timers. The Sinon.JS fake timers
solution not only allows you to set the current Date but it also allows you to control the flow of time. This type of solution is useful if you need to do a test where you need to perform an action and then wait X amount of time before doing something else. Using the Sinon.JS fake timers
would let you code tests for that behaviour in a reliable way.
Tip
You can also consider using the mask
option of the toHaveScreenshot to take a screenshot and ignore the part that has dynamic data such as a Time/Date.
The consoleMessages fixture shows how you can use the Page.on('console') event to capture all Console Messages. See console-messages.ts.
The console-messages.ts has a filter function named isExcluded
so that you can filter out Console Messages you don't care about. For instance when running an Angular 17 app with Vite (which this demo is), the Vite dev server will produce some Console Messages we want to ignore.
The consoleMessages and failOnUnexpectedConsoleMessages test at example.spec.ts shows how you can use the fixture to assert that the app is producing an expected console message.
The failOnUnexpectedConsoleMessages fixture adds an assert to all the tests to check for unexpected Console Messages. If your app produces some Console Messages then you should exclude them using the isAllowed
function available on the fixture. See fail-on-unexpected-console-messages.ts.
This fixture is great to catch left over debug/temp Console Messages.
The failOnUnexpectedConsoleMessages test at example.spec.ts shows how this fixture fails a test if an unexpect console message is produced.
Note
This fixture makes use of the composable property of fixtures and builds upon the consoleMessages fixture.
The uncaughtExceptions fixture shows how you can use the Page.on('pageerror') event to capture all uncaught exceptions that happen within the page. See page-errors.ts.
The uncaughtExceptions test at example.spec.ts shows how this fixture fails a test if an unexpect exception occurs.
The failOnUncaughtExceptions fixture adds an assert to all tests to make sure they don't produce any uncaught exceptions. See fail-on-page-errors.ts.
The failOnUncaughtExceptions test at example.spec.ts shows this fixture making a test fail because it produces an uncaught exception.
Note
This fixture makes use of the composable property of fixtures and builds upon the uncaughtExceptions fixture.
The projectName fixture allows you to control behaviour of your tests based on the Playwright project name. For instance, you might want to skip a test or provide different values to a test depending on the project name.
The projectName test at example.spec.ts shows an example usage of this fixture.
This fixture is useful because it uses the PlaywrightProjectName enum to define the valid names for a Project. With this enum you have a type safe way to filter on Project names.
Playwright supports custom annotations. Annotations are key/value pairs accessible via test.info().annotations. Many reporters support annotations.
The annotations fixture shows how you can add custom annotations to your tests, which are visible on the html
test report:
See annotations.ts. All tests will have these custom annotations.