Writing integration specs for a package


#1

Has anybody written any, or have any insight into, integration specs for an Atom package.

What I’m aiming to do is run some integration tests where I ‘click’ on an item in the tree-view, and check what’s happening with the tabs.

For example:

it "does some stuff", ->
  expect(atom.workspaceView.find(".tab").length).toBe 0
  treeEntries = atom.workspaceView.find(".tree-view .file")
  treeEntries[0].click()
  expect(atom.workspaceView.find(".tab").length).toBe 1

I’ve tried setting up the test like this:

{WorkspaceView}  = require "atom"

describe "My Integration Test", ->
  beforeEach ->
    atom.workspaceView = new WorkspaceView

    waitsForPromise ->
      atom.packages.activatePackage("tabs")
    waitsForPromise ->
      atom.packages.activatePackage("tree-view")
    waitsForPromise ->
      atom.project.open("sample1.js") # Test fixture

  it "does some stuff", ->
    # Same as above

…which doesn’t work. No errors occur, but the DOM in atom.workspaceView is not updated after ‘clicking’ on any tree-view entries.


#2

I just got done updating my white-cursor package and added some integration tests that involve updating the DOM. The secret was adding the atom.workspaceView.attachToDom() call in the setup logic:


#3

https://atom.io/packages/wihte-cursor

:slight_smile:


#4

Awesome, thanks @leedohm! atom.workspaceView.attach ToDom() is great for integration specs as it let’s you see what’s going in the DOM.

Ran into another issue with my use case, though, which is that clicking on a tree entry doesn’t open up a tab. I’m thinking the reason for this is because everything is based on events. When clicking (via jQuery) in the integration test, the resulting event may not have enough time to propagate and activate callbacks before the test is over.

In any case, thanks for the swift response!


#5

Personally, I don’t think you need to go that far in your integration tests. Assuming you’re talking about the standard Tree View, if clicking on an entry doesn’t open a tab then it isn’t your bug to fix. Most of the time, this is the pattern that is used to open a file in tests:

https://github.com/lee-dohm/tabs-to-spaces/blob/master/spec/tabs-to-spaces-spec.coffee#L18-L19


#6

That makes sense.

For the sake of the question, I really simplified my use-case, though. My package applies a certain class to the tab, or closes a tab/editor, in certain situations (such as double clicking on a tree entry, double clicking on the tab, editing the editor associated with the tab, etc.), which is what I’m trying to test.

I would love to be able to do the mentioned actions in an integration test, and see the correct classes being applied and that the correct tabs/editors are in the pane.

Your answer definitely gets me most of the way there.

Seems like the event-based nature of the different packages interacting messes it up, though. If I step through the test in the dev tools, it works perfectly. When I run it normally, though, it fails.


#7

If you’re duplicating the Sublime-style file preview, you might just want to wait a bit. Preview and “smart tabs” is officially on the roadmap now:

That doesn’t help with your question, of course. For that, you might want to have the things that you need to wait on raise an event that you can hook in your tests or you can use setTimeout to wait a certain amount of time for things to percolate through the UI before you check.


#8

I am duplicating the Sublime-style file preview. While it’ll be great once this is in Atom out of the box, I’m enjoying making the package. Now I just need to figure out how to do integration specs…

Anyway, thanks for your help with this.


#9

I figured and wasn’t meaning to discourage you, just giving you all the information :grinning:


#10

No worries. Thanks for your help.

For anybody stumbling across this, it is possible to do this. After activating the packages you want, do something like this:

treeEntry1 = treeView.find(".name[data-name='sample1.js']")
treeEntry1.click()
waits(50)
runs ->
  expect(tabsView.find(".tab").length).toBe 1
  expect(tabsView.find(".active .title").attr("data-name")).toBe "sample1.js"

However, doing this is more trouble than it’s worth. Going through this got me thinking, and now I make a few fake DOM elements in my unit tests.

For instance, create a fake tree-view like this:

tree = $(document.createElement("ol")).addClass("tree-view")
tree.html('<li class="file entry" data-name="test.js">test.js</li>')

# And attach it to the DOM.
atom.workspaceView.prepend(tree)

Now, in my test, I can do tree.find(".file").trigger("dblclick") and test that my package responds correctly.