New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable custom package testing environments #8968

Merged
merged 232 commits into from Oct 15, 2015

Conversation

Projects
None yet
@nathansobo
Contributor

nathansobo commented Sep 28, 2015

This PR aims to improve the experience of running tests in Atom in a few ways.

  • Package authors will be able to specify an atomTestRunner field in their package.json containing a require path. If the field is present, Atom will resolve the path relative to the package's root, expecting the required module to export a function which it will invoke with an object containing the following parameters.
    • testPaths An array of paths to tests to run. Could be paths to files or directories.
    • buildAtomEnvironment A function that can be called to construct an instance of the atom global (it won't automatically be assigned to global.atom, that is left to the test runner to decide.
    • logFile An optional path to a log file to which test output should be logged.
    • headless A boolean indicating whether or not the tests are running headless.
    • legacyTestRunner This function can be invoked to run the legacy Jasmine runner, giving packages a chance to transition to a new test runner while maintaining a subset of their tests in the old environment.
  • The test runner function will be expected to return a promise that resolves with an exit code. When tests are being run in headless mode Atom will exit with this code when the promise resolves. In interactive mode the promise will be ignored.
  • Running tests via the atom CLI has been streamlined. Simply run atom --test path1 path2 to invoke the test runner on the listed paths, expanded relative to the working directory. The --spec-directory option will be deprecated.
  • The buildAtomEnvironment function will construct a clean Atom environment whose state can be reset via a call to reset in between test runs.

Refs #8917
/cc @bolinfest @maxbrunsfeld

Additional Thoughts

Atom's current testing environment has been around since the very first day of Atom development, and is quite a mess. We assign all kinds of globals and mock the clock in evil and inconsistent ways that can cause quite a few headaches when writing tests for new packages.

This PR will give us a good way to make a fresh start. Ideally, a default test runner isn't something we should be supporting in Atom core. Every package should specify its preferred runner, which it can pull in as a development dependency and which Atom can interact with via an evolving interface. It would be good to have a recommended test framework. As it stands I'd probably want to switch bundled packages over to Mocha/Chai, unless people have other suggestions. Someday in the distant future we can finally delete the tangled mess that is our current default testing environment, but we'll keep it around for now.

Tasks

  • Basic clean up around test window initialization
  • Support specifying multiple test paths as arguments from the CLI.
  • Support atomTestRunner field containing a path.
  • Support multiple test paths in the default jasmine test runner.
  • Clean up Atom environment construction so we can instantiate the Atom environment without assigning to globals.
  • Pass buildAtomEnvironment to test runners and use it to assign the atom global in the default test runner, rather than in the test window initialization script.
  • Rename Atom to AtomEnvironment
  • Add a reset method to Atom environment
  • Pass legacyTestRunner parameter.
  • Fix docs generation.
  • Drop the --spec-directory CLI option
    • Stop using --spec-directory in apm test (atom/apm#445)
    • Stop using specDirectory parameter when running tests interactively
  • Drop the Run All Tests command from Atom since it's broken.
  • Shim process.stdout.write and process.stderr.write in the test window
  • Support a timeout flag
  • Expect the test runner to return a promise
  • Update packages to not use deprecated methods
  • Add user-facing documentation for the new workflow and options
  • Move remaining uses of APIs that interact with main process such as ipc to methods on ApplicationDelegate
  • Assign the defaultTarget of the keymaps in the AtomEnvironment constructor.
  • Parameterize the configDirPath and don't attempt any disk I/O in Config or AtomEnvironment if it is undefined. This will allow us to remove several mocks from the spec helper that prevent reading and writing state.
  • Move config.load() into the AtomEnvironment constructor, which will be a no-op in specs where the config dir is undefined. This will allow us to move loadBaseStyleSheets back into the constructor as well so they are available in the environment's default state.
  • Move subscription to core.autoHideMenuBar into AtomEnvironment constructor.
  • Get build green.
  • Document environment parameters (applicationDelegate, window, document)
@izuzak

This comment has been minimized.

Show comment
Hide comment
@izuzak

izuzak Sep 28, 2015

Member

Just a note -- I added this to the list of tasks above:

Add user-facing documentation for the new workflow and options

I think that will help package authors understand and switch to the new workflow. It can definitely be done as a separate PR, but wanted to add it here so we don't forget. ✌️

Member

izuzak commented Sep 28, 2015

Just a note -- I added this to the list of tasks above:

Add user-facing documentation for the new workflow and options

I think that will help package authors understand and switch to the new workflow. It can definitely be done as a separate PR, but wanted to add it here so we don't forget. ✌️

@thomasjo

This comment has been minimized.

Show comment
Hide comment
@thomasjo

thomasjo Sep 28, 2015

Member

I'm struggling to find the words that accurately express how insanely excited I am about this, so I must resort to expressing myself with this beauty

giphy

Member

thomasjo commented Sep 28, 2015

I'm struggling to find the words that accurately express how insanely excited I am about this, so I must resort to expressing myself with this beauty

giphy

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Sep 28, 2015

Contributor

Add user-facing documentation for the new workflow and options

Thanks @izuzak. I actually realized I forgot to list that as I was falling asleep last night.

Contributor

nathansobo commented Sep 28, 2015

Add user-facing documentation for the new workflow and options

Thanks @izuzak. I actually realized I forgot to list that as I was falling asleep last night.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Sep 28, 2015

Contributor

What will the value of testPaths be when apm test is run by default: will it be empty? Will the user always be required to specify paths?

An easy solution is probably to include the absolute path to the Atom package being tested. That way, if the test runner wants to have a default place where tests (or fixtures) live, it can find that by resolving the expected subpath against the location of the Atom package. So if the property were named pathToAtomPackageUnderTest:

import path from 'path';

// Note this assumes testPaths can be a mix of files and directories.
function runTests({pathToAtomPackageUnderTest, testPaths}) {
  if (testPaths.length === 0) {
    testPaths = [path.join(pathToAtomPackageUnderTest, 'spec')];
  }

  // Proceed...
}

The nice thing about this is that running tests for the entire package is still as simple as invoking apm test while only one property needs to be added to package.json (for "atomTestRunner").

Also, what is the return value of the function exported by "atomTestRunner" supposed to be? I'd suggest a Promise that resolves to some sort of object that, at a minimum, indicates whether the test passed or failed so we know what exit code to return from apm test.

Contributor

bolinfest commented Sep 28, 2015

What will the value of testPaths be when apm test is run by default: will it be empty? Will the user always be required to specify paths?

An easy solution is probably to include the absolute path to the Atom package being tested. That way, if the test runner wants to have a default place where tests (or fixtures) live, it can find that by resolving the expected subpath against the location of the Atom package. So if the property were named pathToAtomPackageUnderTest:

import path from 'path';

// Note this assumes testPaths can be a mix of files and directories.
function runTests({pathToAtomPackageUnderTest, testPaths}) {
  if (testPaths.length === 0) {
    testPaths = [path.join(pathToAtomPackageUnderTest, 'spec')];
  }

  // Proceed...
}

The nice thing about this is that running tests for the entire package is still as simple as invoking apm test while only one property needs to be added to package.json (for "atomTestRunner").

Also, what is the return value of the function exported by "atomTestRunner" supposed to be? I'd suggest a Promise that resolves to some sort of object that, at a minimum, indicates whether the test passed or failed so we know what exit code to return from apm test.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Sep 28, 2015

Contributor

Thinking about this more, pathToAtomPackageUnderTest is really important because if there is other metadata that the test runner expects to be baked into the package's package.json file, or dotfiles in the same directory as package.json, it should be able to locate those things easily.

Contributor

bolinfest commented Sep 28, 2015

Thinking about this more, pathToAtomPackageUnderTest is really important because if there is other metadata that the test runner expects to be baked into the package's package.json file, or dotfiles in the same directory as package.json, it should be able to locate those things easily.

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Sep 28, 2015

Contributor

Will the user always be required to specify paths?

Currently apm test already provides its own default (package-root/spec), but there really shouldn't be a reason to run tests via apm anymore at all with this more convenient CLI. I considered adding a default path, but I'm wondering if it's really that hard to supply the directory... This would be the command for running all tests on a package from its directory.

atom -t spec

I'm not convinced a default path is worth the added complexity. The lines of code aren't that big of a deal, but it's just one more magical thing to remember about the command rather than the simple story that the command does what you tell it to do.

Also, what is the return value of the function exported by "atomTestRunner"

Hadn't thought about it yet, but a promise resolving to an error code makes sense. I'm going to provide access to process.stdout.write and process.stderr.write in case headless runners want to write to do terminal output.

Contributor

nathansobo commented Sep 28, 2015

Will the user always be required to specify paths?

Currently apm test already provides its own default (package-root/spec), but there really shouldn't be a reason to run tests via apm anymore at all with this more convenient CLI. I considered adding a default path, but I'm wondering if it's really that hard to supply the directory... This would be the command for running all tests on a package from its directory.

atom -t spec

I'm not convinced a default path is worth the added complexity. The lines of code aren't that big of a deal, but it's just one more magical thing to remember about the command rather than the simple story that the command does what you tell it to do.

Also, what is the return value of the function exported by "atomTestRunner"

Hadn't thought about it yet, but a promise resolving to an error code makes sense. I'm going to provide access to process.stdout.write and process.stderr.write in case headless runners want to write to do terminal output.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Sep 28, 2015

Contributor

@nathansobo I'm not saying the user should have to supply a default path: I'm saying the test runner should be given the option to infer one. (Again, this makes it possible to eventually support a feature in Atom that lets you right click on an Atom package and run all of its tests. Without this, you would always have to prompt the user to ask where the tests are.)

But even if you don't agree with that, I think it makes sense to pass the location of the Atom package, or at least its package.json file. There's no reason to make the test runner try to figure that out.

Contributor

bolinfest commented Sep 28, 2015

@nathansobo I'm not saying the user should have to supply a default path: I'm saying the test runner should be given the option to infer one. (Again, this makes it possible to eventually support a feature in Atom that lets you right click on an Atom package and run all of its tests. Without this, you would always have to prompt the user to ask where the tests are.)

But even if you don't agree with that, I think it makes sense to pass the location of the Atom package, or at least its package.json file. There's no reason to make the test runner try to figure that out.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Sep 28, 2015

Contributor

Also, as I'm currently dealing with tests that fail to terminate, it would be nice if atom --test accepted an optional timeout argument. It seems like most Linux distros have a nice built-in timeout command, but BSD/OS X do not: http://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting/43346.

Contributor

bolinfest commented Sep 28, 2015

Also, as I'm currently dealing with tests that fail to terminate, it would be nice if atom --test accepted an optional timeout argument. It seems like most Linux distros have a nice built-in timeout command, but BSD/OS X do not: http://unix.stackexchange.com/questions/43340/how-to-introduce-timeout-for-shell-scripting/43346.

@sindresorhus sindresorhus referenced this pull request Oct 1, 2015

Open

Add unit tests #1

@EasyHard

This comment has been minimized.

Show comment
Hide comment
@EasyHard

EasyHard Oct 3, 2015

Contributor

mocha would be great! IMHO, features like -g (only run tests matching given regex pattern) and describe.only could help a lot to reduce time wasting on running irrelevant specs.

Contributor

EasyHard commented Oct 3, 2015

mocha would be great! IMHO, features like -g (only run tests matching given regex pattern) and describe.only could help a lot to reduce time wasting on running irrelevant specs.

nathansobo added some commits Sep 25, 2015

Rename “bootstrap” scripts
They’re just window initialization scripts, and this new naming makes
that a lot clearer.
Log to stdout from terminal runner via ipc
For some reason, logging to stderr/stdout from the render process only
works when Atom is run via child_process.spawn, which is how `apm test`
invokes it.

I’m trying to make a convenient interface for running tests directly via
the `atom` command, and this is the only way I could find to long to
stdout from the render process.

I’m also choosing stdout rather than stderr because in this case, you’re
intentionally running the tests and want to see feedback.
Allow a custom test runner path to be specified in package.json
If the nearest containing package.json of a test path has an
atomTestRunner field, we’ll require the specified file as a test runner
rather than the default jasmine runner.
@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Oct 17, 2015

Contributor

OK, I put up a quick fix so that I can use buildAtomEnvironment(): #9195.

Contributor

bolinfest commented Oct 17, 2015

OK, I put up a quick fix so that I can use buildAtomEnvironment(): #9195.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Oct 17, 2015

Contributor

Hmm, I see there is a buildDefaultApplicationDelegate function that is also passed in. Should I be using that instead?

Contributor

bolinfest commented Oct 17, 2015

Hmm, I see there is a buildDefaultApplicationDelegate function that is also passed in. Should I be using that instead?

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Oct 17, 2015

Contributor

OK, for reference, here is the new skeleton I am using for a custom test runner. Is this what is expected?

'use babel';
/* @flow */

/*
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the license found in the LICENSE file in
 * the root directory of this source tree.
 */

type TestRunnerParams = {
  /** Absolute paths to tests to run. Could be paths to files or directories. */
  testPaths: Array<string>,

  /** A boolean indicating whether or not the tests are running headless. */
  headless: boolean,

  /** Creates the `atom` global object. */
  buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal,

  /** Currently undocumnted, but seemingly necessary to use buildAtomEnvironment(). */
  buildDefaultApplicationDelegate: () => Object,

  /** An optional path to a log file to which test output should be logged. */
  logFile: ?string,

  /** Unclear what the contract of this is, but we will not be using it. */
  legacyTestRunner: () => void,
}

type BuildAtomEnvironmentParams = {
  applicationDelegate: Object,
  window: Object,
  document: Object,
  configDirPath?: string,
  enablePersistence?: boolean,
}

/**
 * This function satisfies the contract for a custom Atom test runner.
 */
export default async function({
  testPaths,
  buildAtomEnvironment,
  buildDefaultApplicationDelegate,
  }: TestRunnerParams,
): Promise<number> {
  let applicationDelegate = buildDefaultApplicationDelegate();
  let params = {
    applicationDelegate,
    window,
    document,
  };
  global.atom = buildAtomEnvironment(params);

  // TODO: Run tests for testPaths.

  // Exit with zero if successful.
  return 0;
}
Contributor

bolinfest commented Oct 17, 2015

OK, for reference, here is the new skeleton I am using for a custom test runner. Is this what is expected?

'use babel';
/* @flow */

/*
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the license found in the LICENSE file in
 * the root directory of this source tree.
 */

type TestRunnerParams = {
  /** Absolute paths to tests to run. Could be paths to files or directories. */
  testPaths: Array<string>,

  /** A boolean indicating whether or not the tests are running headless. */
  headless: boolean,

  /** Creates the `atom` global object. */
  buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal,

  /** Currently undocumnted, but seemingly necessary to use buildAtomEnvironment(). */
  buildDefaultApplicationDelegate: () => Object,

  /** An optional path to a log file to which test output should be logged. */
  logFile: ?string,

  /** Unclear what the contract of this is, but we will not be using it. */
  legacyTestRunner: () => void,
}

type BuildAtomEnvironmentParams = {
  applicationDelegate: Object,
  window: Object,
  document: Object,
  configDirPath?: string,
  enablePersistence?: boolean,
}

/**
 * This function satisfies the contract for a custom Atom test runner.
 */
export default async function({
  testPaths,
  buildAtomEnvironment,
  buildDefaultApplicationDelegate,
  }: TestRunnerParams,
): Promise<number> {
  let applicationDelegate = buildDefaultApplicationDelegate();
  let params = {
    applicationDelegate,
    window,
    document,
  };
  global.atom = buildAtomEnvironment(params);

  // TODO: Run tests for testPaths.

  // Exit with zero if successful.
  return 0;
}
@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Oct 19, 2015

Contributor

Argh. Still having trouble reproducing any problem with the TextEditor export on a fresh build.

screen shot 2015-10-19 at 11 49 42 am

As for your description, it's exactly what I had in mind. Is it working for you?

Contributor

nathansobo commented Oct 19, 2015

Argh. Still having trouble reproducing any problem with the TextEditor export on a fresh build.

screen shot 2015-10-19 at 11 49 42 am

As for your description, it's exactly what I had in mind. Is it working for you?

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Oct 20, 2015

Contributor

Just so everyone knows, we figured this out: atom/grim@8807010#commitcomment-13887073

We also concluded that the TextEditor constructor needs to be patched up so it still maintains its existing, albeit not-guaranteed since it was never published as part of 1.0, contract.

Contributor

bolinfest commented Oct 20, 2015

Just so everyone knows, we figured this out: atom/grim@8807010#commitcomment-13887073

We also concluded that the TextEditor constructor needs to be patched up so it still maintains its existing, albeit not-guaranteed since it was never published as part of 1.0, contract.

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Oct 21, 2015

Contributor

We also concluded that the TextEditor constructor needs to be patched up so it still maintains its existing, albeit not-guaranteed since it was never published as part of 1.0, contract.

Sorry, it turns out that the error we were seeing was due to an attempt to subclass the existing TextEditor constructor, which wasn't covered by our shim. @maxbrunsfeld I'm wondering if we should continue to export TextEditor and just make invoking it as a constructor a deprecated action. We could maintain an internal Symbol that can be passed in by Workspace.prototype.buildTextEditor to suppress the deprecation warning. Then it will "just work" for people attempting to subclass, and people can continue to use instanceof checks beyond 2.0, which I don't really have a problem with.

Contributor

nathansobo commented Oct 21, 2015

We also concluded that the TextEditor constructor needs to be patched up so it still maintains its existing, albeit not-guaranteed since it was never published as part of 1.0, contract.

Sorry, it turns out that the error we were seeing was due to an attempt to subclass the existing TextEditor constructor, which wasn't covered by our shim. @maxbrunsfeld I'm wondering if we should continue to export TextEditor and just make invoking it as a constructor a deprecated action. We could maintain an internal Symbol that can be passed in by Workspace.prototype.buildTextEditor to suppress the deprecation warning. Then it will "just work" for people attempting to subclass, and people can continue to use instanceof checks beyond 2.0, which I don't really have a problem with.

@mrodalgaard mrodalgaard referenced this pull request Nov 28, 2015

Closed

Custom test runner using Mocha and Coverage #9859

3 of 4 tasks complete

@banacorn banacorn referenced this pull request Jan 12, 2016

Open

Write tests #28

6 of 11 tasks complete
@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Feb 26, 2016

Contributor

When running a test, is there any way to remove all of the output that surrounds what I write to console.log()? It would be helpful to have the option to have "clean" output that doesn't have the [6237:0226/152313:INFO:CONSOLE(39)] prefix or the source: ... suffix.

Contributor

bolinfest commented Feb 26, 2016

When running a test, is there any way to remove all of the output that surrounds what I write to console.log()? It would be helpful to have the option to have "clean" output that doesn't have the [6237:0226/152313:INFO:CONSOLE(39)] prefix or the source: ... suffix.

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Feb 26, 2016

Contributor

Currently, it seems like specifying a --log-file and doing fs.appendFileSync() is my best workaround, but it's pretty tedious to get the path to the log file everywhere I need it as compared with console.log().

Contributor

bolinfest commented Feb 26, 2016

Currently, it seems like specifying a --log-file and doing fs.appendFileSync() is my best workaround, but it's pretty tedious to get the path to the log file everywhere I need it as compared with console.log().

@50Wliu

This comment has been minimized.

Show comment
Hide comment
@50Wliu
Member

50Wliu commented Feb 26, 2016

@bolinfest

This comment has been minimized.

Show comment
Hide comment
@bolinfest

bolinfest Feb 27, 2016

Contributor

Hmm, so there's also no way to specify additional flags/arguments to your test runner? Maybe we could use -- and pass a list of strings specified after that?

I can specify flags via environment variables and read them out of process.env though.

Contributor

bolinfest commented Feb 27, 2016

Hmm, so there's also no way to specify additional flags/arguments to your test runner? Maybe we could use -- and pass a list of strings specified after that?

I can specify flags via environment variables and read them out of process.env though.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Jul 9, 2016

Hrm, is there currently no way of running a custom test-runner inside the usual spec window? I'd give my left nut to use Mocha/Chai instead of Jasmine.

Nevermind, kek

Alhadis commented Jul 9, 2016

Hrm, is there currently no way of running a custom test-runner inside the usual spec window? I'd give my left nut to use Mocha/Chai instead of Jasmine.

Nevermind, kek

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Jul 12, 2016

Contributor

We're working on making this more official and documented.

Contributor

nathansobo commented Jul 12, 2016

We're working on making this more official and documented.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Jul 12, 2016

Nah it's cool, I already wrote my own... =) Just realised too damn late the reason it wasn't running is because the package.json had been cached in memory (and reloading the window wasn't doing anything, I literally had to quit and restart).

Alhadis commented Jul 12, 2016

Nah it's cool, I already wrote my own... =) Just realised too damn late the reason it wasn't running is because the package.json had been cached in memory (and reloading the window wasn't doing anything, I literally had to quit and restart).

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis Aug 5, 2016

It'd be lovely if we could use package.json to pass arbitrary values to the test-runner:

"atomTestRunner": {
    "path": "./path/to/test-runner",
    "config": {
        
    }
}

The atomTestRunner setting could be extended to accept an object instead of a plain string, treating the latter as if {"path": "…"} were passed instead. Which is similar to NPM's treatment of repository and author properties, among many others.

Alhadis commented Aug 5, 2016

It'd be lovely if we could use package.json to pass arbitrary values to the test-runner:

"atomTestRunner": {
    "path": "./path/to/test-runner",
    "config": {
        
    }
}

The atomTestRunner setting could be extended to accept an object instead of a plain string, treating the latter as if {"path": "…"} were passed instead. Which is similar to NPM's treatment of repository and author properties, among many others.

@Alhadis

This comment has been minimized.

Show comment
Hide comment

Alhadis commented Sep 5, 2016

@yamsellem

This comment has been minimized.

Show comment
Hide comment
@yamsellem

yamsellem Sep 15, 2016

@nathansobo, making it official and documented will be great, but it takes some time, meanwhile, may you please explain in a nutshell how we can take use of it today?

It seems there is already a mocha plugin, and I can wait to launch some mocha test in Atom. Existing mocha integration are not good, it seems Nuclide starts something in that direction but too much bloated to even understand it.

Thanks.

yamsellem commented Sep 15, 2016

@nathansobo, making it official and documented will be great, but it takes some time, meanwhile, may you please explain in a nutshell how we can take use of it today?

It seems there is already a mocha plugin, and I can wait to launch some mocha test in Atom. Existing mocha integration are not good, it seems Nuclide starts something in that direction but too much bloated to even understand it.

Thanks.

@Alhadis

This comment has been minimized.

Show comment
Hide comment
@Alhadis

Alhadis commented Sep 15, 2016

@nathansobo Try this. Seriously. :)

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Sep 15, 2016

Contributor

@Alhadis Looks pretty cool. I like the black background. I'll keep it in mind next time I'm considering a runner, but right now I'm pretty deep into fixing some international keybindings stuff.

Contributor

nathansobo commented Sep 15, 2016

@Alhadis Looks pretty cool. I like the black background. I'll keep it in mind next time I'm considering a runner, but right now I'm pretty deep into fixing some international keybindings stuff.

@nathansobo

This comment has been minimized.

Show comment
Hide comment
@nathansobo

nathansobo Sep 15, 2016

Contributor

@yamsellem You can specify a path in your package.json to point to a file that exports a function. This function will be invoked in your test window with various parameters that are useful for implementing a custom test runner. Take a look at the source of one of the existing runners for ideas on how to use those parameters to build your own runner.

Contributor

nathansobo commented Sep 15, 2016

@yamsellem You can specify a path in your package.json to point to a file that exports a function. This function will be invoked in your test window with various parameters that are useful for implementing a custom test runner. Take a look at the source of one of the existing runners for ideas on how to use those parameters to build your own runner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment