Skip to content

Commit 4c0371f

Browse files
fix: Handle evaled privileged commands (#27267)
1 parent 32cfa50 commit 4c0371f

3 files changed

Lines changed: 54 additions & 5 deletions

File tree

cli/CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
2+
## 12.17.2
3+
4+
_Released 07/18/2023 (PENDING)_
5+
6+
**Bugfixes:**
7+
8+
- Fixed an issue where `cy.writeFile()` would erroneously fail with the error `cy.writeFile() must only be invoked from the spec file or support file`. Fixes [#27097](https://github.com/cypress-io/cypress/issues/27097).
9+
210
## 12.17.1
311

4-
_Released 07/18/2023_
12+
_Released 07/10/2023_
513

614
**Bugfixes:**
715

packages/driver/cypress/e2e/e2e/privileged_commands.cy.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ describe('privileged commands', () => {
115115
cy.get('#basic').selectFile(Uint8Array.from([98, 97, 122]))
116116
})
117117

118+
it('handles evaled code', () => {
119+
window.eval(`
120+
cy.task('return:arg', 'eval arg')
121+
.then(() => {
122+
cy.task('return:arg', 'then eval arg')
123+
})
124+
125+
cy.get('body')
126+
.each(() => {
127+
cy.task('return:arg', 'each eval arg')
128+
})
129+
.within(() => {
130+
cy.task('return:arg', 'within eval arg')
131+
})
132+
`)
133+
})
134+
118135
it('passes in test body .then() callback', () => {
119136
cy.then(() => {
120137
cy.exec('echo "hello"')

packages/server/lib/privileged-commands/privileged-channel.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
const queryStringRegex = /\?.*$/
3232

33+
let hasValidCallbackContext = false
34+
3335
// since this function is eval'd, the scripts are included as stringified JSON
3436
if (scripts) {
3537
scripts = parse(scripts)
@@ -69,6 +71,18 @@
6971
return filteredLines.length > 0
7072
}
7173

74+
const isInCallback = (err) => {
75+
return stringIncludes.call(err.stack, 'thenFn@') || stringIncludes.call(err.stack, 'withinFn@')
76+
}
77+
78+
const hasCallbackInsideEval = (err) => {
79+
if (browserFamily === 'webkit') {
80+
return isInCallback(err) && hasValidCallbackContext
81+
}
82+
83+
return isInCallback(err) && stringIncludes.call(err.stack, '> eval line')
84+
}
85+
7286
// in non-chromium browsers, the stack will include either the spec file url
7387
// or the support file
7488
const hasStackLinesFromSpecOrSupportFile = (err) => {
@@ -96,16 +110,22 @@
96110
'task',
97111
]
98112

113+
const callbackCommands = [
114+
'each',
115+
'then',
116+
'within',
117+
]
118+
99119
function stackIsFromSpecFrame (err) {
100120
if (isSpecBridge) {
101121
return hasSpecBridgeInvocation(err)
102122
}
103123

104124
if (browserFamily === 'chromium') {
105-
return hasSpecFrameStackLines(err)
125+
return hasStackLinesFromSpecOrSupportFile(err) || hasSpecFrameStackLines(err)
106126
}
107127

108-
return hasStackLinesFromSpecOrSupportFile(err)
128+
return hasCallbackInsideEval(err) || hasStackLinesFromSpecOrSupportFile(err)
109129
}
110130

111131
// source: https://github.com/bryc/code/blob/d0dac1c607a005679799024ff66166e13601d397/jshash/experimental/cyrb53.js
@@ -141,8 +161,6 @@
141161
}
142162

143163
async function onCommandInvocation (command) {
144-
if (!arrayIncludes.call(privilegedCommands, command.name)) return
145-
146164
// message doesn't really matter since we're only interested in the stack
147165
const err = new Err('command stack error')
148166

@@ -152,6 +170,12 @@
152170
captureStackTrace.call(Err, err, onCommandInvocation)
153171
}
154172

173+
if (arrayIncludes.call(callbackCommands, command.name)) {
174+
hasValidCallbackContext = stackIsFromSpecFrame(err)
175+
}
176+
177+
if (!arrayIncludes.call(privilegedCommands, command.name)) return
178+
155179
// if stack is not validated as being from the spec frame, don't add
156180
// it as a verified command
157181
if (!stackIsFromSpecFrame(err)) return

0 commit comments

Comments
 (0)