const ancestor = 'селектор элементов, которые надо получить';
const descendant = 'селектор вложенных элементов';
Вариант раз - получаем всех потенциальных предков, отбираем тех, кто содержит кого надо:
Array.prototype.filter.call(
document.querySelectorAll(ancestor),
n => n.querySelector(descendant)
)
Вариант два - получаем тех, кто содержится внутри нужных элементов, поднимаемся вверх:
Array.from(
document.querySelectorAll(`${ancestor} ${descendant}`),
n => n.closest(ancestor)
)
Вариант три (ну, два с половиной) - получаем потенциальных потомков, пробуем подняться до нужных предков:
[...document.querySelectorAll(descendant)].reduce(
(acc, n) => ((n = n.closest(ancestor)) && acc.push(n), acc),
[]
)
UPD.
Наконец-то дождались (ну, почти):
document.querySelectorAll(`${ancestor}:has(${descendant})`)