code: async function beforeHook(done) {
      // height & width : 100%
      fullScreen();
      if (initialled) return done && done();
      let { url, host, port } = _config;
      if (!url) url = host + ':' + port;
      await loadScript('//' + url + '/socket.io/socket.io.js');
      // it's hard to share socket with karma
      // Connection = (opener || parent).karma.socket;
      Connection = io(url);
      Connection.on('runBack', (message) => {
          // console.log('runBack', message);
          message && !message.status ? serialPromiseResolve() : serialPromiseReject(message.status);
      });
      // whether there is contextFrame, wait
      waitingPromise = wrapPromise((resolve) => {
          Connection.on('ready', (message) => {
              let { supportedDefs = '' } = message;
              supportedDefs.split(' ').map((def) => {
                  $$Browser[def] = function () {
                      return this.__toRunnable(def, ...arguments);
                  };
              });
              // console.log('ready', message);
              routePCToMobile();
              resolve();
          });
      });
      await waitingPromise;
      initialled = true;
      done && done();
  }
docs: run first in before()
  @params {function} done if assigned, call done after promise resolved.
  @return promise