Skip to content

Conversation

@lmiller1990
Copy link
Contributor

@lmiller1990 lmiller1990 commented Mar 29, 2022

User facing changelog

Add some code to assert the correct files are created for new projects. It makes it quickly and easy to add new projects and assert the scaffolded code is what we expect.

Additional details

See this file for more details on my idea: https://github.com/cypress-io/cypress/pull/20818/files#diff-4b0c978082d6a9bf6dd7dfb2211caa0bf93f93a20da215a9907bd3e3c840137f

Basically, I added a function in TestActions that is kind of like snapshots for the scaffolded files. If a project hasn't got any expected files (in the cypress-expected directory) we just copy the scaffolded ones there, like a snapshot, for next time the test runs.

If the files do exist, we assert the scaffolded files are the same as the expected ones.

When successful, a test looks like this:
simage

A failure shows the diff:

image

How has the user experience changed?

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)
  • Has a PR for user-facing changes been opened in cypress-documentation?
  • Have API changes been updated in the type definitions?
  • Have new configuration options been added to the cypress.schema.json?

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Mar 29, 2022

Thanks for taking the time to open a PR!

@cypress
Copy link

cypress bot commented Mar 29, 2022



Test summary

17792 0 217 0Flakiness 2


Run details

Project cypress
Status Passed
Commit 044bd4d
Started Apr 1, 2022 3:22 PM
Ended Apr 1, 2022 3:34 PM
Duration 12:03 💡
OS Linux Debian - 10.10
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

xhr.cy.js Flakiness
1 ... > no status when request isnt forced 404
files.cy.js Flakiness
1 ... > has implicit existence assertion, retries and throws a specific error when file does not exist for null encoding

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

@lmiller1990 lmiller1990 marked this pull request as ready for review March 30, 2022 03:47
@lmiller1990 lmiller1990 requested review from a team as code owners March 30, 2022 03:47
})
}

describe('scaffolding new projects', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need more to express the scaffolded CT cypress.config.js, but since that's changing soon with the CT Arch project, I'll add those when we actually implement the changes.

Copy link
Contributor

@flotwig flotwig left a comment

Choose a reason for hiding this comment

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

very cool!

Comment on lines 8 to 10
// Also defined in lib/fixtures, but we do not want to
// import from system-tests into code we ship in production.
const cyTmpDir = path.join(tempDir, 'cy-projects')
Copy link
Contributor

Choose a reason for hiding this comment

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

why are we shipping test code in production? this seems very wrong

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 not super ideal - I will move this into a cy.task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok @flotwig, I put it in a cy.task: 3810fd6

Comment on lines 102 to 105
const files = (
await Promise.all([
globby(path.join(this.ctx.currentProject, 'cypress'), { onlyFiles: true }),
globby(path.join(this.ctx.currentProject, 'cypress.config.*'), { onlyFiles: true }),
Copy link
Contributor

Choose a reason for hiding this comment

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

globby only works with forward slashes, so this will break for Windows contributors: https://github.com/sindresorhus/globby#api

suggested to do something like https://stackoverflow.com/a/63251716/3474615 to ensure these are POSIX paths

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Please see https://github.com/cypress-io/cypress/pull/20818/files#diff-205e537e85adf50907257ece5985a0576754cefa95b0f691cc68bb8c11b7c3d0R98-R118

Shouldn't we just use path.posix.join all the time? Any case to not use it?

Copy link
Contributor

@flotwig flotwig Mar 31, 2022

Choose a reason for hiding this comment

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

I think we should use the real, native path wherever possible, since it's what most APIs expect, and also what users expect. So backslashes (path.win32.sep) on Windows, forward slashes (path.posix.sep) on Linux/macOS. The only exceptions to this that I know of are globby and when we're codegenning paths for import/require.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

"dataloader": "^2.0.0",
"dayjs": "^1.9.3",
"dedent": "^0.7.0",
"disparity": "^3.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

this and temp-dir should be in devDependencies since this is test code

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 moved these from data-context to launchpad when moving the test code to a task, and also moved them into devDependencies, so they are no longer in dependencies.

export class TestActions {
constructor (private ctx: DataContext) {}

async #snapshotScaffoldedFiles (expectedScaffoldDir: string, filesToDiff: FileToDiff[]): Promise<SnapshotScaffoldTestResult> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these functions named with # at the start? I haven't seen this before, and a cursory search suggests it may come from ruby or java?

If it's to denote these functions as internal, then I'd rather use an _, which I've seen in JS before, or even better, don't define them on the class at all. Could put them up above, since they don't use this at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's a new shortcut for doing private methodName() {... I had to look it up too. Honestly I prefer private just because it's more visually distinct, but absent of a coding styleguide to back me up, I was gonna keep it to myself 😄

Copy link
Contributor

@BlueWinds BlueWinds Mar 30, 2022

Choose a reason for hiding this comment

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

I think JS lends itself poorly to OOP / classes, and the less of it we do the better our code is going to come out. :P

Copy link
Contributor Author

@lmiller1990 lmiller1990 Mar 30, 2022

Choose a reason for hiding this comment

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

Sure, we can just use private. My reasoning here was it makes more sense to use a native JS feature, which has runtime privacy guarantees, instead of a compile time only, proprietary TS feature where possible, but I don't think it makes too big a difference either way.

Copy link
Contributor Author

@lmiller1990 lmiller1990 Mar 30, 2022

Choose a reason for hiding this comment

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

I ended up moving everything into a task: https://github.com/cypress-io/cypress/pull/20818/files#diff-205e537e85adf50907257ece5985a0576754cefa95b0f691cc68bb8c11b7c3d0 which is just a function, no class, so this problem is gone.

I do think it's better to use native JS runtime features where we can over TS compile time features, though, but we can discuss that at some point; this PR no longer uses either.

@@ -0,0 +1,11 @@
import { defineConfig } from 'cypress'
Copy link
Contributor

Choose a reason for hiding this comment

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

So this is unrelated to the PR, but I think it would be a good idea to have a comment about what defineConfig actually does and why people should use it. As far as I understand it, its only job is to provide typing information, and is recommended but not required?

Copy link
Contributor

Choose a reason for hiding this comment

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

We have a lot of comments in the other generated files, and it feels strange that the most important one doesn't explain what's going on in here at all.

Copy link
Contributor Author

@lmiller1990 lmiller1990 Mar 30, 2022

Choose a reason for hiding this comment

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

Yep, it's just for type interface - it's a no-op.

It might be good to explain what this does with a comment in the generated code, but changing the actual content of the scaffolded files needs to go through DX and friends. Luckily, if we do, it's trivial to update these tests with the infrastructure introduced here.

Let's follow up with DX internally.

@lmiller1990
Copy link
Contributor Author

lmiller1990 commented Mar 30, 2022

@BlueWinds @flotwig I addressed all the feedback, summary:

  1. moved test code to a task - so we do not ship test code anymore
  2. moved devDependencies to correct location in package.json
  3. using path.posix.join instead of path.join

Can you please re-review? Thanks!

Edit: CI is having some problems (we discussed internally). Let's wait until it's green, then 👀 and ✅.

@lmiller1990
Copy link
Contributor Author

Ok, it's green again! 🙏

ZachJW34
ZachJW34 previously approved these changes Mar 31, 2022
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.

Looks great! Could this system be used for some of the existing system-test projects we have like vue-cli-{configured,unconfigured}? Had a few minor comments but going to approve.

import { cyTmpDir } from '@tooling/system-tests/lib/fixtures'

const systemTestsDir = path.join(__dirname, '..', '..', '..', '..', 'system-tests', 'projects')
const systemTestsDir = path.posix.join(__dirname, '..', '..', '..', '..', 'system-tests', 'projects')
Copy link
Contributor

Choose a reason for hiding this comment

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

on Windows, __dirname will have backslashes in it, and path.posix.join will not do what is expected - it will treat the entire __dirname as a single filename:
image

I'd just keep this as a native path.join and convert to posix paths at only the places necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I see - thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I think I've done this right now. We only use posix for the globby globs now. Can you please double check? Thanks.

@lmiller1990
Copy link
Contributor Author

One more set of 👀 @flotwig 🙏

@lmiller1990 lmiller1990 merged commit 1645431 into 10.0-release Apr 4, 2022
@lmiller1990 lmiller1990 deleted the lmiller1990/UNIFY-1305 branch April 4, 2022 23:42
@lmiller1990
Copy link
Contributor Author

Still managed to mess up the path stuff and broke windows. Fixing... #20914

tgriesser added a commit that referenced this pull request Apr 5, 2022
* 10.0-release: (92 commits)
  chore: remove dependency-tree dep (#20905)
  chore(launchpad): work on infra for scaffold tests (#20818)
  fix: build mjs in the cli (#20889)
  fix(unify): Cypress version link should point to Cypress doc's changelog (#20869)
  fix: windows build (#20854)
  fix: add index.mjs to the published files of cli (#20884)
  refactor: lift indexHtmlFile up to component, add validation (#20870)
  fix: allow migration of pluginsFile using `env` properties (#20770)
  fix: viewport from CLI on CT (#20849)
  Don't communicate if process isn't connected
  Remove config.get
  Update packages/data-context/src/data/ProjectLifecycleManager.ts
  fix: git data source unit test failure (#20875)
  add comment for autoBindDebug
  fix: Ensuring current browser is synchronized between app and launchpad (#20830)
  Fix missed await on merge conflict resolution
  test(unification): move record keys to contexts (#20860)
  test: move record keys to contexts (#20859)
  PR comments
  Fix tests that visit app without a configured testing type
  ...
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