Hello everyone!
Today, we have a special edition for you as we delve into the exciting updates we've recently rolled out in our releases 1.33 and 1.34. Our dynamic duo of Debbie and Lusha sat down to discuss these in detail. So, without further ado, let's dive right in.
UI Mode Update
The UI mode has been the favorite of many and it just got better! In its latest incarnation, the UI mode now includes features such as visualizing the hooks that run before and after a test, as well as fixtures. Moreover, the update also encompasses custom navigation steps within the UI mode.
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }) => {
await test.step('navigate', async () => {
await page.goto('https://playwright.dev/');
});
});
test('has title', async ({ page }) => {
await expect(page).toHaveTitle(/Playwright/);
});
test('get started link', async ({ page }) => {
// ...
});
Not only does this latest update allow for the smoother running of tests, but it also allows for better visual regression testing. For instance, if we do a screenshot test and then someone goes into the code and removes a button, you'd see a failure. This update includes an "Attachments" tab that allows you to explore and compare the screenshots complete with a slider to overlay and better see the differences.
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }) => {
await test.step('navigate', async () => {
await page.goto('https://playwright.dev/');
});
});
test('should take screenshot', async ({ page }) => {
// programmatically remove the button for this example
await page.getByText('Get Started').evaluate((el) => el.remove());
await expect(page).toHaveScreenshot();
});
And here's the cherry on top: all these UI mode features are also coming to the trace viewer. So, when tests fail on CI, you will still get the same experience.
Project Teardown
Before we dive into project teardown, it's important to discuss setup and dependencies. Setting up dependencies between different projects is a useful feature when data is shared between them, for example setting up a database.
Previously, tearing down a database after testing was a difficult task. However, the latest update introduces a "teardown" feature, which allows the smooth running of setup, dependencies, and finally, the cleanup process.
import { defineConfig } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'setup db',
testMatch: /global.setup\.ts/,
teardown: 'cleanup db',
},
{
name: 'cleanup db',
testMatch: /global.teardown\.ts/,
},
{
name: 'chromium',
use: devices['Desktop Chrome'],
dependencies: ['setup'],
},
{
name: 'webkit',
use: devices['Desktop Safari'],
dependencies: ['setup'],
},
],
});
New Locators API
With the new Locators API, you can select elements with more precision. The locator.and
feature allows you to combine different selectors to pinpoint a precise element.
await page.getByRole('button', { name: 'Sign Up' })
.and(page.getByTitle('Sign Up Today'))
.click();
The locator.or
API is used when you want to wait for either of two elements to appear.
const newEmail = page.getByRole('button', { name: 'New email' });
const dialog = page.getByText('Confirm security settings');
await expect(newEmail.or(dialog)).toBeVisible();
Lastly, the hasNot
and hasNotText
API is great for negation, allowing you to locate elements that don't have certain properties.
await page.locator('tr')
.filter({ hasNotText: 'helicopter' })
.filter({ hasNot: page.getByRole('button') })
.screenshot();
Miscellaneous Features
Alongside the major updates, there are some nifty miscellaneous additions as well. These include:
- Expect Configure: This new method allows you to create new instances of "expect" such as soft assertions and slow expects, which enable you to control the behavior of your tests in a more granular way.
const softAssert = expect.configure({ soft: true });
const slowExpect = expect.configure({ timeout: 10_000 });
- Web Server Configurations: The web server now allows you to configure stderr and stdout, helping you to manage your local Dev server more efficiently.
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
// Run your local dev server before starting the tests
webServer: {
command: 'npm run start',
url: 'http://127.0.0.1:3000',
reuseExistingServer: !process.env.CI,
stdout: 'pipe', // Can be ‘ignore’ (default) or ‘pipe’
stderr: 'pipe', // Can be ‘ignore’ or ‘pipe’ (default)
},
});
-
New Web Assertion: A new web assertion
toBeAttached
has been added, which checks whether an element is present in the DOM, even if it is hidden.
await expect(page.getByRole('button', { name: 'Sign Up' })).toBeAttached();
- Custom Reporters' API Method: There's a new async method, 'reporter on exit', which allows you to run postponed jobs.
await reporter.onExit();
- New Events on Browser Context: Console and dialog events now bubble up from all the pages to the browser context.
Console:
browserContext.on('console', message => console.log(message));
await page.evaluate(() => console.log('hello context!'));
Dialog:
context.on('dialog', dialog => {
dialog.accept();
});
All in all, these latest updates offer a multitude of improvements that make the user experience more intuitive and efficient. We are excited for you to try out these new features and we eagerly look forward to your feedback. As always, keep an eye out for our future releases!
And, don't forget to give us a star, subscribe to our Twitter, YouTube, and Discord and give us a star on GitHub. Write us your comments - we read all of them.
Till the next update, happy testing!