Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Hovering over mount in command log does not show component in AUT #24346

Merged
merged 17 commits into from
Nov 1, 2022

Conversation

amehta265
Copy link
Contributor

User facing changelog

Previously when hovering over mount in the reporter of a component test, the AUT shows a blank white view instead of the mounted component. This is not ideal if the user wants to see the component that has been mounted by the mount function.
This PR ensures that the snapshot of the mounted component is taken at the current time thereby guaranteeing component being displayed in the AUT

Additional details

  • Upon further investigation this issue only persists for the vue2 and react18 frameworks. For all other frameworks the intended behavior was happening i.e. The mount command shows the mounted component in the AUT.
  • React18 uses the makeMountFn from react under the hood therefore changes had to be made to the mount function inside npm/react/createMount for this framework.
  • The proposed solution involves the use of the .wait and a mutationObserver. Using the .wait(0, ...) allows cypress to wait until the next tick in the event-loop to take a snapshot of the mounted component. This ensures that all the synchronous code (including the actual mounting of the component) has occurred before we attempt to take a snapshot. The mutationObserver listens to the target node (in our case the data-cy-root) to check if any element is added to it. If all the elements are added we can be sure that the component exists on the AUT and can thereby take the screenshot.

Steps to test

The spec file reporter-ct-mount-hover.cy.ts iterates over several projects from system-tests, scaffolds, opens, and runs a spec file within each project while hovering on the mount function in the command log to ensure the intended functionality.

  1. Go to the packages/app
  2. Run yarn cypress:open
  3. Select e2e testing on your preferred browser and navigate to the reporter-ct-mount-hover.cy.ts spec file.
  4. This test iterates over all major frameworks testing hovering over the mount in the command-log ensuring that the component is visible in the AUT.

How has the user experience changed?

Before:
Screen Shot 2022-10-21 at 3 34 50 PM
After:
Screen Shot 2022-10-21 at 3 29 19 PM

PR Tasks

  • Have tests been added/updated?
  • [na] Has the original issue (or this PR, if no issue exists) been tagged with a release in ZenHub? (user-facing changes only)
  • [na] Has a PR for user-facing changes been opened in cypress-documentation?
  • [na] Have API changes been updated in the type definitions?

Adding commit from another branch to the target branch
:
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Oct 21, 2022

Thanks for taking the time to open a PR!

@amehta265 amehta265 requested review from a team and marktnoonan and removed request for marktnoonan October 21, 2022 19:37
@amehta265 amehta265 changed the title completed test and updated functionality fix: Hovering over mount in command log does not show component in AUT Oct 21, 2022
@cypress
Copy link

cypress bot commented Oct 21, 2022



Test summary

46074 0 4497 0Flakiness 20


Run details

Project cypress
Status Passed
Commit 59a6c20
Started Nov 1, 2022 7:33 PM
Ended Nov 1, 2022 7:51 PM
Duration 17:59 💡
OS Linux Debian -
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

cypress/e2e/e2e/origin/cookie_behavior.cy.ts Flakiness
1 ... > same site / cross origin > XMLHttpRequest > sets cookie on same-site request if withCredentials is true, and attaches to same-site request if withCredentials is true
2 ... > same site / cross origin > fetch > sets same-site cookies if "include" credentials option is specified from request, but does not attach same-site cookies to request by default (same-origin)
3 ... > same site / cross origin > XMLHttpRequest > sets cookie on same-site request if withCredentials is true, and attaches to same-site request if withCredentials is true
4 ... > same site / cross origin > fetch > sets same-site cookies if "include" credentials option is specified from request, but does not attach same-site cookies to request by default (same-origin)
5 ... > same site / cross origin > XMLHttpRequest > sets cookie on same-site request if withCredentials is true, and attaches to same-site request if withCredentials is true
This comment includes only the first 5 flaky tests. See all 20 flaky tests in the Cypress Dashboard.

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

Copy link
Contributor

@astone123 astone123 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 this with React 18 and Vue 2 and I can see snapshots as expected. I wonder why this was only an issue with React 18 and Vue 2. Any idea?

Glad to see consistency between the different frameworks 🎉

@astone123 astone123 requested a review from a team October 24, 2022 18:34
@marktnoonan
Copy link
Contributor

@amehta265 I'm testing this out and don't see the update on this Vue 2 / Nuxt project, wonder if it renders content later than initial mount? Haven't dug in yet. But that might be expected for Nuxt.

nuxt mount

nuxt first command

@astone123
Copy link
Contributor

@marktnoonan how are you getting the changes to npm/vue2 into your project? It was kind of tricky for me. I ended up building npm/vue2 and then copying the npm/vue2/dist folder from my cypress repo into node_modules/vue2 in my project.

@marktnoonan
Copy link
Contributor

@astone123 I was using the e2e test that Ankit set up. I'll try as you suggested!

@marktnoonan
Copy link
Contributor

OK that worked. And just building the npm/vue package fixed the example in the test. I'm going to take another look at the tests, as it probably shouldn't have been passing before I built npm/vue?

Screen Shot 2022-10-24 at 4 19 51 PM

Copy link
Contributor

@marktnoonan marktnoonan left a comment

Choose a reason for hiding this comment

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

Requesting some additional test coverage before we merge to make sure we would catch a regression

@@ -410,6 +412,17 @@ export const mount = (

Cypress.vue = VTUWrapper.vm
Cypress.vueWrapper = VTUWrapper
}).wait(0, { log: false }).then(() => {
if (optionsOrProps.log !== false) {
const observer = new MutationObserver(() => callbackFunc)
Copy link
Contributor

@ZachJW34 ZachJW34 Oct 24, 2022

Choose a reason for hiding this comment

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

Can you explain the benefit of using MutationObserver over something like Vue.nextTick here? The observer seems complex, and to add it I think we would need more safety around its use. For example, what happens if a component throws an error before rendering? Is the observer ever disconnected?

Same comment for React, I was a bit hesitant but we could use act to let the component stabilize.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe the implementation using the MutationObserver here was to generalize the solution across different frameworks. As soon as we get the children for the data-cy-root, the observer is disconnected as you will see in the callbackFunc.
I can see why we can implement framework specific solutions because only vue2 and react are impacted so I'll definitely look into the methods mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed, I have used Vue.nextTick() in npm/vue2 to ensure the hover on mount command functionality for vue2 projects and have used wait(fn, 0) in npm/react

npm/vue2/src/index.ts Outdated Show resolved Hide resolved
name: 'mount',
message: [message],
}).snapshot('mounted').end()
Vue.nextTick(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd expect the nextTick to be wrapped within the chain so as to ensure the tick and log is captured before the next Cypress command is fired. You could convert this function to be async and await Vue.nextTick() as the end.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure we need async/await - could just do it like this, right?

.then((win) => Vue.nextTick())
.then(() => {
  /* stuff */
})

If anyone was curious, under-the-hood nextTick is basically just Promise.resolve (with various fallbacks). It actually uses MutationObserver as a fallback, interestingly enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as the .then(() => Vue.nextTick()) is done after the component creation I'm cool with it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This sounds good. I've made the necessary changes on the latest commit

{ projectName: 'nuxtjs-vue2-configured', test: 'Tutorial.cy' },
]

for (const { projectName, test } of PROJECTS) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Tests are very thorough, and I know this is already ✔️ , but I wonder if we want to consider adding these to an existing test in the future? Scaffolding all these projects is pretty expensive (in terms of CI time) for something that could be exercised in one of the other tests we've got for the various frameworks.

@lmiller1990
Copy link
Contributor

Looks good, but CI has some fails - might want to verify if those are real fails (and fix it) or flake (if so - probably want to make sure we aren't merging flaky tests).

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.

Hovering over mount in command log does not show the mounted component in AUT
6 participants