diff --git a/README.md b/README.md index 3e93843..82352b1 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,35 @@ For selecting component specs: npx cypress-cli-select run --component ``` +If you want to skip straight to selecting specs, titles or tags: + +```bash +npx cypress-cli-select run --specs +# skips straight to spec selection +``` + +```bash +npx cypress-cli-select run --titles +# skips to test title selection +``` + +```bash +npx cypress-cli-select run --tags +# skips to tag selection +``` + +```bash +npx cypress-cli-select run --specs --tags +# skips to spec selection, followed by tag selection +``` + +```bash +npx cypress-cli-select run --specs --titles +# skips to spec selection, followed by title selection +``` + +**Note**: You cannot pass both the `--titles` and `--tags` arguments. + You can also include more cli arguments similar to `cypress run`, as the command harnesses the power of [Cypress module API](https://docs.cypress.io/guides/guides/module-api): ```bash diff --git a/cypress.config.js b/cypress.config.js index 55fa29c..63bf0eb 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -4,9 +4,6 @@ module.exports = defineConfig({ e2e: { trashAssetsBeforeRuns: false, setupNodeEvents(on, config) { - // on("before:run", (details) => { - // console.log(details); - // }); require("@bahmutov/cy-grep/src/plugin")(config); on("task", { log(message) { diff --git a/index.js b/index.js index 85cdb08..6d9c730 100755 --- a/index.js +++ b/index.js @@ -115,6 +115,29 @@ async function runSelectedSpecs() { process.env.SUBMIT_FOCUSED = true; } + if (process.argv.includes("--titles") && process.argv.includes("--tags")) { + console.log("\n"); + console.log(pc.redBright(pc.bold(` Cannot choose both titles and tags `))); + process.exit(); + } + + if (process.argv.includes("--titles")) { + findAndRemoveArgv("--titles"); + process.env.TEST_TITLES = true; + process.env.CY_GREP_FILTER_METHOD = "Titles"; + } + + if (process.argv.includes("--specs")) { + findAndRemoveArgv("--specs"); + process.env.TEST_SPECS = true; + } + + if (process.argv.includes("--tags")) { + findAndRemoveArgv("--tags"); + process.env.TEST_TAGS = true; + process.env.CY_GREP_FILTER_METHOD = "Tags"; + } + // set the testing type // this is used by find-cypress-specs package to get the appropriate spec list if (process.argv.includes("--component")) { @@ -125,6 +148,30 @@ async function runSelectedSpecs() { try { // help menu options + yarg + .completion("--specs", false) + .option("specs", { + desc: "Skips to spec selection prompt", + type: "boolean", + }) + .example("npx cypress-cli-select run --specs"); + + yarg + .completion("--titles", false) + .option("titles", { + desc: "Skips to test title selection prompt", + type: "boolean", + }) + .example("npx cypress-cli-select run --titles"); + + yarg + .completion("--tags", false) + .option("tags", { + desc: "Skips to tag selection prompt", + type: "boolean", + }) + .example("npx cypress-cli-select run --tags"); + yarg .completion("--print-selected", false) .option("print-selected", { @@ -174,51 +221,66 @@ async function runSelectedSpecs() { * Test titles/tags requires the cy-grep package */ // Prompt for use to select spec and test titles or tags option - const specAndTestPrompt = await select({ - message: "Choose to filter by specs, specific test titles or tags: ", - multiple: disableTitleTagChoice ? false : true, - defaultValue: disableTitleTagChoice ? "Specs" : null, - clearInputWhenSelected: true, - selectFocusedOnSubmit: process.env.SUBMIT_FOCUSED, - canToggleAll: true, - options: [ - { - name: "Specs", - value: "Specs", - }, - { - name: "Test titles or tags (requires cy-grep)", - value: "Tests or tags", - disabled: disableTitleTagChoice, - }, - ], - required: true, - }); - - /* - - /* - * NOTE:: Choose test titles or tags - * This requires the cy-grep package - */ - if (specAndTestPrompt.includes("Tests or tags")) { - // Prompt for use to select test titles or tags option - const titleOrTagPrompt = await select({ - message: "Choose to filter by specific test titles or tags: ", - multiple: false, + if ( + !process.env.TEST_TITLES && + !process.env.TEST_SPECS && + !process.env.TEST_TAGS + ) { + const specAndTestPrompt = await select({ + message: "Choose to filter by specs, specific test titles or tags: ", + multiple: disableTitleTagChoice ? false : true, + defaultValue: disableTitleTagChoice ? "Specs" : null, + clearInputWhenSelected: true, + selectFocusedOnSubmit: process.env.SUBMIT_FOCUSED, + canToggleAll: true, options: [ { - name: "Test titles", - value: "Titles", + name: "Specs", + value: "Specs", }, { - name: "Test tags", - value: "Tags", + name: "Test titles or tags (requires cy-grep)", + value: "Tests or tags", + disabled: disableTitleTagChoice, }, ], required: true, }); - process.env.CY_GREP_FILTER_METHOD = titleOrTagPrompt; + if (specAndTestPrompt.includes("Specs")) { + process.env.TEST_SPECS = true; + } + + /* + + /* + * NOTE:: Choose test titles or tags + * This requires the cy-grep package + */ + if (specAndTestPrompt.includes("Tests or tags")) { + // Prompt for use to select test titles or tags option + const titleOrTagPrompt = await select({ + message: "Choose to filter by specific test titles or tags: ", + multiple: false, + options: [ + { + name: "Test titles", + value: "Titles", + }, + { + name: "Test tags", + value: "Tags", + }, + ], + required: true, + }); + process.env.CY_GREP_FILTER_METHOD = titleOrTagPrompt; + if (titleOrTagPrompt.includes("Titles")) { + process.env.TEST_TITLES = true; + } + if (titleOrTagPrompt.includes("Tags")) { + process.env.TEST_TAGS = true; + } + } } // Arrays for storing specs and/or tests // If user passes --print-selected @@ -228,7 +290,7 @@ async function runSelectedSpecs() { /* * NOTE:: Spec section */ - if (specAndTestPrompt.includes("Specs")) { + if (process.env.TEST_SPECS) { const specs = getSpecs(undefined, process.env.TESTING_TYPE, false); if (specs.length > 0) { @@ -334,7 +396,7 @@ async function runSelectedSpecs() { /* * NOTE:: Test Title section */ - if (process.env.CY_GREP_FILTER_METHOD === "Titles") { + if (process.env.TEST_TITLES) { const specs = getSpecs(undefined, process.env.TESTING_TYPE, false); if (specs.length > 0) { @@ -463,7 +525,7 @@ async function runSelectedSpecs() { /* * NOTE:: Tags section */ - if (process.env.CY_GREP_FILTER_METHOD === "Tags") { + if (process.env.TEST_TAGS) { const specs = getSpecs(undefined, process.env.TESTING_TYPE, false); if (specs.length > 0) { @@ -532,19 +594,19 @@ async function runSelectedSpecs() { // NOTE : --print-selected used to show all selected specs/titles/tags if (process.argv.includes("--print-selected")) { findAndRemoveArgv("--print-selected"); - if (specAndTestPrompt.includes("Specs")) { + if (process.env.TEST_SPECS) { console.log("\n"); console.log(pc.bgGreen(pc.black(pc.bold(` Spec(s) selected: `)))); console.log("\n"); console.log(specArr); } - if (process.env.CY_GREP_FILTER_METHOD === "Titles") { + if (process.env.TEST_TITLES) { console.log("\n"); console.log(pc.bgGreen(pc.black(pc.bold(` Test(s) selected: `)))); console.log("\n"); console.log(testArr); } - if (process.env.CY_GREP_FILTER_METHOD === "Tags") { + if (process.env.TEST_TAGS) { console.log("\n"); console.log(pc.bgGreen(pc.black(pc.bold(` Tag(s) selected: `)))); console.log("\n"); diff --git a/package-lock.json b/package-lock.json index 0d80343..5bd349c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cypress-cli-select", - "version": "1.0.2", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cypress-cli-select", - "version": "1.0.2", + "version": "1.1.0", "license": "MIT", "dependencies": { "@bahmutov/cy-grep": "^2.0.14", diff --git a/package.json b/package.json index 7a7710a..ef15589 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cypress-cli-select", - "version": "1.0.2", + "version": "1.1.0", "description": "A Cypress cli prompt to select and run specs, tests or tags", "main": "index.js", "bin": { diff --git a/tests/cli-component.spec.js b/tests/cli-component.spec.js index d7244b3..9f541ed 100644 --- a/tests/cli-component.spec.js +++ b/tests/cli-component.spec.js @@ -120,6 +120,82 @@ describe("component: basic input prompt flows", () => { }); }); +describe("component: prompt flags skip beginning prompts", () => { + it("handles --specs flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--component"], + ["--specs"], + ]); + + expect(await findByText("Select specs to run")).toBeInTheConsole(); + expect(await findByText("src/components/Clock.cy.js")).toBeInTheConsole(); + expect(await findByText("src/components/Stepper.cy.js")).toBeInTheConsole(); + + userEvent.keyboard("[Enter]"); + expect( + await findByText("Select specs to run: src/components/Clock.cy.js"), + ).toBeInTheConsole(); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("handles --titles flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--component"], + ["--titles"], + ]); + + expect(await findByText("Select tests to run")).toBeInTheConsole(); + expect( + await findByText("Clock.cy.js > > mounts"), + ).toBeInTheConsole(); + expect( + await findByText("Stepper.cy.js > > mounts"), + ).toBeInTheConsole(); + + userEvent.keyboard("[Enter]"); + expect( + await findByText("Select tests to run: Clock.cy.js > > mounts"), + ); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("handles --tags flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--component"], + ["--tags"], + ]); + + expect(await findByText("Select tags to run")).toBeInTheConsole(); + expect(await findByText("@p3")).toBeInTheConsole(); + + userEvent.keyboard("[ArrowDown]"); + userEvent.keyboard("[Enter]"); + + expect(await findByText("Select tags to run: @p3")); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("cannot pass both --titles and --tags", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--component"], + ["--titles"], + ["--tags"], + ]); + + expect( + await findByText("Cannot choose both titles and tags"), + ).toBeInTheConsole(); + }); +}); + describe("component: print selected displays prior to run", () => { it("handles spec display", async () => { const { findByText, userEvent } = await render("cd ../../../ && node", [ diff --git a/tests/cli-e2e.spec.js b/tests/cli-e2e.spec.js index a94f55c..81fb330 100644 --- a/tests/cli-e2e.spec.js +++ b/tests/cli-e2e.spec.js @@ -114,6 +114,75 @@ describe("e2e: basic input prompt flows", () => { }); }); +describe("e2e: prompt flags skip beginning prompts", () => { + it("handles --specs flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--specs"], + ]); + + expect(await findByText("Select specs to run")).toBeInTheConsole(); + expect( + await findByText("cypress/e2e/1-getting-started/todo.cy.js"), + ).toBeInTheConsole(); + expect( + await findByText("cypress/e2e/2-advanced-examples/actions.cy.js"), + ).toBeInTheConsole(); + expect( + await findByText("cypress/e2e/2-advanced-examples/aliasing.cy.js"), + ).toBeInTheConsole(); + + userEvent.keyboard("[Enter]"); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("handles --titles flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--titles"], + ]); + + expect(await findByText("Select tests to run")).toBeInTheConsole(); + expect( + await findByText( + "todo.cy.js > example to-do app > displays two todo items by default", + ), + ).toBeInTheConsole(); + + userEvent.keyboard("[Enter]"); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("handles --tags flag", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--tags"], + ]); + + expect(await findByText("Select tags to run")).toBeInTheConsole(); + expect(await findByText("@smoke")).toBeInTheConsole(); + + userEvent.keyboard("[Enter]"); + expect(await findByText("Running Cypress")).toBeInTheConsole(); + }); + + it("cannot pass both --titles and --tags", async () => { + const { findByText, userEvent } = await render("cd ../../../ && node", [ + resolve(__dirname, "../index.js"), + ["--submit-focused"], + ["--titles"], + ["--tags"], + ]); + + expect( + await findByText("Cannot choose both titles and tags"), + ).toBeInTheConsole(); + }); +}); + describe("e2e: print selected displays prior to run", () => { it("handles spec display", async () => { const { findByText, userEvent } = await render("cd ../../../ && node", [