diff --git a/src/client/core/utils/dom.js b/src/client/core/utils/dom.js index a86ba6673f..b78e36efa2 100644 --- a/src/client/core/utils/dom.js +++ b/src/client/core/utils/dom.js @@ -10,6 +10,7 @@ const getElementStyleProperty = hammerhead.utils.style.get; export const getActiveElement = hammerhead.utils.dom.getActiveElement; export const findDocument = hammerhead.utils.dom.findDocument; +export const find = hammerhead.utils.dom.find; export const isElementInDocument = hammerhead.utils.dom.isElementInDocument; export const isElementInIframe = hammerhead.utils.dom.isElementInIframe; export const getIframeByElement = hammerhead.utils.dom.getIframeByElement; @@ -390,8 +391,16 @@ export function isTopWindow (win) { } } -export function findIframeByWindow (iframeWindow, iframeDestinationWindow) { - const iframes = (iframeDestinationWindow || window).document.getElementsByTagName('iframe'); +export function findIframeByWindow (iframeWindow) { + const iframes = []; + + find(document, '*', elem => { + if (elem.tagName === 'IFRAME') + iframes.push(elem); + + if (elem.shadowRoot) + find(elem.shadowRoot, 'iframe', iframe => iframes.push(iframe)); + }); for (let i = 0; i < iframes.length; i++) { if (nativeMethods.contentWindowGetter.call(iframes[i]) === iframeWindow) diff --git a/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow-iframe.html b/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow-iframe.html new file mode 100644 index 0000000000..32b1b66d58 --- /dev/null +++ b/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow-iframe.html @@ -0,0 +1,31 @@ + + + + + Iframe + + + + +
+ + + + diff --git a/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow.html b/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow.html new file mode 100644 index 0000000000..e1abb9f7ae --- /dev/null +++ b/test/functional/fixtures/api/es-next/iframe-switching/pages/shadow.html @@ -0,0 +1,31 @@ + + + + + Title + + + + +
+ + + + diff --git a/test/functional/fixtures/api/es-next/iframe-switching/test.js b/test/functional/fixtures/api/es-next/iframe-switching/test.js index 85b8de73b5..1e02589671 100644 --- a/test/functional/fixtures/api/es-next/iframe-switching/test.js +++ b/test/functional/fixtures/api/es-next/iframe-switching/test.js @@ -23,6 +23,20 @@ describe('[API] t.switchToIframe(), t.switchToMainWindow()', function () { return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Click on element in a nested iframe', DEFAULT_RUN_OPTIONS); }); + it('Should switch context between a shadow iframe and the main window', function () { + return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Click on an element in a shadow iframe and return to the main window', { + ...DEFAULT_RUN_OPTIONS, + skip: ['ie', 'edge'], + }); + }); + + it('Should switch context between a nested shadow iframe and the main window', function () { + return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Click on element in a nested shadow iframe', { + ...DEFAULT_RUN_OPTIONS, + skip: ['ie', 'edge'], + }); + }); + it('Should wait while a target iframe is loaded', function () { return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Click in a slowly loading iframe', DEFAULT_RUN_OPTIONS); }); @@ -64,7 +78,7 @@ describe('[API] t.switchToIframe(), t.switchToMainWindow()', function () { expect(errs[0]).to.contains( 'The specified selector does not match any element in the DOM tree.' + ' > | Selector(\'#non-existent\')'); - expect(errs[0]).to.contains("> 56 | await t.switchToIframe('#non-existent');"); + expect(/> *\d* *\| *await t\.switchToIframe\('#non-existent'\);/.test(errs[0])).ok; }); }); @@ -81,7 +95,7 @@ describe('[API] t.switchToIframe(), t.switchToMainWindow()', function () { return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Try to switch to an incorrect element', { shouldFail: true }) .catch(function (errs) { expect(errs[0]).to.contains('The action element is expected to be an