{"id":1114,"date":"2014-10-11T22:00:08","date_gmt":"2014-10-11T19:00:08","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=1114"},"modified":"2014-10-11T17:55:36","modified_gmt":"2014-10-11T14:55:36","slug":"a-canonical-web-test-in-nodejs","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/","title":{"rendered":"A canonical web test in NodeJS"},"content":{"rendered":"<p>Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has fast tests and restart for a super quick edit-verify cycle when you\u2019re coding.<\/p>\n<p>I like to write tests to verify the server-side and client-side logic, but do you know that the whole solution really is working? You can of course test your service manually after deploying, but that becomes tedious. By using Selenium, we can test that the solution works end-to-end.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>In this article, I show how to write a Mocha test that:<\/p>\n<ol>\n<li>Starts up the Selenium test runner<\/li>\n<li>Creates a browser client that can access the application (using PhantomJS)<\/li>\n<li>Starts up the server and sends the browser to the server (running in ExpressJS)<\/li>\n<li>Clicks a button in the web page that triggers some JavaScript (written in jQuery in this example)<\/li>\n<li>Verifies that the call to the server returns and displays correct data<\/li>\n<\/ol>\n<p>This test can be run with a simple command after you check out the code and requires no setup on the developers computer!<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndescribe(&quot;web application&quot;, function() {\r\n  before(function(done) {\r\n    this.timeout(5000);\r\n    client = startWebDriver(function() {\r\n      startServer(function(url) {\r\n        client.init().url(url, done);\r\n      });\r\n    });\r\n  });\r\n\r\n  after(function(done) {\r\n    client.end(done);\r\n  })\r\n\r\n  it(&quot;clicks menu item&quot;, function(done) {\r\n    client.click(&quot;#showMore&quot;, function(err) {\r\n      client.waitFor(&quot;#results div&quot;, 1000, function(err) {\r\n        client.getText(&quot;#results div&quot;, function(err, text) {\r\n          expect(text).to.have.string(&quot;Here's more&quot;);\r\n          done();\r\n        });\r\n      });\r\n    });\r\n  });\r\n});\r\n<\/pre>\n<p>This test starts a new server and client for each test. When using this for real, you really want to make sure you only start the server and the web driver once as these are expensive operations.<\/p>\n<p>The test case of \u201cit clicks menu item\u201d has a lot of callbacks. There are versions of webdriver APIs for NodeJS which are based on promises that you may enjoy using more.<\/p>\n<h2>implementation details<\/h2>\n<p>The full application can be found on <a href=\"https:\/\/github.com\/jhannes\/wtddjs\/\">Github<\/a>. To implement it, I used the following NPM modules:<\/p>\n<ul>\n<li>phantomjs<\/li>\n<li>selenium-standalone<\/li>\n<li>webdriverjs<\/li>\n<li>expressjs (of course)<\/li>\n<li>mocha and chai (of course)<\/li>\n<\/ul>\n<p>Starting the server looks like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar startServer = function(done) {\r\n  var app = require('..\/app');\r\n  var server = app.listen(0, function() {\r\n    var port = server.address().port;\r\n    done(&quot;http:\/\/localhost:&quot; + port + &quot;\/&quot;, done);\r\n  });\r\n}\r\n<\/pre>\n<p>And the app.js file looks like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar express = require('express');\r\nvar app = express();\r\n\/\/ set up app routes here\r\nmodule.exports = app;\r\n<\/pre>\n<p>I have a server.js file which starts up the express application to run normal (outside the tests).<\/p>\n<p>A simplified version of starting Selenium and WebDriver looks like this:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar startWebDriver = function(done) {\r\n  var selenium = require('selenium-standalone');\r\n  var server = selenium({ stdio: 'pipe' });\r\n  \/\/ call done when server is started\r\n\r\n  var client = require('webdriverjs').remote({\r\n    desiredCapabilities: {browserName: 'phantomjs'}\r\n  });\r\n  return client;\r\n}\r\n<\/pre>\n<p>I found that Selenium and PhantomJS has some issues, at least on Windows, so my final code needed a few hacks to work. See the full details at <a href=\"https:\/\/github.com\/jhannes\/wtddjs\/blob\/master\/test\/webdriver.js\">github<\/a>.<\/p>\n<h2>conclusion<\/h2>\n<p>A web end to end integration test in NodeJS requires a little bit of shaking your fist at the heavens to get to work the first time, not in the least due to the need to work around limitations in Selenium and PhantomJS. But once you got it up and running, you can easily test not only that your logic works, but that your whole application works together.<\/p>\n<p>When making these tests, I allowed for a little flexibility as well: By setting environment variables, the same tests can be run with a manually deployed server, so you can use it to verify that your staging server is up and running (for example). And of course, you can replace PhantomJS as a web browser with Firefox or Chrome and see the tests run for real in your browser.<\/p>\n<p>Automate the end-to-end tests of your NodeJS applications!<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/johannesbrodwall.com\/2014\/07\/03\/a-canonical-web-test-in-nodejs\/\">A canonical web test in NodeJS<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/wcg\/\">WCG partner<\/a> Johannes Brodwall at the <a href=\"http:\/\/johannesbrodwall.com\/\">Thinking Inside a Bigger Box<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has fast tests and restart for a super quick edit-verify cycle when you\u2019re coding. I like to write tests to verify the server-side and client-side logic, but do you know that &hellip;<\/p>\n","protected":false},"author":10,"featured_media":924,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1114","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-node-js"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>A canonical web test in NodeJS - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A canonical web test in NodeJS - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-10-11T19:00:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Johannes Brodwall\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/jhannes\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Johannes Brodwall\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\"},\"author\":{\"name\":\"Johannes Brodwall\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/99d8325df390a9c556f22b1b7ed6c303\"},\"headline\":\"A canonical web test in NodeJS\",\"datePublished\":\"2014-10-11T19:00:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\"},\"wordCount\":678,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg\",\"articleSection\":[\"Node.js\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\",\"name\":\"A canonical web test in NodeJS - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg\",\"datePublished\":\"2014-10-11T19:00:08+00:00\",\"description\":\"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Node.js\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/node-js\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"A canonical web test in NodeJS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/99d8325df390a9c556f22b1b7ed6c303\",\"name\":\"Johannes Brodwall\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a32eb2152b8b7b98c7aa6202e05cbcc7d92b71f4b03edf7d5dc22699dc1b44da?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a32eb2152b8b7b98c7aa6202e05cbcc7d92b71f4b03edf7d5dc22699dc1b44da?s=96&d=mm&r=g\",\"caption\":\"Johannes Brodwall\"},\"description\":\"Johannes is the chief scientist of the software offshore company Exilesoft. He's got close to 15 years programming Java, C# and a long time ago other languages as well. He believes that programming is about more than just writing the code, but that too many people lose touch with the coding as well. He has been organizing software development activities in Oslo for many years. In addition, he often speaks at conferences all over Europe.\",\"sameAs\":[\"http:\/\/johannesbrodwall.com\/\",\"http:\/\/www.linkedin.com\/in\/johannesbrodwall\",\"https:\/\/x.com\/http:\/\/twitter.com\/jhannes\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/johannes-brodwall\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A canonical web test in NodeJS - Web Code Geeks - 2026","description":"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/","og_locale":"en_US","og_type":"article","og_title":"A canonical web test in NodeJS - Web Code Geeks - 2026","og_description":"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has","og_url":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2014-10-11T19:00:08+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg","type":"image\/jpeg"}],"author":"Johannes Brodwall","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/jhannes","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Johannes Brodwall","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/"},"author":{"name":"Johannes Brodwall","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/99d8325df390a9c556f22b1b7ed6c303"},"headline":"A canonical web test in NodeJS","datePublished":"2014-10-11T19:00:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/"},"wordCount":678,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg","articleSection":["Node.js"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/","url":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/","name":"A canonical web test in NodeJS - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg","datePublished":"2014-10-11T19:00:08+00:00","description":"Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/nodejs-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/javascript\/node-js\/a-canonical-web-test-in-nodejs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JavaScript","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/"},{"@type":"ListItem","position":3,"name":"Node.js","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/node-js\/"},{"@type":"ListItem","position":4,"name":"A canonical web test in NodeJS"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/99d8325df390a9c556f22b1b7ed6c303","name":"Johannes Brodwall","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a32eb2152b8b7b98c7aa6202e05cbcc7d92b71f4b03edf7d5dc22699dc1b44da?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a32eb2152b8b7b98c7aa6202e05cbcc7d92b71f4b03edf7d5dc22699dc1b44da?s=96&d=mm&r=g","caption":"Johannes Brodwall"},"description":"Johannes is the chief scientist of the software offshore company Exilesoft. He's got close to 15 years programming Java, C# and a long time ago other languages as well. He believes that programming is about more than just writing the code, but that too many people lose touch with the coding as well. He has been organizing software development activities in Oslo for many years. In addition, he often speaks at conferences all over Europe.","sameAs":["http:\/\/johannesbrodwall.com\/","http:\/\/www.linkedin.com\/in\/johannesbrodwall","https:\/\/x.com\/http:\/\/twitter.com\/jhannes"],"url":"https:\/\/www.webcodegeeks.com\/author\/johannes-brodwall\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/1114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=1114"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/1114\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/924"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=1114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=1114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=1114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}