docs: function () {
      var runner = this;
  
      this.eventEmitter = new serviceUtils.EventEmitter();
      this.stepIterator = new StepIterator(pingIframe);
  
      this.executingStepInIFrameWindow      = null;
      this.stopped                          = false;
      this.listenNativeDialogs              = false;
      this.isFileDownloadingIntervalID      = null;
      this.iframeActionTargetWaitingStarted = false;
  
      this.pageInitialRequestBarrier = null;
  
      this.assertionsAPI = new AssertionsAPI(function (err) {
          runner.stepIterator.onAssertionFailed(err);
      });
  
      actionsAPI.init(this.stepIterator);
  
      this._initNativeDialogs();
  
      initAutomation();
      this._initBarrier();
  
      this._initApi();
      this._initIFrameBehavior();
  
      hammerhead.on(hammerhead.EVENTS.uncaughtJsError, function (err) {
          //NOTE: in this case we should to stop test iterator in iFrame
          if (err.inIFrame && !SETTINGS.get().PLAYBACK)
              runner.stepIterator.stop();
          else if (!SETTINGS.get().SKIP_JS_ERRORS || SETTINGS.get().RECORDING) {
              runner._onFatalError({
                  type:        ERROR_TYPE.uncaughtJSError,
                  scriptErr:   err.msg,
                  pageError:   true,
                  pageDestUrl: err.pageUrl,
                  stepName:    runner.stepIterator.getCurrentStep()
              });
          }
      });
  
      runner.stepIterator.on(StepIterator.ERROR_EVENT, function (e) {
          runner._onFatalError(e);
      });
  
      runner.act._onJSError = function (err) {
          runner._onFatalError({
              type:      ERROR_TYPE.uncaughtJSError,
              scriptErr: (err && err.message) || err
          });
      };
  
      runner.act._start = function (stepNames, testSteps, skipPageWaiting) {
          //NOTE: start test execution only when all content is loaded or if loading
          //timeout is reached (whichever comes first).
          runner._prepareStepsExecuting(function () {
              if (runner.stopped)
                  return;
  
              delete runner.act._onJSError;
              delete runner.act._start;
  
              runner.eventEmitter.emit(runner.TEST_STARTED_EVENT, {
                  nextStep: runner.nextStep
              });
  
              modalBackground.hide();
  
              runner.stepIterator.on(StepIterator.TEST_COMPLETE_EVENT, function (e) {
                  runner._onTestComplete(e);
              });
  
              runner.stepIterator.on(StepIterator.NEXT_STEP_STARTED_EVENT, function (e) {
                  runner._onNextStepStarted(e);
                  runner._clearFileDownloadingInterval();
              });
  
              runner.stepIterator.on(StepIterator.ACTION_TARGET_WAITING_STARTED_EVENT, function (e) {
                  runner._onActionTargetWaitingStarted(e);
              });
  
              runner.stepIterator.on(StepIterator.ACTION_RUN_EVENT, function () {
                  runner._onActionRun();
              });
  
              runner.stepIterator.on(StepIterator.ASSERTION_FAILED_EVENT, function (e) {
                  runner._onAssertionFailed(e);
              });
  
              runner.stepIterator.on(StepIterator.SET_STEPS_SHARED_DATA_EVENT, function (e) {
                  runner._onSetStepsSharedData(e);
              });
  
              runner.stepIterator.on(StepIterator.GET_STEPS_SHARED_DATA_EVENT, function (e) {
                  runner._onGetStepsSharedData(e);
              });
  
              runner.stepIterator.on(StepIterator.TAKE_SCREENSHOT_EVENT, function (e) {
                  runner._onTakeScreenshot(e);
              });
  
              runner.stepIterator.on(StepIterator.BEFORE_UNLOAD_EVENT_RAISED, function () {
                  runner._onBeforeUnload();
              });
  
              runner.stepIterator.on(StepIterator.UNLOAD_EVENT_RAISED, function () {
                  runner._clearFileDownloadingInterval();
              });
  
              runner.listenNativeDialogs = true;
  
              runner.stepIterator.start(stepNames, testSteps, dialogsAPI.resetHandlers,
                  dialogsAPI.checkExpectedDialogs, runner.nextStep);
          }, skipPageWaiting);
      };
  }