Skip to content

Commit

Permalink
chore(webkit): update error stack parsing and related system tests (#…
Browse files Browse the repository at this point in the history
…23730)

* chore(webkit): update error stack parsing and related system tests

* Adding better comment

* Putting column back. Indexing at 1.

* Let's wait for WebKit fixes to land for this

* Using default name/location values already used in stack enhancing logic

* Incorrect bracket in regex

* Trying without location, as the fake location causes more problems downstream.

* Loosening regex around locations in stack replacement

* Defaulting location sans row/column

* Parsing stack lines for reporter with unique regex

* D'oh

* Making the validation against '<unknown>' more specific

* Don't want a capture group here

* Updating spec_isolation system tests

* Consolidating regex pattern to errors package

* Can just keep this global now

* Simplifying regex. Removing lineAndColumn numbers from unknown locations.

* Updating system test stack regex

* Getting better baseline

* Revert "Updating system test stack regex"

This reverts commit 2b91eff.

* Forking normalization for webkit to track down diffs

* Ensure line or column are set before rendering in enhanced stack

* Need to be a little more flexible

* Tweaking leading newline detection

* Trying out new composed regex

* Few more tweaks for multiple leading newlines and file locations without function name

* Updating remainderOfStack pattern with proper escaping

* Cleaning up comments

* Filtering native code from absolute path logic

* Rebuild CI after outage
  • Loading branch information
tbiethman committed Sep 12, 2022
1 parent 282e6c0 commit 405e7f7
Show file tree
Hide file tree
Showing 20 changed files with 1,023 additions and 50 deletions.
52 changes: 44 additions & 8 deletions packages/driver/src/cypress/stack_utils.ts
Expand Up @@ -8,12 +8,13 @@ import $utils from './utils'
import $sourceMapUtils from './source_map_utils'

// Intentionally deep-importing from @packages/errors so as to not bundle the entire @packages/errors in the client unnecessarily
import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack } from '@packages/errors/src/stackUtils'
import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack, stackLineRegex } from '@packages/errors/src/stackUtils'

const whitespaceRegex = /^(\s*)*/
const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/
const customProtocolRegex = /^[^:\/]+:\/{1,3}/
const percentNotEncodedRegex = /%(?![0-9A-F][0-9A-F])/g
const webkitStackLineRegex = /(.*)@(.*)(\n?)/g

const STACK_REPLACEMENT_MARKER = '__stackReplacementMarker'

const hasCrossFrameStacks = (specWindow) => {
Expand Down Expand Up @@ -244,9 +245,7 @@ const cleanFunctionName = (functionName) => {
}

const parseLine = (line) => {
const isStackLine = stackLineRegex.test(line)

if (!isStackLine) return
if (!stackLineRegex.test(line)) return

const parsed = errorStackParser.parse({ stack: line } as any)[0]

Expand Down Expand Up @@ -318,7 +317,14 @@ const getSourceDetailsForLine = (projectRoot, line): LineDetail => {

let absoluteFile

if (relativeFile && projectRoot) {
// WebKit stacks may include an `<unknown>` or `[native code]` location that is not navigable.
// We ensure that the absolute path is not set in this case.

const canBuildAbsolutePath = relativeFile && projectRoot && (
!Cypress.isBrowser('webkit') || (relativeFile !== '<unknown>' && relativeFile !== '[native code]')
)

if (canBuildAbsolutePath) {
absoluteFile = path.resolve(projectRoot, relativeFile)

// rollup-plugin-node-builtins/src/es6/path.js only support POSIX, we have
Expand Down Expand Up @@ -356,7 +362,9 @@ const reconstructStack = (parsedStack) => {

const { whitespace, originalFile, function: fn, line, column } = parsedLine

return `${whitespace}at ${fn} (${originalFile || '<unknown>'}:${line}:${column})`
const lineAndColumn = (Number.isInteger(line) || Number.isInteger(column)) ? `:${line}:${column}` : ''

return `${whitespace}at ${fn} (${originalFile || '<unknown>'}${lineAndColumn})`
}).join('\n').trimEnd()
}

Expand Down Expand Up @@ -392,7 +400,35 @@ const normalizedStack = (err) => {
// Chromium-based errors do, so we normalize them so that the stack
// always includes the name/message
const errString = err.toString()
const errStack = err.stack || ''
let errStack = err.stack || ''

if (Cypress.isBrowser('webkit')) {
// WebKit will not determine the proper stack trace for an error, with stack entries
// missing function names, call locations, or both. This is due to a number of documented
// issues with WebKit:
// https://bugs.webkit.org/show_bug.cgi?id=86493
// https://bugs.webkit.org/show_bug.cgi?id=243668
// https://bugs.webkit.org/show_bug.cgi?id=174380
//
// We update these stack entries with placeholder names/locations to more closely align
// the output with other browsers, minimizing the visual impact to the stack traces we render
// within the command log and console and ensuring that the stacks can be identified within
// and parsed out of test snapshots that include them.
errStack = errStack.replaceAll(webkitStackLineRegex, (match, ...parts: string[]) => {
// We patch WebKit's Error within the AUT as CyWebKitError, causing it to
// be presented within the stack. If we detect it within the stack, we remove it.
if (parts[0] === '__CyWebKitError') {
return ''
}

return [
parts[0] || '<unknown>',
'@',
parts[1] || '<unknown>',
parts[2],
].join('')
})
}

// the stack has already been normalized and normalizing the indentation
// again could mess up the whitespace
Expand Down
2 changes: 1 addition & 1 deletion packages/errors/src/stackUtils.ts
@@ -1,7 +1,7 @@
import _ from 'lodash'
import type { ErrorLike } from './errorTypes'

const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/
export const stackLineRegex = /^\s*(at )?.*@?(?:\(?.*(?::\d+:\d+|<unknown>|\[native code\])+\)?)$/

type MessageLines = [string[], string[]] & {messageEnded?: boolean}

Expand Down
4 changes: 3 additions & 1 deletion packages/reporter/src/errors/error-stack.tsx
Expand Up @@ -76,7 +76,9 @@ const ErrorStack = observer(({ err }: Props) => {
)

if (dontLink) {
return makeLine(key, [whitespace, `at ${fn} (${originalFile}:${line}:${column})`])
const lineAndColumn = (Number.isInteger(line) || Number.isInteger(column)) ? `:${line}:${column}` : ''

return makeLine(key, [whitespace, `at ${fn} (${originalFile}${lineAndColumn})`])
}

const link = (
Expand Down

5 comments on commit 405e7f7

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 405e7f7 Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.8.0/linux-x64/develop-405e7f7ccba1831aa08da5915e7c45ca2ab9e6a3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 405e7f7 Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.8.0/linux-arm64/develop-405e7f7ccba1831aa08da5915e7c45ca2ab9e6a3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 405e7f7 Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.8.0/win32-x64/develop-405e7f7ccba1831aa08da5915e7c45ca2ab9e6a3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 405e7f7 Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.8.0/darwin-arm64/develop-405e7f7ccba1831aa08da5915e7c45ca2ab9e6a3/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 405e7f7 Sep 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.8.0/darwin-x64/develop-405e7f7ccba1831aa08da5915e7c45ca2ab9e6a3/cypress.tgz

Please sign in to comment.