QA How-To
How to Use Playwright getByAltText (2026)
Learn playwright getByAltText with TypeScript, exact and regex matching, role comparisons, duplicate scoping, accessibility guidance, and debugging for 2026.
22 min read | 2,868 words
TL;DR
Use `page.getByAltText(text)` for images and other elements whose alternative text is their meaningful identity. Use role locators for interactive semantics, and scope duplicates through a stable domain region.
Key Takeaways
- Use getByAltText when meaningful alternative text is the element's stable user-facing identity.
- Choose string, exact string, or anchored regex matching according to the content contract.
- Prefer getByRole for an interactive link or button whose role best describes the user action.
- Keep decorative images semantically decorative instead of inventing alt text for testability.
- Scope legitimate duplicate alternatives through a product card, article, dialog, or other domain region.
- Treat alt-locator failures as possible content or accessibility regressions, not only selector maintenance.
Playwright getByAltText() locates an element, usually an image or image-map area, by its text alternative. A resilient playwright getByAltText locator looks like page.getByAltText('Candidate profile photo') and uses the same meaningful alternative text that users of assistive technology receive.
The method accepts a string or regular expression and an optional { exact: true } setting for string matches. This guide shows runnable examples, compares alt text with role and test-id locators, explains empty and duplicate alternatives, covers frames and Shadow DOM, and turns locator failures into useful accessibility feedback.
TL;DR
const logo = page.getByAltText('QAJobFit logo');
await expect(logo).toBeVisible();
await logo.click();
| Need | Locator | Best reason to use it |
|---|---|---|
| Image with meaningful alternative | getByAltText() |
Alternative text is the stable identity |
| Interactive element by role and name | getByRole() |
Models user and assistive-tech interaction |
| Form field | getByLabel() |
Associated label identifies the control |
| Stable product test contract | getByTestId() |
No suitable user-facing identity exists |
| Visual-only implementation hook | CSS locator | Rare, DOM-specific requirement |
Use getByAltText() when the element genuinely supports alt text and that alternative is part of the user experience. Do not add fake alt text only to satisfy a test.
1. What playwright getByAltText does
page.getByAltText(text, options?) returns a Locator. The text argument can be a string or RegExp. For a string, matching is flexible by default; { exact: true } makes it case-sensitive and whole-string, while still trimming whitespace. When the argument is a regular expression, the exact option is ignored because the expression defines its own rules.
const byString = page.getByAltText('QAJobFit logo');
const byExactString = page.getByAltText('QAJobFit logo', { exact: true });
const byPattern = page.getByAltText(/^qajobfit logo$/i);
Because the result is a locator, Playwright resolves it when an action or assertion uses it. It benefits from locator auto-waiting and strictness. A click fails if multiple matching elements remain, which protects the test from acting on an arbitrary image.
The locator is intended for elements that support alternate text, commonly <img> and <area>. It is not a generic query for any element with a property that happens to be named alt. Use role, label, text, title, or test-id locators according to the element's user-facing contract.
Alternative text should describe the image's purpose or content in context. A test that locates alt="image123" may be technically functional but encodes a poor user experience. Locator design and accessible content design meet at this API.
2. Create a runnable getByAltText test
The following file is self-contained and runs with Playwright Test. It uses a data URL for the image source, so the test performs no external request.
import { test, expect } from '@playwright/test';
test('finds a meaningful image by alt text', async ({ page }) => {
await page.setContent(`
<main>
<h1>Candidate profile</h1>
<img
alt="Jordan Lee profile photo"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
>
</main>
`);
const photo = page.getByAltText('Jordan Lee profile photo');
await expect(photo).toBeVisible();
await expect(photo).toHaveAttribute('src', /data:image[/]gif/);
});
The alt locator identifies the image. The assertions check separate contracts: it is visible, and its source uses the expected data format. Do not assert alt again with toHaveAttribute() unless the markup attribute itself is an additional requirement. Successfully resolving getByAltText('Jordan Lee profile photo') already depends on that text alternative.
In a real test, navigate to the product page with page.goto(). Keep the expected alternative close to the domain scenario. A profile photo might include the candidate name, while a company logo might be called QAJobFit. Avoid phrases such as picture of unless that wording is needed to convey information.
The browser may report an image visible even before every image byte has loaded. If successful loading matters, assert the product's loaded state or inspect natural dimensions through an appropriate assertion. Visibility and network success are different facts.
3. Match alt text with strings, exact mode, and regex
Use the narrowest readable match that reflects the content contract. The default string match is convenient when text around a stable phrase can vary. Exact strings prevent unintended partial matches. Regular expressions help with controlled dynamic names.
import { test, expect } from '@playwright/test';
test('uses three supported alt-text matching styles', async ({ page }) => {
await page.setContent(`
<img alt="QAJobFit product logo" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
<img alt="Build status: passing" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
<img alt="Candidate avatar for Morgan Lee" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
`);
await expect(page.getByAltText('product logo')).toBeVisible();
await expect(
page.getByAltText('Build status: passing', { exact: true })
).toBeVisible();
await expect(
page.getByAltText(/^Candidate avatar for [A-Z][a-z]+ [A-Z][a-z]+$/)
).toBeVisible();
});
Default string behavior can match a substring and is case-insensitive, which makes it readable but can become ambiguous. If both QAJobFit product logo and QAJobFit partner product logo exist, use exact mode or add meaningful scope.
An exact string match is case-sensitive and whole-string. Playwright still trims whitespace, so do not use it as the only way to police leading or trailing spaces in raw markup. If whitespace quality is itself a requirement, inspect the attribute explicitly in a focused accessibility test.
A regex uses normal JavaScript behavior. Anchor it when the full alternative must match. Avoid a broad pattern such as /avatar/ on a page with many candidates. Prefer the scenario's known name when deterministic.
4. Choose getByAltText versus getByRole
Both locators can overlap because an image with alt text participates in the accessibility tree. The better choice depends on what identity the test should express.
| Scenario | Prefer | Example |
|---|---|---|
| Noninteractive informative image | getByAltText() |
Candidate profile photo |
| Image itself has an image role | Either, with intent | getByRole('img', { name }) |
| Image is inside a link | getByRole('link', { name }) |
Home link named by logo alt |
| Image-like button | getByRole('button', { name }) |
Submit control with an accessible name |
| Decorative image | Neither by meaningful name | It should have empty alternative |
| No user-facing stable identity | getByTestId() sparingly |
Visual implementation marker |
Consider a linked logo:
await page.setContent(`
<a href="/">
<img alt="QAJobFit home" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
</a>
`);
await page.getByRole('link', { name: 'QAJobFit home' }).click();
The user's action is activating a link, so the role locator communicates more than selecting the descendant image and clicking it. The image alt contributes to the link's accessible name.
For an informative chart that is not interactive, getByAltText('Pass rate by release') is direct. For a clickable chart control, prefer the interactive role and accessible name. A role locator also catches mistakes where a visual control is built from a noninteractive element without proper semantics.
Locator preference is not a universal ranking. Use the locator that best captures the element's user-perceived contract.
5. Handle decorative and empty alt text correctly
Decorative images should normally have an empty alt attribute so assistive technology can ignore them. Do not give a flourish a fake description just to make it easy to locate.
<img alt="" src="/images/section-divider.svg">
A functional test usually should not interact with that image at all. Assert the surrounding content or behavior. If visual presence is a real requirement, use visual testing or a deliberate test contract, not invented alternative text.
Empty alt is different from a missing alt attribute. An empty alternative intentionally marks an image as decorative in common HTML usage. A missing alternative can cause assistive technology to announce an unhelpful filename or URL. Include automated accessibility analysis and focused markup tests where this distinction matters.
Avoid page.getByAltText('') as a general decorative-image selector. A page may contain many decorative images, and the locator will not express which visual you mean. Strictness will also reject a single-target action when multiple elements match.
If a decorative image is purely CSS background, getByAltText() is not applicable because no alternate-text element exists. Test semantic content and interactions through accessible locators. Use screenshot comparison only when layout or artwork itself creates user risk.
This is an important coaching point: testability should reinforce accessibility, but it should not distort semantic content. Add an accessible name when users need one. Add a test ID when automation alone needs a stable implementation contract.
6. Scope duplicate alt text without using nth
Repeated alternatives can be legitimate. A product list may show the same brand logo in multiple cards. Playwright locators are strict for single-element operations, so an unscoped click on duplicated alt text fails rather than guessing.
import { test, expect } from '@playwright/test';
test('scopes a repeated logo to the correct product card', async ({ page }) => {
await page.setContent(`
<ul>
<li>
<h2>Starter plan</h2>
<img alt="QAJobFit logo" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
<button>Choose plan</button>
</li>
<li>
<h2>Team plan</h2>
<img alt="QAJobFit logo" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">
<button>Choose plan</button>
</li>
</ul>
`);
const teamCard = page.getByRole('listitem').filter({ hasText: 'Team plan' });
await expect(teamCard.getByAltText('QAJobFit logo')).toBeVisible();
await teamCard.getByRole('button', { name: 'Choose plan' }).click();
});
The card is scoped by meaningful content, then the image and button are located within it. This is stronger than getByAltText('QAJobFit logo').nth(1), which depends on order. If a new card is inserted, nth(1) may silently target a different product.
You can also filter a parent with has: page.getByAltText(...) when the image identity distinguishes the container. Keep both locators in the same frame and use a parent that represents a stable domain region.
If duplicated alternatives actually describe different informative images, the content may be under-specified. Work with design and accessibility owners to decide whether alternatives should include distinguishing information.
7. Locate image links and image-map areas
getByAltText() can locate elements such as images and <area> elements that support alternative text. Image maps are uncommon, but the locator semantics are straightforward.
import { test, expect } from '@playwright/test';
test('locates an image-map area by alternative text', async ({ page }) => {
await page.setContent(`
<img
alt="Office floor map"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
usemap="#office-map"
>
<map name="office-map">
<area
shape="rect"
coords="0,0,100,100"
href="#lab"
alt="Automation lab"
>
</map>
<h2 id="lab">Automation lab</h2>
`);
const labArea = page.getByAltText('Automation lab');
await expect(labArea).toHaveAttribute('href', '#lab');
});
The example asserts the area's destination instead of clicking coordinates on a one-pixel demo image. In a real image map, a click test can verify navigation, while accessibility coverage confirms every meaningful area has a useful alternative.
For an ordinary image inside a link, locate the link by role and the accessible name derived from the image's alt when the intended action is navigation. Use the image locator when the image itself is the subject of the assertion, such as a product badge or candidate photo.
Avoid using an image filename as alternative text. automation-lab-final-v3.png exposes implementation history rather than purpose and creates a brittle test. The accessible phrase should survive asset replacement.
8. Use playwright getByAltText inside components, frames, and Shadow DOM
Locator-producing methods are available on Page, Locator, and FrameLocator, so you can narrow scope before matching alternative text.
const card = page.getByRole('article', { name: 'Execution summary' });
await expect(card.getByAltText('Passed tests chart')).toBeVisible();
For an iframe:
const reportFrame = page.frameLocator('iframe[title="Test report"]');
await expect(reportFrame.getByAltText('Failure trend chart')).toBeVisible();
Frame boundaries are real. A page-level locator does not automatically search an iframe document. Use a FrameLocator with a stable title or other frame identity.
Playwright locators generally work through open Shadow DOM, so the same alt locator can find an image inside an open shadow root. XPath is a poor workaround because it does not pierce shadow roots in Playwright and ties the test to DOM structure.
await page.setContent(`<user-card></user-card>`);
await page.evaluate(() => {
const host = document.querySelector('user-card');
const root = host?.attachShadow({ mode: 'open' });
if (root) {
root.innerHTML = '<img alt="Morgan Lee avatar" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==">';
}
});
await expect(page.getByAltText('Morgan Lee avatar')).toBeVisible();
Closed shadow roots are not available to normal locator traversal. Test a closed component through its public user-facing interface rather than implementation internals.
9. Combine getByAltText with meaningful assertions
Finding an image is only the start. Choose assertions based on the risk. Visibility proves the layout exposes it. An attribute assertion can prove a stable source contract. A role or link assertion can prove interaction. Natural dimensions can help detect a failed image load.
import { test, expect } from '@playwright/test';
test('verifies that a logo loaded successfully', async ({ page }) => {
await page.setContent(`
<img
alt="QAJobFit logo"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
>
`);
const logo = page.getByAltText('QAJobFit logo');
await expect(logo).toBeVisible();
await expect(logo).toHaveJSProperty('complete', true);
await expect(logo).toHaveJSProperty('naturalWidth', 1);
});
toHaveJSProperty() is a locator assertion and retries. This example uses a known one-pixel data image, so naturalWidth is deterministic. On a responsive production asset, assert a positive width through controlled evaluation or a suitable product state rather than hard-coding an incidental dimension.
Do not assert everything for every image. A content page may need only accessible identity and visibility. A critical QR code may need successful load plus a decoded or backend contract. A clickable brand mark may need navigation.
If image loading depends on a network request, traces and request evidence can reveal 404 or policy errors. Keep accessibility naming, visual correctness, and transport success as distinct test claims so failures are actionable.
10. Debug playwright getByAltText failures
First determine the failure type. Zero matches suggests wrong or missing alternative text, wrong frame, wrong page state, or a closed shadow boundary. Multiple matches indicates ambiguous scope. An actionability failure means the element was found but could not be used as requested. A failed visibility or load assertion is a separate product state.
Inspect the rendered DOM and accessibility snapshot in Playwright's trace viewer. Confirm that the expected string is the actual alt value and not a caption, title, filename, CSS background description, or nearby text. If the target is interactive, check whether role and accessible name express the action better.
Temporary focused evidence can help:
const images = page.locator('img');
console.log('image count:', await images.count());
console.log('alt values:', await images.evaluateAll(nodes =>
nodes.map(node => node.getAttribute('alt'))
));
Remove broad logging after diagnosis, especially if alternatives may contain customer information.
Do not repair ambiguity with .first() or .nth() until you can explain why order is the requirement. Scope to a dialog, article, list item, or other domain region. If text changed intentionally, update the test with the content contract. If it changed accidentally, treat the failure as an accessibility regression.
The Playwright stability and actionability guide helps when a found image is covered, detached, or moving. For expect target errors, use the Playwright Locator assertion fix.
11. Build a locator strategy and review checklist
A team guideline should describe intent, not ban or mandate one method. Review each locator with these questions:
- What does the user call this element?
- Is it interactive, and if so, what is its role and accessible name?
- Does the element legitimately support alternative text?
- Is the alternative meaningful in context and stable across asset changes?
- Could the page contain duplicates, and what domain region scopes the target?
- Is a test ID a more honest automation-only contract?
Use getByAltText() for meaningful images and areas. Use getByRole() for interactive semantics. Use getByLabel() for form fields. Use getByTestId() when a stable explicit testing contract is needed and no user-facing locator fits. Avoid long CSS and XPath chains that mirror implementation structure.
Pair functional tests with accessibility tooling, because a locator passing does not constitute an accessibility audit. It confirms one accessible identity and can expose regressions, but it does not check contrast, reading order, keyboard behavior, or the quality of every alternative.
For broader framework design, typing Playwright fixtures for QA can centralize page objects without hiding locator intent. Interview preparation can continue with Playwright questions for experienced SDETs.
12. Treat alternative text as owned product content
Alternative text can change because an image's purpose changes, content is localized, or an accessibility review improves wording. Decide who owns those strings and how automation updates are reviewed. A changed locator is not automatically test maintenance noise. It can reveal an intended content revision, a regression, or an outdated scenario.
For localized products, do not force English alt values into every project. Use locale-owned expected content or assert a stable interactive role when the exact translation is outside the scenario. Keep a small set of content checks that verify meaningful translations and avoid regex patterns so loose that any language or phrase passes.
Dynamic alternatives should remain deterministic when the underlying domain data is controlled. A candidate image can be located with the known candidate name created by the test. Avoid reading the current alt attribute and feeding it back as the expected locator, which proves nothing. When privacy matters, synthetic names should appear in fixtures, traces, and reports instead of copied production identities.
Interview Questions and Answers
Q: What does Playwright getByAltText() return?
It returns a Locator. The locator is resolved when used and participates in Playwright auto-waiting and strictness. Its text argument can be a string or regular expression.
Q: When should you prefer getByRole() over getByAltText()?
Prefer role when the target is an interactive element and the action is best described by its role and accessible name. For an image inside a home link, getByRole('link', { name: 'QAJobFit home' }) communicates navigation better than clicking the descendant image.
Q: What does { exact: true } change?
For a string, it requires a case-sensitive whole-string match while still trimming whitespace. It is ignored when the text argument is a regular expression because the regex defines matching behavior.
Q: How should a test handle two images with the same alt text?
Scope the locator to a meaningful region such as a product card, article, or dialog. Avoid choosing .nth() unless order is truly the business contract. If the images convey different information, review whether their alternatives need distinction.
Q: Should decorative images have alt text for automation?
They should generally have an empty alternative when they convey no content. Do not invent a spoken description for testability. Use surrounding semantics, a visual test, or a deliberate test ID if automation must identify a decorative implementation detail.
Q: Does a passing alt-text locator prove the page is accessible?
No. It proves that one element can be found by that alternative text. A full assessment also considers alternative quality, keyboard access, roles, names, contrast, structure, focus, and other accessibility requirements.
Q: How do you locate alt text inside an iframe?
Create a FrameLocator for the iframe and call getByAltText() from it. Page-level locators do not cross into iframe documents automatically. Use a stable frame identity such as its title.
Common Mistakes
- Using
getByAltText()for arbitrary elements that do not support alternative text. - Giving decorative images fake descriptions just to create a locator.
- Clicking a linked image when a link role locator better expresses the action.
- Relying on partial default matching when two alternatives share the same phrase.
- Using a broad regex such as
/logo/across a page with many logos. - Resolving duplicates with
.first()or.nth()instead of meaningful scope. - Expecting a page locator to search inside an iframe.
- Confusing alt text with a caption,
title, filename, or nearby visible text. - Treating visibility as proof that image bytes loaded successfully.
- Treating one passing locator as a complete accessibility audit.
- Replacing an intentional text change with a brittle CSS path.
- Logging every image alternative in CI when content may contain personal information.
Conclusion
Playwright getByAltText() is a clear, resilient locator for elements whose text alternative is their meaningful user-facing identity. Use a string, exact string, or controlled regex, then scope duplicates through domain regions and assert the actual behavior or image state the scenario requires.
Review one image-heavy page in your suite. Replace structural selectors with appropriate alt or role locators, preserve empty alternatives for decoration, and raise ambiguous or misleading text as an accessibility and content-quality issue rather than hiding it in test code.
Interview Questions and Answers
What does getByAltText return?
It returns a Playwright Locator. The query is resolved when an action or assertion uses it, so it benefits from locator auto-waiting and strictness.
When should getByRole be preferred over getByAltText?
Prefer role when the target is interactive and its role plus accessible name best describe the action. A linked logo is usually better located as a link, even though its image alt contributes the link name.
What does exact true change for getByAltText?
It makes a string match case-sensitive and whole-string while still trimming whitespace. The option is ignored for a regex because the expression itself defines matching rules.
How should duplicate alt text be handled?
Scope the locator through a meaningful product region such as a card or article. Do not use `.first()` or `.nth()` unless order is the domain contract. Also review whether the content is genuinely distinguishable.
Should decorative images receive descriptive alt text for automation?
No. Decorative images should normally use an empty alternative so assistive technology ignores them. Use a visual test or explicit automation contract instead of changing semantics for selector convenience.
Does a passing getByAltText locator prove accessibility?
No. It confirms one alternative-text identity, but accessibility also includes wording quality, roles, keyboard use, focus, contrast, structure, and many other requirements. Pair functional locators with dedicated accessibility testing.
How do you locate an image by alt text inside an iframe?
Create a `FrameLocator` for the target iframe and call `getByAltText()` from that object. Use a stable frame title or other identity because page locators do not automatically traverse frame documents.
Frequently Asked Questions
What does Playwright getByAltText return?
It returns a Locator that participates in Playwright auto-waiting and strictness. The text argument can be a string or regular expression.
Which elements work with getByAltText?
Use it for elements that support alternative text, commonly images and image-map areas. It is not a generic locator for arbitrary elements with nearby descriptive text.
Is getByAltText case-sensitive?
Default string matching is flexible and case-insensitive. With `{ exact: true }`, a string match is case-sensitive and whole-string, while still trimming whitespace. A regular expression controls its own case behavior.
Should I use getByAltText or getByRole for a linked image?
Prefer `getByRole("link", { name })` when the intended action is navigation. The image alt can contribute to the link's accessible name, while the role locator communicates the interaction.
How do I handle duplicate alt text in Playwright?
Scope the locator to a meaningful card, article, dialog, or list item. Avoid `.nth()` unless ordering is truly the requirement, and review whether informative images need more distinct alternatives.
Should decorative images have alt text for tests?
Decorative images should generally retain an empty alternative. Do not invent spoken content for automation. Use surrounding semantics, visual coverage, or an honest test ID if a technical contract is needed.
Does getByAltText work inside an iframe?
Call `getByAltText()` from a `FrameLocator` that identifies the iframe. A page-level locator does not cross into an iframe document automatically.