Today I'm going to develop a test that will let us know if everything on the main page of my blog is showing up as expected. This will be a longer example of what is possible to achieve with Playwright testing.
If you want to follow along with this post, but don't yet know how to use Playwright, check out my post Getting Started with Playwright.
Expanding on the test
I'm going to take my two tests from the last post and combine them into one test whose goal will be to verify that certain elements are visible and clickable on the main page of my blog.
Imports, goto, and verify title
First, import test
and expect
from playwright/test.
We'll then start by opening up an instance of the test()
method, naming our test 'verify main page content is visible and links are clickable'
, and filling the second argument with the async
keyword and an empty callback function.
const { test, expect } = require('@playwright/test');
test('verify main page content is visible and links are clickable', async ({ page }) => {
});
The first thing we'll do within the test is navigate to the url we want to test.
test('verify main page content is visible and links are clickable', async ({ page }) => {
await page.goto('https://madelinecaples.hashnode.dev/');
});
Then we'll check to see if our page has the title we expect it to have.
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle('Madeline\'s Machine Learning Log');
Check header for image and title
Next, we'll use a locator to find the header section, and see whether the header has the title and tiny image of the author that we expect. The locator getByRole
will allow us to search the page for links. Then we can narrow down that search to links that have the name
'Madeline\'s Machine Learning Log'
(don't forget to escape before the apostrophe). We'll save that locator to a variable named headerTitle
so that we can use it below to check if it's visible with the method toBeVisible
.
We'll use our headerTitle
variable to also find the img
within the header title, using the getByRole
locator. We'll save that locator to the variable name headerTitleImage
, and then check to see if the image is visible. We'll also check if headerTitleImage
has the correct alt text with the method toHaveAttribute
which takes two arguments: the attribute you're looking for, and the text you expect the attribute to have.
// Expect header to contain image and correct title
const headerTitle = page.getByRole('link', { name: 'Madeline\'s Machine Learning Log'});
await expect(headerTitle).toBeVisible();
const headerTitleImage = headerTitle.getByRole('img');
await expect(headerTitleImage).toBeVisible();
await expect(headerTitleImage).toHaveAttribute('alt', 'Madeline Caples');
Check author container for image and text
Next, we'll check to see if the section containing the blog author looks the way we expect it to. Conveniently, we can locate the author container element with the class name 'blog-author-container'
and save it to a variable, blogAuthorContainer
.
Then we can use that locator to further narrow down elements within the author container. We'll get the blogAuthorImage
with blogAuthorContainer.getByRole('img')
and we'll get the blogAuthorTitle
with blogAuthorContainer.getByRole('link').last()
. We have to use last
because there are two links within the author container and we want the second one. We'll expect the title to have the text 'Madeline Caples
.
Finally, we'll find the headline
by searching within blogAuthorContainer
for paragraph
elements, and expect it to have the text "I explain machine learning concepts in plain English."
// check if blog author container has the expected elements
const blogAuthorContainer = page.locator('.blog-author-container');
const blogAuthorImage = blogAuthorContainer.getByRole('img');
await expect(blogAuthorImage).toBeVisible();
await expect(blogAuthorImage).toHaveAttribute('alt', 'Madeline Caples');
const blogAuthorTitle = blogAuthorContainer.getByRole('link').last();
await expect(blogAuthorTitle).toHaveText('Madeline Caples');
const headline = blogAuthorContainer.getByRole('paragraph');
await expect(headline).toHaveText('I explain machine learning concepts in plain English');
A quick note: If I ever change the headline of my blog, these tests will fail, which is a downside of hardcoding these values into the tests, rather than having them be populated in some other way.
Check if all links are clickable
Our last portion for this test is to make sure that all links on the page are enabled (clickable). We can use the all()
method on our locator to select all elements that match that locator and do something to them. Since we're going to be doing the same thing - checking if links are enabled - multiple times, it makes sense to use a for-loop. Within the loop, we can expect the link
to be enabled.
// expect all links on page to be enabled
for (const link of await page.getByRole('link').all()) {
await expect(link).toBeEnabled();
}
Closing comments
There's much more that can be added to make this test better. There are two options for refactoring what we already have which will make the test more readable and easier to debug. Stay tuned for future articles where I describe those options!