From 7b1f7ee6f50a1b6a00d4be9673e7314cb22b3a83 Mon Sep 17 00:00:00 2001
From: Ryan Olson <107872820+ryanolson-aumni@users.noreply.github.com>
Date: Thu, 30 Nov 2023 13:09:01 -0700
Subject: [PATCH] Add support for --spec CLI option (#167)

* Add support for --spec CLI option

As an alternative to -d, you can pass spec file paths (just like you
would in Cypress). If --spec is present, it will use that to determine
which tests to run.

Resolves #155

* Fix usage of argv.spec
---
 README.md          |  7 +++++++
 lib/settings.js    | 17 ++++++++++++-----
 lib/test-suites.js | 13 +++++++++----
 package.json       |  1 +
 4 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index ff583dc..60f59a6 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,12 @@ Run with npx (no package installation needed)
 npx cy:parallel -s cy:run -t 2 -d '<your-cypress-specs-folder>' -a '"<your-cypress-cmd-args>"'
 ```
 
+## Passing Specs
+
+```
+cypress-parallel -s cy:run -t 2 -a '\"<your-cypress-cmd-args>\"' --spec path/to/spec1.spec.js path/to/spec2.spec.js
+```
+
 ### Scripts options
 
 | Option            | Alias | Description                        | Type   |
@@ -77,6 +83,7 @@ npx cy:parallel -s cy:run -t 2 -d '<your-cypress-specs-folder>' -a '"<your-cypre
 | --args            | -a    | Your npm Cypress command arguments | string |
 | --threads         | -t    | Number of threads                  | number |
 | --specsDir        | -d    | Cypress specs directory            | string |
+| --spec            |       | Cypress spec file paths            | string |
 | --weightsJson     | -w    | Parallel weights json file         | string |
 | --reporter        | -r    | Reporter to pass to Cypress.       | string |
 | --reporterOptions | -o    | Reporter options                   | string |
diff --git a/lib/settings.js b/lib/settings.js
index b137871..c3e5954 100644
--- a/lib/settings.js
+++ b/lib/settings.js
@@ -27,6 +27,10 @@ const argv = yargs
     type: 'string',
     description: 'Cypress specs directory'
   })
+  .option('spec', {
+    type: 'array',
+    description: 'List of Cypress spec paths'
+  })
   .option('args', {
     alias: 'a',
     type: 'string',
@@ -58,10 +62,10 @@ const argv = yargs
     default: true,
     description: 'Strict mode checks'
   })
-   .option('weightsJson', {
-     alias: 'w',
-     type: 'string',
-     description: 'Parallel weights json file'
+  .option('weightsJson', {
+    alias: 'w',
+    type: 'string',
+    description: 'Parallel weights json file'
   }).argv;
 
 if (!argv.script) {
@@ -82,9 +86,12 @@ const COLORS = [
 const settings = {
   threadCount: argv.threads ? argv.threads : 2,
   testSuitesPath: argv.specsDir ? argv.specsDir : 'cypress/integration',
+  testSuitesPaths: argv.spec ? argv.spec : undefined,
   shouldBail: argv.bail ? argv.bail : false,
   isVerbose: argv.verbose ? argv.verbose : false,
-  weightsJSON: argv.weightsJson ? argv.weightsJson : 'cypress/parallel-weights.json',
+  weightsJSON: argv.weightsJson
+    ? argv.weightsJson
+    : 'cypress/parallel-weights.json',
   defaultWeight: 1,
   reporter: argv.reporter,
   reporterModulePath: argv.reporterModulePath
diff --git a/lib/test-suites.js b/lib/test-suites.js
index 3a02412..f63f758 100644
--- a/lib/test-suites.js
+++ b/lib/test-suites.js
@@ -27,8 +27,11 @@ const getFilePathsByGlob = (pattern) => {
 
 async function getTestSuitePaths() {
   const isPattern = settings.testSuitesPath.includes('*');
+
   let fileList;
-  if (isPattern) {
+  if (settings.testSuitesPaths) {
+    fileList = settings.testSuitesPaths;
+  } else if (isPattern) {
     console.log(`Using pattern ${settings.testSuitesPath} to find test suites`);
     fileList = await getFilePathsByGlob(settings.testSuitesPath);
   } else {
@@ -46,8 +49,10 @@ async function getTestSuitePaths() {
 
   // We can't run more threads than suites
   if (fileList.length < settings.threadCount) {
-    console.log(`Thread setting is ${settings.threadCount}, but only ${fileList.length} test suite(s) were found. Adjusting configuration accordingly.`)
-    settings.threadCount = fileList.length
+    console.log(
+      `Thread setting is ${settings.threadCount}, but only ${fileList.length} test suite(s) were found. Adjusting configuration accordingly.`
+    );
+    settings.threadCount = fileList.length;
   }
 
   return fileList;
@@ -87,7 +92,7 @@ function distributeTestsByWeight(testSuitePaths) {
     threads[0].list.push(key);
     threads[0].weight += +value;
   }
-  
+
   // Run slowest group first
   threads.sort((a, b) => b.weight - a.weight);
 
diff --git a/package.json b/package.json
index dd3619f..163c6e3 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
     "cy:open": "cypress open",
     "cy:run": "cypress run --browser chrome --headless",
     "cy:parallel": "node_modules/.bin/cypress-parallel -s cy:run -t 4 -d 'cypress/integration/1/*.js'",
+    "cy:parallel:some": "node_modules/.bin/cypress-parallel -s cy:run -t 2 --spec cypress/integration/1/new-pizza.spec.js cypress/integration/2/pizza.spec.js",
     "cy:parallel:many": "node_modules/.bin/cypress-parallel -s cy:run -t 8 -d 'cypress/integration/**/*.js'",
     "cy:parallel:spec": "node_modules/.bin/cypress-parallel -s cy:run -t 2 -d cypress/integration/1 -r spec",
     "cy:parallel:junit": "node_modules/.bin/cypress-parallel -s cy:run -t 2 -d cypress/integration/1 -r mocha-junit-reporter -o 'mochaFile=demo-app/reporting/junit/e2e-junit-[hash].xml'",