0

so the thing is. I am building an Angular Test Explorer. I am able to see all the tests and run them all together by using the karma module like this:

  public async runWithModule(): Promise<void> {
    return new Promise<void>(resolve => {
      karma.runner.run({ port: 9876 }, (exitCode: number) => {
        global.console.log("karma run done with ", exitCode);
        resolve();
      });
    });
  }

I am also able to run specific set of tests creating a shell and passing --grep

const command = `karma run -- --grep="${tests}"`;
const exec = require("child_process").exec;
exec(command, {
  cwd: this.angularProjectRootPath + "/node_modules/karma/bin/",
});

unfortunately the method for running a set of tests works different depending on the OS as the shell its different. This is giving me some problems.

I was wondering if anybody cant point me out how is that angular cli is doing karma run and specifying a set of tests when you do a regular ng test.

I asked in the karma repository and support without any answer so that's why I am asking here, I also tried finding that part of the code in the repository of the angular devkit. I have found where they do the karma.server but could not find the part I need.

JJJ
  • 32,902
  • 20
  • 89
  • 102
  • You can simply edit the `.spec.ts` test files and choose the tests you want to execute. Check this link https://stackoverflow.com/questions/44373909/how-can-i-run-a-single-protractor-test-in-intellij/44375864#44375864. So if you want to automate this, you can write a node script to edit the files and run the tests you want to execute using the method described in the link above. – Unsinkable Sam Mar 11 '19 at 09:42
  • As I am building a test explorer my app will run the tests from a project that the user is working. I have no control over those files and definitely not a good a idea that an application you re running modifies files from your hard drive. There must be a way to do this from code without editing the files. Currently if you run ng test you can pick a test to only run that one, I just have no idea how they do it – Patricio Ferraggi Mar 11 '19 at 09:59

1 Answers1

0

The solution is to make an http request to the browser to path /run. this will trigger karma run, you can also specify a set of tests by using --grep= as you would do on commandline

public async runTests(tests: any): Promise<void> {
  const karmaRunParameters = this.createKarmaRunConfiguration(tests);

  await this.runWithConfig(karmaRunParameters.config);
}

private createKarmaRunConfiguration(tests: any) {
  // if testName is undefined, reset jasmine.getEnv().specFilter function
  // otherwise, last specified specFilter will be used

  if (tests[0] === "root" || tests[0] === undefined) {
    tests = "";
  }
  const serverPort = 9876;
  const urlRoot = "/run";
  const config = {
    port: serverPort,
    refresh: true,
    urlRoot,
    hostname: "localhost",
    clientArgs: [] as string[],
  };
  config.clientArgs = [`--grep=${tests}`];
  return { config, tests };
}

private runWithConfig(config: any): Promise<void> {
  return new Promise<void>(resolve => {
    const options = {
      hostname: config.hostname,
      path: config.urlRoot,
      port: config.port,
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
    };

    const http = require("http");

    const request = http.request(options);

    request.on("error", (e: any) => {
      if (e.code === "ECONNREFUSED") {
        global.console.error("There is no server listening on port %d", options.port);
      }
    });

    request.end(JSON.stringify({
      args: config.clientArgs,
      removedFiles: config.removedFiles,
      changedFiles: config.changedFiles,
      addedFiles: config.addedFiles,
      refresh: config.refresh,
    }));

    request.on("close",() =>{ resolve(); });
  });
}

Test are being run correctly Test explorer running Angular/Karma tests with the specified method