Skip to content

Commit 3e6d6bf

Browse files
chore: Updates based on PR feedback (#21137)
* add generic to cy.origin type * fix log type, update/add comments * fix comment indentation * specific generic * move RemoteState to internal types * add on links to experimental flag descriptions * chore: reduce nesting by flipping condition * fix test title * simplify failing log * rename variable * delete error property * fix types * fix type * remove unnecessary todo * update wait test * jquery -> this * update comment * remove vestigial autoRun * use finally * re-throw non-security errors * move back getting index * add new state types * remove unnecessary export * startsWith -> includes * it -> them * update system test * remove use of promise constructor * Revert "remove use of promise constructor" This reverts commit 35ccc28. * log errors from Page.getFrameTree * test if anything breaks when removing optional chaining operator * remove vestigial file * handle queue ending in cross-origin driver * fix coordinates spec * improve chrome/firefox check in extension * improve secure cookie regex * use production mode for cross-origin driver bundle * adding remoteStates.getPrimary * catch and ignore queue errors * remove optional chaining in postMessage handler * removed unnecessary async * update frame tree on cri client reconnect * fix formatting * renaming remoteStates variable * prevent requests from being paused if experimentalSessionAndOrigin flag is off Co-authored-by: Matt Schile <[email protected]>
1 parent ebaaf18 commit 3e6d6bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+447
-342
lines changed

cli/schema/cypress.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@
256256
"experimentalSessionAndOrigin": {
257257
"type": "boolean",
258258
"default": false,
259-
"description": "Enables cross-origin and improved session support, including the `cy.origin` and `cy.session` commands."
259+
"description": "Enables cross-origin and improved session support, including the `cy.origin` and `cy.session` commands. See https://on.cypress.io/origin and https://on.cypress.io/session."
260260
},
261261
"experimentalSourceRewriting": {
262262
"type": "boolean",

cli/types/cypress.d.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,6 @@ declare namespace Cypress {
5656
password: string
5757
}
5858

59-
interface RemoteState {
60-
auth?: Auth
61-
domainName: string
62-
strategy: 'file' | 'http'
63-
origin: string
64-
fileServer: string | null
65-
props: Record<string, any>
66-
}
67-
6859
interface Backend {
6960
/**
7061
* Firefox only: Force Cypress to run garbage collection routines.
@@ -1430,7 +1421,7 @@ declare namespace Cypress {
14301421
* cy.get('h1').should('equal', 'Example Domain')
14311422
* })
14321423
*/
1433-
origin(urlOrDomain: string, fn: () => void): Chainable
1424+
origin<T extends any>(urlOrDomain: string, fn: () => void): Chainable<T>
14341425

14351426
/**
14361427
* Enables running Cypress commands in a secondary origin.
@@ -1441,9 +1432,9 @@ declare namespace Cypress {
14411432
* expect(foo).to.equal('foo')
14421433
* })
14431434
*/
1444-
origin<T>(urlOrDomain: string, options: {
1435+
origin<T, S extends any>(urlOrDomain: string, options: {
14451436
args: T
1446-
}, fn: (args: T) => void): Chainable
1437+
}, fn: (args: T) => void): Chainable<S>
14471438

14481439
/**
14491440
* Get the parent DOM element of a set of DOM elements.
@@ -2846,7 +2837,7 @@ declare namespace Cypress {
28462837
*/
28472838
experimentalInteractiveRunEvents: boolean
28482839
/**
2849-
* Enables cross-origin and improved session support, including the `cy.origin` and `cy.session` commands.
2840+
* Enables cross-origin and improved session support, including the `cy.origin` and `cy.session` commands. See https://on.cypress.io/origin and https://on.cypress.io/session.
28502841
* @default false
28512842
*/
28522843
experimentalSessionAndOrigin: boolean
@@ -2981,7 +2972,6 @@ declare namespace Cypress {
29812972
projectName: string
29822973
projectRoot: string
29832974
proxyUrl: string
2984-
remote: RemoteState
29852975
report: boolean
29862976
reporterRoute: string
29872977
reporterUrl: string
@@ -5766,7 +5756,8 @@ declare namespace Cypress {
57665756
}
57675757

57685758
interface LogConfig extends Timeoutable {
5769-
id: number
5759+
/** Unique id for the log, in the form of '<origin>-<number>' */
5760+
id: string
57705761
/** The JQuery element for the command. This will highlight the command in the main window when debugging */
57715762
$el: JQuery
57725763
/** The scope of the log entry. If child, will appear nested below parents, prefixed with '-' */
@@ -5779,7 +5770,7 @@ declare namespace Cypress {
57795770
message: any
57805771
/** Set to false if you want to control the finishing of the command in the log yourself */
57815772
autoEnd: boolean
5782-
/** Set to false if you want to control the finishing of the command in the log yourself */
5773+
/** Set to true to immediately finish the log */
57835774
end: boolean
57845775
/** Return an object that will be printed in the dev tools console */
57855776
consoleProps(): ObjectLike

packages/driver/cypress/fixtures/auth/index.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@
7070

7171
} else {
7272
const token = JSON.parse(cypressAuthToken)
73-
// ToDo, check for expiry maybe?
74-
7573
// If the token exists, hooray, give them a logout button to destroy the token and refresh.
7674
const tag = document.createElement("p");
7775
const text = document.createTextNode(`Welcome ${token.body.username}`);

packages/driver/cypress/integration/commands/navigation_spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,9 +2344,9 @@ describe('src/cy/commands/navigation', () => {
23442344
}
23452345

23462346
cy.on('command:queue:before:end', () => {
2347-
// force us to become unstable immediately
2348-
// else the beforeunload event fires at the end
2349-
// of the tick which is too late
2347+
// force us to become unstable immediately
2348+
// else the beforeunload event fires at the end
2349+
// of the tick which is too late
23502350
cy.isStable(false, 'testing')
23512351

23522352
win.location.href = '/timeout?ms=100'

packages/driver/cypress/integration/cypress/log_spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ describe('src/cypress/log', function () {
9191
expect(LogUtils.countLogsByTests(tests)).to.equal(6)
9292
})
9393

94-
it('returns zero if there are no agents routes or commands', () => {
94+
it('returns zero if there are no agents, routes, or commands', () => {
9595
const tests = {
9696
a: {
9797
notAThing: true,

packages/driver/cypress/integration/dom/coordinates_spec.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,18 @@ describe('src/dom/coordinates', () => {
238238
}
239239

240240
it('returns true if parent is a window and not an iframe', () => {
241-
const win = getWindowLikeObject()
241+
const win = cy.state('window')
242242

243243
expect(isAUTFrame(win)).to.be.true
244244
})
245245

246-
it('returns true if parent is a window and getting its frameElement property throws an error', () => {
246+
it('returns true if parent is a window and getting its frameElement property throws a cross-origin error', () => {
247247
const win = getWindowLikeObject()
248+
const err = new Error('cross-origin error')
249+
250+
err.name = 'SecurityError'
248251

249-
cy.stub($elements, 'getNativeProp').throws('cross-origin error')
252+
cy.stub($elements, 'getNativeProp').throws(err)
250253

251254
expect(isAUTFrame(win)).to.be.true
252255
})

packages/driver/cypress/integration/e2e/multi-domain/commands/multi_domain_log.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ context('cy.origin log', () => {
1616
})
1717

1818
it('logs in primary and secondary origins', () => {
19-
cy.origin('http://foobar.com:3500', () => {
19+
cy.origin<string>('http://foobar.com:3500', () => {
2020
const afterLogAdded = new Promise<void>((resolve) => {
2121
const listener = (attrs) => {
2222
if (attrs.message === 'test log in cy.origin') {

packages/driver/cypress/integration/e2e/multi-domain/commands/multi_domain_waiting.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ context('cy.origin waiting', () => {
88

99
it('.wait()', () => {
1010
cy.origin('http://foobar.com:3500', () => {
11-
cy.wait(500)
11+
const delay = cy.spy(Cypress.Promise, 'delay')
12+
13+
cy.wait(50).then(() => {
14+
expect(delay).to.be.calledWith(50, 'wait')
15+
})
1216
})
1317
})
1418

packages/driver/cypress/integration/e2e/multi-domain/multi_domain_yield_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ describe('cy.origin yields', () => {
118118
done()
119119
})
120120

121-
cy.origin('http://foobar.com:3500', () => {
121+
cy.origin<JQuery>('http://foobar.com:3500', () => {
122122
cy.get('[data-cy="dom-check"]')
123123
})
124124
.then((subject) => subject.text())
@@ -134,7 +134,7 @@ describe('cy.origin yields', () => {
134134
done()
135135
})
136136

137-
cy.origin('http://foobar.com:3500', () => {
137+
cy.origin<{ key: Function }>('http://foobar.com:3500', () => {
138138
cy.wrap({
139139
key: () => {
140140
return 'whoops'

packages/driver/src/cy/commands/navigation.ts

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import debugFn from 'debug'
1313
const debug = debugFn('cypress:driver:navigation')
1414

1515
let id = null
16-
let previousUrlVisited: LocationObject | undefined
16+
let previouslyVisitedLocation: LocationObject | undefined
1717
let hasVisitedAboutBlank: boolean = false
1818
let currentlyVisitingAboutBlank: boolean = false
1919
let knownCommandCausedInstability: boolean = false
@@ -30,7 +30,7 @@ const reset = (test: any = {}) => {
3030

3131
// continuously reset this
3232
// before each test run!
33-
previousUrlVisited = undefined
33+
previouslyVisitedLocation = undefined
3434

3535
// make sure we reset that we haven't
3636
// visited about blank again
@@ -53,33 +53,7 @@ const timedOutWaitingForPageLoad = (ms, log) => {
5353
const anticipatedCrossOriginHref = cy.state('anticipatingCrossOriginResponse')?.href
5454

5555
// Were we anticipating a cross origin page when we timed out?
56-
if (anticipatedCrossOriginHref) {
57-
// We remain in an anticipating state until either a load even happens or a timeout.
58-
cy.isAnticipatingCrossOriginResponseFor(undefined)
59-
60-
// By default origins is just this location.
61-
let originPolicies = [$Location.create(location.href).originPolicy]
62-
63-
const currentCommand = cy.queue.state('current')
64-
65-
if (currentCommand?.get('name') === 'origin') {
66-
// If the current command is a cy.origin command, we should have gotten a request on the origin it expects.
67-
originPolicies = [cy.state('latestActiveOriginPolicy')]
68-
} else if (Cypress.isCrossOriginSpecBridge && cy.queue.isOnLastCommand()) {
69-
// If this is a cross origin spec bridge and we're on the last command, we should have gotten a request on the origin of one of the parents.
70-
originPolicies = cy.state('parentOriginPolicies')
71-
}
72-
73-
$errUtils.throwErrByPath('navigation.cross_origin_load_timed_out', {
74-
args: {
75-
configFile: Cypress.config('configFile'),
76-
ms,
77-
crossOriginUrl: $Location.create(anticipatedCrossOriginHref),
78-
originPolicies,
79-
},
80-
onFail: log,
81-
})
82-
} else {
56+
if (!anticipatedCrossOriginHref) {
8357
$errUtils.throwErrByPath('navigation.timed_out', {
8458
args: {
8559
configFile: Cypress.config('configFile'),
@@ -88,9 +62,35 @@ const timedOutWaitingForPageLoad = (ms, log) => {
8862
onFail: log,
8963
})
9064
}
65+
66+
// We remain in an anticipating state until either a load even happens or a timeout.
67+
cy.isAnticipatingCrossOriginResponseFor(undefined)
68+
69+
// By default origins is just this location.
70+
let originPolicies = [$Location.create(location.href).originPolicy]
71+
72+
const currentCommand = cy.queue.state('current')
73+
74+
if (currentCommand?.get('name') === 'origin') {
75+
// If the current command is a cy.origin command, we should have gotten a request on the origin it expects.
76+
originPolicies = [cy.state('latestActiveOriginPolicy')]
77+
} else if (Cypress.isCrossOriginSpecBridge && cy.queue.isOnLastCommand()) {
78+
// If this is a cross origin spec bridge and we're on the last command, we should have gotten a request on the origin of one of the parents.
79+
originPolicies = cy.state('parentOriginPolicies')
80+
}
81+
82+
$errUtils.throwErrByPath('navigation.cross_origin_load_timed_out', {
83+
args: {
84+
configFile: Cypress.config('configFile'),
85+
ms,
86+
crossOriginUrl: $Location.create(anticipatedCrossOriginHref),
87+
originPolicies,
88+
},
89+
onFail: log,
90+
})
9191
}
9292

93-
const cannotVisitDifferentOrigin = ({ remote, existing, originalUrl, previousUrlVisited, log, isCrossOriginSpecBridge = false }) => {
93+
const cannotVisitDifferentOrigin = ({ remote, existing, originalUrl, previouslyVisitedLocation, log, isCrossOriginSpecBridge = false }) => {
9494
const differences: string[] = []
9595

9696
if (remote.protocol !== existing.protocol) {
@@ -109,7 +109,7 @@ const cannotVisitDifferentOrigin = ({ remote, existing, originalUrl, previousUrl
109109
onFail: log,
110110
args: {
111111
differences: differences.join(', '),
112-
previousUrl: previousUrlVisited,
112+
previousUrl: previouslyVisitedLocation,
113113
attemptedUrl: remote,
114114
originalUrl,
115115
isCrossOriginSpecBridge,
@@ -123,12 +123,12 @@ const cannotVisitDifferentOrigin = ({ remote, existing, originalUrl, previousUrl
123123
$errUtils.throwErrByPath('visit.cannot_visit_different_origin', errOpts)
124124
}
125125

126-
const cannotVisitPreviousOrigin = ({ remote, originalUrl, previousUrlVisited, log }) => {
126+
const cannotVisitPreviousOrigin = ({ remote, originalUrl, previouslyVisitedLocation, log }) => {
127127
const errOpts = {
128128
onFail: log,
129129
args: {
130130
attemptedUrl: remote,
131-
previousUrl: previousUrlVisited,
131+
previousUrl: previouslyVisitedLocation,
132132
originalUrl,
133133
},
134134
errProps: {
@@ -434,9 +434,7 @@ const stabilityChanged = (Cypress, state, config, stable) => {
434434
}
435435

436436
const onCrossOriginFailure = (err) => {
437-
options._log.set('message', '--page loaded--').snapshot().end()
438-
options._log.set('state', 'failed')
439-
options._log.set('error', err)
437+
options._log.set('message', '--page loaded--').snapshot().error(err)
440438

441439
resolve()
442440
}
@@ -526,6 +524,7 @@ type InvalidContentTypeError = Error & {
526524

527525
interface InternalVisitOptions extends Partial<Cypress.VisitOptions> {
528526
_log?: Log
527+
hasAlreadyVisitedUrl: boolean
529528
}
530529

531530
export default (Commands, Cypress, cy, state, config) => {
@@ -852,7 +851,7 @@ export default (Commands, Cypress, cy, state, config) => {
852851
onLoad () {},
853852
})
854853

855-
options.hasAlreadyVisitedUrl = !!previousUrlVisited
854+
options.hasAlreadyVisitedUrl = !!previouslyVisitedLocation
856855

857856
if (!_.isUndefined(options.qs) && !_.isObject(options.qs)) {
858857
$errUtils.throwErrByPath('visit.invalid_qs', { args: { qs: String(options.qs) } })
@@ -1125,7 +1124,7 @@ export default (Commands, Cypress, cy, state, config) => {
11251124
// if the origin currently matches
11261125
// then go ahead and change the iframe's src
11271126
if (remote.originPolicy === existing.originPolicy) {
1128-
previousUrlVisited = remote
1127+
previouslyVisitedLocation = remote
11291128

11301129
url = $Location.fullyQualifyUrl(url)
11311130

@@ -1138,10 +1137,10 @@ export default (Commands, Cypress, cy, state, config) => {
11381137
// if we've already cy.visit'ed in the test and we are visiting a new origin,
11391138
// throw an error, else we'd be in a endless loop,
11401139
// we also need to disable retries to prevent the endless loop
1141-
if (previousUrlVisited) {
1140+
if (previouslyVisitedLocation) {
11421141
$utils.getTestFromRunnable(state('runnable'))._retries = 0
11431142

1144-
const params = { remote, existing, originalUrl, previousUrlVisited, log: options._log }
1143+
const params = { remote, existing, originalUrl, previouslyVisitedLocation, log: options._log }
11451144

11461145
return cannotVisitDifferentOrigin(params)
11471146
}
@@ -1151,7 +1150,7 @@ export default (Commands, Cypress, cy, state, config) => {
11511150
// origin which isn't allowed within a cy.origin block
11521151
if (Cypress.isCrossOriginSpecBridge) {
11531152
const existingAutOrigin = win ? $Location.create(win.location.href) : $Location.create(Cypress.state('currentActiveOriginPolicy'))
1154-
const params = { remote, existing, originalUrl, previousUrlVisited: existingAutOrigin, log: options._log, isCrossOriginSpecBridge: true, isPrimaryOrigin }
1153+
const params = { remote, existing, originalUrl, previouslyVisitedLocation: existingAutOrigin, log: options._log, isCrossOriginSpecBridge: true, isPrimaryOrigin }
11551154

11561155
return isPrimaryOrigin ? cannotVisitPreviousOrigin(params) : cannotVisitDifferentOrigin(params)
11571156
}
@@ -1238,6 +1237,7 @@ export default (Commands, Cypress, cy, state, config) => {
12381237
// not a network failure, and we should throw the original error
12391238
if (err.isCallbackError || err.isCrossOrigin) {
12401239
delete err.isCallbackError
1240+
delete err.isCrossOrigin
12411241
throw err
12421242
}
12431243

packages/driver/src/cy/location.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const create = (state) => ({
1515
return location
1616
} catch (e) {
1717
// it is possible we do not have access to the location
18-
// for example, if the app has redirected to a 2nd origin
18+
// for example, if the app has redirected to a different origin
1919
return ''
2020
}
2121
},

packages/driver/src/cypress/command_queue.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,15 @@ export class CommandQueue extends Queue<Command> {
262262
// @ts-ignore
263263
run () {
264264
const next = () => {
265-
// start at 0 index if one is not already set
266-
let index = this.state('index') || this.state('index', 0)
267-
268265
// bail if we've been told to abort in case
269266
// an old command continues to run after
270267
if (this.stopped) {
271268
return
272269
}
273270

271+
// start at 0 index if one is not already set
272+
let index = this.state('index') || this.state('index', 0)
273+
274274
const command = this.at(index)
275275

276276
// if the command should be skipped, just bail and increment index

0 commit comments

Comments
 (0)