Skip to content

Commit d028437

Browse files
chore: Implement cross-domain sibling iframe (#16708)
1 parent 6400e81 commit d028437

File tree

15 files changed

+161
-30
lines changed

15 files changed

+161
-30
lines changed

cli/types/cypress.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5498,6 +5498,8 @@ declare namespace Cypress {
54985498
message: any
54995499
/** Set to false if you want to control the finishing of the command in the log yourself */
55005500
autoEnd: boolean
5501+
/** Set to false if you want to control the finishing of the command in the log yourself */
5502+
end: boolean
55015503
/** Return an object that will be printed in the dev tools console */
55025504
consoleProps(): ObjectLike
55035505
}

packages/driver/cypress/fixtures/multidomain-aut.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
<h1>Multidomain AUT</h1>
77
<p>Some text in the cross-domain AUT</p>
88
<script>
9-
setTimeout(() => {
10-
window.onReady()
11-
}, 500)
9+
// currently this is hard-coded, but will be dynamically injected in the future
10+
document.domain = 'localhost'
11+
12+
top.postMessage('app:cross:domain:window:load', '*')
1213
</script>
1314
</body>
1415
</html>

packages/driver/cypress/fixtures/multidomain.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<head>
44
</head>
55
<body>
6-
<iframe src="http://localhost:3501/fixtures/multidomain-aut.html" width="800" height="800"></iframe>
7-
<iframe src="http://localhost:3501/fixtures/multidomain-sibling.html" width="10" height="10"></iframe>
6+
<a href="http://localhost:3501/fixtures/multidomain-aut.html">Go to localhost:3501</a>
87
</body>
98
</html>
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1-
// NOTE: this test only exists for manual verification as the
2-
// multidomain bundle is a very incomplete work-in-progress
3-
it('loads multidomain playground', () => {
1+
// FIXME: Skip this for now since it's flaky
2+
it.skip('verifies initial implementation of sibling iframe and switchToDomain', (done) => {
3+
top.addEventListener('message', (event) => {
4+
if (event.data && event.data.text) {
5+
expect(event.data.text).to.equal('Some text in the cross-domain AUT')
6+
expect(event.data.host).to.equal('localhost:3501')
7+
done()
8+
}
9+
}, false)
10+
11+
cy.viewport(900, 300)
412
cy.visit('/fixtures/multidomain.html')
13+
cy.get('a').click()
14+
// @ts-ignore
15+
cy.switchToDomain('localhost:3501', () => {
16+
// @ts-ignore
17+
cy.now('get', 'p').then(($el) => {
18+
top.postMessage({ host: location.host, text: $el.text() }, '*')
19+
})
20+
})
521
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: Cypress.State) {
2+
Commands.addAll({
3+
switchToDomain (domain, fn) {
4+
Cypress.log({
5+
name: 'switchToDomain',
6+
type: 'parent',
7+
message: domain,
8+
end: true,
9+
})
10+
11+
Cypress.action('cy:cross:domain:message', 'run:in:domain', fn.toString())
12+
},
13+
})
14+
}

packages/driver/src/cypress.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,18 @@ class $Cypress {
476476
case 'cy:scrolled':
477477
return this.emit('scrolled', ...args)
478478

479+
case 'app:cross:domain:window:load':
480+
return this.emit('cross:domain:window:load', args[0])
481+
482+
case 'cy:switch:domain':
483+
return this.emit('switch:domain', args[0])
484+
485+
case 'runner:cross:domain:driver:ready':
486+
return this.emit('cross:domain:driver:ready')
487+
488+
case 'cy:cross:domain:message':
489+
return this.emit('cross:domain:message', ...args)
490+
479491
case 'app:uncaught:exception':
480492
return this.emitMap('uncaught:exception', ...args)
481493

packages/driver/src/cypress/commands.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const builtInCommands = [
3838
require('../cy/commands/window'),
3939
require('../cy/commands/xhr'),
4040
require('../cy/net-stubbing').addCommand,
41+
require('../cy/multidomain').addCommands,
4142
]
4243

4344
const getTypeByPrevSubject = (prevSubject) => {

packages/driver/src/cypress/cy.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,9 @@ const create = function (specWindow, Cypress, Cookies, state, config, log) {
10281028
let onpl; let r
10291029

10301030
try {
1031-
setWindowDocumentProps(getContentWindow($autIframe), state)
1031+
const autWindow = getContentWindow($autIframe)
1032+
1033+
setWindowDocumentProps(autWindow, state)
10321034

10331035
// we may need to update the url now
10341036
urlNavigationEvent('load')
@@ -1037,14 +1039,25 @@ const create = function (specWindow, Cypress, Cookies, state, config, log) {
10371039
// because they would have been automatically applied during
10381040
// onBeforeAppWindowLoad, but in the case where we visited
10391041
// about:blank in a visit, we do need these
1040-
contentWindowListeners(getContentWindow($autIframe))
1042+
contentWindowListeners(autWindow)
10411043

10421044
Cypress.action('app:window:load', state('window'))
10431045

1044-
// we are now stable again which is purposefully
1045-
// the last event we call here, to give our event
1046-
// listeners time to be invoked prior to moving on
1047-
return stability.isStable(true, 'load')
1046+
// FIXME: temporary hard-coded hack to get multidomain working
1047+
if (!autWindow?.location?.pathname?.includes('multidomain-aut')) {
1048+
// we are now stable again which is purposefully
1049+
// the last event we call here, to give our event
1050+
// listeners time to be invoked prior to moving on
1051+
return stability.isStable(true, 'load')
1052+
}
1053+
1054+
Cypress.once('cross:domain:window:load', () => {
1055+
Cypress.once('cross:domain:driver:ready', () => {
1056+
stability.isStable(true, 'load')
1057+
})
1058+
1059+
Cypress.action('cy:switch:domain', 'localhost:3501')
1060+
})
10481061
} catch (err) {
10491062
let e = err
10501063

packages/driver/src/multidomain/index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,19 @@ export const initialize = (autWindow) => {
4040
timeout () {},
4141
})
4242

43-
$Commands.create(Cypress, cy, Cypress.state)
43+
$Commands.create(Cypress, cy, Cypress.state, Cypress.config)
44+
45+
window.addEventListener('message', (event) => {
46+
if (event.data && event.data.message === 'run:in:domain') {
47+
const stringifiedTestFn = event.data.data
48+
49+
autWindow.eval(`(${stringifiedTestFn})()`)
50+
}
51+
}, false)
52+
53+
top.postMessage('cross:domain:driver:ready', '*')
54+
55+
autWindow.cy = cy
4456

4557
return {
4658
cy,

packages/runner/multidomain/index.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
import { initialize } from '@packages/driver/src/multidomain'
22

3-
const autWindow = window.parent.frames[0]
4-
5-
const { cy } = initialize(autWindow)
6-
7-
autWindow.onReady = () => {
8-
cy.now('get', 'p').then(($el) => {
9-
// eslint-disable-next-line no-console
10-
console.log('got the paragaph with text:', $el.text())
11-
})
12-
}
3+
initialize(window.parent.frames[0])
134

145
/*
156

0 commit comments

Comments
 (0)