Skip to content

Conversation

@astone123
Copy link
Contributor

@astone123 astone123 commented Oct 10, 2025

This PR closes https://github.com/cypress-io/cypress-services/issues/11991

Additional details

There are a few cases where we don't correctly derive the test body invocation details from the stack trace. This PR fixes those scenarios by looking for at eval or at Suite.eval in Chrome stack traces, and lines with anonymous functions in Firefox stack traces. This will allow Cypress Studio and "Open in IDE" features to work in more cases than they did before.

One of these situations is when it has been re-written as itGrep which happens in the @cypress/grep and @bahmutov/cy-grep plugins. This allows us to determine the correct invocation details for the test.

Steps to test

I tested this with the @bahmutov/cy-grep package. Install the package and register it in your support file in accordance with the documentation. Open Cypress Studio by clicking the "edit in studio" button next to a test. Verify that the test content is loaded correctly and you can edit and save the test as expected.

How has the user experience changed?

Users of @bahmutov/cy-grep package can now use Cypress studio as intended

PR Tasks


Note

Normalizes test-body invocationDetails by trimming stacks (Chrome/Firefox, including wrapped it), updates reporter to send correct IDE targets, adds comprehensive e2e/unit tests, and updates changelog.

  • Driver:
    • stack_utils: add stackTrimmedToTestInvocation and enhance getInvocationDetails(specWindow, root, 'test') to trim to actual test invocation (Chromium: at eval/at Suite.eval; Firefox: anonymous frame). Export InvocationDetails.
    • mocha.ts: pass 'test' when setting test.invocationDetails.
  • App/Reporter:
    • E2E verifies "Open in IDE" sends correct file/line/column for before hook, basic test body, and wrapped it.
  • Tests:
    • New e2e stack_utils-invocationDetails.cy.ts validating Chrome/Firefox and wrapped it line/column/stack.
    • Unit tests for stack trimming and fallback behavior; add wrapped-it.cy.js fixture.
  • Changelog:
    • Add bugfix noting corrected stack traces used for test invocation details.

Written by Cursor Bugbot for commit 50418a8. This will update automatically on new commits. Configure here.

@astone123 astone123 self-assigned this Oct 10, 2025
@astone123 astone123 closed this Oct 10, 2025
@cypress
Copy link

cypress bot commented Oct 10, 2025

cypress    Run #67355

Run Properties:  status check passed Passed #67355  •  git commit 50418a845c: only modify stacks for e2e tests
Project cypress
Branch Review astone123/fix-itgrep-trace
Run status status check passed Passed #67355
Run duration 19m 13s
Commit git commit 50418a845c: only modify stacks for e2e tests
Committer astone123
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 14
Tests that did not run due to a developer annotating a test with .skip  Pending 1108
Tests that did not run due to a failure in a mocha hook  Skipped 4
Tests that passed  Passing 26602
View all changes introduced in this branch ↗︎

Warning

Partial Report: The results for the Application Quality reports may be incomplete.

UI Coverage  45.48%
  Untested elements 188  
  Tested elements 161  
Accessibility  97.98%
  Failed rules  4 critical   8 serious   2 moderate   2 minor
  Failed elements 101  

@astone123
Copy link
Contributor Author

@mschile @mabela416
After looking at fixing this on the cloud side for a bit, I think the best way to handle the grep stack issue is with a solution like this on the app side. We use the invocation details in various places across the app to decide which test to focus in studio mode and other things, so normalizing the stack on the cloud side doesn't fix the issue entirely. Let me know what you think

@astone123 astone123 reopened this Oct 28, 2025
@astone123 astone123 requested a review from mabela416 October 28, 2025 13:07
Copy link
Contributor

@mabela416 mabela416 left a comment

Choose a reason for hiding this comment

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

I tested it locally and it works

}
}

// if the stack includes the 'itGrep' function, remove any lines that include it
Copy link
Contributor

Choose a reason for hiding this comment

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

Likely good to reference what itGrep is and where it is coming from (same with above) https://github.com/cypress-io/cypress/blob/develop/npm/grep/src/register.ts#L77. people who aren't familiar with @cypress/grep will struggle to understand what this means.

The other concern I have is that there could be something legitimate in the stack that has itGrep in it that we want to capture but are omitting it here. Or is this only considered when trying to calculate the row/column in the spec file where the error occurred?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment there. I'm pretty sure this function is specifically used to identify where the test was executed from, so this shouldn't affect anything else. If it does, it'll be limited to use of the grep plugin

@astone123
Copy link
Contributor Author

@mschile I updated this so that it works for tests with .only as well as tests that are nested in suite definitions

@astone123 astone123 changed the title fix: (studio) remove itGrep lines from stack trace when determining invocationDetails fix: normalize test body invocationDetails from stack traces Nov 6, 2025
@astone123 astone123 requested a review from AtofStryker November 7, 2025 15:57
line.trim().startsWith('at eval') ||
line.trim().startsWith('at Suite.eval')
)
})
Copy link

Choose a reason for hiding this comment

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

Bug: Flawed Stack Trimming Breaks Test Debugging

The Chromium stack trimming logic uses startsWith('at eval') and startsWith('at Suite.eval'), which incorrectly matches function names like evalScripts, evaluate, or Suite.evalSomething. This causes the stack to be trimmed at the wrong location, breaking invocation details for tests when such function names appear in the stack trace.

Fix in Cursor Fix in Web

Copy link
Contributor

Choose a reason for hiding this comment

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

Can probably add a space to at eval and at Suit.eval

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call, added a space to the end of those

@astone123 astone123 requested a review from mschile November 13, 2025 16:22
Comment on lines 71 to 73
// There are cases where there are other lines in the stack trace before the invocation (eg. `context.it.only`, `createRunnable`, etc)
// The actual test invocation line starts with either 'at eval' or 'at Suite.eval',
// so remove all lines until we reach the test invocation line
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// There are cases where there are other lines in the stack trace before the invocation (eg. `context.it.only`, `createRunnable`, etc)
// The actual test invocation line starts with either 'at eval' or 'at Suite.eval',
// so remove all lines until we reach the test invocation line
// The actual test invocation line starts with either 'at eval' or 'at Suite.eval',
// so remove all lines until we reach the test invocation line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

})

// if we removed all the lines then something went wrong. return the original stack instead
if (modifiedStack.trim() === 'Error') {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems brittle, I think in the stackWithLinesRemoved callback above, you can create a copy of the lines and then do your processing on that copy. Before returning lines, you can check if all of the lines were removed and if they were, you can return the original lines, otherwise return the copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated this to create a copy of the lines and check to make sure there are lines in the copy before returning it

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this spec is correct (possibly AI generated nonsense?).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed this spec in favor of packages/driver/cypress/e2e/cypress/stack_utils-invocationDetails.cy.ts

Copy link
Contributor

Choose a reason for hiding this comment

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

We also have an existing stack_utils.cy.js file that we can add to for any getInvocationDetails tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ended up making a separate spec for these instead of adding them to stack_utils.cy.js

@astone123 astone123 requested a review from mschile November 14, 2025 20:02
// if the hook is the test, and it's an e2e test,, we will try to remove the lines that are not the actual invocation of the test
if (type === 'test' && specWindow.Cypress.testingType !== 'component') {
stack = stackTrimmedToTestInvocation(stack, specWindow)
}
Copy link

Choose a reason for hiding this comment

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

Bug: Prevent errors from missing Cypress object.

Accessing specWindow.Cypress.testingType without checking if specWindow.Cypress exists will throw an error when users quickly reload tests, since specWindow.Cypress can be null or undefined in those cases. The check should be inside the existing if (specWindow.Cypress) block or include its own null check.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants