docs: function createPage(casper) {
      /*jshint maxstatements:20*/
      "use strict";
      var page = require('webpage').create();
      page.onAlert = function onAlert(message) {
          casper.log('[alert] ' + message, "info", "remote");
          casper.emit('remote.alert', message);
          if (utils.isFunction(casper.options.onAlert)) {
              casper.options.onAlert.call(casper, casper, message);
          }
      };
      page.onConfirm = function onConfirm(message) {
          if ('page.confirm' in casper._filters) {
              return casper.filter('page.confirm', message);
          }
          return true;
      };
      page.onConsoleMessage = function onConsoleMessage(msg) {
          // client utils casper console message
          var consoleTest = /^\[casper\.echo\]\s?([\s\S]*)/.exec(msg);
          if (consoleTest && consoleTest.length === 2) {
              casper.echo(consoleTest[1]);
              return; // don't trigger remote.message event for these
          }
          // client utils log messages
          var logLevel = "info",
              logTest = /^\[casper:(\w+)\]\s?([\s\S]*)/m.exec(msg);
          if (logTest && logTest.length === 3) {
              logLevel = logTest[1];
              msg = logTest[2];
              casper.log(msg, logLevel, "remote");
          } else {
              casper.emit('remote.message', msg);
          }
      };
  
      page.onCallback = function onCallback(data){
          casper.emit('remote.callback',data);
      };
  
      page.onError = function onError(msg, trace) {
          casper.emit('page.error', msg, trace);
      };
      page.onInitialized = function onInitialized() {
          casper.emit('page.initialized', page);
          if (utils.isFunction(casper.options.onPageInitialized)) {
              casper.log("Post-configuring WebPage instance", "debug");
              casper.options.onPageInitialized.call(casper, page);
          }
      };
      page.onLoadStarted = function onLoadStarted() {
          // in some case, there is no navigation requested event, so
          // be sure that browserInitializing is false to not block checkStep()
          casper.browserInitializing = false;
          casper.loadInProgress = true;
          casper.emit('load.started');
      };
      page.onLoadFinished = function onLoadFinished(status) {
          /*jshint maxstatements:20*/
          if (status !== "success") {
              casper.emit('load.failed', {
                  status:      status,
                  http_status: casper.currentHTTPStatus,
                  url:         casper.requestUrl
              });
              var message = 'Loading resource failed with status=' + status;
              if (casper.currentHTTPStatus) {
                  message += f(' (HTTP %d)', casper.currentHTTPStatus);
              }
              message += ': ' + casper.requestUrl;
              casper.log(message, "warning");
              casper.navigationRequested = false;
              casper.browserInitializing = false;
              if (utils.isFunction(casper.options.onLoadError)) {
                  casper.options.onLoadError.call(casper, casper, casper.requestUrl, status);
              }
          }
          // local client scripts
          casper.injectClientScripts();
          // remote client scripts
          casper.includeRemoteScripts();
          // Client-side utils injection
          casper.injectClientUtils();
          // history
          casper.history.push(casper.getCurrentUrl());
          casper.emit('load.finished', status);
          casper.loadInProgress = false;
      };
      page.onNavigationRequested = function onNavigationRequested(url, type, willNavigate, isMainFrame) {
          casper.log(f('Navigation requested: url=%s, type=%s, willNavigate=%s, isMainFrame=%s',
                       url, type, willNavigate, isMainFrame), "debug");
          casper.browserInitializing = false;
          if (isMainFrame && casper.requestUrl !== url) {
              var currentUrl = casper.requestUrl;
              var newUrl = url;
              var pos = currentUrl.indexOf('#')
              if (pos !== -1) {
                  currentUrl = currentUrl.substring(0, pos);
              }
              pos = newUrl.indexOf('#')
              if (pos !== -1) {
                  newUrl = newUrl.substring(0, pos);
              }
              // for URLs that are only different by their hash part
              // don't turn navigationRequested to true, because
              // there will not be loadStarted, loadFinished events
              // so it could cause issues (for exemple, checkStep that
              // do no execute the next step -> infinite loop on checkStep)
              if (currentUrl !== newUrl)
                  casper.navigationRequested  = true;
  
              if (willNavigate) {
                  casper.requestUrl = url;
              }
          }
          casper.emit('navigation.requested', url, type, willNavigate, isMainFrame);
      };
      page.onPageCreated = function onPageCreated(popupPage) {
          casper.emit('popup.created', popupPage);
          popupPage.onLoadFinished = function onLoadFinished() {
              // SlimerJS needs this line of code because of issue
              // https://github.com/laurentj/slimerjs/issues/48
              // else checkStep turns into an infinite loop
              // after clicking on an <a target="_blank">
              casper.navigationRequested  = false;
              casper.popups.push(popupPage);
              casper.emit('popup.loaded', popupPage);
          };
          popupPage.onClosing = function onClosing(closedPopup) {
              casper.popups.clean(closedPopup);
              casper.emit('popup.closed', closedPopup);
          };
      };
      page.onPrompt = function onPrompt(message, value) {
          return casper.filter('page.prompt', message, value);
      };
      page.onResourceReceived = function onResourceReceived(resource) {
          http.augmentResponse(resource);
          casper.emit('resource.received', resource);
          if (utils.isFunction(casper.options.onResourceReceived)) {
              casper.options.onResourceReceived.call(casper, casper, resource);
          }
          casper.handleReceivedResource(resource);
      };
      page.onResourceRequested = function onResourceRequested(requestData, request) {
          casper.emit('resource.requested', requestData, request);
          if (requestData.url === casper.requestUrl) {
              casper.emit('page.resource.requested', requestData, request);
          }
          if (utils.isFunction(casper.options.onResourceRequested)) {
              casper.options.onResourceRequested.call(casper, casper, requestData, request);
          }
      };
      page.onUrlChanged = function onUrlChanged(url) {
          casper.log(f('url changed to "%s"', url), "debug");
          casper.navigationRequested = false;
          casper.emit('url.changed', url);
      };
      casper.emit('page.created', page);
      return page;
  }