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

feat: Enable create from Vue component for projects with custom spec patterns #23298

Merged
merged 15 commits into from
Aug 18, 2022

Conversation

astone123
Copy link
Contributor

@astone123 astone123 commented Aug 11, 2022

User facing changelog

This is a part of the create from Vue component effort. It shouldn't have its own changelog entry

Additional details

In the last create from Vue component PR, I excluded projects with custom spec patterns to separate out complexity. In order to release the feature, this also needs to work for projects with custom spec patterns.

Steps to test

  1. Open a Vue project that has a custom spec pattern defined for CT
  2. If your project has specs, click on the "+ New Spec" button
  3. Verify that you can see the "Create from component" card
  4. Click on the card and then choose a Vue component from the list.
  5. Verify that the spec file that is created matches your project's spec pattern and that the component you selected is imported correctly into the spec file (best way to verify this is to run the new spec and ensure that the spec mounts correctly).

How has the user experience changed?

Users will now see the "Create from component" generator card when adding a new spec to a Vue project using component testing when the project has a custom spec pattern defined in its configuration.

PR Tasks

  • Have tests been added/updated?
  • 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?

@astone123 astone123 requested review from a team as code owners August 11, 2022 22:17
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Aug 11, 2022

Thanks for taking the time to open a PR!

@@ -0,0 +1,5 @@
module.exports = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The diff looks really big because I added a new project to system-tests. I needed a project that had a custom spec pattern but was a Vue project.

You should be safe to ignore any changed files under system-tests/projects/

@lmiller1990 lmiller1990 removed the request for review from a team August 12, 2022 07:01
Copy link
Contributor

@ZachJW34 ZachJW34 left a comment

Choose a reason for hiding this comment

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

Gave it a thorough test and it worked great! Just a few comments

packages/app/cypress/e2e/specs.cy.ts Outdated Show resolved Hide resolved
packages/app/cypress/e2e/specs.cy.ts Outdated Show resolved Hide resolved
packages/data-context/src/actions/ProjectActions.ts Outdated Show resolved Hide resolved
packages/data-context/src/codegen/spec-options.ts Outdated Show resolved Hide resolved

return componentPath.startsWith('.') ? componentPath : `./${componentPath}`
return `./${this.parsedPath.base}`
Copy link
Contributor

Choose a reason for hiding this comment

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

Would ./ cause any issues for Windows?

Copy link
Contributor

@rockindahizzy rockindahizzy Aug 12, 2022

Choose a reason for hiding this comment

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

Would using path.join('./', componentPath)resolve any issue with os specifics?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is for the component import path in the component e.g. import App from '<relative-path>'.js. These should always be forward slashes, but still something we should check on Windows since we might be putting backslashes in the path where they shouldn't be.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah this should be fine on Windows because this is the path we're using to import the component in the tests. Mark tested my last PR on Windows that had similar logic and he said it worked well.

I'll try this out on my Windows VM before I merge it, anyone feel free to do the same

Copy link
Contributor

Choose a reason for hiding this comment

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

Empty-generator is what's happening now, so that sounds OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gave it a try on my Windows and a spec that is generated using a custom spec-pattern

@ZachJW34 yeah I think this is happening because when I use path in spec-options it takes the OS into account, so the path it gives me has backslashes in it on Windows 🤔

Kind of hacky, but what do we think about just replacing \ with / for these relative paths? I still need to use Node path to get the relative path of the component module compared to the spec directory, but I don't want it to use OS-specific slashes because this is a relative import being written to a file

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can use this function

export function toPosix (file: string, sep: string = path.sep) {
return file.split(sep).join(path.posix.sep)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks Lachlan, this should fix the issue on Windows

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah the replacement makes sense, we have a few examples of posixify-ing paths in the codebase

@cypress
Copy link

cypress bot commented Aug 12, 2022



Test summary

37840 0 615 0Flakiness 7


Run details

Project cypress
Status Passed
Commit a2b4ff7
Started Aug 18, 2022 12:50 PM
Ended Aug 18, 2022 1:05 PM
Duration 15:07 💡
OS Linux Debian - 11.3
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

cypress/e2e/commands/net_stubbing.cy.ts Flakiness
1 network stubbing > intercepting request > can delay with deprecated delayMs param
2 network stubbing > intercepting request > can delay with deprecated delayMs param
3 network stubbing > intercepting request > can delay with deprecated delayMs param
4 network stubbing > intercepting request > can delay with deprecated delayMs param
5 network stubbing > intercepting request > can delay with deprecated delayMs param
This comment includes only the first 5 flaky tests. See all 7 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

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

I found an inconsistency: it's using " for the component import but ' for the describe/it blocks. Feels a bit bad, quick fix? 🙏

image

packages/data-context/src/codegen/spec-options.ts Outdated Show resolved Hide resolved
packages/data-context/src/sources/ProjectDataSource.ts Outdated Show resolved Hide resolved
- Use object for getPathFromSpecPattern params
- Use single quotes for file import in generated spec
- Remove unnecessary async keyword
… github.com:cypress-io/cypress into astone123/23071-create-from-vue-custom-spec-pattern
Copy link
Contributor

@ZachJW34 ZachJW34 left a comment

Choose a reason for hiding this comment

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

Found a bug while creating a spec from a component that already has an existing spec when using a custom spec pattern. The copy gets appended after the .cy, causing the spec to not match.

Screen.Recording.2022-08-15.at.10.08.27.AM.mov

@astone123
Copy link
Contributor Author

@ZachJW34 it looks like that issue already exists currently for create empty spec. If you try to create a file with the same name, we append "copy" and it ends up not matching the spec pattern. We don't give a warning there either.

I wonder if we could push this bug fix off into a separate issue since it already exists and is common logic between the two cards.

@ZachJW34
Copy link
Contributor

ZachJW34 commented Aug 15, 2022

@ZachJW34 it looks like that issue already exists currently for create empty spec. If you try to create a file with the same name, we append "copy" and it ends up not matching the spec pattern. We don't give a warning there either.

I wonder if we could push this bug fix off into a separate issue since it already exists and is common logic between the two cards.

What is the reproduction for the empty spec bug? I gave it a try and it seemed to be working. I ran through empty-spec generation twice for src/ComponentName.cy.js (the default) and got:

  • src/ComponentName.cy.js
  • src/ComponentName-copy-1.cy.js

This is the expected output and it matches the specPattern. For the create-from-component, the output was src/App.cy-copy-1.js where the cy and copy are swapped.

Also, I posted a comment regarding Windows import paths: #23298 (comment)

@astone123
Copy link
Contributor Author

@ZachJW34 Oh right, you wouldn't be able to see the bug with that spec pattern. I was using 'src/specs-folder/*-cypress-spec.js' as my spec pattern, and with both methods of generation I saw the issue.

So in order to see it with empty, you need a custom suffix for your file names. I see that it's a different issue for create from component though, so I'll check it out

@lmiller1990
Copy link
Contributor

My changes were responded to!

@lmiller1990
Copy link
Contributor

I found another edge case:

  1. Go to frontend-shared
  2. Change specPattern to **/*.test.js
  3. Go to open mode
  4. It should show no specs found (since you changed the pattern)
  5. Create a spec for Alert.vue
  6. It creates a spec in Alert.test.js (top level) but the UI shows "Created in src/components/Alert.test.js.

@lmiller1990 lmiller1990 self-requested a review August 15, 2022 23:29
@lmiller1990
Copy link
Contributor

Dismissing my review since I found a bug.

Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

#23298 (comment)

May need a mini brief around the edge cases, I am not sure the expected filename and path is clear (above behavior is expected based on current code, but certainly not what you'd want).

@lmiller1990
Copy link
Contributor

I found an edge case. Here's my expected output when creating a new spec:

specPattern existing specs component expected new spec
src/**/*.js n/a src/Foo.vue src/Foo.cy.js
**/*.js n/a src/Foo.vue src/Foo.cy.js
**/*.js src/Bar.cy.js src/Foo.vue src/Foo.cy.js
**/*.js src/Foo.cy.js src/Foo.vue src/Foo-copy-1.cy.js

Case 2 is problematic. I think it's because we use https://github.com/cypress-io/cypress/pull/23298/files#diff-c351c3ec7e69c56e8c57fdf49babbece37086dbb43b9fc07a386f3cd33e508c9R52. When I created a spec in a new project where the spec pattern is **/*.cy.ts, I chose src/Alert.vue for the spec, and it's creating it at the top level - Alert.cy.tsx, which is not really what you'd expect.

sinon.restore()
});

[{ testName: 'src/specs-folder/*.cy.{js,jsx}', componentPath: 'ComponentName.vue', specs: [], pattern: 'src/specs-folder/*.cy.{js,jsx}', expectedPath: 'src/specs-folder/ComponentName.cy.js' },
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice way to cover all the cases

@lmiller1990
Copy link
Contributor

Just checking if we need a re-review or should this go back to in progress? Also might be good to clarify the test plan for the various edge cases (eg what we will do for **/*.test.js for CT projects without any specs, etc). 🙏

@astone123
Copy link
Contributor Author

Okay, after looking at this some more I updated the assertions for the unit tests and fixed a couple things with extensions. This doesn't match the table that @lmiller1990 put in an earlier comment, but these do match the default file name for the empty spec generator.

I'm hoping that this is good enough for now, as the plan for this wasn't to change the underlying defaultSpecFileName logic that we use. If we want to change our default spec name logic then I think we should follow up with another issue, or we should update this generator to allow the user to input their own file path for the spec.

To get an idea of the different cases that we have test coverage for and which file paths they result in, check out this test block

@ZachJW34 can you verify that you can create duplicate files and the -copy doesn't get added to your file extension now?

Copy link
Contributor

@ZachJW34 ZachJW34 left a comment

Choose a reason for hiding this comment

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

My comments have been addressed!

One last thing I'd like to throw out, would it make sense to create the sibling path first and check to see if it matches the specPattern before calling the getDefaultSpecFileName? This would reduce the likelihood that a spec gets generated away from it's sibling component when using a specPattern like **/*.cy.js

Just a thought, going to ✅

@lmiller1990
Copy link
Contributor

I also verified, copy naming bug is gone, I think this is good for now - I do expect this feature to receive lots of updates moving forward, we can address/rejig/rethink more when we get the next requirement/stories. Nice job, this one sure turned out to have some hidden complexity.

Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

LGTM

Will leave merging to @astone123 since I think there's one more potential (optional) change that @ZachJW34 pointed out that you may or may not want to do - I'm thinking we ship this and focus on Studio/other stuff for now, though?

@astone123
Copy link
Contributor Author

My comments have been addressed!

One last thing I'd like to throw out, would it make sense to create the sibling path first and check to see if it matches the specPattern before calling the getDefaultSpecFileName? This would reduce the likelihood that a spec gets generated away from it's sibling component when using a specPattern like **/*.cy.js

Just a thought, going to ✅

Yeah, I started on this but it ended up being more complicated than I originally thought, so I decided that for now we should just go with the behavior of the existing spec generator card. Will open an issue to improve this

@astone123 astone123 merged commit 0318262 into develop Aug 18, 2022
@astone123 astone123 deleted the astone123/23071-create-from-vue-custom-spec-pattern branch August 18, 2022 15:00
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.

Add 'create from Vue component' card to projects with custom spec patterns
6 participants