QA How-To
Playwright getByTitle: Examples and Best Practices
Master Playwright getByTitle examples for exact, partial, regex, scoped, iframe, and assertion patterns, with practical locator best practices for 2026.
24 min read | 3,745 words
TL;DR
Use page.getByTitle('value') to locate an element by its title attribute. Add { exact: true } for a case-sensitive whole-string match, pass a RegExp for variable titles, and scope the locator when titles repeat.
Key Takeaways
- Use getByTitle when the title attribute is the product contract you need to locate or verify.
- Choose exact matching for stable full titles and regular expressions for intentional variable content.
- Scope title locators to a component, frame, or semantic role before using positional shortcuts.
- Keep strictness enabled and make duplicate titles explicit instead of hiding ambiguity with first.
- Assert the user-visible outcome after an action, not only the title attribute used to find the element.
- Prefer role, label, text, or test ID locators when those signals better represent user behavior.
- Treat title as supplemental accessibility information, not a replacement for an accessible name.
Playwright getByTitle examples are most useful when an application deliberately exposes a stable HTML title attribute, such as an icon button tooltip, an issue count label, or a diagram control. Use page.getByTitle('Issues count') for a normal match, add { exact: true } for a case-sensitive whole-string match, or pass a regular expression when part of the title is dynamic.
getByTitle returns a Locator, so it participates in Playwright's auto-waiting, retryable assertions, chaining, strictness, and frame-aware locator model. It does not read the document title and it does not locate visible text unless that same text is present in the title attribute.
This guide uses runnable Playwright Test and TypeScript examples, explains exact and regular expression matching, compares locator choices, and shows how to keep title-based tests readable without coupling an entire suite to tooltip copy.
TL;DR
import { test, expect } from '@playwright/test';
test('reads an issue count by title', async ({ page }) => {
await page.setContent('<span title="Issues count">25 issues</span>');
const count = page.getByTitle('Issues count');
await expect(count).toHaveText('25 issues');
});
| Need | Recommended locator |
|---|---|
| Stable title attribute | getByTitle('Issues count') |
| Full, case-sensitive title | getByTitle('Issues count', { exact: true }) |
| Variable title value | getByTitle(/^Build status: (passed |
| Accessible button identity | getByRole('button', { name: 'Close' }) |
| Form control identity | getByLabel('Email address') |
| Deliberate test contract | getByTestId('build-status') |
A title locator is valid when title is meaningful and stable. It should not automatically outrank a role, label, or test ID that communicates the product intent more clearly.
1. Playwright getByTitle Examples: What the Locator Matches
getByTitle locates elements by the HTML title attribute. The method is available from Page, Locator, and FrameLocator, which means you can search the full page, search within a component, or search within an iframe.
Consider this markup:
<button type="button" title="Refresh dashboard">
<svg aria-hidden="true"></svg>
</button>
<span title="Last synchronized time">10:42 AM</span>
These locators match the two elements:
const refresh = page.getByTitle('Refresh dashboard');
const lastSync = page.getByTitle('Last synchronized time');
The return value is a Locator, not an ElementHandle. Playwright resolves a locator again when an action or assertion runs. If the application replaces the button during a React render, the locator can still resolve the current matching element.
The text argument accepts a string or RegExp. A string uses flexible matching by default. The exact option changes a string match to a case-sensitive, whole-string match, while still trimming whitespace. When a regular expression is passed, exact is ignored because the expression itself defines matching behavior.
getByTitle is not related to page.title(). The following APIs answer different questions:
| API | Purpose | Example result |
|---|---|---|
| page.getByTitle('Help') | Locate an element whose title attribute matches | Locator |
| locator.getAttribute('title') | Read one matched element's raw title attribute | string or null |
| expect(locator).toHaveAttribute('title', 'Help') | Retry until an attribute matches | Assertion |
| page.title() | Read the document's title element | string |
| expect(page).toHaveTitle(/Dashboard/) | Retry until the document title matches | Assertion |
This distinction is a frequent interview and code review topic. Use the locator for an element and page title APIs for browser-tab metadata.
2. Build a Runnable Test Fixture for Title Locators
A small page.setContent fixture makes title matching behavior easy to learn without depending on a live application. Save this as tests/get-by-title.spec.ts in a Playwright Test project:
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }) => {
await page.setContent([
'<main>',
' <h1>Release dashboard</h1>',
' <section aria-label="Build">',
' <button type="button" title="Refresh build status">Refresh</button>',
' <output title="Build status: passed">Passed</output>',
' </section>',
' <section aria-label="Deployment">',
' <button type="button" title="Refresh deployment status">Refresh</button>',
' <output title="Deployment status: pending">Pending</output>',
' </section>',
'</main>',
].join(''));
});
test('locates a stable title', async ({ page }) => {
await expect(page.getByTitle('Build status: passed')).toHaveText('Passed');
});
test('clicks an element located by title', async ({ page }) => {
const refresh = page.getByTitle('Refresh build status');
await expect(refresh).toBeEnabled();
await refresh.click();
});
Run it with:
npx playwright test tests/get-by-title.spec.ts
The fixture is intentionally semantic. Sections have accessible names, buttons have visible text, and title adds context. In a product test, the refresh action should be followed by a business assertion, such as a changed timestamp or a matching API result. The example stops at the locator behavior because the static fixture has no application logic.
Do not call waitForSelector before getByTitle. Locator actions automatically wait for relevant actionability conditions, and web-first assertions retry. A separate wait usually duplicates behavior and can create two timeout paths.
If you are new to locator priorities, Playwright getByRole patterns explains why an accessible role and name often provide the strongest user-facing contract.
Keep this fixture focused on locator behavior. Product-level tests should use the application's real route and data, while small page.setContent tests can document matching rules quickly and deterministically.
3. Use Exact, Partial, and Regular Expression Matching Deliberately
Default string matching is convenient for descriptive titles, but a team should choose matching behavior intentionally. Given these elements:
<span title="Build status">Passed</span>
<span title="Build status details">Completed in 42 seconds</span>
<span title="build status">Passed</span>
A broad string can match more than one element:
const broad = page.getByTitle('Build status');
await expect(broad).toHaveCount(3);
Use exact when the complete title is stable and letter case matters:
const exact = page.getByTitle('Build status', { exact: true });
await expect(exact).toHaveText('Passed');
The exact option still trims whitespace around the expected and actual title. It is not a byte-for-byte attribute comparison. If raw whitespace itself is a requirement, locate the element by a stable signal and assert the attribute with an appropriate regular expression or evaluate the DOM property explicitly.
A regular expression is better for a controlled dynamic suffix:
const result = page.getByTitle(/^Build status: (passed|failed)$/i);
await expect(result).toHaveText(/Passed|Failed/);
Avoid an expression such as /status/i when the page has many status elements. A regex should describe valid variation, not erase useful specificity.
When copy contains punctuation, pass a string rather than building a complex CSS selector:
const help = page.getByTitle('What does "ready" mean?');
await help.click();
Because getByTitle accepts the value directly, you avoid CSS quote escaping. For localization, do not use one English title across every locale unless the application contract is English. Read expected strings from the same locale-aware test data strategy used for visible labels, or choose a stable test ID when the title copy is intentionally translated.
4. Scope Repeated Titles to a Component
Repeated title attributes are common. A dashboard can have one Refresh button per card, and every button may use title="Refresh". Playwright actions are strict, so clicking a locator that resolves to multiple elements throws a strict mode violation. That is useful feedback: the test has not identified which refresh action the requirement describes.
Scope the search to a meaningful container:
import { test, expect } from '@playwright/test';
test('refreshes only the billing card', async ({ page }) => {
await page.setContent([
'<section aria-label="Billing">',
' <button title="Refresh">Refresh</button>',
' <output title="Updated at">10:00</output>',
'</section>',
'<section aria-label="Orders">',
' <button title="Refresh">Refresh</button>',
' <output title="Updated at">10:01</output>',
'</section>',
].join(''));
const billing = page.getByRole('region', { name: 'Billing' });
const refresh = billing.getByTitle('Refresh');
await expect(refresh).toHaveCount(1);
await refresh.click();
});
Locator.getByTitle searches inside the locator's subtree. This reads as a domain statement: find the Billing region, then its Refresh control.
You can also combine independent signals with and():
const refresh = page
.getByRole('button', { name: 'Refresh' })
.and(page.getByTitle('Refresh billing data'));
await refresh.click();
The result must satisfy both locators. This can be useful when a title supplies context not present in repeated visible names. Prefer clear scoping over nth(), first(), or last(). Positional selection is appropriate only when order is itself the requirement, such as selecting the first ranked result. Otherwise it hides duplicate titles and breaks when layout order changes.
When ambiguity is unexpected, follow the diagnostic process in fixing Playwright strict mode violations instead of suppressing strictness.
5. Playwright getByTitle Examples for Icons, Status, and Tooltips
Icon-only controls are a common reason teams reach for getByTitle. First inspect the accessibility contract. A title attribute on a button may expose supplemental text in some browser and assistive technology combinations, but a clear accessible name such as aria-label is more explicit.
For a button with both signals, prefer role for the action and assert title separately when tooltip copy matters:
<button
type="button"
aria-label="Close notification"
title="Close notification"
>
<svg aria-hidden="true"></svg>
</button>
const close = page.getByRole('button', { name: 'Close notification' });
await expect(close).toHaveAttribute('title', 'Close notification');
await close.click();
For a noninteractive status whose title is the stable identifying contract, getByTitle is direct:
const status = page.getByTitle(/^Build status:/);
await expect(status).toHaveText('Passed');
await expect(status).toHaveAttribute('title', 'Build status: passed');
A native title tooltip is controlled by the browser and operating system. Hovering an element does not necessarily expose that native tooltip as a normal DOM node, so do not expect getByRole('tooltip') to find it. If the application renders a custom tooltip element on hover, test that DOM content through its role or visible text:
const help = page.getByRole('button', { name: 'API token help' });
await help.hover();
await expect(page.getByRole('tooltip')).toHaveText(
'Tokens expire after the configured lifetime.',
);
This is different from locating the trigger by its title attribute. Separate the trigger identity, title attribute, and rendered tooltip behavior in your test design.
For counters, title can identify what a terse number means:
await expect(page.getByTitle('Open defects count')).toHaveText('7');
Assert the number with toHaveText rather than reading textContent and comparing later. The web-first assertion retries during asynchronous rendering.
6. Use getByTitle Inside Lists, Frames, and Shadow DOM
Title locators compose with other locator types. In a product list, locate a business object first and then find its titled control:
const product = page
.getByRole('listitem')
.filter({ hasText: 'Mechanical Keyboard' });
await product.getByTitle('Add to comparison').click();
await expect(page.getByRole('status')).toHaveText(
'Mechanical Keyboard added to comparison',
);
The product filter chooses the card, and getByTitle chooses the control within it. For a stronger domain contract, the card could use a test ID while the control keeps its title.
For an iframe, start with frameLocator and then call getByTitle:
import { test, expect } from '@playwright/test';
test('opens help inside a support frame', async ({ page }) => {
await page.setContent([
'<iframe',
' title="Support center"',
' srcdoc="<button title="Open keyboard shortcuts">Shortcuts</button>"',
'></iframe>',
].join(''));
const support = page.frameLocator('iframe[title="Support center"]');
const shortcuts = support.getByTitle('Open keyboard shortcuts');
await expect(shortcuts).toBeVisible();
await shortcuts.click();
});
Notice that the iframe's own title is selected with a CSS attribute selector to create the FrameLocator, while the button inside uses FrameLocator.getByTitle. page.getByTitle('Support center') would locate the iframe element itself, not enter its document.
Playwright locators, including CSS-based and user-facing locators, work through open shadow roots by default in normal supported cases. A title inside an open custom element can be located directly:
await page.getByTitle('Expand account menu').click();
Closed shadow roots are not traversable. If a component hides all testable behavior in a closed root, test through its public user interaction or ask the component owner for a testable contract.
7. Compare getByTitle With Role, Text, Label, and Test ID
Locator choice should follow the requirement, not a universal ranking copied into every code review. The following table is a practical decision reference.
| Locator | Best signal | User-facing | Common risk |
|---|---|---|---|
| getByRole | ARIA role and accessible name | Yes | Requires accurate accessibility semantics |
| getByLabel | Form label association | Yes | Duplicate or missing labels |
| getByText | Visible content | Yes | Repeated copy or broad containers |
| getByTitle | HTML title attribute | Usually supplemental | Tooltip copy can change or be absent |
| getByAltText | Image alternative text | Yes | Decorative and informative images can be confused |
| getByTestId | Explicit test contract | No | Can ignore broken user-facing semantics |
| locator with CSS | DOM structure or attribute | Usually no | Refactors can break implementation selectors |
Choose getByTitle when the title value is meaningful to the behavior. Examples include a compact status label with a stable title, an embedded viewer whose controls are contracted by title, or a legacy widget that exposes no stronger signal.
Choose getByRole for interactive elements when role and accessible name express how a user finds the control. Choose getByLabel for inputs. Choose getByTestId when visible and accessibility copy is intentionally variable or when a domain object lacks a stable user-facing name. Playwright getByTestId examples covers configuration and naming patterns.
Do not combine every available attribute to make a locator appear strong. A five-condition selector is often brittle because any harmless copy change breaks it. Use the smallest set of stable signals that uniquely expresses intent.
A good code review question is: if this locator fails, does the failure point to a product regression, a contract change, or merely a layout refactor? Prefer locators whose failures produce useful information.
8. Assert Attributes and Outcomes Without Overtesting
Locating by title proves that an element currently has a matching title at action time. It does not prove the action succeeded, the visible state is correct, or the title remains accurate after an update.
Use web-first assertions around behavior:
import { test, expect } from '@playwright/test';
test('refreshes the build status', async ({ page }) => {
await page.goto('/builds/42');
const refresh = page.getByTitle('Refresh build status');
const status = page.getByTitle(/^Build status:/);
await expect(refresh).toBeEnabled();
await refresh.click();
await expect(status).toHaveText(/Passed|Failed/);
await expect(status).toHaveAttribute(
'title',
/^Build status: (passed|failed)$/,
);
});
The assertion checks both terse visible output and its expanded title. Do not assert every DOM attribute on the button. Class names, generated IDs, and internal framework attributes usually do not belong to the acceptance criteria.
If an action sends a request, prefer an observable saved state or a precisely matched response. Avoid waitForTimeout. A fixed delay guesses when the system will finish and makes the suite slower even when the update is immediate.
For negative behavior, toHaveCount(0) is often clearer than a nonvisible assertion when no titled element should exist:
await expect(page.getByTitle('Delete project')).toHaveCount(0);
Use toBeHidden when the element is expected to remain in the DOM but hidden. State the product expectation explicitly.
Soft assertions can collect several display defects, but do not continue into destructive actions after a critical locator assertion fails. A title mismatch on a delete control is a reason to stop, not a reason to click a nearby fallback.
9. Design Page Objects That Preserve Locator Intent
A page object should expose domain concepts while retaining Playwright's Locator behavior. Return locators for elements that tests may assert in different ways, and create action methods for stable workflows.
import { expect, type Locator, type Page } from '@playwright/test';
export class BuildPage {
constructor(private readonly page: Page) {}
status(): Locator {
return this.page.getByTitle(/^Build status:/);
}
refreshButton(): Locator {
return this.page
.getByRole('button', { name: 'Refresh' })
.and(this.page.getByTitle('Refresh build status'));
}
async refresh(): Promise<void> {
await this.refreshButton().click();
await expect(this.status()).toHaveText(/Passed|Failed/);
}
}
A test can use the object without losing a precise assertion:
test('shows a terminal status after refresh', async ({ page }) => {
const build = new BuildPage(page);
await page.goto('/builds/42');
await build.refresh();
await expect(build.status()).toHaveAttribute(
'title',
/^Build status: (passed|failed)$/,
);
});
Avoid a generic function such as findByTitle(title: string) that only renames page.getByTitle. It adds indirection but no domain meaning. Similarly, do not return a boolean from an immediate isVisible check when a Locator would let assertions retry.
Centralize title copy only when it is genuinely a shared product contract. A giant constants file for every tooltip makes tests harder to read and can encourage mass updates that conceal a product change. Local, descriptive values are often clearer.
If localization changes title text, inject locale-specific expected copy into the page object or use a different stable signal for actions. Keep a small set of focused content tests to verify translations rather than coupling every workflow to one language.
10. Debug getByTitle Failures Systematically
When a title locator times out, inspect what the application rendered before changing the selector. Common causes include a missing title attribute, changed capitalization with exact matching, an iframe boundary, a closed shadow root, a delayed component, or the wrong page state.
Run the focused test with Inspector or capture a trace:
npx playwright test tests/get-by-title.spec.ts --debug
npx playwright test tests/get-by-title.spec.ts --trace=on
Useful diagnostic assertions include:
const candidate = page.locator('[title]');
await expect(candidate).not.toHaveCount(0);
console.log(await candidate.evaluateAll(elements =>
elements.map(element => element.getAttribute('title')),
));
Keep broad attribute inspection in debugging code, not in the final test. It can reveal actual titles without weakening the production locator.
If getByTitle matches multiple elements, count and inspect them:
const matches = page.getByTitle('Refresh');
console.log('Refresh title count:', await matches.count());
console.log(await matches.allTextContents());
Then scope by a region, card, row, or frame. Do not immediately append first().
Use locator.describe() to improve trace and report language for a complicated composed locator:
const refresh = page
.getByRole('button', { name: 'Refresh' })
.and(page.getByTitle('Refresh billing data'))
.describe('Billing refresh button');
await refresh.click();
Description does not change matching. It makes diagnostics easier to read. Keep descriptions short and domain-specific.
If a title changes after hover or focus, verify whether the application mutates the attribute. Locate the stable trigger through role or test ID, perform the interaction, and then assert the new title rather than trying to find a value that does not exist yet.
11. Establish Team Best Practices for Title Locators
A maintainable policy can be short:
- Use getByTitle only when title is a deliberate, meaningful signal.
- Prefer role and accessible name for interactive controls when they are available.
- Use exact matching when full title copy is stable.
- Use narrowly anchored regex for known dynamic fragments.
- Scope duplicates by a domain container.
- Keep strictness and fix ambiguity.
- Assert the outcome after actions.
- Test native title attributes separately from custom tooltip DOM.
- Review localization and accessibility implications.
- Avoid fixed waits and raw element handles.
Code review should examine the HTML contract as well as the test. If an icon-only button has only title and no clear accessible name, the right fix may be in the product markup. Adding aria-label or visible text improves usability and produces a better role locator.
Do not forbid getByTitle just because another locator is more common. Embedded editors, charts, third-party controls, and compact status views often expose stable titles. The question is whether title is a reliable expression of intent in that component.
Balance workflow coverage with focused contract tests. Most end-to-end tests should locate controls through how users perceive them. A smaller set can verify that important title values remain correct, translated, and synchronized with visible state.
For broader semantic checks, Playwright ARIA snapshot examples show how to assert an accessible structure without encoding every CSS detail.
Interview Questions and Answers
Q: What does Playwright getByTitle locate?
It locates elements by the HTML title attribute and returns a Locator. It does not read the document title. Page, Locator, and FrameLocator expose the method, so the search can be global, scoped, or inside an iframe.
Q: What is the difference between getByTitle and page.title()?
getByTitle finds DOM elements whose title attribute matches a string or regular expression. page.title() returns the current document title as a string, and expect(page).toHaveTitle() is the retrying assertion for it. They test element metadata and page metadata respectively.
Q: How does exact matching work?
With a string, { exact: true } requests a case-sensitive whole-string match while still trimming whitespace. The default string behavior is more flexible. When the text argument is a RegExp, the expression defines matching and exact is ignored.
Q: How do you handle several elements with the same title?
Scope the locator to a meaningful container such as a region, row, dialog, or card. You can also combine title with a role using locator.and(). Avoid first() unless first position is explicitly part of the requirement.
Q: Is getByTitle better than getByRole?
Neither is universally better. getByRole usually expresses an interactive element through accessibility semantics, while getByTitle is appropriate when the title attribute itself is a stable product signal. Choose the locator that best represents the requirement and produces useful failures.
Q: Can getByTitle locate an element inside an iframe?
Yes, call getByTitle from a FrameLocator, for example page.frameLocator('iframe').getByTitle('Help'). Calling page.getByTitle on the iframe's title finds the iframe element but does not enter its document.
Q: Why can a title locator pass while the feature is still broken?
Finding or clicking an element proves only that the locator matched and the input action completed. The application may not update, save, or display the expected result. Always assert a user-visible or domain outcome after the action.
Q: How would you debug a strict mode violation from getByTitle?
I would count and inspect all matches, then identify the missing domain scope. I would narrow through a region, row, frame, role, or stable test ID. I would not hide unexpected duplicates with a positional shortcut.
Common Mistakes
- Confusing an element title attribute with the browser document title.
- Using getByTitle for a button when a clear role and accessible name better express the action.
- Assuming a native title tooltip becomes a DOM element with role="tooltip".
- Passing a broad substring or regex that matches several unrelated controls.
- Adding first() to silence strict mode without understanding duplicates.
- Building CSS attribute selectors with fragile quote escaping instead of passing a title value directly.
- Reading textContent immediately instead of using a retrying assertion.
- Clicking a titled control without asserting the resulting state.
- Reusing English title copy in locale-specific tests without a localization strategy.
- Treating title as a replacement for an accessible name.
- Calling waitForSelector or waitForTimeout before locator actions.
- Trying to cross an iframe boundary with a page-level locator.
- Wrapping getByTitle in a generic helper that removes useful context.
- Asserting irrelevant implementation attributes along with the title contract.
Conclusion
Playwright getByTitle examples are reliable when title is a stable part of the interface contract. Use a string for normal matching, exact for a stable complete value, and a focused regular expression for controlled variation. Scope duplicate titles through the component or frame that owns them, then assert the behavior that follows.
Your next step is to audit one title-based test in your suite. Confirm that title is the best signal, replace positional shortcuts with meaningful scope, and add a web-first outcome assertion. That small review usually improves both failure clarity and product accessibility conversations.
Interview Questions and Answers
What does Playwright getByTitle return?
It returns a Locator that targets elements by their HTML title attribute. The locator is resolved when an action or assertion runs, so it benefits from auto-waiting and retryability. It is available from Page, Locator, and FrameLocator.
How is getByTitle different from page.title?
getByTitle locates a DOM element whose title attribute matches. page.title() reads the document title shown as browser-tab metadata. For a retrying document title assertion, I use expect(page).toHaveTitle().
When would you use exact true with getByTitle?
I use it when the complete title is a stable contract and substring matches would be ambiguous. It performs a case-sensitive whole-string match but still trims whitespace. For controlled dynamic content, I prefer a narrowly anchored regular expression.
How do you resolve duplicate title locators?
I scope through a domain container such as a row, card, region, or dialog. If two signals are both meaningful, I can intersect a role locator and title locator with and(). I avoid first() unless ordering is the tested requirement.
Would you prefer getByTitle over getByRole for an icon button?
I first inspect the accessibility semantics. If the button has a reliable accessible name, getByRole usually best represents the user interaction, and I assert title separately if tooltip copy matters. If a third-party control exposes only a stable title, getByTitle may be the practical contract.
How do you locate a titled element inside an iframe?
I create a FrameLocator for the iframe and call getByTitle from that object. The iframe element's own title can help identify the frame, but locating the frame element does not enter its document. FrameLocator keeps subsequent matching in the correct frame.
Why should a test assert more than a successful getByTitle click?
The click only proves that Playwright found an actionable element and sent input. It does not prove that the application changed, persisted data, or displayed correct feedback. I add a web-first assertion for the business outcome.
How would you debug a getByTitle timeout?
I inspect the trace and actual title attributes, then check page state, case, frame boundaries, shadow DOM, and delayed rendering. I confirm that the title exists before weakening the locator. If several matches exist, I add domain scope rather than a positional shortcut.
Frequently Asked Questions
What does getByTitle do in Playwright?
getByTitle locates an element by its HTML title attribute and returns a Locator. It supports normal locator actions, auto-waiting, chaining, strictness, and web-first assertions.
How do I make Playwright getByTitle exact?
Pass { exact: true } as the second argument, for example page.getByTitle('Issues count', { exact: true }). This produces a case-sensitive whole-string match while still trimming whitespace.
Can Playwright getByTitle use a regular expression?
Yes. Pass a RegExp such as page.getByTitle(/^Build status: (passed|failed)$/i). The regular expression controls matching, so the exact option is ignored.
Is getByTitle the same as checking the page title?
No. getByTitle finds an element by its title attribute. Use page.title() to read the document title or expect(page).toHaveTitle() for a retrying assertion.
How do I use getByTitle when several elements have the same title?
First locate a meaningful container such as a region, row, dialog, or card, then call getByTitle inside it. You can also combine role and title with locator.and() when both signals matter.
Does getByTitle work inside iframes?
Yes. Create a FrameLocator and call getByTitle from it, such as page.frameLocator('#support').getByTitle('Open help'). A page-level locator cannot directly search inside a child frame.
Should I use getByTitle or getByRole?
Use getByRole when an interactive control has accurate accessibility semantics and a stable accessible name. Use getByTitle when the title attribute itself is the meaningful and stable contract you need.
Why does getByTitle throw a strict mode violation?
The locator matched more than one element before a strict action. Inspect the matches and add meaningful component, row, frame, role, or test ID scope instead of automatically selecting the first match.
Related Guides
- How to Use Playwright getByTitle (2026)
- Playwright drag and drop: Examples and Best Practices
- Playwright getByAltText: Examples and Best Practices
- Playwright getByTestId: Examples and Best Practices
- Playwright mock date and time: Examples and Best Practices
- Playwright popup and new tab handling: Examples and Best Practices