describe()

in Tests-Legacy/L0/VsTest/_suite.ts [27:1450]


describe('VsTest Suite', function () {
    this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000);

    before((done) => {
        if (psm.testSupported()) {
            psr = new psm.PSRunner();
            psr.start();
        }
        done();
    });

    after(function () {
        if (psr) {
            psr.kill();
        }
    });

    if (!os.type().match(/^Win/)) {
        console.log('Skipping vstest tests. Vstest tests run only on windows.');
        return;
    }

    it('CodeCoverage enabled in tools installer flow with no settings file given', (done) => {
        try {
            settingsHelper.updateSettingsFileAsRequired(undefined, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[0].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('CodeCoverage and Test Impact enabled in tools installer flow with no settings file given', (done) => {
        try {           
            settingsHelper.updateSettingsFileAsRequired(undefined, false, { tiaEnabled: true, baseLineBuildIdFile: path.join(__dirname, 'data', 'baselineBuildId.txt') }, undefined, false, undefined, true, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[1].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    
    it('CodeCoverage enabled in tools installer flow and settings file containing a data collector', (done) => {
        try {     
            const settingsFilePath = path.join(__dirname, 'data', 'ContainsTestImpactDataCollector.runsettings');      
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[1].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('Test Impact enabled with a run settings file with an exsiting data collector', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'UseVerifiableInstrumentationNotPresent.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: true, baseLineBuildIdFile: path.join(__dirname, 'data', 'baselineBuildId.txt') }, undefined, false, undefined, true, false)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            // Note: DataCollector[1] is used to assert because a data collector already existed in the runsettings file
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[1].Configuration[0].ImpactLevel, 'file', 'Test impact data collector addition failed.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('Test Impact enabled with a run settings file with an empty datacollectors node', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'RunsettingsWithEmptyDataCollectorsNode.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: true, baseLineBuildIdFile: path.join(__dirname, 'data', 'baselineBuildId.txt') }, undefined, false, undefined, true, false)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[0].Configuration[0].ImpactLevel, 'file', 'Test impact data collector addition failed.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('CodeCoverage enabled in tools installer flow with invalid settings file', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'Invalid.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[0].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('CodeCoverage enabled in tools installer flow with Valid settings file, without any configuration', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithoutRunConfiguration.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[0].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('CodeCoverage enabled in tools installer flow with Valid settings file, without any UseVerifiableInstrumentation node', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'UseVerifiableInstrumentationNotPresent.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[0].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('CodeCoverage enabled in tools installer flow with Valid settings file, with a UseVerifiableInstrumentation node', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'UseVerifiableInstrumentationNodePresent.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, undefined, false, true)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            // Note: DataCollectors[1] is used to assert because a data collector already existed in the runsettings file
                            assert.equal(settings.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector[1].Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation, 'False', 'UseVerifiableInstrumentation not set to false.');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('Vstest task without test results files input', (done) => {
        setResponseFile('vstestGood.json');
        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length > 0, 'should have written to stderr');
                assert(tr.failed, 'task should have failed');
                assert(tr.stdErrContained('Input required: testAssembly'));
                done();
            })
            .fail((err) => {
                done(err);
            });
    });
    it('Vstest task with test results files filter', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile2 /source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('VSTest task with VS2017 installed on build agent and latest option is selected in definition', (done) => {

        const vstestCmd = ['\\vs2017\\installation\\folder\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe', '/path/to/test.dll', '/logger:trx'].join(' ');
        setResponseFile('vs2017.json');

        const tr = new trm.TaskRunner('VSTest', false, true, false);
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/path/to/test.dll');
        tr.setInput('vsTestVersion', 'latest');
        tr.setInput('vstestLocationMethod', 'version');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result' + tr.stderr + tr.stdout);
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr + tr.stdout);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest' + tr.stdout + tr.stderr);
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('VSTest task with only VS2015 installed on build agent and latest option is selected in definition', (done) => {

        const vstestCmd = ['\\vs\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe', '/path/to/test.dll', '/logger:trx'].join(' ');
        setResponseFile('vs2015.json');

        const tr = new trm.TaskRunner('VSTest', false, true, false);
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/path/to/test.dll');
        tr.setInput('vsTestVersion', 'latest');
        tr.setInput('vstestLocationMethod', 'version');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result' + tr.stderr + tr.stdout);
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr + tr.stdout);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest' + tr.stdout + tr.stderr);
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with test results files filter and exclude filter', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern\n!/source/dir/some/*excludePattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with test results files as path', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task when vstest fails', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile2 /source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestFails.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length > 0, 'should have written to stderr');
                assert(tr.failed, 'task should have failed');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish/) < 0, 'should not have published test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task when vstest is set to ignore test failures', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile2 /source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestSucceedsOnIgnoreFailure.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should have not written to stderr. error: ' + tr.stderr);
                assert(!tr.failed, 'task should not have failed');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish/) < 0, 'should not have published test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with test case filter', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/TestCaseFilter:testFilter', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('testFiltercriteria', 'testFilter');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with enable code coverage', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/EnableCodeCoverage', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('codeCoverageEnabled', 'true');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with settings file', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/Settings:E:\\settings.runsettings', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'E:\\settings.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with invalid settings file', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'random.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length !== 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.failed, 'task should have failed');
                assert(tr.stderr.search(/The specified settings/) >= 0, 'should print error');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with run in parallel and UI tests', (done) => {

        let vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        let tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('uiTests', 'true');
        tr.setInput('runInParallel', 'true');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/Running UI tests in parallel on the same machine can lead to errors. Consider disabling the ‘run in parallel’ option or run UI tests using a separate task./) >= 0, 'should have given a warning for ui tests and run in parallel selection.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with run in parallel and vs 2015 below update1', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0'); // response file sets below update1
        tr.setInput('runInParallel', 'true');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                assert(tr.stdout.search(/Install Visual Studio 2015 Update 3 or higher on your build agent machine to run the tests in parallel./) >= 0, 'should have given a warning for update1 or higher requirement');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    /* Temp commenting out tests to unblock CI */

    // it('Vstest task with run in parallel and vs 2017', (done) => {
    //     setResponseFile('vstestGoodRunInParallel.json');
    //     const tr = new trm.TaskRunner('VSTest', false, true, true); // normalize slash, ignore temp path, enable regex match

    //     tr.setInput('testSelector', 'testAssemblies');
    //     tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
    //     tr.setInput('vstestLocationMethod', 'version');
    //     tr.setInput('vsTestVersion', '15.0');
    //     tr.setInput('runInParallel', 'true');

    //     tr.run()
    //         .then(() => {
    //             assert(tr.resultWasSet, 'task should have set a result');
    //             assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
    //             assert(tr.succeeded, 'task should have succeeded');
    //             assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
    //             assert(tr.stdout.search(/Install Visual Studio 2015 Update 3 or higher on your build agent machine to run the tests in parallel./) < 0, 'should not have given a warning for update3 or higher requirement');
    //             done();
    //         })
    //         .fail((err) => {
    //             console.log(tr.stderr);
    //             console.log(tr.stdout);
    //             done(err);
    //         });
    // });

    // it('Vstest task with run in parallel and vs 2015 update3 or higher', (done) => {
    //     setResponseFile('vstestRunInParallel.json');

    //     const tr = new trm.TaskRunner('VSTest', false, true, true); // normalize slash, ignore temp path, enable regex match
    //     tr.setInput('testSelector', 'testAssemblies');
    //     tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
    //     tr.setInput('vstestLocationMethod', 'version');
    //     tr.setInput('vsTestVersion', '14.0'); // response file sets above update1
    //     tr.setInput('runInParallel', 'true');

    //     tr.run()
    //         .then(() => {
    //             assert(tr.resultWasSet, 'task should have set a result');
    //             assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
    //             assert(tr.succeeded, 'task should have succeeded');
    //             assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
    //             assert(tr.stdout.search(/Install Visual Studio 2015 Update 3 or higher on your build agent machine to run the tests in parallel./) < 0, 'should not have given a warning for update3 or higher requirement.');
    //             done();
    //         })
    //         .fail((err) => {
    //             done(err);
    //         });
    // });

    it('Vstest task with custom adapter path', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx', '/TestAdapterPath:E:\\path\\to\\customadapters'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('pathtoCustomTestAdapters', 'E:/path/to/customadapters');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with test adapter should be found automatically', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx', '/TestAdapterPath:E:\\source\\dir'].join(' ');
        setResponseFile('vstestGoodwithNugetAdapter.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('searchFolder', 'E:\\source\\dir');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with runsettings file and tia.enabled set to false', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/Settings:E:\\settings.runsettings', '/logger:trx'].join(' ');
        setResponseFile('vstestGoodWithTiaDisabled.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'E:\\settings.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                const result = (tr.stdout.search(/No settings file provided or the provided settings file does not exist. Creating run settings file for enabling test impact data collector/) < 0);
                assert(result, 'should add not test impact collector to runsettings file.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with runsettings file and tia.enabled undefined', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/Settings:E:\\settings.runsettings', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'E:\\settings.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                const result = (tr.stdout.search(/No settings file provided or the provided settings file does not exist. Creating run settings file for enabling test impact data collector/) < 0);
                assert(result, 'should add not test impact collector to runsettings file.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with results directory as absolute path in run settings file', (done) => {

        const settingsFilePath = path.join(__dirname, 'data', 'ResultsDirectoryWithAbsolutePath.runsettings');
        const resultsDirectory = 'C:\\test'; // settings file has this result directory.

        const responseJsonFilePath: string = path.join(__dirname, 'vstestGood.json');
        let responseJsonContent = JSON.parse(fs.readFileSync(responseJsonFilePath, 'utf-8'));
        responseJsonContent = mockHelper.setupMockResponsesForPaths(responseJsonContent, [settingsFilePath, resultsDirectory]);
        const newResponseFilePath: string = path.join(__dirname, 'newresponse.json');
        fs.writeFileSync(newResponseFilePath, JSON.stringify(responseJsonContent));

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');

        setResponseFile(path.basename(newResponseFilePath));

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', settingsFilePath);

        tr.run()
            .then(() => {
                assert(tr.stdout.indexOf('creating path: ' + resultsDirectory) >= 0, 'should have created results directory.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with results directory as relative path in run settings file', (done) => {

        const settingsFilePath = path.join(__dirname, 'data', 'ResultsDirectoryWithRelativePath.runsettings');
        const resultsDirectory = path.join(__dirname, 'data', 'result'); // settings file has this result directory.

        const responseJsonFilePath: string = path.join(__dirname, 'vstestGood.json');
        let responseJsonContent = JSON.parse(fs.readFileSync(responseJsonFilePath, 'utf-8'));
        responseJsonContent = mockHelper.setupMockResponsesForPaths(responseJsonContent, [settingsFilePath, resultsDirectory]);
        const newResponseFilePath: string = path.join(__dirname, 'newresponse.json');
        fs.writeFileSync(newResponseFilePath, JSON.stringify(responseJsonContent));

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile(path.basename(newResponseFilePath));

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', settingsFilePath);

        tr.run()
            .then(() => {
                //vstest task reads result directory from settings file and creates it.
                assert(tr.stdout.indexOf('creating path: ' + resultsDirectory) >= 0, 'should have created results directory.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with results directory empty in run settings file', (done) => {

        const settingsFilePath = path.join(__dirname, 'data', 'RunSettingsWithoutResultsDirectory.runsettings');
        const resultsDirectory = '\\source\\dir\\TestResults'; // when results directory is empty in settings file, default result directory should be considered.

        const responseJsonFilePath: string = path.join(__dirname, 'vstestGood.json');
        let responseJsonContent = JSON.parse(fs.readFileSync(responseJsonFilePath, 'utf-8'));
        responseJsonContent = mockHelper.setupMockResponsesForPaths(responseJsonContent, [settingsFilePath, resultsDirectory]);
        const newResponseFilePath: string = path.join(__dirname, 'newresponse.json');
        fs.writeFileSync(newResponseFilePath, JSON.stringify(responseJsonContent));

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile(path.basename(newResponseFilePath));

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', settingsFilePath);

        tr.run()
            .then(() => {
                //vstest task reads result directory from settings file and creates it.
                assert(tr.stdout.indexOf('creating path: ' + resultsDirectory) >= 0, 'should have created results directory.');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task should not use diag option when system.debug is not set', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.run()
            .then(() => {
                console.log(tr.stderr.length);
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('/diag') < 0, '/diag option should not be used for vstest.console.exe');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task should not use diag option when system.debug is set to false', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGoodSysDebugFalse.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.run()
            .then(() => {
                console.log('The errors are..........' + tr.stderr);
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('/diag') < 0, '/diag option should not be used for vstest.console.exe');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task verify test results are dropped at correct location in case of release', (done) => {

        const vstestCmd = [sysVstestLocation, '/artifacts/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestRM.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/artifacts/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/##vso\[results.publish type=VSTest;mergeResults=false;resultFiles=\\artifacts\\dir\\TestResults\\a.trx;\]/) >= 0, 'should publish test results.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                console.log(err);
                done(err);
            });
    });

    it('Vstest task with serach directory input', (done) => {

        const vstestCmd = [sysVstestLocation, '/search/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/search/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('searchDirectory', '/search/dir');
        tr.run()
            .then(() => {
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('/diag') < 0, '/diag option should not be used for vstest.console.exe');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with single otherConsoleOptions', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx', '/UseVsixExtensions'].join(' ');
        setResponseFile('vstestOtherConsoleOptions.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('otherConsoleOptions', '/UseVsixExtensions');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('running vstest with other console params single..') >= 0, 'should have proper console output.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with multiple otherConsoleOptions', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/logger:trx', '/UseVsixExtensions', '/Enablecodecoverage'].join(' ');
        setResponseFile('vstestOtherConsoleOptions.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('otherConsoleOptions', '/UseVsixExtensions /Enablecodecoverage');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('running vstest with other console params multiple..') >= 0, 'should have proper console output.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with /Enablecodecoverage as otherConsoleOptions as well as Code Coverage enabled in UI', (done) => {

        const vstestCmd = [sysVstestLocation, '/source/dir/someFile1', '/EnableCodeCoverage', '/logger:trx', '/Enablecodecoverage'].join(' ');
        setResponseFile('vstestOtherConsoleOptions.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('otherConsoleOptions', '/Enablecodecoverage');
        tr.setInput('codeCoverageEnabled', 'true');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.failed, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.indexOf('running vstest with other console duplicate params..') >= 0, 'should have proper console output.');
                assert(tr.stdout.indexOf('The parameter \"/EnableCodeCoverage\" should be provided only once.') >= 0, 'should have code coverage duplicate issue.');
                assert(tr.stdout.indexOf('##vso[task.issue type=error;]Error: \\vs\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe failed with return code: 1') >= 0, 'should have proper error message.');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('RunInParallel enabled with no settings file given', (done) => {
        try {
            settingsHelper.updateSettingsFileAsRequired(undefined, true, { tiaEnabled: false }, undefined, false, undefined)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'Runparallel setting not set properly');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('RunInParallel enabled with invalid settings file', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'Invalid.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, true, { tiaEnabled: false }, undefined, false, undefined)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'Runparallel setting not set properly');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('RunInParallel enabled with Valid settings file, without any configuration', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithoutRunConfiguration.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, true, { tiaEnabled: false }, undefined, false, undefined)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'RunInparallel setting not set properly');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('RunInParallel enabled with Valid settings file, without any MaxCpuCount node in RunConfigurations', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithoutMaxCpuCountNode.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, true, { tiaEnabled: false }, undefined, false, undefined)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'RunInparallel setting not set properly');
                            assert.equal(settings.RunSettings.RunConfiguration[0].TargetFrameworkVersion, 'Framework40', 'RunInparallel should delete any other existing settings');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('RunInParallel enabled with Valid settings file, with MaxCpuCount set to 1', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithMaxCpuCountAs1.runsettings');
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, true, { tiaEnabled: false }, undefined, false, undefined)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'Runparallel setting not set properly');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('Updating runsettings with overridden parameters', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithoutRunConfiguration.runsettings');
            const overriddenParams = '-webAppUrl testVal -webAppInvalid testVal3 -webAppPassword testPass';
            let webAppUrlValue = '';
            let webAppPasswordValue = '';

            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, overriddenParams)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            const parametersArray = settings.RunSettings.TestRunParameters[0].Parameter;
                            parametersArray.forEach(function (parameter) {
                                if (parameter.$.Name === 'webAppUrl') {
                                    webAppUrlValue = parameter.$.Value;
                                } else if (parameter.$.Name === 'webAppInvalid') {
                                    assert.fail(parameter.$.Name, undefined, 'test param should not exist');
                                } else if (parameter.$.name === 'webAppPassword') {
                                    webAppPasswordValue = parameter.$.value;
                                }
                            });

                            assert.equal(webAppUrlValue, 'testVal', 'test run parameters must be overridden');
                            assert.equal(webAppPasswordValue, 'testPass', 'test run parameters must be overridden');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });
    it('Updating testsettings with overridden parameters', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidWithProperties.testsettings');
            const overriddenParams = '-webAppUrl testVal -webAppInvalid testVal3 -webAppPassword testPass --webAppUserName testuser';
            let webAppUrlValue = '';
            let webAppPasswordValue = '';
            let webAppUsername = '';

            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, overriddenParams)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            const parametersArray = settings.TestSettings.Properties[0].Property;
                            parametersArray.forEach(function (parameter) {
                                if (parameter.$.Name === 'webAppUrl') {
                                    webAppUrlValue = parameter.$.Value;
                                } else if (parameter.$.name === 'webAppInvalid') {
                                    assert.fail(parameter.$.Name, undefined, 'test param should not exist');
                                } else if (parameter.$.name === 'webAppPassword') {
                                    webAppPasswordValue = parameter.$.value;
                                } else if (parameter.$.name === '-webAppUserName') {
                                    webAppUsername = parameter.$.Value;
                                }
                            });
                            assert.equal(webAppUrlValue, 'testVal', 'testsettings properties must be overridden');
                            assert.equal(webAppPasswordValue, 'testPass', 'testsettings properties must be overridden');
                            assert.equal(webAppUsername, 'testuser', 'testsettings properties must be overriden');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });


    //Case: Valid xml with multiple properties having same name within Properites section
    //Such a case is invalide test settings file and test platform will fail, as a function updateSettingsFileAsRequired should promise to override all repeated Properties with same value
    it('Updating valid testsettings having repeated property name with overridden parameters', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'ValidTestSettingsWithRepeatedProperty.testsettings');
            const overriddenParams = '-webAppUrl testVal -webAppInvalid testVal3 -webAppPassword testPass';
            let webAppUrlValue = '';
            let webAppUrlValue2 = '';
            let webAppPasswordValue = '';
            let webAppUsername = '';

            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, overriddenParams)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            const parametersArray = settings.TestSettings.Properties[0].Property;
                            let i = 0;
                            parametersArray.forEach(function (parameter) {
                                if (parameter.$.Name === 'webAppUrl') {
                                    if (i === 0) {
                                        webAppUrlValue = parameter.$.Value;
                                    }
                                    else if (i === 1) {
                                        webAppUrlValue2 = parameter.$.Value
                                    }
                                    i++;
                                } else if (parameter.$.name === 'webAppInvalid') {
                                    assert.fail(parameter.$.Name, undefined, 'test param should not exist');
                                } else if (parameter.$.name === 'webAppPassword') {
                                    webAppPasswordValue = parameter.$.value;
                                } else if (parameter.$.name === '-webAppUserName') {
                                    webAppUsername = parameter.$.Value;
                                }
                            });
                            assert.equal(webAppUrlValue, 'testVal', 'testsettings properties must be overridden');
                            assert.equal(webAppPasswordValue, 'testPass', 'testsettings properties must be overridden');
                            assert.equal(webAppUsername, 'Admin', 'testsettings properties must not be overriden');
                            assert.equal(webAppUrlValue2, 'testVal', 'testsettings properties must be overridden');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    //Case: Valid xml with multiple properties section is provided, updateSettingsFileAsRequired will only replace properties in first section
    //Such a case is invalid test settings file and test platform will fail, as a function updateSettingsFileAsRequired should promise to override Properties in first section only
    it('Updating Invalid testsettings having multiple properties sections with overridden parameters', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'InvalidWithMultiplePropertiesSections.testsettings');
            const overriddenParams = '-webAppUrl testVal -webAppInvalid testVal3 -webAppPassword testPass';
            let webAppUrlValue = '';
            let webAppPasswordValue = '';
            let webAppUrlValue2 = '';
            let webAppUsername = '';

            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, false, { tiaEnabled: false }, undefined, false, overriddenParams)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            const parametersArray = settings.TestSettings.Properties[0].Property;
                            parametersArray.forEach(function (parameter) {
                                if (parameter.$.Name === 'webAppUrl') {
                                    webAppUrlValue = parameter.$.Value;
                                } else if (parameter.$.name === 'webAppInvalid') {
                                    assert.fail(parameter.$.Name, undefined, 'test param should not exist');
                                } else if (parameter.$.name === 'webAppPassword') {
                                    webAppPasswordValue = parameter.$.value;
                                } else if (parameter.$.name === '-webAppUserName') {
                                    webAppUsername = parameter.$.Value;
                                }
                            });
                            const parametersArray2 = settings.TestSettings.Properties[1].Property
                            parametersArray2.forEach(function (parameter) {
                                if (parameter.$.Name === 'webAppUrl') {
                                    webAppUrlValue2 = parameter.$.Value;
                                }
                            });

                            assert.equal(webAppUrlValue, 'testVal', 'testsettings properties must be overridden');
                            assert.equal(webAppPasswordValue, 'testPass', 'testsettings properties must be overridden');
                            assert.equal(webAppUsername, 'Admin', 'testsettings properties must not be overriden');
                            assert.equal(webAppUrlValue2, 'Duplicatelocalhost', 'testsettings properties must not be overridden');
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    //In case of invalid xml provided by user or xml not having required tags, updateSettingsFileAsRequired returns a default run settings
    it('Updating invalid testsettings with overridden parameters', (done) => {
        try {
            const settingsFilePath = path.join(__dirname, 'data', 'Invalid.testsettings');
            const overriddenParams = '-webAppUrl testVal -webAppInvalid testVal3 -webAppPassword testPass';
            settingsHelper.updateSettingsFileAsRequired(settingsFilePath, true, { tiaEnabled: false }, undefined, false, overriddenParams)
                .then(function (settingsXml: string) {
                    utils.Helper.getXmlContents(settingsXml)
                        .then(function (settings) {
                            assert.equal(settings.RunSettings.RunConfiguration[0].MaxCpuCount, 0, 'Default setting not set properly' + settings);
                            done();
                        });
                });
        } catch (error) {
            assert.fail('updateSettingsFileAsRequired failed');
            done(error);
        }
    });

    it('modiyArgument test', (done) => {
        let modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile("somestring");
        assert.equal(modifiedString, "\"somestring\"", "string doesnt match");

        modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile("some string.dll");
        assert.equal(modifiedString, "\"some string.dll\"", "string doesnt match");

        modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile("/settings:c:\\a b\\1.settings");
        assert.equal(modifiedString, '/settings:\"c:\\a b\\1.settings\"', "string doesnt match");

        modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile('/settings:\"c:\\a b\\1.settings\"');
        assert.equal(modifiedString, '/settings:\"c:\\a b\\1.settings\"', "string doesnt match");

        modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile("/logger:trx");
        assert.equal(modifiedString, '/logger:\"trx\"', "string doesnt match");

        modifiedString = utils.Helper.modifyVsTestConsoleArgsForResponseFile(null);
        assert.equal(modifiedString, null, "string doesnt match");

        done();
    });

    it('Vstest should throw proper error for invalid vstest.console.exe location', (done) => {

        setResponseFile('vstestInvalidVstestPath.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'location');
        tr.setInput('vstestLocation', 'C:/vstest.console.exe');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.failed, 'task should have failed');
                assert(tr.stdout.indexOf('The location of \'vstest.console.exe\' specified \'C:/vstest.console.exe\' does not exist.') >= 0,
                    'should throw invalid path error');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest search folder field supports double dots', (done) => {
        const vstestCmd = [sysVstestLocation, '/source/dir/someFile2 /source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('searchFolder', 'E:\\source\\dir\\..');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/Search folder : E:\\source/) >= 0, 'searching in the wrong path with double dots');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest search folder field supports single dots', (done) => {
        const vstestCmd = [sysVstestLocation, '/source/dir/someFile2 /source/dir/someFile1', '/logger:trx'].join(' ');
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/some/*pattern');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('searchFolder', 'E:\\source\\.\\dir');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.ran(vstestCmd), 'should have run vstest');
                assert(tr.stdout.search(/Search folder : E:\\source\\dir/) >= 0, 'searching in the wrong path with single dots');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with settings file path with double dots is supported', (done) => {

        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'E:\\source\\dir\\..\\settings.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.stdout.search(/Run settings file : E:\\source\\settings.runsettings/) >= 0, 'wrong path for settings file with double dots');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with settings file path with single dots is supported', (done) => {
        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('runSettingsFile', 'E:\\source\\dir\\.\\settings.runsettings');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.stdout.search(/Run settings file : E:\\source\\dir\\settings.runsettings/) >= 0, 'wrong path for settings file with single dots');
                done();
            })
            .fail((err) => {
                done(err);
            });
    });

    it('Vstest task with custom adapter path with double dots is supported', (done) => {

        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('pathtoCustomTestAdapters', 'E:/path/to/../customadapters');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.stdout.search(/Path to custom adapters : E:\\path\\customadapters/) >= 0, 'wrong path for custom adapters with double dots');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });

    it('Vstest task with custom adapter path with single dots is supported', (done) => {

        setResponseFile('vstestGood.json');

        const tr = new trm.TaskRunner('VSTest');
        tr.setInput('testSelector', 'testAssemblies');
        tr.setInput('testAssemblyVer2', '/source/dir/someFile1');
        tr.setInput('vstestLocationMethod', 'version');
        tr.setInput('vsTestVersion', '14.0');
        tr.setInput('pathtoCustomTestAdapters', 'E:/path/to/./customadapters');

        tr.run()
            .then(() => {
                assert(tr.resultWasSet, 'task should have set a result');
                assert(tr.stderr.length === 0, 'should not have written to stderr. error: ' + tr.stderr);
                assert(tr.succeeded, 'task should have succeeded');
                assert(tr.stdout.search(/Path to custom adapters : E:\\path\\to\\customadapters/) >= 0, 'wrong path for custom adapters with single dots');
                done();
            })
            .fail((err) => {
                console.log(tr.stdout);
                done(err);
            });
    });
});