diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js
index a8e00011..9db9c06e 100644
--- a/src/__tests__/element-queries.js
+++ b/src/__tests__/element-queries.js
@@ -642,6 +642,23 @@ test('query/get title element of SVG', () => {
expect(queryByTitle('Close').id).toEqual('svg-title')
})
+test('query/get nested title element of SVG graphics element', () => {
+ const {getByTitle, queryByTitle} = render(`
+
+ `)
+
+ expect(getByTitle('Close').id).toEqual('svg-path')
+ expect(queryByTitle('Close').id).toEqual('svg-path')
+})
+
test('queryByTitle matches case with non-string matcher', () => {
const {queryByTitle} = render(``)
expect(queryByTitle(1)).toBeTruthy()
diff --git a/src/queries/title.ts b/src/queries/title.ts
index 7366855f..b44c75dd 100644
--- a/src/queries/title.ts
+++ b/src/queries/title.ts
@@ -14,9 +14,21 @@ import {
buildQueries,
} from './all-utils'
-const isSvgTitle = (node: HTMLElement) =>
- node.tagName.toLowerCase() === 'title' &&
- node.parentElement?.tagName.toLowerCase() === 'svg'
+const getSvgTitleOwner = (node: HTMLElement) => {
+ if (
+ node.tagName.toLowerCase() !== 'title' ||
+ node.namespaceURI !== 'http://www.w3.org/2000/svg'
+ ) {
+ return null
+ }
+
+ const parent = node.parentElement
+ if (!parent || parent.tagName.toLowerCase() === 'svg') {
+ return node
+ }
+
+ return parent
+}
const queryAllByTitle: AllByBoundAttribute = (
container,
@@ -26,14 +38,25 @@ const queryAllByTitle: AllByBoundAttribute = (
checkContainerType(container)
const matcher = exact ? matches : fuzzyMatches
const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer})
- return Array.from(
- container.querySelectorAll('[title], svg > title'),
- ).filter(
- node =>
- matcher(node.getAttribute('title'), node, text, matchNormalizer) ||
- (isSvgTitle(node) &&
- matcher(getNodeText(node), node, text, matchNormalizer)),
- )
+ const results = new Set()
+
+ Array.from(
+ container.querySelectorAll('[title], svg title'),
+ ).forEach(node => {
+ if (matcher(node.getAttribute('title'), node, text, matchNormalizer)) {
+ results.add(node)
+ }
+
+ const svgTitleOwner = getSvgTitleOwner(node)
+ if (
+ svgTitleOwner &&
+ matcher(getNodeText(node), svgTitleOwner, text, matchNormalizer)
+ ) {
+ results.add(svgTitleOwner)
+ }
+ })
+
+ return Array.from(results)
}
const getMultipleError: GetErrorFunction<[unknown]> = (c, title) =>