diff --git a/.gitignore b/.gitignore index ee10fbf..75954ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ .DS_STORE -node_modules \ No newline at end of file +node_modules +*.jar +chromedriver +chromedriver_linux64.zip diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f52e14d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,70 @@ +language: node_js + +node_js: + - "node" + - "4.1" + - "5.7" + # last working: + - "0.10" + +before_install: + # download and start selenium server - thought that it is not necessary, but without the website is not available within SauceLabs. + # download selenium server - when updating the jar: adapt the SELENIUMVERSION in the test files, too. + # Latest version: http://www.seleniumhq.org/download/ + - curl -O https://selenium-release.storage.googleapis.com/2.50/selenium-server-standalone-2.50.1.jar + # Download and install the chromedriver to be able to execute the browser tests locally + # Latest version: https://sites.google.com/a/chromium.org/chromedriver/downloads + - curl https://chromedriver.storage.googleapis.com/2.20/chromedriver_linux64.zip > chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin && sudo chmod +rx chromedriver /usr/local/bin/chromedriver + # start this before installation to let the server be up and ready without extra waiting time. + - java -jar selenium-server-standalone-2.50.1.jar -Dwebdriver.chrome.driver=./chromedriver & + #- sleep 15 works only on Win7/chrome44 and Win7/ie11 + - sleep 15 + - echo "$(date +%H:%M:%S.%N) - before_install end" + + +before_script: + #- sudo npm install - is automatically executed when install is missing + # node app.js is started in postinstall of npm install + # - node app.js & + # check that the web app is running: + - wget http://localhost:3000/authors || true + # show the beginning of the file - the whole file is not displayed within TRAVIS (because line is too long?) + - cat authors | cut -d'/' -f1 + +script: + - echo "$(date +%H:%M:%S.%N) - script begin" + - sleep 15 + - which node && node -v && npm version || true + # automatically runs `npm test` - therefore the call to mocha is located in package.json + #- mocha --reporter spec + #- export TEST_RUN_LOCAL=true && npm test + #- echo "Run the same tests as above, but using the remote browser." + - export TEST_RUN_LOCAL=false && npm test + +addons: + sauce_connect: true + +env: + global: + - secure: "EvQvxbIQRYDF2NvRDlC8tLeoKabuhi9D+d9y89jsVniyAkMd6HXzU6N+/rsKWnLSYg4fDzadHvXUN+ge9BP1JwMFsH1OOCifBCQQLfnrZQ1phnQEhwl8LDQHVZbRv9Wsk474+NcGkGiDOrjUjbadR6YCrisPt3CHAB1XQw4zIzE=" + - secure: "sAGCSM9rCbANjWeeLnF8i2y450c4EPGUuhlOeFCxnlisduDkiQ6sZgusOlL2NiPQwmHTCcVNn7reBcuUGg1NZJfRt4NMju9OtqzS/JLk2RW9+J3zUkDrx5tQhaivWlThakRAIpNeHpCBEL9tWk68pDZw+Bfc1e1Jh4H3ji91KtI=" +# Use platform configurator https://docs.saucelabs.com/reference/platforms-configurator +# Get the names and versions from the node.js tab in the section "COPY CODE". +# Use underscore for spaces in platform and browser names - they are replaced inside js. + matrix: + - _BROWSER: "firefox" + _PLATFORM: "Linux" + _VERSION: "44.0" + - _BROWSER: "firefox" + _PLATFORM: "Windows_7" + _VERSION: "44.0" + - _BROWSER: "chrome" + _PLATFORM: "Windows_7" + _VERSION: "48.0" + - _BROWSER: "internet_explorer" + _PLATFORM: "Windows_7" + _VERSION: "11.0" +# navigation on the 'page test' does not work - no idea why 8-( + - _BROWSER: "microsoftedge" + _PLATFORM: "Windows_10" + _VERSION: "20.10240" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6cb1975 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ + +SELENIUMVERSION=2.50 +SELENIUMJAR=selenium-server-standalone-$(SELENIUMVERSION).1.jar +SELENIUMPID=$(shell ps -ef | grep 'selenium-server-standalone-$(SELENIUMVERSION).1.jar$$' | cut -d ' ' -f 2-3) +APPPID=$(shell ps -ef | grep 'node app.js$$' | cut -d ' ' -f 2-3) + +all: test + +$(SELENIUMJAR): + @echo "Getting selenium server $(SELENIUMJAR) ..." + curl -O https://selenium-release.storage.googleapis.com/$(SELENIUMVERSION)/$(SELENIUMJAR) + +launchselenium: $(SELENIUMJAR) +ifneq (,$(SELENIUMPID)) + @echo "Selenium server $(SELENIUMJAR) is already running. Process id: $(SELENIUMPID)" +else + @echo "Starting selenium server $(SELENIUMJAR) ..." + java -jar $(SELENIUMJAR) & + sleep 5 +endif + +launchapp: +ifneq (,$(APPPID)) + @echo "node app.js is already running. Process id: $(APPPID)" +else + @echo "Starting node app.js ..." + node app.js & +endif + +test: launchselenium launchapp + npm test + + +.PHONY: all test launchapp launchselenium diff --git a/README b/README deleted file mode 100644 index e69de29..0000000 diff --git a/README.md b/README.md new file mode 100644 index 0000000..23538f5 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +Selenium example +================ + +[![Build Status](https://travis-ci.org/leutloff/selenium-example.png?branch=master)](https://travis-ci.org/leutloff/selenium-example) +[![Dependencies](https://gemnasium.com/leutloff/selenium-example.png)](https://gemnasium.com/leutloff/selenium-example) + + +This project provides two complete simple examples written in JavaScript ([node.js](http://nodejs.org/)) +using the Web Application Test Framework [Selenium](http://docs.seleniumhq.org/projects/webdriver/). +A complete description is provided from the initial author [Nathan Oehlman](https://github.com/nathanoehlman) at +[http://unexpectedliteral.com/2012/05/09/automated-functional-testing-with-javascript-using-mocha-and-selenium-part-2/](http://unexpectedliteral.com/2012/05/09/automated-functional-testing-with-javascript-using-mocha-and-selenium-part-2/). + +The used test runner is [Mocha](http://visionmedia.github.io/mocha/). +Two styles of result checking TDD and BDD are shown. Both styles are provided by the [Chai](http://chaijs.com/) Library. + + +Install the prerequisites +======================== + +For locally running tests: + +- Check that node.js and npm are installed, e.g. execute `node --version` and `npm --version`. + If this is not the case install them, e.g. + sudo apt-get install nodejs -y + curl https://npmjs.org/install.sh > install-npm.sh && sudo sh install-npm.sh +- Install the chromedriver for your system, e.g. for Linux + curl https://chromedriver.storage.googleapis.com/2.21/chromedriver_linux64.zip > chromedriver_linux64.zip + unzip chromedriver_linux64.zip + sudo mv chromedriver /usr/local/bin + sudo chmod +rx /usr/local/bin/chromedriver +- Install Mocha globally: + sudo npm install -g mocha +- To install the other Javascript related parts just execute + sudo npm install +- Then exceute + make + or install and launch selenium server, e.g. + curl -O https://selenium-release.storage.googleapis.com/2.50/selenium-server-standalone-2.50.1.jar + java -jar selenium-server-standalone-2.50.1.jar & + and start the tests with npm + npm test + + +Executing the examples +====================== + +Just call `mocha`. Mocha will then execute all the scripts in the directory named test. + + +Troubleshooting +=============== + +1) The test 'simple internet' fails and there is this message shown: + Only local connections are allowed. + +Ensure that the chromedriver is matching the selenium-server, e.g. try +upgrade both to the latest releases. \ No newline at end of file diff --git a/app.js b/app.js index 0ab7f77..0bb7145 100644 --- a/app.js +++ b/app.js @@ -4,34 +4,36 @@ */ var express = require('express') - , routes = require('./routes'); + , routes = require('./routes') + , http = require('http') + , path = require('path'); +var bodyParser = require('body-parser'); +var serveStatic = require('serve-static'); -var app = module.exports = express.createServer(); +var app = express(); // Configuration - -app.configure(function(){ - app.set('views', __dirname + '/views'); - app.set('view engine', 'jade'); - app.use(express.bodyParser()); - app.use(express.methodOverride()); - app.use(app.router); - app.use(express.static(__dirname + '/public')); -}); - -app.configure('development', function(){ - app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); -}); - -app.configure('production', function(){ - app.use(express.errorHandler()); -}); +app.set('port', process.env.PORT || 3000); +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); +//app.use(favicon(__dirname + '/public/favicon.ico')); - add static-favicon to dependencies, too +//app.use(express.logger('dev')); replaced by morgan +//deprecated: app.use(require('body-parser')()); +app.use(bodyParser.json()) +app.use(require('method-override')()); // Routes - app.get('/', routes.index); app.get('/authors', routes.authors); app.get('/books', routes.books); -app.listen(3000); -console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); +app.use(serveStatic(path.join(__dirname, 'public'))); + +// development only +if ('development' === app.get('env')) { + app.use(require('errorhandler')()); +} + +http.createServer(app).listen(app.get('port'), function(){ + console.log("Express server listening on port %d in %s mode...", app.get('port'), app.get('env')); +}); diff --git a/package.json b/package.json index 299ff16..c2549c2 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,26 @@ { "name": "selenium-example", - "version": "0.0.1", + "version": "1.3.4", + "license": "MIT", "private": true, "dependencies": { - "express": "2.5.8", - "jade": ">= 0.0.1" + "body-parser": "~1.15.0", + "errorhandler": "~1.4.3", + "express": "~4.13.4", + "jade": "~1.11.0", + "method-override": "~2.3.5", + "serve-static": "~1.10.2" }, "devDependencies": { - "mocha": "*", - "chai": "*", - "webdriverjs": "*" + "chai": "~3.5.0", + "mocha": "~2.4.5", + "saucelabs": "~1.2.0", + "util": "~0.10.3", + "webdriverio": "~4.0.5" + }, + "scripts": { + "postinstall" : "node app.js &", + "start" : "node app.js &", + "test": "mocha --reporter spec --timeout 300000 test/simple_internet.js test/simple_test.js test/page_test.js" } -} \ No newline at end of file +} diff --git a/test/page_test.js b/test/page_test.js new file mode 100644 index 0000000..caf277b --- /dev/null +++ b/test/page_test.js @@ -0,0 +1,158 @@ +var chai = require('chai'); +var assert = chai.assert, // TDD + expect = chai.expect, // BDD + webdriverio = require('webdriverio'); + +process.on('uncaughtException', function(e) { + console.log(require('util').inspect(e, {showHidden:true})); +}); + +var options = {}; + +process.on('uncaughtException', function(e) { + console.log(require('util').inspect(e, {showHidden:true})); +}); + +if ((process.env.TRAVIS === 'true') && (process.env.TEST_RUN_LOCAL !== 'true')) { + var BROWSERNAME = (process.env._BROWSER || process.env.BROWSER || 'chrome').replace(/_/g,' '); + var BROWSERVERSION = process.env._VERSION || process.env.VERSION || '*'; + var BROWSERPLATFORM = (process.env._PLATFORM || process.env.PLATFORM || 'Linux').replace(/_/g,' '); + var BUILDID = process.env.TRAVIS_BUILD_ID || 'unknown-buildid'; + var TUNNELIDENTIFIER = process.env.TRAVIS_JOB_NUMBER || 'unknown-jobnumber'; + // select selenium version - for available versions see https://docs.saucelabs.com/reference/test-configuration/#specifying-a-selenium-version + var SELENIUMVERSION = '2.50.1'; + +// console.log('BROWSERNAME: ' + BROWSERNAME); +// console.log('BROWSERVERSION: ' + BROWSERVERSION); +// console.log('BROWSERPLATFORM: ' + BROWSERPLATFORM); +// console.log('BUILDID: ' + BUILDID); +// console.log('TUNNELIDENTIFIER: ' + TUNNELIDENTIFIER); + + var options = { desiredCapabilities: { + browserName: BROWSERNAME, + version: BROWSERVERSION, + platform: BROWSERPLATFORM, + tags: ['examples'], + name: 'Run web app \'page test\' using webdriverio/Selenium.', + build: BUILDID, + 'tunnel-identifier': TUNNELIDENTIFIER, + 'selenium-version': SELENIUMVERSION + }, + // for w/o sauce connect + // host: 'ondemand.saucelabs.com', + // port: 80, + // use with sauce connect: + host: 'localhost', + port: 4445, + user: process.env.SAUCE_USERNAME, + key: process.env.SAUCE_ACCESS_KEY, + logLevel: 'verbose' + }; +} +else +{ + options = { + desiredCapabilities: { + browserName: 'chrome' + } + }; +} + + +describe('Run web app \'page test\' using webdriverio/Selenium.', function() { + this.timeout(300000); + var client = {}; + + before(function(done) { + // console.log('--before--'); + this.timeout(300000); + + client = webdriverio.remote(options); + + // start the session + client.init() + .call(done); + }); + + after(function(done) { + //console.log('--after--'); + client.end() + .call(done); + }); + + beforeEach(function(done) { + //console.log('--beforeEach--'); + this.timeout(300000); // some time is needed for the browser start up, on my system 3000 should work, too. + // Navigate to the URL for each test + client.url('http://localhost:3000') + .call(done); + }); + + it('checks the title only - using TDD style check', function(done) { + // uses property getTitle() + client + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Library'); // TDD + }) + .call(done); + }); + + it('checks the title only, a second time - but using BDD style check', function(done) { + client + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + expect(title).to.have.string('Library'); // BDD + }) + // uses underlying protocol function title() + .title(function(err, result) { + if (err) throw err; + //console.log('2 Title was: ' + result.value); + expect(result.value).to.have.string('Library'); // BDD + }) + .call(done);; + }); + + it('should be able to navigate between the pages', function(done) { + this.timeout(12000); + client + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Library'); + }) + .click('#authors') + .waitForExist('#back', 10000) + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Authors'); + }) + .getText('#author1').then(function(result) { + //console.log('#author1: ' + result); + expect(result).to.have.string('Patrick Rothfuss'); + }) + .click('#back') + .waitForExist('#books', 1000) + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Library'); + }) + .click('#books') + .waitForExist('#back', 1000) + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Books'); + }) + .getText('#book1').then(function(result) { + //console.log('#book1: ' + result); + assert.strictEqual(result, 'Wise Man\'s Fear'); + }) + .click('#back') + .waitForExist('#authors', 1000) + .getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Library'); + }) + .call(done); + }); + +}); diff --git a/test/simple_internet.js b/test/simple_internet.js new file mode 100644 index 0000000..3a8ea2d --- /dev/null +++ b/test/simple_internet.js @@ -0,0 +1,90 @@ +var assert = require('chai').assert, + webdriverio = require('webdriverio'); +var env = GLOBAL.env = {}; +var client = {}; + +//console.log('process.env.TRAVIS: %s', process.env.TRAVIS || 'no'); +//console.log('TEST_RUN_LOCAL: %s', process.env.TEST_RUN_LOCAL || '-'); + +process.on('uncaughtException', function(e) { + console.log(require('util').inspect(e, {showHidden:true})); +}); + +if ((process.env.TRAVIS === 'true') && (process.env.TEST_RUN_LOCAL !== 'true')) { + console.log('running tests (simple internet) on SauceLabs using sauce connect...'); + + var BROWSERNAME = (process.env._BROWSER || process.env.BROWSER || 'chrome').replace(/_/g,' '); + var BROWSERVERSION = process.env._VERSION || process.env.VERSION || '*'; + var BROWSERPLATFORM = (process.env._PLATFORM || process.env.PLATFORM || 'Linux').replace(/_/g,' '); + var BUILDID = process.env.TRAVIS_BUILD_ID || 'unknown-buildid'; + var TUNNELIDENTIFIER = process.env.TRAVIS_JOB_NUMBER || 'unknown-jobnumber'; + // select selenium version - for available versions see https://docs.saucelabs.com/reference/test-configuration/#specifying-a-selenium-version + var SELENIUMVERSION = '2.50.1'; + + console.log('BROWSERNAME: ' + BROWSERNAME); + console.log('BROWSERVERSION: ' + BROWSERVERSION); + console.log('BROWSERPLATFORM: ' + BROWSERPLATFORM); + console.log('BUILDID: ' + BUILDID); + console.log('TUNNELIDENTIFIER: ' + TUNNELIDENTIFIER); + console.log('SELENIUMVERSION: ' + SELENIUMVERSION); + + var options = { desiredCapabilities: { + browserName: BROWSERNAME, + version: BROWSERVERSION, + platform: BROWSERPLATFORM, + tags: ['examples'], + name: 'Run a \'simple internet\' test using webdriverio/Selenium.', + build: BUILDID, + 'tunnel-identifier': TUNNELIDENTIFIER, + 'selenium-version': SELENIUMVERSION + }, + // for w/o sauce connect + // host: 'ondemand.saucelabs.com', + // port: 80, + // use with sauce connect: + host: 'localhost', + port: 4445, + user: process.env.SAUCE_USERNAME, + key: process.env.SAUCE_ACCESS_KEY, + logLevel: 'verbose' + }; +} +else +{ + console.log('running tests (simple internet) locally...'); + options = { + desiredCapabilities: { + browserName: 'chrome' + }, + host: 'localhost', + port: 4444 + }; +} + +describe('Run a \'simple internet\' test using webdriverio/Selenium.', function() { + this.timeout(300000);// 6000 too fast on windows systems + + before(function(done){ + this.timeout(300000);// 6000 too fast on windows systems + client = webdriverio.remote(options); + client.init().call(done); + }); + + it('should be able to view page on internet, checks the title only using TDD style check', function(done) { + this.timeout(300000); // some time is needed for the browser start up, on my system 3000 should work, too. + + client + .url('https://www.google.com') + // uses property getTitle() + .getTitle().then(function(title) { + console.log('Title was: ' + title); + assert.strictEqual(title, 'Google'); + }) + .call(done); + }); + + after(function(done) { + client.end().call(done); + }); + +}); diff --git a/test/simple_test.js b/test/simple_test.js new file mode 100644 index 0000000..7c442f8 --- /dev/null +++ b/test/simple_test.js @@ -0,0 +1,95 @@ +var assert = require('chai').assert, + expect = require('chai').expect, + webdriverio = require('webdriverio'); +var env = GLOBAL.env = {}; +var client = {}; + +//console.log('process.env.TRAVIS: %s', process.env.TRAVIS || '-'); +//console.log('TEST_RUN_LOCAL: %s', process.env.TEST_RUN_LOCAL || '-'); + +process.on('uncaughtException', function(e) { + console.log(require('util').inspect(e, {showHidden:true})); +}); + +if ((process.env.TRAVIS === 'true') && (process.env.TEST_RUN_LOCAL !== 'true')) { + console.log('running tests (simple_test) on SauceLabs using sauce connect...'); + console.log('TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')'); + + var BROWSERNAME = (process.env._BROWSER || process.env.BROWSER || 'chrome').replace(/_/g,' '); + var BROWSERVERSION = process.env._VERSION || process.env.VERSION || '*'; + var BROWSERPLATFORM = (process.env._PLATFORM || process.env.PLATFORM || 'Linux').replace(/_/g,' '); + var BUILDID = process.env.TRAVIS_BUILD_ID || 'unknown-buildid'; + var TUNNELIDENTIFIER = process.env.TRAVIS_JOB_NUMBER || 'unknown-jobnumber'; + // select selenium version - for available versions see https://docs.saucelabs.com/reference/test-configuration/#specifying-a-selenium-version + var SELENIUMVERSION = '2.50.1'; + + console.log('BROWSERNAME: ' + BROWSERNAME); + console.log('BROWSERVERSION: ' + BROWSERVERSION); + console.log('BROWSERPLATFORM: ' + BROWSERPLATFORM); + console.log('BUILDID: ' + BUILDID); + console.log('TUNNELIDENTIFIER: ' + TUNNELIDENTIFIER); + + var options = { desiredCapabilities: { + browserName: BROWSERNAME, + version: BROWSERVERSION, + platform: BROWSERPLATFORM, + tags: ['examples'], + name: 'Run a \'simple test\' using webdriverio/Selenium.', + build: BUILDID, + 'tunnel-identifier': TUNNELIDENTIFIER, + 'selenium-version': SELENIUMVERSION + }, + // for w/o sauce connect + // host: 'ondemand.saucelabs.com', + // port: 80, + // use with sauce connect: + host: 'localhost', + port: 4445, + user: process.env.SAUCE_USERNAME, + key: process.env.SAUCE_ACCESS_KEY, + logLevel: 'verbose' + }; +} +else +{ + console.log('running tests (simple_test) locally...'); + options = { + desiredCapabilities: { + browserName: 'chrome' + }, + host: 'localhost', + port: 4444 + }; +} + +describe('Run a \'simple test\' using webdriverio/Selenium.', function() { + + before(function(done) { + this.timeout(300000); + client = webdriverio.remote(options); + client.init() + .call(done); + }); + + beforeEach(function(done) { + this.timeout(300000); // some time is needed for the browser start up, on my system 3000 should work, too. + // Navigate to the URL for each test + client.url('http://localhost:3000') + .call(done); + }); + + it('should be able to view the home page', function(done) { + client.getTitle().then(function(title) { + //console.log('Title was: ' + title); + assert.strictEqual(title, 'Library'); // TDD + expect(title).to.have.string('Library'); // BDD + }) + .call(done); + }); + + after(function(done) { + client.end() + .call(done); + }); + +}); diff --git a/tests/page_test.js b/tests/page_test.js deleted file mode 100644 index 89c913c..0000000 --- a/tests/page_test.js +++ /dev/null @@ -1,62 +0,0 @@ -var expect = require('chai').expect, - webdriverjs = require("webdriverjs"), - client = webdriverjs.remote(); - -describe('Run Selenium tests', function() { - - before(function(done) { - // Add some helper commands - client.addCommand('hasText', function(selector, text, callback) { - this.getText(selector, function(result) { - expect(result.value).to.have.string(text); - callback(); - }); - }); - client.addCommand('waitUntilVisible', function(element, callback) { - var self = this; - function checkElement() { - self.isVisible(element, function(result) { - if (result === true) { - callback(); - } else { - setTimeout(checkElement, 500); - } - }); - } - checkElement(); - }); - done(); - }); - - beforeEach(function(done) { - // Navigate to the URL for each test - client.init(); - client.url('http://localhost:3000', done); - }); - - it('should be able to navigate betwen the pages', function(done) { - this.timeout(10000); - client - .hasText('#title', 'Library') - .click('#authors') - .waitUntilVisible("#authorList", function() { - client - .hasText('#author1', 'Patrick Rothfuss') - .click('#back') - .waitUntilVisible('#books', function() { - client - .click('#books') - .waitUntilVisible('#bookList', function() { - client.hasText('book1', "Wise Man's Fear"); - done(); - }); - }); - }); - }); - - afterEach(function(done) { - client.end(); - done(); - }); - -}); \ No newline at end of file diff --git a/tests/simple_test.js b/tests/simple_test.js deleted file mode 100644 index ba3517f..0000000 --- a/tests/simple_test.js +++ /dev/null @@ -1,36 +0,0 @@ -var expect = require('chai').expect, - webdriverjs = require("webdriverjs"), - client = webdriverjs.remote(); - -describe('Run Selenium tests', function() { - - before(function(done) { - // Add some helper commands - client.addCommand('hasText', function(selector, text, callback) { - this.getText(selector, function(result) { - expect(result.value).to.have.string(text); - callback(); - }); - }); - done(); - }); - - beforeEach(function(done) { - // Navigate to the URL for each test - client.init(); - client.url('http://localhost:3000', done); - }); - - it('should be able to view the home page', function(done) { - this.timeout(10000); - client.hasText('#title', 'Library'); - done(); - - }); - - afterEach(function(done) { - client.end(); - done(); - }); - -}); \ No newline at end of file diff --git a/views/authors.jade b/views/authors.jade index 5e1c5ab..76c7d96 100644 --- a/views/authors.jade +++ b/views/authors.jade @@ -1,9 +1,13 @@ -h1#title= title +extends layout -ul#authorList - li#author1 Patrick Rothfuss - li#author2 William Shakespeare - li#author3 Eric Flint - li#author4 George Orwell - -a#back(href='/') Back \ No newline at end of file +block content + h1#title= title + + ul#authorList + li#author1 Patrick Rothfuss + li#author2 William Shakespeare + li#author3 Eric Flint + li#author4 George Orwell + + p + a#back(href='/') Back diff --git a/views/books.jade b/views/books.jade index c8c1910..2c9c9d2 100644 --- a/views/books.jade +++ b/views/books.jade @@ -1,9 +1,13 @@ -h1#title= title +extends layout -ul#bookList - li#book1 Wise Man's Fear - li#book2 Hamlet - li#book3 1632 - li#book4 1984 - -a#back(href='/') Back \ No newline at end of file +block content + h1#title= title + + ul#bookList + li#book1 Wise Man's Fear + li#book2 Hamlet + li#book3 1632 + li#book4 1984 + + p + a#back(href='/') Back diff --git a/views/index.jade b/views/index.jade index 4b29c4a..e9de18e 100644 --- a/views/index.jade +++ b/views/index.jade @@ -1,7 +1,10 @@ -h1#title= title -p Welcome to the Library +extends layout -p - a#authors(href='/authors') Authors -p - a#books(href='/books') Books \ No newline at end of file +block content + h1#title= title + p Welcome to the #{title} + + p + a#authors(href='/authors') Authors + p + a#books(href='/books') Books diff --git a/views/layout.jade b/views/layout.jade index 1a36941..15af079 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -1,6 +1,7 @@ -!!! +doctype html html head title= title link(rel='stylesheet', href='/stylesheets/style.css') - body!= body \ No newline at end of file + body + block content