Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 130 lines (111 sloc) 4.105 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
{ assert, brains, Browser } = require("./helpers")


describe "Promises", ->

  before (done)->
    brains.get "/promises", (req, res)->
      res.send """
<script>document.title = "Loaded"</script>
"""
    brains.ready done


  # The simplest promise looks like this:
  #
  # browser.visit("/promises")
  # .then(done, done)
  #
  # The first done callback is called with no arguments if the promise resolves
  # successfully. The second done callback is called with an error if the
  # promise is rejected, causing the test to fail.

  describe "visit", ->
    before (done)->
      @browser = new Browser()
      @browser.visit("/promises")
        .then(done, done)

    it "should resolve when page is done loading", ->
      assert.equal @browser.document.title, "Loaded"


    # You can chain multiple promises together, each one is used to
    # resolve/reject the next one.
    #
    # In CoffeeScript, a function that doesn't end with return statement will
    # return the value of the last statement.
    #
    # In the first step we have explicit return, that value is used to resolve
    # the next promise.
    #
    # In the second step we have implicit return.
    #
    # In the third step we have an implicit return of a promise. This works out
    # like you expect, resolving of that promise takes us to the fourth step.
    describe "chained", ->
      before (done)->
        @browser = new Browser()
        @browser.visit("/promises")
          .then =>
            # This value is used to resolve the next value
            return "Then"
          .then (value)=>
            @browser.document.title = value
          .then (value)=>
            assert.equal value, "Then"
            # The document title changes only if we wait for the event loop
            @browser.window.setTimeout ->
              @document.title = "Later"
            , 0
            # This promise is used to resolve the next one
            return @browser.wait()
          .then(done, done)

      it "should resolve when page is done loading", ->
        assert.equal @browser.document.title, "Later"


  # In practice you would do something like:
  #
  # browser.visit("/promises")
  # .then ->
  # browser.fill "Email", "armbiter@example.com"
  # browser.fill "Password", "b100d"
  # .then ->
  # browser.pressButton "Let me in"
  # .then done, done
  describe "error", ->
    before (done)->
      browser = new Browser()
      browser.visit("/promises/nosuch")
        .then(done)
        .fail (@error)=>
          done()

    it "should reject with an error", ->
      assert.equal @error.message, "Server returned status code 404"


  # In practice you would do something like:
  #
  # browser.visit("/promises")
  # .then ->
  # assert.equal browser.document.title, "What I expected"
  # .then done, done
  describe "failed assertion", ->
    before (done)->
      browser = new Browser()
      browser.visit("/promises")
        .then ->
          assert.equal browser.document.title, "Ooops", "Assertion haz a fail"
        .fail (@error)=>
          done()

    it "should reject with an error", ->
      assert.equal @error.message, "Assertion haz a fail"


    # Chaining allows us to capture errors once at the very end of the chain.
    #
    # Here we expect an error to happen and that should pass the test.
    #
    # If an error doesn't happen, we call done with a value and that would fail
    # the test.
    describe "chained", ->
      before (done)->
        browser = new Browser()
        browser.visit("/promises")
          .then ->
            assert.equal browser.document.title, "Ooops", "Assertion haz a fail"
          .then ->
            assert.equal browser.document.title, "Ooops", "I'm here against all odds"
          .then ->
            assert.equal browser.document.title, "Ooops", "I'm here against all odds"
          .fail (@error)=>
            done()
          .finally(done)

      it "should reject with an error", ->
        assert.equal @error.message, "Assertion haz a fail"
Something went wrong with that request. Please try again.