Skip to content

Commit

Permalink
Iframe driver fixes (closes DevExpress#1842, closes DevExpress#1875)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderMoskovkin committed Oct 24, 2017
1 parent 44ca231 commit aca42f4
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 18 deletions.
16 changes: 10 additions & 6 deletions src/client/driver/driver-link/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ const WAIT_IFRAME_RESPONSE_DELAY = 500;


export default class ChildDriverLink {
constructor (driverWindow, driverId, iframeAvailabilityTimeout) {
this.driverWindow = driverWindow;
this.driverIframe = domUtils.findIframeByWindow(driverWindow);
this.driverId = driverId;
this.iframeAvailabilityTimeout = iframeAvailabilityTimeout;
constructor (driverWindow, driverId) {
this.driverWindow = driverWindow;
this.driverIframe = domUtils.findIframeByWindow(driverWindow);
this.driverId = driverId;
this.iframeAvailabilityTimeout = null;
}

set availabilityTimeout (val) {
this.iframeAvailabilityTimeout = val;
}

_ensureIframe () {
Expand Down Expand Up @@ -83,7 +87,7 @@ export default class ChildDriverLink {
var msg = new ExecuteCommandMessage(command, testSpeed);

return Promise.all([
sendMessageToDriver(msg, this.driverWindow, this.timeout, CurrentIframeIsNotLoadedError),
sendMessageToDriver(msg, this.driverWindow, this.iframeAvailabilityTimeout, CurrentIframeIsNotLoadedError),
this._waitForCommandResult()
]);
})
Expand Down
14 changes: 9 additions & 5 deletions src/client/driver/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,26 +298,30 @@ export default class Driver {
this._onReady(status);
}

_ensureChildDriverLink (iframeWindow, ErrorCtor) {
_ensureChildDriverLink (iframeWindow, ErrorCtor, selectorTimeout) {
// NOTE: a child driver should establish connection with the parent when it's loaded.
// Here we are waiting while the appropriate child driver do this if it didn't do yet.
return waitFor(() => this._getChildDriverLinkByWindow(iframeWindow), CHECK_IFRAME_DRIVER_LINK_DELAY, this.selectorTimeout)
return waitFor(() => this._getChildDriverLinkByWindow(iframeWindow), CHECK_IFRAME_DRIVER_LINK_DELAY, selectorTimeout)
.catch(() => {
throw new ErrorCtor();
});
}

_switchToIframe (selector, iframeErrorCtors) {
return getExecuteSelectorResult(selector, this.selectorTimeout, null,
var hasSpecificTimeout = typeof selector.timeout === 'number';
var commandSelectorTimeout = hasSpecificTimeout ? selector.timeout : this.selectorTimeout;

return getExecuteSelectorResult(selector, commandSelectorTimeout, null,
() => new iframeErrorCtors.NotFoundError(), () => iframeErrorCtors.IsInvisibleError(), this.statusBar)
.then(iframe => {
if (!domUtils.isIframeElement(iframe))
throw new ActionElementNotIframeError();

return this._ensureChildDriverLink(iframe.contentWindow, iframeErrorCtors.NotLoadedError);
return this._ensureChildDriverLink(iframe.contentWindow, iframeErrorCtors.NotLoadedError, commandSelectorTimeout);
})
.then(childDriverLink => {
this.activeChildDriverLink = childDriverLink;
childDriverLink.availabilityTimeout = commandSelectorTimeout;
this.activeChildDriverLink = childDriverLink;
this.contextStorage.setItem(ACTIVE_IFRAME_SELECTOR, selector);
});
}
Expand Down
12 changes: 9 additions & 3 deletions src/client/driver/iframe-driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default class IframeDriver extends Driver {
// NOTE: do nothing because hammerhead sends js error to the top window directly
}

_onConsoleMessage () {
// NOTE: do nothing because hammerhead sends console messages to the top window directly
}

// Messaging between drivers
_initParentDriverListening () {
eventSandbox.message.on(eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, e => {
Expand All @@ -39,10 +43,12 @@ export default class IframeDriver extends Driver {
return;

this.lastParentDriverMessageId = msg.id;
this.speed = msg.testSpeed;

this.parentDriverLink.confirmMessageReceived(msg.id);
this._onCommand(msg.command);
this.readyPromise.then(() => {
this.speed = msg.testSpeed;
this.parentDriverLink.confirmMessageReceived(msg.id);
this._onCommand(msg.command);
});
}

if (msg.type === MESSAGE_TYPE.setNativeDialogHandler) {
Expand Down
10 changes: 10 additions & 0 deletions test/functional/fixtures/regression/gh-1842/pages/iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GH-1842 iframe</title>
</head>
<body>
<h1>GH-1842 iframe</h1>
</body>
</html>
11 changes: 11 additions & 0 deletions test/functional/fixtures/regression/gh-1842/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>GH-1842</title>>
</head>
<body>
<h1>GH-1842</h1>
<iframe id="reloading-iframe" src="reloading-iframe.html?delay=1000"></iframe>
<iframe id="iframe" src="iframe.html?delay=1000"></iframe>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GH-1842 reloading iframe</title>
</head>
<body>
<h1>GH-1842 reloading iframe</h1>
<script>
window.setTimeout(function () {
if (!window.top.iframeReloads)
window.top.iframeReloads = 0;

if (window.top.iframeReloads < 3) {
window.top.iframeReloads++;
document.location.href = document.location.href;
}
}, 0);
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions test/functional/fixtures/regression/gh-1842/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe('[Regression](GH-1842)', function () {
it('Should wait if an iframe reloads during the switchToIframe command execution', function () {
return runTests('testcafe-fixtures/index-test.js', 'gh-1842', { selectorTimeout: 10000 });
});

it('Should take into account iframe selector\'s timeout option', function () {
return runTests('testcafe-fixtures/index-test.js', 'Individual timeout', { selectorTimeout: 200 });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Selector } from 'testcafe';

fixture `GH-1842`
.page `http://localhost:3000/fixtures/regression/gh-1842/pages/index.html`;

test('gh-1842', async t => {
await t
.switchToIframe('#reloading-iframe')
.click('body')
.click('body');
});

test('Individual timeout', async t => {
const iframe = Selector('#iframe', { timeout: 10000 });

await t
.switchToIframe(iframe)
.expect(Selector('body').visible).ok('iframe is loaded')
.switchToMainWindow();
});
6 changes: 4 additions & 2 deletions test/functional/fixtures/regression/gh-1875/pages/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
</head>
<body>
<h1>GH-1875 iframe</h1>
<script>console.log('log message 1')</script>
<script>
console.log('log message 1');
</script>
</body>
</html>
</html>
4 changes: 2 additions & 2 deletions test/functional/fixtures/regression/gh-1875/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe.only('[Regression](GH-1875)', function () {
describe('[Regression](GH-1875)', function () {
it('Should listen console messages in iframes before it loaded completely', function () {
return runTests('testcafe-fixtures/index-test.js', 'gh-1875');
return runTests('testcafe-fixtures/index-test.js', 'gh-1875', { selectorTimeout: 10000 });
});
});

0 comments on commit aca42f4

Please sign in to comment.