find-cypress-specs 1.8.0 → 1.12.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
@@ -1,4 +1,4 @@
1
- # find-cypress-specs ![cypress version](https://img.shields.io/badge/cypress-9.2.0-brightgreen)
1
+ # find-cypress-specs [![renovate-app badge][renovate-badge]][renovate-app] ![cypress version](https://img.shields.io/badge/cypress-9.4.1-brightgreen) [![ci](https://github.com/bahmutov/find-cypress-specs/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bahmutov/find-cypress-specs/actions/workflows/ci.yml)
2
2
 
3
3
  > Find Cypress spec files using the config settings
4
4
 
@@ -8,6 +8,25 @@ $ npx find-cypress-specs
8
8
  cypress/e2e/spec.js,cypress/e2e/featureA/user.js
9
9
  ```
10
10
 
11
+ ## against branch
12
+
13
+ By default, this module simply prints all spec filenames. You can add `--branch` parameter to only print the specs changed against that `origin/branch`.
14
+
15
+ ```bash
16
+ $ npx find-cypress-specs --branch main
17
+ # prints only some specs, the ones that have changed against the "origin/main"
18
+ ```
19
+
20
+ ### number of changed files
21
+
22
+ You can print just the number of changed specs
23
+
24
+ ```bash
25
+ $ npx find-cypress-specs --branch main --count
26
+ # prints the number of spec files changed against the branch "origin/main"
27
+ 5
28
+ ```
29
+
11
30
  ## Test names
12
31
 
13
32
  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))
@@ -31,6 +50,8 @@ found 2 specs (4 tests, 1 pending)
31
50
 
32
51
  Where the tags are listed inside `[ ... ]` (see [cypress-grep](https://github.com/cypress-io/cypress-grep)) and the [pending tests](https://glebbahmutov.com/blog/cypress-test-statuses/) are marked with `⊙` character.
33
52
 
53
+ You can print the results in JSON format using `--json` or `-j` option.
54
+
34
55
  ## Test tags
35
56
 
36
57
  You can count tags attached to the individual tests using `--tags` arguments
@@ -47,6 +68,8 @@ Tag Tests
47
68
 
48
69
  Each tag count includes the tests that use the tag directly, and the _effective_ tags applied from the parent suites.
49
70
 
71
+ You can print the results in JSON format using `--json` or `-j` option.
72
+
50
73
  ## Details
51
74
 
52
75
  Cypress uses the resolved [configuration values](https://on.cypress.io/configuration) to find the spec files to run. It searches the `integrationFolder` for all patterns listed in `testFiles` and removes any files matching the `ignoreTestFiles` patterns.
@@ -101,3 +124,6 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
101
124
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
102
125
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
103
126
  OTHER DEALINGS IN THE SOFTWARE.
127
+
128
+ [renovate-badge]: https://img.shields.io/badge/renovate-app-blue.svg
129
+ [renovate-app]: https://renovateapp.com/
package/bin/find.js CHANGED
@@ -1,16 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const arg = require('arg')
4
- const { getSpecs } = require('../src')
4
+ const { getSpecs, collectResults, findChangedFiles } = require('../src')
5
5
  const fs = require('fs')
6
6
  const pluralize = require('pluralize')
7
7
  const { getTestNames, formatTestList, countTags } = require('find-test-names')
8
8
  const consoleTable = require('console.table')
9
+ const debug = require('debug')('find-cypress-specs')
9
10
 
10
11
  const args = arg({
11
12
  '--names': Boolean,
12
13
  '--tags': Boolean,
14
+ // output in JSON format
13
15
  '--json': Boolean,
16
+ // find the specs that have changed against this Git branch
17
+ '--branch': String,
18
+ '--count': Number,
14
19
 
15
20
  // aliases
16
21
  '-n': '--names',
@@ -18,8 +23,11 @@ const args = arg({
18
23
  '-t': '--tags',
19
24
  '--tag': '--tags',
20
25
  '-j': '--json',
26
+ '-b': '--branch',
21
27
  })
22
28
 
29
+ debug('arguments %o', args)
30
+
23
31
  const specs = getSpecs()
24
32
  if (args['--names'] || args['--tags']) {
25
33
  if (!specs.length) {
@@ -47,13 +55,7 @@ if (args['--names'] || args['--tags']) {
47
55
 
48
56
  if (args['--names']) {
49
57
  if (args['--json']) {
50
- result.structure.forEach((t) => {
51
- if (t.type === 'test') {
52
- jsonResults[filename].push(t.name)
53
- } else if (t.type === 'suite') {
54
- jsonResults[filename].push(t.name)
55
- }
56
- })
58
+ collectResults(result.structure, jsonResults[filename])
57
59
  } else {
58
60
  if (result.pendingTestCount) {
59
61
  console.log(
@@ -110,10 +112,26 @@ if (args['--names'] || args['--tags']) {
110
112
  // every entry is [tag, count], so compare the tags
111
113
  return a[0].localeCompare(b[0])
112
114
  })
113
- const table = consoleTable.getTable(['Tag', 'Tests'], sortedTagEntries)
114
- console.log(table)
115
+ if (args['--json']) {
116
+ // assemble a json object with the tag counts
117
+ const tagResults = Object.fromEntries(sortedTagEntries)
118
+ console.log(JSON.stringify(tagResults, null, 2))
119
+ } else {
120
+ const table = consoleTable.getTable(['Tag', 'Tests'], sortedTagEntries)
121
+ console.log(table)
122
+ }
115
123
  }
116
124
  }
125
+ } else if (args['--branch']) {
126
+ debug('determining specs changed against branch %s', args['--branch'])
127
+ const changedFiles = findChangedFiles(args['--branch'])
128
+ debug('changed files %o', changedFiles)
129
+ const changedSpecs = specs.filter((file) => changedFiles.includes(file))
130
+ if (args['--count']) {
131
+ console.log(changedSpecs.length)
132
+ } else {
133
+ console.log(changedSpecs.join(','))
134
+ }
117
135
  } else {
118
136
  console.log(specs.join(','))
119
137
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "find-cypress-specs",
3
- "version": "1.8.0",
3
+ "version": "1.12.0",
4
4
  "description": "Find Cypress spec files using the config settings",
5
5
  "main": "src",
6
6
  "files": [
@@ -16,7 +16,11 @@
16
16
  "demo": "DEBUG=find-cypress-specs node ./bin/find",
17
17
  "demo-names": "node ./bin/find --names",
18
18
  "demo-tags": "node ./bin/find --tags",
19
+ "demo-tags-json": "node ./bin/find --tags --json",
19
20
  "demo-names-and-tags": "node ./bin/find --names --tags",
21
+ "demo-names-and-tags-json": "node ./bin/find --names --tags --json",
22
+ "demo-names-json": "node ./bin/find --names --json",
23
+ "print-changed-specs": "node ./bin/find --branch main",
20
24
  "semantic-release": "semantic-release"
21
25
  },
22
26
  "repository": {
@@ -34,10 +38,10 @@
34
38
  "homepage": "https://github.com/bahmutov/find-cypress-specs#readme",
35
39
  "devDependencies": {
36
40
  "ava": "^4.0.0",
37
- "cypress": "^9.2.0",
41
+ "cypress": "9.4.1",
38
42
  "execa-wrap": "^1.4.0",
39
43
  "prettier": "^2.5.1",
40
- "semantic-release": "^18.0.1"
44
+ "semantic-release": "19.0.2"
41
45
  },
42
46
  "dependencies": {
43
47
  "arg": "^5.0.1",
@@ -46,6 +50,7 @@
46
50
  "find-test-names": "^1.14.1",
47
51
  "globby": "^11.0.4",
48
52
  "minimatch": "^3.0.4",
49
- "pluralize": "^8.0.0"
53
+ "pluralize": "^8.0.0",
54
+ "shelljs": "^0.8.5"
50
55
  }
51
56
  }
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ const fs = require('fs')
3
3
  const path = require('path')
4
4
  const globby = require('globby')
5
5
  const minimatch = require('minimatch')
6
+ const shell = require('shelljs')
6
7
 
7
8
  const MINIMATCH_OPTIONS = { dot: true, matchBase: true }
8
9
 
@@ -72,9 +73,66 @@ function getSpecs() {
72
73
  return specs
73
74
  }
74
75
 
76
+ function collectResults(structure, results) {
77
+ structure.forEach((t) => {
78
+ const info = {
79
+ name: t.name,
80
+ type: t.type,
81
+ tags: t.tags,
82
+ }
83
+ if (t.pending) {
84
+ info.pending = t.pending
85
+ }
86
+ results.push(info)
87
+ if (t.type === 'suite') {
88
+ if (t.suites && t.suites.length) {
89
+ // skip empty nested suites
90
+ info.suites = []
91
+ collectResults(t.suites, info.suites)
92
+ }
93
+
94
+ if (t.tests && t.tests.length) {
95
+ // skip empty nested tests
96
+ info.tests = []
97
+ collectResults(t.tests, info.tests)
98
+ }
99
+ }
100
+ })
101
+ }
102
+
103
+ /**
104
+ * Finds files changed or added in the current branch when compared to the "origin/branch".
105
+ * Returns a list of filenames. If there are no files, returns an empty list.
106
+ * @param {string} branch The branch to compare against.
107
+ */
108
+ function findChangedFiles(branch) {
109
+ if (!branch) {
110
+ throw new Error('branch is required')
111
+ }
112
+
113
+ if (!shell.which('git')) {
114
+ shell.echo('Sorry, this script requires git')
115
+ return []
116
+ }
117
+
118
+ const result = shell.exec(
119
+ `git diff --name-only --diff-filter=AMR origin/${branch}`,
120
+ { silent: true },
121
+ )
122
+ if (result.code !== 0) {
123
+ debug('git diff failed with code %d', result.code)
124
+ return []
125
+ }
126
+
127
+ const filenames = result.stdout.split('\n').filter(Boolean)
128
+ return filenames
129
+ }
130
+
75
131
  module.exports = {
76
132
  getSpecs,
77
133
  // individual utilities
78
134
  getConfig,
79
135
  findCypressSpecs,
136
+ collectResults,
137
+ findChangedFiles,
80
138
  }