Skip to content

Commit 30d7917

Browse files
authored
fix: UNIFY-1389 proper absolute pathing in stack_utils (#20858)
* fix: UNIFY-1389 proper absolute pathing in stack_utils * Add test for absolute path resolve fix * add failing test for webpack absolute path line * fix for webpack absolute line * confirmed fix for absolute rather than relative path in cy tests
1 parent 2909c93 commit 30d7917

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

packages/driver/cypress/e2e/cypress/stack_utils.cy.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,54 @@ Error: spec iframe stack
262262
])
263263
})
264264

265+
it('strips webpack protocol and maintains absolute path', () => {
266+
$sourceMapUtils.getSourcePosition.returns({
267+
file: 'cypress:////root/absolute/path/some_other_file.ts',
268+
line: 2,
269+
column: 1,
270+
})
271+
272+
$sourceMapUtils.getSourcePosition.onCall(1).returns({
273+
file: 'webpack:////root/absolute/path/cypress/integration/features/source_map_spec.coffee',
274+
line: 4,
275+
column: 3,
276+
})
277+
278+
const sourceStack = $stackUtils.getSourceStack(generatedStack, projectRoot)
279+
280+
expect(sourceStack.sourceMapped).to.equal(`Error: spec iframe stack
281+
at foo.bar (cypress:////root/absolute/path/some_other_file.ts:2:2)
282+
at Context.<anonymous> (webpack:////root/absolute/path/cypress/integration/features/source_map_spec.coffee:4:4)\
283+
`)
284+
285+
expect(sourceStack.parsed).to.eql([
286+
{
287+
message: 'Error: spec iframe stack',
288+
whitespace: '',
289+
},
290+
{
291+
function: 'foo.bar',
292+
fileUrl: 'http://localhost:1234/source_map_spec.js',
293+
originalFile: 'cypress:////root/absolute/path/some_other_file.ts',
294+
relativeFile: '/root/absolute/path/some_other_file.ts',
295+
absoluteFile: '/root/absolute/path/some_other_file.ts',
296+
line: 2,
297+
column: 2,
298+
whitespace: ' ',
299+
},
300+
{
301+
function: 'Context.<anonymous>',
302+
fileUrl: 'http://localhost:1234/tests?p=cypress/integration/features/source_map_spec.js',
303+
originalFile: 'webpack:////root/absolute/path/cypress/integration/features/source_map_spec.coffee',
304+
relativeFile: '/root/absolute/path/cypress/integration/features/source_map_spec.coffee',
305+
absoluteFile: '/root/absolute/path/cypress/integration/features/source_map_spec.coffee',
306+
line: 4,
307+
column: 4,
308+
whitespace: ' ',
309+
},
310+
])
311+
})
312+
265313
it('returns empty object if there\'s no stack', () => {
266314
expect($stackUtils.getSourceStack()).to.eql({})
267315
})
@@ -364,6 +412,27 @@ Error: spec iframe stack
364412
expect(details.relativeFile).to.equal('cypress/integration/spec%with space &^$ emoji👍_你好.js')
365413
expect(details.absoluteFile).to.equal(`${projectRoot}/cypress/integration/spec%with space &^$ emoji👍_你好.js`)
366414
})
415+
416+
it('maintains absolute path when provided', () => {
417+
cy.stub($sourceMapUtils, 'getSourcePosition').returns({
418+
file: '/root/path/cypress/integration/spec.js',
419+
line: 1,
420+
column: 0,
421+
})
422+
423+
// stack is fairly irrelevant in this test - testing transforming getSourcePosition response
424+
const stack = stripIndent`
425+
Error
426+
at Object../cypress/integration/spec.js (http://localhost:50129/__cypress/tests?p=/root/path/cypress/integration/spec.js:99:1)
427+
`
428+
429+
const projectRoot = '/Users/gleb/git/cypress-example-todomvc'
430+
const details = $stackUtils.getSourceDetailsForFirstLine(stack, projectRoot)
431+
432+
expect(details.originalFile).to.equal('/root/path/cypress/integration/spec.js')
433+
expect(details.relativeFile).to.equal('/root/path/cypress/integration/spec.js')
434+
expect(details.absoluteFile).to.equal(`/root/path/cypress/integration/spec.js`)
435+
})
367436
})
368437

369438
context('.stackWithUserInvocationStackSpliced', () => {

packages/driver/src/cypress/stack_utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitS
1212

1313
const whitespaceRegex = /^(\s*)*/
1414
const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/
15-
const customProtocolRegex = /^[^:\/]+:\/+/
15+
const customProtocolRegex = /^[^:\/]+:\/{1,3}/
1616
const percentNotEncodedRegex = /%(?![0-9A-F][0-9A-F])/g
1717
const STACK_REPLACEMENT_MARKER = '__stackReplacementMarker'
1818

@@ -318,7 +318,7 @@ const getSourceDetailsForLine = (projectRoot, line): LineDetail => {
318318
fileUrl: generatedDetails.file,
319319
originalFile,
320320
relativeFile,
321-
absoluteFile: (relativeFile && projectRoot) ? path.join(projectRoot, relativeFile) : undefined,
321+
absoluteFile: (relativeFile && projectRoot) ? path.resolve(projectRoot, relativeFile) : undefined,
322322
line: sourceDetails.line,
323323
// adding 1 to column makes more sense for code frame and opening in editor
324324
column: sourceDetails.column + 1,

packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ async function makeE2ETasks () {
103103
let remoteGraphQLIntercept: RemoteGraphQLInterceptor | undefined
104104
let scaffoldedProjects = new Set<string>()
105105

106+
const cachedCwd = process.cwd()
107+
106108
clearCtx()
107109
ctx = setCtx(makeDataContext({ mode: 'open', modeOptions: { cwd: process.cwd() } }))
108110

@@ -133,10 +135,21 @@ async function makeE2ETasks () {
133135
async __internal__before () {
134136
Fixtures.remove()
135137
scaffoldedProjects = new Set()
138+
process.chdir(cachedCwd)
136139

137140
return { launchpadPort }
138141
},
139142

143+
/**
144+
* Force a reset to the correct CWD after all tests have completed, just incase this
145+
* was modified by any code under test.
146+
*/
147+
__internal__after () {
148+
process.chdir(cachedCwd)
149+
150+
return null
151+
},
152+
140153
/**
141154
* Called before each test to do global setup/cleanup
142155
*/

packages/frontend-shared/cypress/e2e/support/e2eSupport.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ beforeEach(() => {
174174
taskInternal('__internal__beforeEach', undefined)
175175
})
176176

177+
after(() => {
178+
taskInternal('__internal__after', undefined)
179+
})
180+
177181
function scaffoldProject (projectName: ProjectFixture, options: { timeout?: number} = {}) {
178182
return logInternal({ name: 'scaffoldProject', message: projectName }, () => {
179183
return taskInternal('__internal_scaffoldProject', projectName, options)

0 commit comments

Comments
 (0)