find-cypress-specs 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,8 @@ $ npx find-cypress-specs
8
8
  cypress/e2e/spec.js,cypress/e2e/featureA/user.js
9
9
  ```
10
10
 
11
+ Supports JS and TS specs
12
+
11
13
  ## against branch
12
14
 
13
15
  By default, this module simply prints all spec filenames. You can add `--branch` parameter to only print the specs changed against that `origin/branch`.
@@ -22,22 +24,17 @@ $ npx find-cypress-specs --branch main
22
24
  When dealing with a long-term branch, you do not want to see the changed files in the main branch. Instead, you want to only consider the specs changed in the _current_ branch all the way to its parent commit. You can pass the flag `--parent` to only pick the modified and added specs.
23
25
 
24
26
  ```bash
25
- $ npx find-cypress-specs --parent
27
+ $ npx find-cypress-specs --branch main --parent
26
28
  # same as
27
- # git diff --name-only --diff-filter=AMR HEAD^!
29
+ # git diff --name-only --diff-filter=AMR $(git merge-base origin/main HEAD)..
28
30
  ```
29
31
 
30
- Note: in order to trace the commits back to the parent commit of the branch, fetch the entire repo or enough commits to have this information when checking out the repo. For example, in [pr.yml](./.github/workflows/pr.yml) we fetch the entire history
31
-
32
- ```yml
33
- - name: Checkout 🛎
34
- # https://github.com/actions/checkout
35
- uses: actions/checkout@v3
36
- # check out all the commits in the repo
37
- # to make sure we detect the changed files in this branch
38
- # against its parent commit
39
- with:
40
- fetch-depth: 0
32
+ Note: to get the changed files, we need to fetch the repo, see [pr.yml](./.github/workflows/pr.yml)
33
+
34
+ ```
35
+ $ checkout
36
+ $ git fetch
37
+ $ npx find-cypress-specs --branch main --parent
41
38
  ```
42
39
 
43
40
  ### number of changed files
@@ -50,6 +47,16 @@ $ npx find-cypress-specs --branch main --count
50
47
  5
51
48
  ```
52
49
 
50
+ ### filter by a tag
51
+
52
+ You can filter all changed specs and only report (and count) the specs that have changed AND include the given tag(s)
53
+
54
+ ```bash
55
+ $ npx find-cypress-specs --branch main --tagged @user,@preview
56
+ # prints only some specs, the ones that have changed against the "origin/main"
57
+ # and that have any tests or suites inside tagged "@user" or "@preview"
58
+ ```
59
+
53
60
  ## Test names
54
61
 
55
62
  You can print each spec file with the suite and test names inside of it (found using [find-test-names](https://github.com/bahmutov/find-test-names))
@@ -122,6 +129,10 @@ Run the utility with environment variable `DEBUG=find-cypress-specs` to see the
122
129
 
123
130
  - [Use Ava Snapshots And Execa-wrap To Write End-to-End Tests For CLI Utilities](https://youtu.be/rsw17RqP0G0)
124
131
 
132
+ ## Examples
133
+
134
+ - [chat.io](https://github.com/bahmutov/chat.io) as described in the blog post [Get Faster Feedback From Your Cypress Tests Running On CircleCI](https://glebbahmutov.com/blog/faster-ci-feedback-on-circleci/)
135
+
125
136
  ## Small print
126
137
 
127
138
  Author: Gleb Bahmutov <gleb.bahmutov@gmail.com> © 2022
package/bin/find.js CHANGED
@@ -1,12 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const arg = require('arg')
4
- const {
5
- getSpecs,
6
- collectResults,
7
- findChangedFiles,
8
- findChangedFilesAgainstParent,
9
- } = require('../src')
4
+ const { getSpecs, collectResults, findChangedFiles } = require('../src')
10
5
  const { pickTaggedTestsFrom } = require('../src/tagged')
11
6
  const { addCounts } = require('../src/count')
12
7
  const { stringAllInfo } = require('../src/print')
@@ -23,7 +18,7 @@ const args = arg({
23
18
  '--json': Boolean,
24
19
  // find the specs that have changed against this Git branch
25
20
  '--branch': String,
26
- // find the specs that have changed against the parent of this branch
21
+ // find the specs that have changed against the parent of the branch
27
22
  '--parent': Boolean,
28
23
  '--count': Boolean,
29
24
  // filter all tests to those that have the given tag
@@ -118,19 +113,31 @@ if (args['--names'] || args['--tags']) {
118
113
  }
119
114
  } else if (args['--branch']) {
120
115
  debug('determining specs changed against branch %s', args['--branch'])
121
- const changedFiles = findChangedFiles(args['--branch'])
116
+ const changedFiles = findChangedFiles(args['--branch'], args['--parent'])
122
117
  debug('changed files %o', changedFiles)
123
- const changedSpecs = specs.filter((file) => changedFiles.includes(file))
124
- if (args['--count']) {
125
- console.log(changedSpecs.length)
126
- } else {
127
- console.log(changedSpecs.join(','))
118
+ debug('comparing against the specs %o', specs)
119
+ let changedSpecs = specs.filter((file) => changedFiles.includes(file))
120
+ debug('changed specs %o', changedSpecs)
121
+
122
+ if (args['--tagged']) {
123
+ const splitTags = args['--tagged']
124
+ .split(',')
125
+ .map((s) => s.trim())
126
+ .filter(Boolean)
127
+ debug('filtering changed specs by tags %o', splitTags)
128
+ changedSpecs = changedSpecs.filter((file) => {
129
+ const source = fs.readFileSync(file, 'utf8')
130
+ const result = getTestNames(source, true)
131
+ const specTagCounts = countTags(result.structure)
132
+ const specHasTags = Object.keys(specTagCounts).some((tag) =>
133
+ splitTags.includes(tag),
134
+ )
135
+ debug('spec %s has tags? %o', file, specHasTags)
136
+
137
+ return specHasTags
138
+ })
128
139
  }
129
- } else if (args['--parent']) {
130
- debug('determining specs changed against the parent of this branch')
131
- const changedFiles = findChangedFilesAgainstParent()
132
- debug('changed files %o', changedFiles)
133
- const changedSpecs = specs.filter((file) => changedFiles.includes(file))
140
+
134
141
  if (args['--count']) {
135
142
  console.log(changedSpecs.length)
136
143
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "find-cypress-specs",
3
- "version": "1.15.0",
3
+ "version": "1.17.0",
4
4
  "description": "Find Cypress spec files using the config settings",
5
5
  "main": "src",
6
6
  "files": [
@@ -43,7 +43,10 @@
43
43
  "cypress": "9.5.3",
44
44
  "execa-wrap": "^1.4.0",
45
45
  "prettier": "^2.5.1",
46
- "semantic-release": "19.0.2"
46
+ "really-need": "^1.9.2",
47
+ "semantic-release": "19.0.2",
48
+ "sinon": "^13.0.1",
49
+ "typescript": "^4.6.3"
47
50
  },
48
51
  "dependencies": {
49
52
  "arg": "^5.0.1",
package/src/index.js CHANGED
@@ -4,6 +4,7 @@ const path = require('path')
4
4
  const globby = require('globby')
5
5
  const minimatch = require('minimatch')
6
6
  const shell = require('shelljs')
7
+ const pluralize = require('pluralize')
7
8
 
8
9
  const MINIMATCH_OPTIONS = { dot: true, matchBase: true }
9
10
 
@@ -25,7 +26,7 @@ function getConfig(filename = 'cypress.json') {
25
26
  function findCypressSpecs(opts = {}) {
26
27
  const defaults = {
27
28
  integrationFolder: 'cypress/integration',
28
- testFiles: '**/*.js',
29
+ testFiles: '**/*.{js,ts}',
29
30
  ignoreTestFiles: [],
30
31
  }
31
32
  const options = {
@@ -104,8 +105,9 @@ function collectResults(structure, results) {
104
105
  * Finds files changed or added in the current branch when compared to the "origin/branch".
105
106
  * Returns a list of filenames. If there are no files, returns an empty list.
106
107
  * @param {string} branch The branch to compare against.
108
+ * @param {boolean} useParent Determine the changes only against the parent commit.
107
109
  */
108
- function findChangedFiles(branch) {
110
+ function findChangedFiles(branch, useParent) {
109
111
  if (!branch) {
110
112
  throw new Error('branch is required')
111
113
  }
@@ -117,39 +119,53 @@ function findChangedFiles(branch) {
117
119
 
118
120
  // can we find updated and added files?
119
121
  debug('finding changed files against %s', branch)
120
- const command = `git diff --name-only --diff-filter=AMR origin/${branch}`
121
- debug('command: %s', command)
122
+ debug('using parent?', useParent)
122
123
 
123
- const result = shell.exec(command, { silent: true })
124
- if (result.code !== 0) {
125
- debug('git diff failed with code %d', result.code)
126
- return []
127
- }
124
+ if (useParent) {
125
+ let result = shell.exec(`git merge-base origin/${branch} HEAD`, {
126
+ silent: true,
127
+ })
128
+ if (result.code !== 0) {
129
+ debug('git failed to find merge base with the branch %s', branch)
130
+ return []
131
+ }
128
132
 
129
- const filenames = result.stdout.split('\n').filter(Boolean)
130
- return filenames
131
- }
133
+ const commit = result.stdout.trim()
134
+ debug('merge commit with branch "%s" is %s', branch, commit)
135
+ result = shell.exec(`git diff --name-only --diff-filter=AMR ${commit}..`, {
136
+ silent: true,
137
+ })
138
+ if (result.code !== 0) {
139
+ debug('git diff failed with code %d', result.code)
140
+ return []
141
+ }
132
142
 
133
- /**
134
- * Finds files modified or added against the parent commit of the current branch.
135
- * Returns a list of filenames. If there are no files, returns an empty list.
136
- */
137
- function findChangedFilesAgainstParent() {
138
- if (!shell.which('git')) {
139
- shell.echo('Sorry, this script requires git')
140
- return []
141
- }
143
+ const filenames = result.stdout
144
+ .split('\n')
145
+ .filter(Boolean)
146
+ .map((s) => s.trim())
147
+ return filenames
148
+ } else {
149
+ const command = `git diff --name-only --diff-filter=AMR origin/${branch}`
150
+ debug('command: %s', command)
151
+
152
+ const result = shell.exec(command, { silent: true })
153
+ if (result.code !== 0) {
154
+ debug('git diff failed with code %d', result.code)
155
+ return []
156
+ }
142
157
 
143
- const result = shell.exec(`git diff --name-only --diff-filter=AMR HEAD^!`, {
144
- silent: true,
145
- })
146
- if (result.code !== 0) {
147
- debug('git diff failed with code %d', result.code)
148
- return []
158
+ const filenames = result.stdout
159
+ .split('\n')
160
+ .filter(Boolean)
161
+ .map((s) => s.trim())
162
+ debug(
163
+ 'found %d changed %s',
164
+ filenames.length,
165
+ pluralize('file', filenames.length),
166
+ )
167
+ return filenames
149
168
  }
150
-
151
- const filenames = result.stdout.split('\n').filter(Boolean)
152
- return filenames
153
169
  }
154
170
 
155
171
  module.exports = {
@@ -159,5 +175,4 @@ module.exports = {
159
175
  findCypressSpecs,
160
176
  collectResults,
161
177
  findChangedFiles,
162
- findChangedFilesAgainstParent,
163
178
  }