Testing Google Apps Script web app, which adds two levels of iframe to your content.
Test hangs on await Selector(..)()
Test runs normally
Your website URL (or attach your complete example):
https://script.google.com/macros/s/AKfycbznLgTmhAx4iz4tdfY__7I_326s3ZLqWQaR3HKoJi37R0U4OcM/exec
Your complete test code (or attach your test files):
fixture`Testcafe nested iframe freezing issue repro`
.page('https://script.google.com/macros/s/AKfycbznLgTmhAx4iz4tdfY__7I_326s3ZLqWQaR3HKoJi37R0U4OcM/exec');
import { Selector } from 'testcafe';
test('It stucks on nested iframe selector', async t => {
await t
.switchToIframe('#sandboxFrame')
.switchToIframe('#userHtmlFrame');
await Selector('#helloworld')();
console.log("This is never logged as it's stuck");
});
Your complete test report:
None.
I've reproduced this issue in versions 0.23.2 and 0.23.3-alpha.4. The test works fine if I click the #helloworld selector instead of waiting for the #helloworld selector to appear. We will investigate the issue and notify you about our results.
It would also hang on await t.expect(Selector(...).exists).ok(), forgot to put that in the repro.
Any updates?
Thank you for your patience, I found the cause of this issue. There is a problem with cross-domain iframes and the isCrossDomainWindows function - CORS rules block access to the location property of the cross-domain windows. It's strange that we didn't encounter it earlier.
Anything I can do to help?
Any updates?
@fnlctrl,
I apologize聽for the delayed response. I'm researching this issue and will fix it. Thank you for your patience.
I've figured out the cause of this issue. All event handlers are cleaned after the document.open function call. Therefore, the nested iframe does not handle messages from the top window. I've simplified the provided example:
Server for reproducing
const http = require('http');
http
.createServer((req, res) => {
switch (req.url) {
case '/':
res.writeHead(200, { 'content-type': 'text/html' });
res.end(`<iframe src="http://localhost:2201/"></iframe>`);
break;
default:
res.end();
}
})
.listen(2200);
http
.createServer((req, res) => {
switch (req.url) {
case '/':
res.writeHead(200, { 'content-type': 'text/html' });
res.end(`
<iframe src="/iframe"></iframe>
<script>
var iframe = document.querySelector('iframe');
iframe.contentDocument.open();
iframe.contentDocument.write('<div id="helloworld">Hello world</div>');
iframe.contentDocument.close();
</script>
`);
break;
case '/iframe':
res.writeHead(200, { 'content-type': 'text/html' });
res.end(``);
break;
default:
res.end();
}
})
.listen(2201);
Test
fixture`fixture`
.page('http://localhost:2200/');
import { Selector } from 'testcafe';
test('test', async t => {
await t
.switchToIframe('iframe')
.switchToIframe('iframe');
const selector = Selector('div');
await s();
console.log("This is never logged as it's stuck");
});
Could you please give us an estimate on when this can be fixed ? It's a blocker for all of our test cases and I have to revert to wdio if not fixable. Thank you for your work, testcafe is amazing so far.
Unfortunately I can't give an estimate for a fix yet because the issue is rather complex. However I will try to provide a workaround in the next couple of days.
The current workaround I'm using is to avoid using selector api and to use client functions like t.eval(() => document.querySelector(....)) This is ugly, but is ok for my use case.
馃帀 馃帀 馃帀 馃帀 馃帀
This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests. We recommend you ask TestCafe API, usage and configuration inquiries on StackOverflow.
Most helpful comment
The current workaround I'm using is to avoid using selector api and to use client functions like
t.eval(() => document.querySelector(....))This is ugly, but is ok for my use case.