Browse Source

replace e2e tests with nightwatch

Evan You 8 years ago
parent
commit
09178ab7e2

+ 3 - 0
.gitignore

@@ -8,3 +8,6 @@ examples/**/build.js
 types/typings
 types/typings
 types/test/*.js
 types/test/*.js
 explorations
 explorations
+*.log
+test/e2e/reports
+test/e2e/screenshots

+ 1 - 1
examples/counter/Counter.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <div>
+  <div id="app">
     Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.
     Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.
     <button @click="increment">+</button>
     <button @click="increment">+</button>
     <button @click="decrement">-</button>
     <button @click="decrement">-</button>

+ 1 - 1
examples/shopping-cart/components/App.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <div class="app">
+  <div id="app">
     <h1>Shopping Cart Example</h1>
     <h1>Shopping Cart Example</h1>
     <hr>
     <hr>
     <h2>Products</h2>
     <h2>Products</h2>

+ 1 - 3
examples/todomvc/components/App.vue

@@ -31,9 +31,7 @@
         <li v-for="(val, key) in filters">
         <li v-for="(val, key) in filters">
           <a :href="'#/' + key"
           <a :href="'#/' + key"
             :class="{ selected: visibility === key }"
             :class="{ selected: visibility === key }"
-            @click="visibility = key">
-            {{ key | capitalize }}
-          </a>
+            @click="visibility = key">{{ key | capitalize }}</a>
         </li>
         </li>
       </ul>
       </ul>
       <button class="clear-completed"
       <button class="clear-completed"

+ 1 - 2
package.json

@@ -12,7 +12,7 @@
     "dev": "cd examples && webpack-dev-server --inline --hot --no-info",
     "dev": "cd examples && webpack-dev-server --inline --hot --no-info",
     "test": "eslint src && npm run test:unit && npm run test:e2e",
     "test": "eslint src && npm run test:unit && npm run test:e2e",
     "test:unit": "jasmine JASMINE_CONFIG_PATH=test/unit/jasmine.json",
     "test:unit": "jasmine JASMINE_CONFIG_PATH=test/unit/jasmine.json",
-    "test:e2e": "npm run build-examples && casperjs test --concise ./test/e2e",
+    "test:e2e": "node test/e2e/runner.js",
     "build": "node build/build.js",
     "build": "node build/build.js",
     "release": "bash build/release.sh",
     "release": "bash build/release.sh",
     "docs": "cd docs && gitbook serve",
     "docs": "cd docs && gitbook serve",
@@ -37,7 +37,6 @@
     "babel-preset-es2015-rollup": "^1.1.1",
     "babel-preset-es2015-rollup": "^1.1.1",
     "babel-preset-stage-2": "^6.1.18",
     "babel-preset-stage-2": "^6.1.18",
     "babel-runtime": "^6.0.0",
     "babel-runtime": "^6.0.0",
-    "casperjs": "^1.1.0-beta5",
     "css-loader": "^0.23.1",
     "css-loader": "^0.23.1",
     "eslint": "^2.2.0",
     "eslint": "^2.2.0",
     "eslint-config-vue": "^1.0.0",
     "eslint-config-vue": "^1.0.0",

+ 0 - 36
test/e2e/cart.js

@@ -1,36 +0,0 @@
-casper.test.begin('shopping-cart', 16, function (test) {
-  casper
-  .start('examples/shopping-cart/index.html')
-  .wait(120) // api simulation
-  .then(function () {
-    test.assertElementCount('li', 3)
-    test.assertElementCount('.cart button[disabled]', 1)
-    test.assertSelectorHasText('li:nth-child(1)', 'iPad 4 Mini')
-    test.assertSelectorHasText('.cart', 'Please add some products to cart')
-    test.assertSelectorHasText('.cart', 'Total: $0.00')
-  })
-  .thenClick('li:nth-child(1) button', function () {
-    test.assertSelectorHasText('.cart', 'iPad 4 Mini - $500.01 x 1')
-    test.assertSelectorHasText('.cart', 'Total: $500.01')
-  })
-  .thenClick('li:nth-child(1) button', function () {
-    test.assertSelectorHasText('.cart', 'iPad 4 Mini - $500.01 x 2')
-    test.assertSelectorHasText('.cart', 'Total: $1,000.02')
-    test.assertElementCount('li:nth-child(1) button[disabled]', 1)
-  })
-  .thenClick('li:nth-child(2) button', function () {
-    test.assertSelectorHasText('.cart', 'H&M T-Shirt White - $10.99 x 1')
-    test.assertSelectorHasText('.cart', 'Total: $1,011.01')
-  })
-  .thenClick('.cart button')
-  .wait(120)
-  .then(function () {
-    test.assertSelectorHasText('.cart', 'Please add some products to cart')
-    test.assertSelectorHasText('.cart', 'Total: $0.00')
-    test.assertSelectorHasText('.cart', 'Checkout successful')
-    test.assertElementCount('.cart button[disabled]', 1)
-  })
-  .run(function () {
-    test.done()
-  })
-})

+ 0 - 52
test/e2e/chat.js

@@ -1,52 +0,0 @@
-casper.test.begin('chat', 16, function (test) {
-  casper
-  .start('examples/chat/index.html')
-  .then(function () {
-    test.assertSelectorHasText('.thread-count', 'Unread threads: 2')
-    test.assertElementCount('.thread-list-item', 3)
-    test.assertSelectorHasText('.thread-list-item.active', 'Functional Heads')
-    test.assertSelectorHasText('.message-thread-heading', 'Functional Heads')
-    test.assertElementCount('.message-list-item', 2)
-    test.assertSelectorHasText('.message-list-item:nth-child(1) .message-author-name', 'Bill')
-    test.assertSelectorHasText('.message-list-item:nth-child(1) .message-text', 'Hey Brian')
-  })
-  .then(function () {
-    this.sendKeys('.message-composer', 'hi')
-    enter()
-  })
-  .wait(50) // the demo simulates API latency
-  .then(function () {
-    test.assertElementCount('.message-list-item', 3)
-    test.assertSelectorHasText('.message-list-item:nth-child(3)', 'hi')
-  })
-  .thenClick('.thread-list-item:nth-child(2)', function () {
-    test.assertSelectorHasText('.thread-list-item.active', 'Dave and Bill')
-    test.assertSelectorHasText('.message-thread-heading', 'Dave and Bill')
-    test.assertElementCount('.message-list-item', 2)
-    test.assertSelectorHasText('.message-list-item:nth-child(1) .message-author-name', 'Bill')
-    test.assertSelectorHasText('.message-list-item:nth-child(1) .message-text', 'Hey Dave')
-  })
-  .then(function () {
-    this.sendKeys('.message-composer', 'hi')
-    enter()
-  })
-  .wait(50) // the demo simulates API latency
-  .then(function () {
-    test.assertElementCount('.message-list-item', 3)
-    test.assertSelectorHasText('.message-list-item:nth-child(3)', 'hi')
-  })
-  .run(function () {
-    test.done()
-  })
-})
-
-function enter () {
-  casper.evaluate(function () {
-    // casper.mouseEvent can't set keyCode
-    var field = document.querySelector('.message-composer')
-    var e = document.createEvent('HTMLEvents')
-    e.initEvent('keyup', true, true)
-    e.keyCode = 13
-    field.dispatchEvent(e)
-  })
-}

+ 0 - 32
test/e2e/counter.js

@@ -1,32 +0,0 @@
-casper.test.begin('counter', 8, function (test) {
-  casper
-  .start('examples/counter/index.html')
-  .then(function () {
-    test.assertSelectorHasText('div', 'Clicked: 0 times')
-  })
-  .thenClick('button:nth-child(1)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 1 times')
-  })
-  .thenClick('button:nth-child(2)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 0 times')
-  })
-  .thenClick('button:nth-child(3)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 0 times')
-  })
-  .thenClick('button:nth-child(1)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 1 times')
-  })
-  .thenClick('button:nth-child(3)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 2 times')
-  })
-  .thenClick('button:nth-child(4)', function () {
-    test.assertSelectorHasText('div', 'Clicked: 2 times')
-  })
-  .wait(1000)
-  .then(function () {
-    test.assertSelectorHasText('div', 'Clicked: 3 times')
-  })
-  .run(function () {
-    test.done()
-  })
-})

+ 47 - 0
test/e2e/nightwatch.config.js

@@ -0,0 +1,47 @@
+// http://nightwatchjs.org/guide#settings-file
+module.exports = {
+  'src_folders': ['test/e2e/specs'],
+  'output_folder': 'test/e2e/reports',
+  'custom_commands_path': ['node_modules/nightwatch-helpers/commands'],
+  'custom_assertions_path': ['node_modules/nightwatch-helpers/assertions'],
+
+  'selenium': {
+    'start_process': true,
+    'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
+    'host': '127.0.0.1',
+    'port': 4444,
+    'cli_args': {
+      'webdriver.chrome.driver': 'node_modules/chromedriver/lib/chromedriver/chromedriver'
+    }
+  },
+
+  'test_settings': {
+    'default': {
+      'selenium_port': 4444,
+      'selenium_host': 'localhost',
+      'silent': true,
+      'screenshots': {
+        'enabled': true,
+        'on_failure': true,
+        'on_error': false,
+        'path': 'test/e2e/screenshots'
+      }
+    },
+
+    'chrome': {
+      'desiredCapabilities': {
+        'browserName': 'chrome',
+        'javascriptEnabled': true,
+        'acceptSslCerts': true
+      }
+    },
+
+    'phantomjs': {
+      'desiredCapabilities': {
+        'browserName': 'phantomjs',
+        'javascriptEnabled': true,
+        'acceptSslCerts': true
+      }
+    }
+  }
+}

+ 35 - 0
test/e2e/runner.js

@@ -0,0 +1,35 @@
+var path = require('path')
+var spawn = require('cross-spawn')
+var args = process.argv.slice(2)
+
+var server = args.indexOf('--dev') > -1
+  ? null
+  : require('../../examples/server')
+
+if (args.indexOf('--config') === -1) {
+  args = args.concat(['--config', 'test/e2e/nightwatch.config.js'])
+}
+if (args.indexOf('--env') === -1) {
+  args = args.concat(['--env', 'phantomjs'])
+}
+var i = args.indexOf('--test')
+if (i > -1) {
+  args[i + 1] = 'test/e2e/specs/' + args[i + 1]
+}
+if (args.indexOf('phantomjs') > -1) {
+  process.env.PHANTOMJS = true
+}
+
+var runner = spawn('./node_modules/.bin/nightwatch', args, {
+  stdio: 'inherit'
+})
+
+runner.on('exit', function (code) {
+  server && server.close()
+  process.exit(code)
+})
+
+runner.on('error', function (err) {
+  server && server.close()
+  throw err
+})

+ 30 - 0
test/e2e/specs/cart.js

@@ -0,0 +1,30 @@
+module.exports = {
+  'shopping cart': function (browser) {
+    browser
+    .url('http://localhost:8080/shopping-cart/')
+      .waitForElementVisible('#app', 1000)
+      .waitFor(120) // api simulation
+      .assert.count('li', 3)
+      .assert.count('.cart button[disabled]', 1)
+      .assert.containsText('li:nth-child(1)', 'iPad 4 Mini')
+      .assert.containsText('.cart', 'Please add some products to cart')
+      .assert.containsText('.cart', 'Total: $0.00')
+      .click('li:nth-child(1) button')
+      .assert.containsText('.cart', 'iPad 4 Mini - $500.01 x 1')
+      .assert.containsText('.cart', 'Total: $500.01')
+      .click('li:nth-child(1) button')
+      .assert.containsText('.cart', 'iPad 4 Mini - $500.01 x 2')
+      .assert.containsText('.cart', 'Total: $1,000.02')
+      .assert.count('li:nth-child(1) button[disabled]', 1)
+      .click('li:nth-child(2) button')
+      .assert.containsText('.cart', 'H&M T-Shirt White - $10.99 x 1')
+      .assert.containsText('.cart', 'Total: $1,011.01')
+      .click('.cart button')
+      .waitFor(120)
+      .assert.containsText('.cart', 'Please add some products to cart')
+      .assert.containsText('.cart', 'Total: $0.00')
+      .assert.containsText('.cart', 'Checkout successful')
+      .assert.count('.cart button[disabled]', 1)
+      .end()
+  }
+}

+ 28 - 0
test/e2e/specs/chat.js

@@ -0,0 +1,28 @@
+module.exports = {
+  'chat': function (browser) {
+    browser
+      .url('http://localhost:8080/chat/')
+      .waitForElementVisible('.chatapp', 1000)
+      .assert.containsText('.thread-count', 'Unread threads: 2')
+      .assert.count('.thread-list-item', 3)
+      .assert.containsText('.thread-list-item.active', 'Functional Heads')
+      .assert.containsText('.message-thread-heading', 'Functional Heads')
+      .assert.count('.message-list-item', 2)
+      .assert.containsText('.message-list-item:nth-child(1) .message-author-name', 'Bill')
+      .assert.containsText('.message-list-item:nth-child(1) .message-text', 'Hey Brian')
+      .enterValue('.message-composer', 'hi')
+      .waitFor(50) // fake api
+      .assert.count('.message-list-item', 3)
+      .assert.containsText('.message-list-item:nth-child(3)', 'hi')
+      .click('.thread-list-item:nth-child(2)')
+      .assert.containsText('.thread-list-item.active', 'Dave and Bill')
+      .assert.containsText('.message-thread-heading', 'Dave and Bill')
+      .assert.count('.message-list-item', 2)
+      .assert.containsText('.message-list-item:nth-child(1) .message-author-name', 'Bill')
+      .assert.containsText('.message-list-item:nth-child(1) .message-text', 'Hey Dave')
+      .enterValue('.message-composer', 'hi')
+      .waitFor(50) // fake api
+      .assert.count('.message-list-item', 3)
+      .assert.containsText('.message-list-item:nth-child(3)', 'hi')
+  }
+}

+ 23 - 0
test/e2e/specs/counter.js

@@ -0,0 +1,23 @@
+module.exports = {
+  'counter': function (browser) {
+    browser
+    .url('http://localhost:8080/counter/')
+      .waitForElementVisible('#app', 1000)
+      .assert.containsText('div', 'Clicked: 0 times')
+      .click('button:nth-child(1)')
+      .assert.containsText('div', 'Clicked: 1 times')
+      .click('button:nth-child(2)')
+      .assert.containsText('div', 'Clicked: 0 times')
+      .click('button:nth-child(3)')
+      .assert.containsText('div', 'Clicked: 0 times')
+      .click('button:nth-child(1)')
+      .assert.containsText('div', 'Clicked: 1 times')
+      .click('button:nth-child(3)')
+      .assert.containsText('div', 'Clicked: 2 times')
+      .click('button:nth-child(4)')
+      .assert.containsText('div', 'Clicked: 2 times')
+      .waitFor(1000)
+      .assert.containsText('div', 'Clicked: 3 times')
+      .end()
+  }
+}

+ 154 - 0
test/e2e/specs/todomvc.js

@@ -0,0 +1,154 @@
+module.exports = {
+  'todomvc': function (browser) {
+    browser
+    .url('http://localhost:8080/todomvc/')
+      .waitForElementVisible('.todoapp', 1000)
+      .assert.notVisible('.main')
+      .assert.notVisible('.footer')
+      .assert.count('.filters .selected', 1)
+      .assert.evaluate(function () {
+        return document.querySelector('.filters .selected').textContent === 'All'
+      }, null, 'filter should be "All"')
+
+    createNewItem('test')
+      .assert.count('.todo', 1)
+      .assert.notVisible('.todo .edit')
+      .assert.containsText('.todo label', 'test')
+      .assert.containsText('.todo-count strong', '1')
+      .assert.checked('.todo .toggle', false)
+      .assert.visible('.main')
+      .assert.visible('.footer')
+      .assert.notVisible('.clear-completed')
+      .assert.value('.new-todo', '')
+
+    createNewItem('test2')
+      .assert.count('.todo', 2)
+      .assert.containsText('.todo:nth-child(2) label', 'test2')
+      .assert.containsText('.todo-count strong', '2')
+
+    // toggle
+    browser
+      .click('.todo .toggle')
+      .assert.count('.todo.completed', 1)
+      .assert.cssClassPresent('.todo:nth-child(1)', 'completed')
+      .assert.containsText('.todo-count strong', '1')
+      .assert.visible('.clear-completed')
+
+    createNewItem('test3')
+      .assert.count('.todo', 3)
+      .assert.containsText('.todo:nth-child(3) label', 'test3')
+      .assert.containsText('.todo-count strong', '2')
+
+    createNewItem('test4')
+    createNewItem('test5')
+      .assert.count('.todo', 5)
+      .assert.containsText('.todo-count strong', '4')
+
+    // toggle more
+    browser
+      .click('.todo:nth-child(4) .toggle')
+      .click('.todo:nth-child(5) .toggle')
+      .assert.count('.todo.completed', 3)
+      .assert.containsText('.todo-count strong', '2')
+
+    // remove
+    removeItemAt(1)
+      .assert.count('.todo', 4)
+      .assert.count('.todo.completed', 2)
+      .assert.containsText('.todo-count strong', '2')
+    removeItemAt(2)
+      .assert.count('.todo', 3)
+      .assert.count('.todo.completed', 2)
+      .assert.containsText('.todo-count strong', '1')
+
+    // remove all
+    browser
+      .click('.clear-completed')
+      .assert.count('.todo', 1)
+      .assert.containsText('.todo label', 'test2')
+      .assert.count('.todo.completed', 0)
+      .assert.containsText('.todo-count strong', '1')
+      .assert.notVisible('.clear-completed')
+
+    // prepare to test filters
+    createNewItem('test')
+    createNewItem('test')
+      .click('.todo:nth-child(2) .toggle')
+      .click('.todo:nth-child(3) .toggle')
+
+    // active filter
+    browser
+      .click('.filters li:nth-child(2) a')
+      .assert.count('.todo', 1)
+      .assert.count('.todo.completed', 0)
+      // add item with filter active
+      createNewItem('test')
+      .assert.count('.todo', 2)
+
+    // complted filter
+    browser.click('.filters li:nth-child(3) a')
+      .assert.count('.todo', 2)
+      .assert.count('.todo.completed', 2)
+
+    // toggling with filter active
+    browser
+      .click('.todo .toggle')
+      .assert.count('.todo', 1)
+      .click('.filters li:nth-child(2) a')
+      .assert.count('.todo', 3)
+      .click('.todo .toggle')
+      .assert.count('.todo', 2)
+
+    // editing triggered by blur
+    browser
+      .click('.filters li:nth-child(1) a')
+      .dblClick('.todo:nth-child(1) label')
+      .assert.count('.todo.editing', 1)
+      .assert.focused('.todo:nth-child(1) .edit')
+      .clearValue('.todo:nth-child(1) .edit')
+      .setValue('.todo:nth-child(1) .edit', 'edited!')
+      .click('footer') // blur
+      .assert.count('.todo.editing', 0)
+      .assert.containsText('.todo:nth-child(1) label', 'edited!')
+
+    // editing triggered by enter
+    browser
+      .dblClick('.todo label')
+      .enterValue('.todo:nth-child(1) .edit', 'edited again!')
+      .assert.count('.todo.editing', 0)
+      .assert.containsText('.todo:nth-child(1) label', 'edited again!')
+
+    // cancel
+    browser
+      .dblClick('.todo label')
+      .clearValue('.todo:nth-child(1) .edit')
+      .setValue('.todo:nth-child(1) .edit', 'edited!')
+      .trigger('.todo:nth-child(1) .edit', 'keyup', 27)
+      .assert.count('.todo.editing', 0)
+      .assert.containsText('.todo:nth-child(1) label', 'edited again!')
+
+    // empty value should remove
+    browser
+      .dblClick('.todo label')
+      .enterValue('.todo:nth-child(1) .edit', ' ')
+      .assert.count('.todo', 3)
+
+    // toggle all
+    browser
+      .click('.toggle-all')
+      .assert.count('.todo.completed', 3)
+      .click('.toggle-all')
+      .assert.count('.todo:not(.completed)', 3)
+      .end()
+
+    function createNewItem (text) {
+      return browser.enterValue('.new-todo', text)
+    }
+
+    function removeItemAt (n) {
+      return browser
+        .moveToElement('.todo:nth-child(' + n + ')', 10, 10)
+        .click('.todo:nth-child(' + n + ') .destroy')
+    }
+  }
+}

+ 45 - 45
test/e2e/todomvc.js

@@ -4,8 +4,8 @@ casper.test.begin('todomvc', 57, function (test) {
   .then(function () {
   .then(function () {
     test.assertNotVisible('.main', '.main should be hidden')
     test.assertNotVisible('.main', '.main should be hidden')
     test.assertNotVisible('.footer', '.footer should be hidden')
     test.assertNotVisible('.footer', '.footer should be hidden')
-    test.assertElementCount('.filters .selected', 1, 'should have one filter selected')
-    test.assertSelectorHasText('.filters .selected', 'All', 'default filter should be "All"')
+    .assert.count('.filters .selected', 1, 'should have one filter selected')
+    .assert.containsText('.filters .selected', 'All', 'default filter should be "All"')
   })
   })
 
 
   // let's add a new item -----------------------------------------------
   // let's add a new item -----------------------------------------------
@@ -19,10 +19,10 @@ casper.test.begin('todomvc', 57, function (test) {
     createNewItem()
     createNewItem()
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 1, 'new item should be created')
+    .assert.count('.todo', 1, 'new item should be created')
     test.assertNotVisible('.todo .edit', 'new item edit box should be hidden')
     test.assertNotVisible('.todo .edit', 'new item edit box should be hidden')
-    test.assertSelectorHasText('.todo label', 'test', 'new item should have correct label text')
-    test.assertSelectorHasText('.todo-count strong', '1', 'remaining count should be 1')
+    .assert.containsText('.todo label', 'test', 'new item should have correct label text')
+    .assert.containsText('.todo-count strong', '1', 'remaining count should be 1')
     test.assertEvalEquals(function () {
     test.assertEvalEquals(function () {
       return __utils__.findOne('.todo .toggle').checked
       return __utils__.findOne('.todo .toggle').checked
     }, false, 'new item toggle should not be checked')
     }, false, 'new item toggle should not be checked')
@@ -38,19 +38,19 @@ casper.test.begin('todomvc', 57, function (test) {
     createNewItem('test2')
     createNewItem('test2')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 2, 'should have 2 items now')
-    test.assertSelectorHasText('.todo:nth-child(2) label', 'test2', 'new item should have correct label text')
-    test.assertSelectorHasText('.todo-count strong', '2', 'remaining count should be 2')
+    .assert.count('.todo', 2, 'should have 2 items now')
+    .assert.containsText('.todo:nth-child(2) label', 'test2', 'new item should have correct label text')
+    .assert.containsText('.todo-count strong', '2', 'remaining count should be 2')
   })
   })
 
 
   // mark one item as completed -----------------------------------------
   // mark one item as completed -----------------------------------------
 
 
   .thenClick('.todo .toggle', function () {
   .thenClick('.todo .toggle', function () {
-    test.assertElementCount('.todo.completed', 1, 'should have 1 item completed')
+    .assert.count('.todo.completed', 1, 'should have 1 item completed')
     test.assertEval(function () {
     test.assertEval(function () {
       return __utils__.findOne('.todo').classList.contains('completed')
       return __utils__.findOne('.todo').classList.contains('completed')
     }, 'it should be the first one')
     }, 'it should be the first one')
-    test.assertSelectorHasText('.todo-count strong', '1', 'remaining count should be 1')
+    .assert.containsText('.todo-count strong', '1', 'remaining count should be 1')
     test.assertVisible('.clear-completed', '.clear-completed should now be visible')
     test.assertVisible('.clear-completed', '.clear-completed should now be visible')
   })
   })
 
 
@@ -60,9 +60,9 @@ casper.test.begin('todomvc', 57, function (test) {
     createNewItem('test3')
     createNewItem('test3')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 3, 'should have 3 items now')
-    test.assertSelectorHasText('.todo:nth-child(3) label', 'test3', 'new item should have correct label text')
-    test.assertSelectorHasText('.todo-count strong', '2', 'remaining count should be 2')
+    .assert.count('.todo', 3, 'should have 3 items now')
+    .assert.containsText('.todo:nth-child(3) label', 'test3', 'new item should have correct label text')
+    .assert.containsText('.todo-count strong', '2', 'remaining count should be 2')
   })
   })
 
 
   // add moreeee, now we assume they all work properly ------------------
   // add moreeee, now we assume they all work properly ------------------
@@ -72,8 +72,8 @@ casper.test.begin('todomvc', 57, function (test) {
     createNewItem('test5')
     createNewItem('test5')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 5, 'should have 5 items now')
-    test.assertSelectorHasText('.todo-count strong', '4', 'remaining count should be 4')
+    .assert.count('.todo', 5, 'should have 5 items now')
+    .assert.containsText('.todo-count strong', '4', 'remaining count should be 4')
   })
   })
 
 
   // check more as completed --------------------------------------------
   // check more as completed --------------------------------------------
@@ -82,33 +82,33 @@ casper.test.begin('todomvc', 57, function (test) {
     this.click('.todo:nth-child(5) .toggle')
     this.click('.todo:nth-child(5) .toggle')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo.completed', 3, 'should have 3 item completed')
-    test.assertSelectorHasText('.todo-count strong', '2', 'remaining count should be 2')
+    .assert.count('.todo.completed', 3, 'should have 3 item completed')
+    .assert.containsText('.todo-count strong', '2', 'remaining count should be 2')
   })
   })
 
 
   // remove a completed item --------------------------------------------
   // remove a completed item --------------------------------------------
 
 
   .thenClick('.todo:nth-child(1) .destroy', function () {
   .thenClick('.todo:nth-child(1) .destroy', function () {
-    test.assertElementCount('.todo', 4, 'should have 4 items now')
-    test.assertElementCount('.todo.completed', 2, 'should have 2 item completed')
-    test.assertSelectorHasText('.todo-count strong', '2', 'remaining count should be 2')
+    .assert.count('.todo', 4, 'should have 4 items now')
+    .assert.count('.todo.completed', 2, 'should have 2 item completed')
+    .assert.containsText('.todo-count strong', '2', 'remaining count should be 2')
   })
   })
 
 
   // remove a incompleted item ------------------------------------------
   // remove a incompleted item ------------------------------------------
 
 
   .thenClick('.todo:nth-child(2) .destroy', function () {
   .thenClick('.todo:nth-child(2) .destroy', function () {
-    test.assertElementCount('.todo', 3, 'should have 3 items now')
-    test.assertElementCount('.todo.completed', 2, 'should have 2 item completed')
-    test.assertSelectorHasText('.todo-count strong', '1', 'remaining count should be 1')
+    .assert.count('.todo', 3, 'should have 3 items now')
+    .assert.count('.todo.completed', 2, 'should have 2 item completed')
+    .assert.containsText('.todo-count strong', '1', 'remaining count should be 1')
   })
   })
 
 
   // remove all completed ------------------------------------------------
   // remove all completed ------------------------------------------------
 
 
   .thenClick('.clear-completed', function () {
   .thenClick('.clear-completed', function () {
-    test.assertElementCount('.todo', 1, 'should have 1 item now')
-    test.assertSelectorHasText('.todo label', 'test2', 'the remaining one should be the second one')
-    test.assertElementCount('.todo.completed', 0, 'should have no completed items now')
-    test.assertSelectorHasText('.todo-count strong', '1', 'remaining count should be 1')
+    .assert.count('.todo', 1, 'should have 1 item now')
+    .assert.containsText('.todo label', 'test2', 'the remaining one should be the second one')
+    .assert.count('.todo.completed', 0, 'should have no completed items now')
+    .assert.containsText('.todo-count strong', '1', 'remaining count should be 1')
     test.assertNotVisible('.clear-completed', '.clear-completed should be hidden')
     test.assertNotVisible('.clear-completed', '.clear-completed should be hidden')
   })
   })
 
 
@@ -124,8 +124,8 @@ casper.test.begin('todomvc', 57, function (test) {
 
 
   // active filter ----------------------------------------------------------
   // active filter ----------------------------------------------------------
   .thenClick('.filters li:nth-child(2) a', function () {
   .thenClick('.filters li:nth-child(2) a', function () {
-    test.assertElementCount('.todo', 1, 'filter active should have 1 item')
-    test.assertElementCount('.todo.completed', 0, 'visible items should be incomplete')
+    .assert.count('.todo', 1, 'filter active should have 1 item')
+    .assert.count('.todo.completed', 0, 'visible items should be incomplete')
   })
   })
 
 
   // add item with filter active --------------------------------------------
   // add item with filter active --------------------------------------------
@@ -134,24 +134,24 @@ casper.test.begin('todomvc', 57, function (test) {
     createNewItem('test')
     createNewItem('test')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 2, 'should be able to create new item when fitler active')
+    .assert.count('.todo', 2, 'should be able to create new item when fitler active')
   })
   })
 
 
   // completed filter -------------------------------------------------------
   // completed filter -------------------------------------------------------
   .thenClick('.filters li:nth-child(3) a', function () {
   .thenClick('.filters li:nth-child(3) a', function () {
-    test.assertElementCount('.todo', 2, 'filter completed should have 2 items')
-    test.assertElementCount('.todo.completed', 2, 'visible items should be completed')
+    .assert.count('.todo', 2, 'filter completed should have 2 items')
+    .assert.count('.todo.completed', 2, 'visible items should be completed')
   })
   })
 
 
   // toggling todos when filter is active -----------------------------------
   // toggling todos when filter is active -----------------------------------
   .thenClick('.todo .toggle', function () {
   .thenClick('.todo .toggle', function () {
-    test.assertElementCount('.todo', 1, 'should have only 1 item left')
+    .assert.count('.todo', 1, 'should have only 1 item left')
   })
   })
   .thenClick('.filters li:nth-child(2) a', function () {
   .thenClick('.filters li:nth-child(2) a', function () {
-    test.assertElementCount('.todo', 3, 'should have only 3 items now')
+    .assert.count('.todo', 3, 'should have only 3 items now')
   })
   })
   .thenClick('.todo .toggle', function () {
   .thenClick('.todo .toggle', function () {
-    test.assertElementCount('.todo', 2, 'should have only 2 items now')
+    .assert.count('.todo', 2, 'should have only 2 items now')
   })
   })
 
 
   // test editing triggered by blur ------------------------------------------
   // test editing triggered by blur ------------------------------------------
@@ -160,7 +160,7 @@ casper.test.begin('todomvc', 57, function (test) {
     doubleClick('.todo:nth-child(1) label')
     doubleClick('.todo:nth-child(1) label')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo.editing', 1, 'should have one item being edited')
+    .assert.count('.todo.editing', 1, 'should have one item being edited')
     test.assertEval(function () {
     test.assertEval(function () {
       var input = document.querySelector('.todo:nth-child(1) .edit')
       var input = document.querySelector('.todo:nth-child(1) .edit')
       return input === document.activeElement
       return input === document.activeElement
@@ -171,8 +171,8 @@ casper.test.begin('todomvc', 57, function (test) {
     this.sendKeys('.todo:nth-child(1) .edit', 'edited!') // doneEdit triggered by blur
     this.sendKeys('.todo:nth-child(1) .edit', 'edited!') // doneEdit triggered by blur
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
-    test.assertSelectorHasText('.todo:nth-child(1) label', 'edited!', 'item should have updated text')
+    .assert.count('.todo.editing', 0, 'item should no longer be edited')
+    .assert.containsText('.todo:nth-child(1) label', 'edited!', 'item should have updated text')
   })
   })
 
 
   // test editing triggered by enter ----------------------------------------
   // test editing triggered by enter ----------------------------------------
@@ -185,8 +185,8 @@ casper.test.begin('todomvc', 57, function (test) {
     keyUp(13) // Enter
     keyUp(13) // Enter
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
-    test.assertSelectorHasText('.todo:nth-child(1) label', 'edited again!', 'item should have updated text')
+    .assert.count('.todo.editing', 0, 'item should no longer be edited')
+    .assert.containsText('.todo:nth-child(1) label', 'edited again!', 'item should have updated text')
   })
   })
 
 
   // test cancel ------------------------------------------------------------
   // test cancel ------------------------------------------------------------
@@ -199,8 +199,8 @@ casper.test.begin('todomvc', 57, function (test) {
     keyUp(27) // ESC
     keyUp(27) // ESC
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
-    test.assertSelectorHasText('.todo label', 'edited again!', 'item should not have updated text')
+    .assert.count('.todo.editing', 0, 'item should no longer be edited')
+    .assert.containsText('.todo label', 'edited again!', 'item should not have updated text')
   })
   })
 
 
   // test empty input remove ------------------------------------------------
   // test empty input remove ------------------------------------------------
@@ -212,15 +212,15 @@ casper.test.begin('todomvc', 57, function (test) {
     this.sendKeys('.todo:nth-child(1) .edit', ' ')
     this.sendKeys('.todo:nth-child(1) .edit', ' ')
   })
   })
   .then(function () {
   .then(function () {
-    test.assertElementCount('.todo', 3, 'item should have been deleted')
+    .assert.count('.todo', 3, 'item should have been deleted')
   })
   })
 
 
   // test toggle all
   // test toggle all
   .thenClick('.toggle-all', function () {
   .thenClick('.toggle-all', function () {
-    test.assertElementCount('.todo.completed', 3, 'should toggle all items to completed')
+    .assert.count('.todo.completed', 3, 'should toggle all items to completed')
   })
   })
   .thenClick('.toggle-all', function () {
   .thenClick('.toggle-all', function () {
-    test.assertElementCount('.todo:not(.completed)', 3, 'should toggle all items to active')
+    .assert.count('.todo:not(.completed)', 3, 'should toggle all items to active')
   })
   })
 
 
   // run
   // run