@bahmutov/cy-grep 1.0.0 → 1.2.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
@@ -19,13 +19,13 @@ All other tests will be marked pending, see why in the [Cypress test statuses](h
19
19
 
20
20
  If you have multiple spec files, all specs will be loaded, and every test will be filtered the same way, since the grep is run-time operation and cannot eliminate the spec files without loading them. If you want to run only specific tests, use the built-in [--spec](https://on.cypress.io/command-line#cypress-run-spec-lt-spec-gt) CLI argument.
21
21
 
22
- Watch the video [intro to cypress-grep plugin](https://www.youtube.com/watch?v=HS-Px-Sghd8)
22
+ Watch the video [intro to cypress-grep plugin](https://www.youtube.com/watch?v=HS-Px-Sghd8) and study my 🎓 Cypress course [Cypress Plugins](https://cypress.tips/courses/cypress-plugins).
23
23
 
24
24
  Table of Contents
25
25
 
26
26
  <!-- MarkdownTOC autolink="true" -->
27
27
 
28
- - [@bahmutov/cy-grep](#bahmutovcy-grep)
28
+ - [@bahmutov/cy-grep ](#bahmutovcy-grep-)
29
29
  - [Install](#install)
30
30
  - [Support file](#support-file)
31
31
  - [Config file](#config-file)
@@ -49,6 +49,7 @@ Table of Contents
49
49
  - [TypeScript support](#typescript-support)
50
50
  - [General advice](#general-advice)
51
51
  - [DevTools console](#devtools-console)
52
+ - [grepFailed](#grepfailed)
52
53
  - [Debugging](#debugging)
53
54
  - [Log messages](#log-messages)
54
55
  - [Debugging in the plugin](#debugging-in-the-plugin)
@@ -80,7 +81,8 @@ yarn add -D @bahmutov/cy-grep
80
81
  **required:** load this module from the [support file](https://on.cypress.io/writing-and-organizing-tests#Support-file) or at the top of the spec file if not using the support file. You import the registration function and then call it:
81
82
 
82
83
  ```js
83
- // cypress/support/index.js
84
+ // cypress/support/e2e.js
85
+
84
86
  // load and register the grep feature using "require" function
85
87
  // https://github.com/bahmutov/cy-grep
86
88
  const registerCypressGrep = require('@bahmutov/cy-grep')
@@ -89,7 +91,7 @@ registerCypressGrep()
89
91
  // if you want to use the "import" keyword
90
92
  // note: `./index.d.ts` currently extends the global Cypress types and
91
93
  // does not define `registerCypressGrep` so the import path is directly
92
- // pointed to the `support.js` file
94
+ // pointed to the support file
93
95
  import registerCypressGrep from '@bahmutov/cy-grep/src/support'
94
96
  registerCypressGrep()
95
97
 
@@ -110,13 +112,14 @@ registerCypressGrep()
110
112
  e2e: {
111
113
  setupNodeEvents(on, config) {
112
114
  require('@bahmutov/cy-grep/src/plugin')(config);
115
+ // IMPORTANT: return the config object
113
116
  return config;
114
- },
117
+ },
115
118
  }
116
119
  }
117
120
  ```
118
121
 
119
- Installing the plugin via `setupNodeEvents()` is required to enable the [grepFilterSpecs](#grepfilterspecs) feature.
122
+ Installing the plugin via `setupNodeEvents()` is required to enable the [grepFilterSpecs](#pre-filter-specs-grepfilterspecs) feature.
120
123
 
121
124
  ## Usage Overview
122
125
 
@@ -352,9 +355,12 @@ $ npx cypress run --env grepTags=@smoke,grepFilterSpecs=true
352
355
  **Tip:** you can set this environment variable in the [config file](https://docs.cypress.io/guides/references/configuration) file to enable it by default and skip using the environment variable:
353
356
 
354
357
  ```js
358
+ // config file
355
359
  {
356
- "env": {
357
- "grepFilterSpecs": true
360
+ "e2e": {
361
+ "env": {
362
+ "grepFilterSpecs": true
363
+ }
358
364
  }
359
365
  }
360
366
  ```
@@ -494,20 +500,33 @@ Cypress.grep('hello', '@smoke', 10)
494
500
 
495
501
  - to remove the grep strings enter `Cypress.grep()`
496
502
 
503
+ ### grepFailed
504
+
505
+ Once the tests finish, you can run just the failed tests from DevTools console
506
+
507
+ ```text
508
+ > Cypress.grepFailed()
509
+ ```
510
+
511
+ **Tip:** use `Cypress.grep()` to reset and run all the tests
512
+
513
+ 📝 Read the blog post [Run Just The Failed Tests In Cypress](https://glebbahmutov.com/blog/run-failed-tests/).
514
+
497
515
  ## Debugging
498
516
 
499
- When debugging a problem, first make sure you are using the expected version of this plugin, as some features might be only available in the [later releases](https://github.com/cypress-io/cypress-grep/releases).
517
+ When debugging a problem, first make sure you are using the expected version of this plugin, as some features might be only available in the [later releases](https://github.com/bahmutov/cy-grep/releases).
500
518
 
501
519
  ```
502
- # get the cypress-grep version using NPM
503
- $ npm ls cypress-grep
520
+ # get the plugin's version using NPM
521
+ $ npm ls @bahmutov/cy-grep
504
522
  ...
505
- └── cypress-grep@2.10.1
506
- # get the cypress-grep version using Yarn
507
- $ yarn why cypress-grep
523
+ └── @bahmutov/cy-grep@1.1.0
524
+
525
+ # get the plugin's version using Yarn
526
+ $ yarn why @bahmutov/cy-grep
508
527
  ...
509
- => Found "cypress-grep@2.10.1"
510
- info Has been hoisted to "cypress-grep"
528
+ => Found "@bahmutov/cy-grep@1.1.0"
529
+ info Has been hoisted to "@bahmutov/cy-grep"
511
530
  info This module exists because it's specified in "devDependencies".
512
531
  ...
513
532
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bahmutov/cy-grep",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Filter Cypress tests using title or tags",
5
5
  "main": "src/support.js",
6
6
  "scripts": {
package/src/index.d.ts CHANGED
@@ -26,6 +26,20 @@ declare namespace Cypress {
26
26
  }
27
27
 
28
28
  interface Cypress {
29
+ /**
30
+ * Runs only the tests that contain the given "grep" string
31
+ * in the title, or have specific tags.
32
+ * @param grep Part of the test title
33
+ * @param tags Tags to filter tests by
34
+ * @param burn Number of times to repeat each test
35
+ */
29
36
  grep?: (grep?: string, tags?: string, burn?: string) => void
37
+ /**
38
+ * Take the current test statuses and run only the failed tests.
39
+ * Run this static method from the DevTools console.
40
+ * Tip: use Cypress.grep() to reset and run all tests.
41
+ * @example Cypress.grepFailed()
42
+ */
43
+ grepFailed?: () => void
30
44
  }
31
45
  }
package/src/plugin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const debug = require('debug')('cypress-grep')
2
2
  const globby = require('globby')
3
- const { getTestNames } = require('find-test-names')
3
+ const { getTestNames, findEffectiveTestTags } = require('find-test-names')
4
4
  const fs = require('fs')
5
5
  const { version } = require('../package.json')
6
6
  const { parseGrep, shouldTestRun } = require('./utils')
@@ -9,7 +9,7 @@ const { parseGrep, shouldTestRun } = require('./utils')
9
9
  * Prints the cypress-grep environment values if any.
10
10
  * @param {Cypress.ConfigOptions} config
11
11
  */
12
- function cypressGrepPlugin (config) {
12
+ function cypressGrepPlugin(config) {
13
13
  if (!config || !config.env) {
14
14
  return config
15
15
  }
@@ -117,15 +117,14 @@ function cypressGrepPlugin (config) {
117
117
  const text = fs.readFileSync(specFile, { encoding: 'utf8' })
118
118
 
119
119
  try {
120
- const testInfo = getTestNames(text)
121
-
120
+ const testTags = findEffectiveTestTags(text)
121
+ // we get back a single object with keys being full test titles
122
+ // and the values being arrays of effective test tags
122
123
  debug('spec file %s', specFile)
123
- debug('test info: %o', testInfo.tests)
124
-
125
- return testInfo.tests.some((info) => {
126
- const shouldRun = shouldTestRun(parsedGrep, null, info.tags)
127
-
128
- return shouldRun
124
+ debug('effective test tags %o', testTags)
125
+ return Object.keys(testTags).some((testTitle) => {
126
+ const effectiveTags = testTags[testTitle]
127
+ return shouldTestRun(parsedGrep, null, effectiveTags)
129
128
  })
130
129
  } catch (err) {
131
130
  console.error('Could not determine test names in file: %s', specFile)
package/src/support.js CHANGED
@@ -253,4 +253,38 @@ if (!Cypress.grep) {
253
253
  }
254
254
  }
255
255
 
256
+ if (!Cypress.grepFailed) {
257
+ Cypress.grepFailed = function () {
258
+ // @ts-ignore
259
+ let root = Cypress.state('runnable')
260
+ while (root.parent) {
261
+ root = root.parent
262
+ }
263
+ const failedTestTitles = []
264
+
265
+ function findFailedTests(suite) {
266
+ suite.tests.forEach((test) => {
267
+ if (test.state === 'failed') {
268
+ // TODO use the full test title
269
+ failedTestTitles.push(test.title)
270
+ }
271
+ })
272
+ suite.suites.forEach((suite) => {
273
+ findFailedTests(suite)
274
+ })
275
+ }
276
+ findFailedTests(root)
277
+
278
+ if (!failedTestTitles.length) {
279
+ console.log('No failed tests found')
280
+ } else {
281
+ console.log('running only the failed tests')
282
+ console.log(failedTestTitles)
283
+ const grepTitles = failedTestTitles.join(';')
284
+ // @ts-ignore
285
+ Cypress.grep(grepTitles)
286
+ }
287
+ }
288
+ }
289
+
256
290
  module.exports = cypressGrep