alexkrechik / VSCucumberAutoComplete

Cucumber (Gherkin) Full Support Extension for VSCode
https://marketplace.visualstudio.com/items?itemName=alexkrechik.cucumberautocomplete
MIT License
332 stars 80 forks source link

Feature Request: Test selected Feature or Scenario #281

Open Shinigami92 opened 5 years ago

Shinigami92 commented 5 years ago

If you are in a .feature file, it would be nice if we can right-click on a Feature or Scenario and perform an action like Test Feature or Test selected Scenario

alexkrechik commented 5 years ago

Could you please advice - what such action should do (call some VSCode command or something else)? Do you have an example in some other language extension?

Shinigami92 commented 5 years ago

At first it was only a proposal  😅 In IDEs like Intellij, NetBeans or eclipse I can right-click on a JUnit Test and select Run Test And now I hope we can have such a cool feature for .feature Files in VSCode.

I found out that you can run specific tests from Cucumber with the command cucumber --test test/mytest.js

You can also run tests from gherkin files with cucumber --test test/features/mytest.feature:10 (linenumber) Docs

Shinigami92 commented 5 years ago

I have never written an extension for VSCode But maybe this could be helpful: https://github.com/Microsoft/vscode-extension-samples/tree/master/terminal-sample https://code.visualstudio.com/api/extension-guides/command

So we can introduce a command and run the current open feature file or additionally the scenario where the cursor is. Command like (when you are in an open feature file) >Cucumber: Run Feature or >Cucumber: Run selected Scenario

And then a Terminal is created and run the Test

alexkrechik commented 5 years ago

Ok, thank you, I'll investigate how to add some VSCode command to the feature/scenario context menu.

nicollaas94 commented 5 years ago

@alexkrechik do you have any plans in implementing this feature or would you be interested in a PR for it? I also do not have any experience in developing vs code extensions, but I do have a vs task script to run the selected (by current line) test, maybe can be useful as a starting point?

alexkrechik commented 5 years ago

Sorry for the long response. Yeah, let's look at this feature. Will try to resolve it on this weekend. Any PR or live example will help.

nicollaas94 commented 4 years ago

So I guess a PR will not be so helpful as a comment here, so others can already do what I do. Keep in mind, I have a very custom setup to run my tests using cucumber with Protractor from angular CLI:

My VS Code debug Launches: I do have a dependency in one custom task to launch angular serve "NG SERVE" if not yet running. I did added 3 options: Run all tests Run current line Run selection by feature name

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug tests",
            "type": "node",
            "request": "launch",
            "console": "integratedTerminal",
            "program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
            "stopOnEntry": false,
            "preLaunchTask": "EnsureServingAngular",
            "args": [
                "${workspaceRoot}/e2e/protractor.conf.js",
                "--params=useCustomTimeout=-1",
            ],
        },
        {
            "name": "Debug tests Current line",
            "type": "node",
            "request": "launch",
            "console": "integratedTerminal",
            "program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
            "stopOnEntry": false,
            "preLaunchTask": "EnsureServingAngular",
            "args": [
                "${workspaceRoot}/e2e/protractor.conf.js",
                "--params=useCustomTimeout=-1,fromLine=${relativeFile}:${lineNumber}",
            ],
        },      
        {
            "name": "Debug tests Selected Name",
            "type": "node",
            "request": "launch",
            "console": "integratedTerminal",
            "program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
            "stopOnEntry": false,
            "preLaunchTask": "EnsureServingAngular",
            "args": [
                "${workspaceRoot}/e2e/protractor.conf.js",
                "--params=useCustomTimeout=-1,fromName=${selectedText}",
            ],
        }
    ]

}

My cucumber extension settings are exactly like Cucumber Extension recommends, so skipping.

My vscode Tasks: Here I have one task to automatically restore my packages when I open vs code, and one to ensure I'm serving angular.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558 
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "restorePackages",
            "type": "shell",
            "command": "yarn",
            "runOptions": {
                "runOn": "folderOpen"
            }
        },
        {
            "label": "EnsureServingAngular",
            "type": "npm",
            "script": "start",
            "isBackground": true,
            "presentation": {
                "focus": true,
                "panel": "dedicated"
            },
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "typescript",
                "source": "ts",
                "applyTo": "closedDocuments",
                "fileLocation": [
                    "relative",
                    "${cwd}"
                ],
                "pattern": "$tsc",
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": {
                        "regexp": "(.*?)"
                    },
                    "endsPattern": {
                        "regexp": "Compiled |Failed to compile."
                    }
                }
            }
        },
    ]
}

And last but not least, My protractor config, where I pass my custom params in a way that protractor will understand:

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const reporter = require('cucumber-html-reporter');
const fs = require('fs');
const jsonReports = process.cwd() + "\\reports\\json";
const htmlReports = process.cwd() + "\\reports\\html";
const targetJson = jsonReports + "\\cucumber_report.json";
const customConfigs = {};
const customCucumberOptions = {};
let stepTimeout = 5000;
for (const arg of process.argv) {
    if (arg.startsWith("--params=")) {
        // custom params
        const params = arg.substr("--params=".length).split(',');       
        if (params.some(p => p=== 'useMultiCapabilities')) {
            customConfigs.multiCapabilities = [
                // https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
                { 'browserName': 'chrome' },
                { 'browserName': 'firefox' },
                // if want to run IE 11: https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver
            ]
        }
        if (params.some(p => p.includes('useCustomTimeout='))){
            const param = params.find(p => p.includes('useCustomTimeout='));
            const timeout = +param.split('=')[1]
            stepTimeout = timeout;
        }
        if (params.some(p => p.includes('fromLine='))){
            const param = params.find(p => p.includes('fromLine='));
            const lineSpec = param.split('=')[1].replace(/\\/g,'/').replace('e2e/','./')
            customConfigs.specs = [lineSpec];
        }
        if (params.some(p => p.includes('fromName='))){
            const param = params.find(p => p.includes('fromName='));
            const name = param.split('=')[1];
            customCucumberOptions.name = name;
        }

    }
}

exports.config = {

    framework: 'custom',
    frameworkPath: require.resolve('protractor-cucumber-framework'),

    capabilities:  {
        'browserName': 'chrome'
    },
    allScriptsTimeout: 11000,
    directConnect: true, // disable if will run browsers other than Chrome and Firefox
    baseUrl: 'http://localhost:4200/',

    specs: [
        './src/features/**/*.feature'
    ],
    cucumberOpts: {
        require: ['./src/steps/**/*.step.ts'],
        format: "json:./reports/json/cucumber_report.json",
        defaultTimeout: stepTimeout,
        ...customCucumberOptions
    },

    onPrepare() {
        require('ts-node').register({
            project: require('path').join(__dirname, './tsconfig.e2e.json')
        });
        if (!fs.existsSync(jsonReports)) {
            fs.mkdirSync(jsonReports, { recursive: true });
        }
    },
    onComplete() {
        reporter.generate({
            jsonFile: targetJson,
            output: htmlReports + '/cucumber_reporter.html',
            reportSuiteAsScenarios: true,
            theme: 'bootstrap',
        });
    },

    ...customConfigs,
};

Custom framework options: https://github.com/protractor-cucumber-framework/protractor-cucumber-framework/blob/c07f7b941118848077e1cdca098462a1106e0854/test/test.js#L49

Shelex commented 4 years ago

I suppose this feature could be implemented by adding configuration options for different framework+cucumber integration, and add some switch with logic what should be done to execute single scenario. I have done it for cypress in next way: vscode cypress extension. Idea is simple - set focus tag above scenario nearest to cursor and execute command in terminal. The problem is how it should be handled for different frameworks.