Skip to content

Commit 22737d2

Browse files
chore: create infrastructure to support backend function in cy.prompt (#31803)
* chore: add promptBackend as an additional Cypress-attached function * Update packages/app/src/runner/event-manager.ts * update types * fix types * fix spacing * refactor * additional refactor * fix type build * fix build * refactor * reword messages * fix * debugging * undo debugging * PR comment * fix tests * fix tests * fix tests * fix test
1 parent ebba6e4 commit 22737d2

File tree

22 files changed

+237
-174
lines changed

22 files changed

+237
-174
lines changed

cli/types/cypress.d.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,11 +1826,6 @@ declare namespace Cypress {
18261826
*/
18271827
prevUntil<E extends Node = HTMLElement>(element: E | JQuery<E>, filter?: string, options?: Partial<Loggable & Timeoutable>): Chainable<JQuery<E>>
18281828

1829-
/**
1830-
* TODO: add docs
1831-
*/
1832-
prompt(message: string, options?: Partial<Loggable & Timeoutable>): Chainable<Subject>
1833-
18341829
/**
18351830
* Read a file and yield its contents.
18361831
*
@@ -3163,11 +3158,6 @@ declare namespace Cypress {
31633158
* @default false
31643159
*/
31653160
experimentalStudio: boolean
3166-
/**
3167-
* Enables the prompt command feature.
3168-
* @default false
3169-
*/
3170-
experimentalPromptCommand: boolean
31713161
/**
31723162
* Adds support for testing in the WebKit browser engine used by Safari. See https://on.cypress.io/webkit-experiment for more information.
31733163
* @default false

packages/app/src/runner/event-manager.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -798,21 +798,7 @@ export class EventManager {
798798
},
799799
)
800800

801-
/**
802-
* Call a backend request for the requesting spec bridge since we cannot have websockets in the spec bridges.
803-
* Return it's response.
804-
*/
805-
Cypress.primaryOriginCommunicator.on('backend:request', async ({ args }, { source, responseEvent }) => {
806-
let response
807-
808-
try {
809-
response = await Cypress.backend(...args)
810-
} catch (error) {
811-
response = { error }
812-
}
813-
814-
Cypress.primaryOriginCommunicator.toSource(source, responseEvent, response)
815-
})
801+
Cypress.handlePrimaryOriginSocketEvent(Cypress, 'backend:request')
816802

817803
/**
818804
* Call an automation request for the requesting spec bridge since we cannot have websockets in the spec bridges.

packages/driver/cypress.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const baseConfig: Cypress.ConfigOptions = {
77
experimentalStudio: true,
88
experimentalMemoryManagement: true,
99
experimentalWebKitSupport: true,
10+
// @ts-expect-error - this will not error when we actually release the experimentalPromptCommand flag
1011
experimentalPromptCommand: true,
1112
hosts: {
1213
'foobar.com': '127.0.0.1',

packages/driver/cypress/e2e/commands/prompt.cy.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@ describe('src/cy/commands/prompt', () => {
77
return
88
}
99

10-
cy.visit('/fixtures/dom.html')
10+
cy.visit('http://www.foobar.com:3500/fixtures/dom.html')
1111

1212
// TODO: add more tests when cy.prompt is built out, but for now this just
1313
// verifies that the command executes without throwing an error
14+
// @ts-expect-error - this will not error when we actually release the experimentalPromptCommand flag
1415
cy.prompt('Hello, world!')
16+
17+
cy.visit('http://www.barbaz.com:3500/fixtures/dom.html')
18+
19+
cy.origin('http://www.barbaz.com:3500', () => {
20+
// @ts-expect-error - this will not error when we actually release the experimentalPromptCommand flag
21+
cy.prompt('Hello, world!')
22+
})
1523
})
1624
})

packages/driver/cypress/e2e/e2e/origin/patches.cy.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
6363
describe('from the AUT', () => {
6464
beforeEach(() => {
6565
cy.intercept('/test-request').as('testRequest')
66-
cy.stub(Cypress, 'backend').log(false).callThrough()
66+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
6767

6868
cy.visit('/fixtures/primary-origin.html')
6969
cy.get('a[data-cy="xhr-fetch-requests"]').click()
@@ -87,7 +87,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
8787

8888
cy.wait('@testRequest')
8989
cy.then(() => {
90-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
90+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
9191
url: 'http://www.foobar.com:3500/test-request',
9292
resourceType: 'fetch',
9393
credentialStatus: assertCredentialStatus,
@@ -107,7 +107,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
107107

108108
cy.wait('@testRequest')
109109
cy.then(() => {
110-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
110+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
111111
url: 'http://www.foobar.com:3500/test-request',
112112
resourceType: 'fetch',
113113
credentialStatus: assertCredentialStatus,
@@ -127,7 +127,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
127127

128128
cy.wait('@testRequest')
129129
cy.then(() => {
130-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
130+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
131131
url: 'http://www.foobar.com:3500/test-request',
132132
resourceType: 'fetch',
133133
credentialStatus: assertCredentialStatus,
@@ -152,7 +152,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
152152
)
153153

154154
cy.then(() => {
155-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
155+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
156156
})
157157
})
158158

@@ -171,7 +171,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
171171
)
172172

173173
cy.then(() => {
174-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
174+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
175175
url: 'http://app.foobar.com:3500/test-request',
176176
resourceType: 'fetch',
177177
credentialStatus: 'include',
@@ -184,7 +184,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
184184
describe('from the spec bridge', () => {
185185
beforeEach(() => {
186186
cy.intercept('/test-request').as('testRequest')
187-
cy.stub(Cypress, 'backend').log(false).callThrough()
187+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
188188

189189
cy.visit('/fixtures/primary-origin.html')
190190
cy.get('a[data-cy="xhr-fetch-requests"]').click()
@@ -216,7 +216,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
216216
})
217217

218218
cy.then(() => {
219-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
219+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
220220
url: 'http://www.foobar.com:3500/test-request-credentials',
221221
resourceType: 'fetch',
222222
credentialStatus: assertCredentialStatus,
@@ -246,7 +246,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
246246
})
247247

248248
cy.then(() => {
249-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
249+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
250250
url: 'http://www.foobar.com:3500/test-request-credentials',
251251
resourceType: 'fetch',
252252
credentialStatus: assertCredentialStatus,
@@ -274,7 +274,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
274274
})
275275

276276
cy.then(() => {
277-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
277+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
278278
url: 'http://www.foobar.com:3500/test-request-credentials',
279279
resourceType: 'fetch',
280280
credentialStatus: assertCredentialStatus,
@@ -297,7 +297,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
297297
})
298298

299299
cy.then(() => {
300-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
300+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
301301
})
302302
})
303303
})
@@ -326,7 +326,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
326326
})
327327

328328
cy.then(() => {
329-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
329+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
330330
url: 'http://app.foobar.com:3500/test-request',
331331
resourceType: 'fetch',
332332
credentialStatus: 'include',
@@ -339,13 +339,13 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
339339
// manually remove the spec bridge iframe to ensure Cypress.state('window') is not already set
340340
window.top?.document.getElementById('Spec\ Bridge:\ foobar.com')?.remove()
341341

342-
cy.stub(Cypress, 'backend').log(false).callThrough()
342+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
343343

344344
cy.visit('/fixtures/primary-origin.html')
345345
cy.get('a[data-cy="xhr-fetch-requests-onload"]').click()
346346

347347
cy.then(() => {
348-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
348+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
349349
url: 'http://localhost:3500/foo.bar.baz.json',
350350
resourceType: 'fetch',
351351
credentialStatus: 'same-origin',
@@ -354,7 +354,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
354354
})
355355

356356
it('does not patch fetch in the spec window or the AUT if the AUT is on the primary', () => {
357-
cy.stub(Cypress, 'backend').log(false).callThrough()
357+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
358358
cy.visit('fixtures/xhr-fetch-requests.html')
359359

360360
cy.window().then((win) => {
@@ -371,14 +371,14 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
371371
cy.then(async () => {
372372
await fetch('/test-request')
373373

374-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
374+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('request:sent:with:credentials')
375375
})
376376

377377
// expect AUT to NOT be patched in primary
378378
cy.window().then(async (win) => {
379379
await win.fetch('/test-request')
380380

381-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
381+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('request:sent:with:credentials')
382382
})
383383
})
384384
})
@@ -387,7 +387,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
387387
describe('from the AUT', () => {
388388
beforeEach(() => {
389389
cy.intercept('/test-request').as('testRequest')
390-
cy.stub(Cypress, 'backend').log(false).callThrough()
390+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
391391

392392
cy.visit('/fixtures/primary-origin.html')
393393
cy.get('a[data-cy="xhr-fetch-requests"]').click()
@@ -409,7 +409,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
409409

410410
cy.wait('@testRequest')
411411
cy.then(() => {
412-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
412+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
413413
url: 'http://www.foobar.com:3500/test-request',
414414
resourceType: 'xhr',
415415
credentialStatus: withCredentials,
@@ -431,7 +431,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
431431
})
432432

433433
cy.then(() => {
434-
expect(Cypress.backend).to.have.been.calledWithMatch('request:sent:with:credentials')
434+
expect(Cypress.backendRequestHandler).to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
435435
})
436436
})
437437
})
@@ -449,7 +449,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
449449
})
450450

451451
cy.then(() => {
452-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
452+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
453453
url: 'http://app.foobar.com:3500/test-request',
454454
resourceType: 'xhr',
455455
credentialStatus: true,
@@ -461,9 +461,9 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
461461
describe('from the spec bridge', () => {
462462
beforeEach(() => {
463463
cy.intercept('/test-request').as('testRequest')
464-
cy.stub(Cypress, 'backend').log(false).callThrough()
464+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
465465
cy.origin('http://www.foobar.com:3500', () => {
466-
cy.stub(Cypress, 'backend').log(false).callThrough()
466+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
467467
})
468468

469469
cy.visit('/fixtures/primary-origin.html')
@@ -501,7 +501,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
501501
})
502502

503503
cy.then(() => {
504-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
504+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
505505
url: 'http://www.foobar.com:3500/test-request-credentials',
506506
resourceType: 'xhr',
507507
credentialStatus: withCredentials,
@@ -523,7 +523,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
523523
})
524524

525525
cy.then(() => {
526-
expect(Cypress.backend).to.have.been.calledWithMatch('request:sent:with:credentials')
526+
expect(Cypress.backendRequestHandler).to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
527527
})
528528
})
529529

@@ -553,7 +553,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
553553
})
554554

555555
cy.then(() => {
556-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
556+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
557557
url: 'http://app.foobar.com:3500/test-request',
558558
resourceType: 'xhr',
559559
credentialStatus: true,
@@ -567,13 +567,13 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
567567
// manually remove the spec bridge iframe to ensure Cypress.state('window') is not already set
568568
window.top?.document.getElementById('Spec\ Bridge:\ foobar.com')?.remove()
569569

570-
cy.stub(Cypress, 'backend').log(false).callThrough()
570+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
571571

572572
cy.visit('/fixtures/primary-origin.html')
573573
cy.get('a[data-cy="xhr-fetch-requests-onload"]').click()
574574

575575
cy.then(() => {
576-
expect(Cypress.backend).to.have.been.calledWith('request:sent:with:credentials', {
576+
expect(Cypress.backendRequestHandler).to.have.been.calledWith('backend:request', 'request:sent:with:credentials', {
577577
url: 'http://localhost:3500/foo.bar.baz.json',
578578
resourceType: 'xhr',
579579
credentialStatus: false,
@@ -582,7 +582,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
582582
})
583583

584584
it('does not patch xmlHttpRequest in the spec window or the AUT if the AUT is on the primary', () => {
585-
cy.stub(Cypress, 'backend').log(false).callThrough()
585+
cy.stub(Cypress, 'backendRequestHandler').log(false).callThrough()
586586
cy.visit('fixtures/xhr-fetch-requests.html')
587587

588588
cy.window().then((win) => {
@@ -614,7 +614,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
614614
xhr.send()
615615
})
616616

617-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
617+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
618618
})
619619

620620
// expect AUT to NOT be patched in primary
@@ -636,7 +636,7 @@ describe('src/cross-origin/patches', { browser: '!webkit', defaultCommandTimeout
636636
xhr.send()
637637
})
638638

639-
expect(Cypress.backend).not.to.have.been.calledWithMatch('request:sent:with:credentials')
639+
expect(Cypress.backendRequestHandler).not.to.have.been.calledWithMatch('backend:request', 'request:sent:with:credentials')
640640
})
641641
})
642642
})

packages/driver/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"chai-subset": "1.6.0",
5454
"clone": "2.1.2",
5555
"common-tags": "1.8.0",
56+
"component-emitter": "1.3.0",
5657
"compression": "1.8.0",
5758
"cookie-parser": "1.4.5",
5859
"core-js-pure": "3.21.0",

packages/driver/src/cross-origin/communicator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ export class SpecBridgeCommunicator extends EventEmitter {
336336
}: {
337337
event: string
338338
data?: Cypress.ObjectLike
339-
options: {syncGlobals: boolean}
339+
options?: {syncGlobals: boolean}
340340
timeout: number
341341
}) {
342342
return new Promise<T>((resolve, reject) => {

packages/driver/src/cross-origin/cypress.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { bindToListeners } from '../cy/listeners'
1414
import { handleOriginFn } from './origin_fn'
1515
import { FINAL_SNAPSHOT_NAME } from '../cy/snapshots'
1616
import { handleLogs } from './events/logs'
17-
import { handleSocketEvents } from './events/socket'
17+
import { handleCrossOriginSocketEvent, handleDefaultCrossOriginSocketEvents } from './events/socket'
1818
import { handleSpecWindowEvents } from './events/spec_window'
1919
import { handleErrorEvent } from './events/errors'
2020
import { handleScreenshots } from './events/screenshots'
@@ -120,6 +120,12 @@ const setup = ({ cypressConfig, env, isProtocolEnabled }: { cypressConfig: Cypre
120120

121121
const { state, config } = Cypress
122122

123+
// These need to happen before the commands are created so that commands can
124+
// use things like Cypress.backend during their creation.
125+
handleDefaultCrossOriginSocketEvents(Cypress)
126+
127+
Cypress.handleCrossOriginSocketEvent = handleCrossOriginSocketEvent
128+
123129
// @ts-ignore
124130
Cypress.Commands = $Commands.create(Cypress, cy, state, config)
125131
// @ts-ignore
@@ -141,7 +147,6 @@ const setup = ({ cypressConfig, env, isProtocolEnabled }: { cypressConfig: Cypre
141147

142148
handleOriginFn(Cypress, cy)
143149
handleLogs(Cypress)
144-
handleSocketEvents(Cypress)
145150
handleSpecWindowEvents(cy)
146151
handleMiscEvents(Cypress, cy)
147152
handleScreenshots(Cypress)

0 commit comments

Comments
 (0)