Ejemplo n.º 1
0
 (function () {
   var absolute = Utils.resolveHref(_this.browser.location.href, url);
   var matchedURL = matchingText.filter(function (element) {
     return element.href === absolute;
   });
   assert(matchedURL.length, message || "Expected at least one link matching the given text and URL");
 })();
Ejemplo n.º 2
0
    value: function handleRedirect(browser, request, response) {
      var status = response.status;

      if (status === 301 || status === 302 || status === 303 || status === 307 || status === 308) {
        if (request.redirect === 'error') return Fetch.Response.error();

        var _location = response.headers.get('Location');
        if (_location === null) return response;

        if (request._redirectCount >= 20) return Fetch.Response.error();

        browser.emit('redirect', request, response, _location);
        ++request._redirectCount;
        if (status !== 307) {
          request.method = 'GET';
          request.headers['delete']('Content-Type');
          request.headers['delete']('Content-Length');
          request.headers['delete']('Content-Transfer-Encoding');
        }

        // This request is referer for next
        request.headers.set('Referer', request.url);
        request.url = Utils.resolveHref(request.url, _location);
        return browser.pipeline._runPipeline(request);
      } else return response;
    }
Ejemplo n.º 3
0
  // -- Prepare request --

  // This handler normalizes the request URL.
  //
  // It turns relative URLs into absolute URLs based on the current document URL
  // or base element, or if no document open, based on browser.site property.
  static normalizeURL(browser, request) {
    if (browser.document)
    // Resolve URL relative to document URL/base, or for new browser, using
    // Browser.site
      request.url = DOM.resourceLoader.resolve(browser.document, request.url);
    else
      request.url = Utils.resolveHref(browser.site || 'http://localhost', request.url);
  }
Ejemplo n.º 4
0
  // Navigation
  // ----------

  // browser.visit(url, callback?)
  //
  // Loads document from the specified URL, processes events and calls the callback, or returns a promise.
  visit(url, options, callback) {
    if (arguments.length < 3 && typeof options === 'function')
      [options, callback] = [{}, options];

    const site = /^(https?:|file:)/i.test(this.site) ? this.site : `http://${this.site || 'localhost'}/`;
    url = Utils.resolveHref(site, URL.format(url));

    if (this.window)
      this.tabs.close(this.window);
    this.errors = [];
    this.tabs.open({ url: url, referrer: this.referrer });
    return this._wait(options, callback);
  }
Ejemplo n.º 5
0
 // Asserts that a link exists with the given text and URL.
 link(selector, text, url, message) {
   const elements = this.browser.queryAll(selector);
   assert(elements.length, message || `Expected selector "${selector}" to return one or more elements`);
   const matchingText = elements.filter(element => element.textContent.trim() === text);
   if (isRegExp(url)) {
     const matchedRegexp = matchingText.filter(element => url.test(element.href));
     assert(matchedRegexp.length, message || `Expected at least one link matching the given text and URL`);
   } else {
     const absolute    = Utils.resolveHref(this.browser.location.href, url);
     const matchedURL  = matchingText.filter(element => element.href === absolute);
     assert(matchedURL.length, message || `Expected at least one link matching the given text and URL`);
   }
 }
Ejemplo n.º 6
0
// Builds and returns a new Request, adding form parameters to URL (GET) or
// request body (POST).
function buildRequest(args) {
  var browser = args.browser;
  var method = args.method;
  var params = args.params;

  var site = /^(https?:|file:)/i.test(browser.site) ? browser.site : 'http://' + (browser.site || 'locahost');
  var url = Utils.resolveHref(site, URL.format(args.url));

  var headers = new Fetch.Headers(args.headers);

  // HTTP header Referer, but Document property referrer
  var referrer = args.referrer || browser.referrer || browser.referer || args.history.url;
  if (referrer && !headers.has('Referer')) headers.set('Referer', referrer);
  if (!headers.has('Accept')) headers.set('Accept', 'text/html,*/*');

  if (/^GET|HEAD|DELETE$/i.test(method)) {
    var uri = URL.parse(url, true);
    if (params)
      // These methods use query string parameters instead
      _core.Object.assign(uri.query, params);
    return new Fetch.Request(URL.format(uri), { method: method, headers: headers });
  }

  var mimeType = (args.encoding || '').split(';')[0];
  // Default mime type, but can also be specified in form encoding
  if (mimeType === '' || mimeType === 'application/x-www-form-urlencoded') {
    var urlEncoded = QS.stringify(params || {});
    headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
    return new Fetch.Request(url, { method: method, headers: headers, body: urlEncoded });
  }

  if (mimeType === 'multipart/form-data') {
    var _ret = (function () {
      var form = new Fetch.FormData();
      if (params) _core.Object.keys(params).forEach(function (name) {
        params[name].forEach(function (value) {
          form.append(name, value);
        });
      });
      return {
        v: new Fetch.Request(url, { method: method, headers: headers, body: form })
      };
    })();

    if (typeof _ret === 'object') {
      return _ret.v;
    }
  }

  throw new TypeError('Unsupported content type ' + mimeType);
}
Ejemplo n.º 7
0
 Assert.prototype.url = function url(expected, message) {
   if (typeof expected === "string") {
     var absolute = Utils.resolveHref(this.browser.location.href, expected);
     assertMatch(this.browser.location.href, absolute, message);
   } else if (isRegExp(expected) || typeof expected === "function") assertMatch(this.browser.location.href, expected, message);else {
     var url = URL.parse(this.browser.location.href, true);
     for (var key in expected) {
       var value = expected[key];
       // Gracefully handle default values, e.g. document.location.hash for
       // "/foo" is "" not null, not undefined.
       var defaultValue = key === "port" ? 80 : null;
       assertMatch(url[key] || defaultValue, value || defaultValue, message);
     }
   }
 };
Ejemplo n.º 8
0
// Builds and returns a new Request, adding form parameters to URL (GET) or
// request body (POST).
function buildRequest(args) {
  const { browser, method } = args;
  const params  = args.params || new Map();
  const site    = /^(https?:|file:)/i.test(browser.site) ? browser.site : `http://${browser.site || 'locahost'}`;
  const url     = Utils.resolveHref(site, URL.format(args.url));

  const headers = new Fetch.Headers(args.headers);

  // HTTP header Referer, but Document property referrer
  const referrer = args.referrer || browser.referrer || browser.referer || args.history.url;
  if (referrer && !headers.has('Referer'))
    headers.set('Referer', referrer);
  if (!headers.has('Accept'))
    headers.set('Accept', 'text/html,*/*');

  if (/^GET|HEAD|DELETE$/i.test(method)) {
    const uri = URL.parse(url, true);
    // These methods use query string parameters instead
    for (let [name, values] of params)
      uri.query[name] = values;
    return new Fetch.Request(URL.format(uri), { method, headers });
  }

  const mimeType = (args.encoding || '').split(';')[0];
  // Default mime type, but can also be specified in form encoding
  if (mimeType === '' || mimeType === 'application/x-www-form-urlencoded') {
    const urlEncoded = [...params]
      .map(function([name, values]) {
        return values.map(value => `${QS.escape(name)}=${QS.escape(value)}`).join('&');
      })
      .join('&');

    headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
    return new Fetch.Request(url, { method, headers, body: urlEncoded });
  }

  if (mimeType === 'multipart/form-data') {
    const form = new Fetch.FormData();
    for (let [name, values] of params)
      for (let value of values)
        form.append(name, value);
    return new Fetch.Request(url, { method, headers, body: form });
  }

  throw new TypeError(`Unsupported content type ${mimeType}`);
}
Ejemplo n.º 9
0
 // Asserts that current page has the expected URL.
 //
 // Expected value can be a String, RegExp, Function or an object, in which case
 // object properties are tested against the actual URL (e.g. pathname, host,
 // query).
 url(expected, message) {
   if (typeof expected === 'string') {
     const absolute = Utils.resolveHref(this.browser.location.href, expected);
     assertMatch(this.browser.location.href, absolute, message);
   } else if (isRegExp(expected) || typeof expected === 'function')
     assertMatch(this.browser.location.href, expected, message);
   else {
     const url = URL.parse(this.browser.location.href, true);
     for (let key in expected) {
       let value = expected[key];
       // Gracefully handle default values, e.g. document.location.hash for
       // "/foo" is "" not null, not undefined.
       let defaultValue = (key === 'port') ? 80 : null;
       assertMatch(url[key] || defaultValue, value || defaultValue, message);
     }
   }
 }
Ejemplo n.º 10
0
// Builds and returns a new Request, adding form parameters to URL (GET) or
// request body (POST).
function buildRequest(args) {
  const { browser, method, params } = args;
  const site  = /^(https?:|file:)/i.test(browser.site) ? browser.site : `http://${browser.site || 'locahost'}`;
  const url   = Utils.resolveHref(site, URL.format(args.url));

  const headers = new Fetch.Headers(args.headers);

  // HTTP header Referer, but Document property referrer
  const referrer = args.referrer || browser.referrer || browser.referer || args.history.url;
  if (referrer && !headers.has('Referer'))
    headers.set('Referer', referrer);
  if (!headers.has('Accept'))
    headers.set('Accept', 'text/html,*/*');

  if (/^GET|HEAD|DELETE$/i.test(method)) {
    const uri = URL.parse(url, true);
    if (params)
      // These methods use query string parameters instead
      Object.assign(uri.query, params);
    return new Fetch.Request(URL.format(uri), { method, headers });
  }

  const mimeType = (args.encoding || '').split(';')[0];
  // Default mime type, but can also be specified in form encoding
  if (mimeType === '' || mimeType === 'application/x-www-form-urlencoded') {
    const urlEncoded = QS.stringify(params || {});
    headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
    return new Fetch.Request(url, { method, headers, body: urlEncoded });
  }

  if (mimeType === 'multipart/form-data') {
    const form = new Fetch.FormData();
    if (params)
      Object.keys(params).forEach((name)=> {
        params[name].forEach((value)=> {
          form.append(name, value);
        });
      });
    return new Fetch.Request(url, { method, headers, body: form });
  }

  throw new TypeError(`Unsupported content type ${mimeType}`);
}
Ejemplo n.º 11
0
  // Initializes a request.
  //
  // Calling this method an already active request (one for which open()or
  // openRequest()has already been called) is the equivalent of calling abort().
  open(method, url, useAsync, user, password) { // jshint ignore:line
    if (useAsync === false)
      throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 'Zombie does not support synchronous XHR requests');

    // Abort any pending request.
    this.abort();

    // Check supported HTTP method
    this._method = method.toUpperCase();
    if (/^(CONNECT|TRACE|TRACK)$/.test(this._method))
      throw new DOMException(DOMException.SECURITY_ERR, 'Unsupported HTTP method');
    if (!/^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/.test(this._method))
      throw new DOMException(DOMException.SYNTAX_ERR, 'Unsupported HTTP method');

    const headers = new Fetch.Headers();

    // Normalize the URL and check security
    url = URL.parse(Utils.resolveHref(this._window.location.href, url));
    // Don't consider port if they are standard for http and https
    if ((url.protocol === 'https:' && url.port === '443') ||
        (url.protocol === 'http:'  && url.port === '80'))
      delete url.port;

    if (!/^https?:$/i.test(url.protocol))
      throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 'Only HTTP/S protocol supported');
    url.hostname = url.hostname || this._window.location.hostname;
    url.host = url.port ? `${url.hostname}:${url.port}` : url.hostname;
    if (url.host !== this._window.location.host) {
      headers.set('Origin', `${this._window.location.protocol}//${this._window.location.host}`);
      this._cors = headers.get('Origin');
    }
    url.hash = null;
    if (user)
      url.auth = `${user}:${password}`;
    // Used for logging requests
    this._url       = URL.format(url);
    this._headers   = headers;

    // Reset response status
    this._stateChanged(XMLHttpRequest.OPENED);
  }
Ejemplo n.º 12
0
  function DOMURL(url, base) {
    _classCallCheck(this, DOMURL);

    assert(url != null, new DOM.DOMException("Failed to construct 'URL': Invalid URL"));
    if (base) url = Utils.resolveHref(base, url);
    var parsed = URL.parse(url || "about:blank");
    var origin = parsed.protocol && parsed.hostname && "" + parsed.protocol + "//" + parsed.hostname;
    Object.defineProperties(this, {
      hash: { value: parsed.hash, enumerable: true },
      host: { value: parsed.host, enumerable: true },
      hostname: { value: parsed.hostname, enumerable: true },
      href: { value: URL.format(parsed), enumerable: true },
      origin: { value: origin, enumerable: true },
      password: { value: parsed.password, enumerable: true },
      pathname: { value: parsed.pathname, enumerable: true },
      port: { value: parsed.port, enumerable: true },
      protocol: { value: parsed.protocol, enumerable: true },
      search: { value: parsed.search, enumerable: true },
      username: { value: parsed.username, enumerable: true }
    });
  }
Ejemplo n.º 13
0
 constructor(url, base) {
   if (url == null)
      throw new TypeError('Failed to construct \'URL\': Invalid URL');
   if (base)
     url = Utils.resolveHref(base, url);
   const parsed = URL.parse(url || 'about:blank');
   const origin = parsed.protocol && parsed.hostname && `${parsed.protocol}//${parsed.hostname}`;
   Object.defineProperties(this, {
     hash:     { value: parsed.hash,         enumerable: true },
     host:     { value: parsed.host,         enumerable: true },
     hostname: { value: parsed.hostname,     enumerable: true },
     href:     { value: URL.format(parsed),  enumerable: true },
     origin:   { value: origin,              enumerable: true },
     password: { value: parsed.password,     enumerable: true },
     pathname: { value: parsed.pathname,     enumerable: true },
     port:     { value: parsed.port,         enumerable: true },
     protocol: { value: parsed.protocol,     enumerable: true  },
     search:   { value: parsed.search,       enumerable: true },
     username: { value: parsed.username,     enumerable: true }
   });
 }
Ejemplo n.º 14
0
  function DOMURL(url, base) {
    _classCallCheck(this, DOMURL);

    if (url == null) throw new TypeError('Failed to construct \'URL\': Invalid URL');
    if (base) url = Utils.resolveHref(base, url);
    var parsed = URL.parse(url || 'about:blank');
    var origin = parsed.protocol && parsed.hostname && '' + parsed.protocol + '//' + parsed.hostname;
    _core.Object.defineProperties(this, {
      hash: { value: parsed.hash, enumerable: true },
      host: { value: parsed.host, enumerable: true },
      hostname: { value: parsed.hostname, enumerable: true },
      href: { value: URL.format(parsed), enumerable: true },
      origin: { value: origin, enumerable: true },
      password: { value: parsed.password, enumerable: true },
      pathname: { value: parsed.pathname, enumerable: true },
      port: { value: parsed.port, enumerable: true },
      protocol: { value: parsed.protocol, enumerable: true },
      search: { value: parsed.search, enumerable: true },
      username: { value: parsed.username, enumerable: true }
    });
  }
Ejemplo n.º 15
0
// Builds and returns a new Request, adding form parameters to URL (GET) or
// request body (POST).
function buildRequest(args) {
  var browser = args.browser;
  var method = args.method;

  var params = args.params || new _Map();
  var site = /^(https?:|file:)/i.test(browser.site) ? browser.site : 'http://' + (browser.site || 'locahost');
  var url = Utils.resolveHref(site, URL.format(args.url));

  var headers = new Fetch.Headers(args.headers);

  // HTTP header Referer, but Document property referrer
  var referrer = args.referrer || browser.referrer || browser.referer || args.history.url;
  if (referrer && !headers.has('Referer')) headers.set('Referer', referrer);
  if (!headers.has('Accept')) headers.set('Accept', 'text/html,*/*');

  if (/^GET|HEAD|DELETE$/i.test(method)) {
    var uri = URL.parse(url, true);
    // These methods use query string parameters instead
    var _iteratorNormalCompletion3 = true;
    var _didIteratorError3 = false;
    var _iteratorError3 = undefined;

    try {
      for (var _iterator3 = _getIterator(params), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
        var _step3$value = _slicedToArray(_step3.value, 2);

        var _name = _step3$value[0];
        var values = _step3$value[1];

        uri.query[_name] = values;
      }
    } catch (err) {
      _didIteratorError3 = true;
      _iteratorError3 = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion3 && _iterator3['return']) {
          _iterator3['return']();
        }
      } finally {
        if (_didIteratorError3) {
          throw _iteratorError3;
        }
      }
    }

    return new Fetch.Request(URL.format(uri), { method: method, headers: headers });
  }

  var mimeType = (args.encoding || '').split(';')[0].toLowerCase();
  // Default mime type, but can also be specified in form encoding
  if (mimeType === '' || mimeType === 'application/x-www-form-urlencoded') {
    var urlEncoded = [].concat(_toConsumableArray(params)).map(function (_ref) {
      var _ref2 = _slicedToArray(_ref, 2);

      var name = _ref2[0];
      var values = _ref2[1];

      return values.map(function (value) {
        return QS.escape(name) + '=' + QS.escape(value);
      }).join('&');
    }).join('&');

    headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
    return new Fetch.Request(url, { method: method, headers: headers, body: urlEncoded });
  }

  if (mimeType === 'multipart/form-data') {
    var form = new Fetch.FormData();
    var _iteratorNormalCompletion4 = true;
    var _didIteratorError4 = false;
    var _iteratorError4 = undefined;

    try {
      for (var _iterator4 = _getIterator(params), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
        var _step4$value = _slicedToArray(_step4.value, 2);

        var _name2 = _step4$value[0];
        var values = _step4$value[1];
        var _iteratorNormalCompletion5 = true;
        var _didIteratorError5 = false;
        var _iteratorError5 = undefined;

        try {
          for (var _iterator5 = _getIterator(values), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
            var value = _step5.value;

            form.append(_name2, value);
          }
        } catch (err) {
          _didIteratorError5 = true;
          _iteratorError5 = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion5 && _iterator5['return']) {
              _iterator5['return']();
            }
          } finally {
            if (_didIteratorError5) {
              throw _iteratorError5;
            }
          }
        }
      }
    } catch (err) {
      _didIteratorError4 = true;
      _iteratorError4 = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion4 && _iterator4['return']) {
          _iterator4['return']();
        }
      } finally {
        if (_didIteratorError4) {
          throw _iteratorError4;
        }
      }
    }

    return new Fetch.Request(url, { method: method, headers: headers, body: form });
  }

  throw new TypeError('Unsupported content type ' + mimeType);
}
Ejemplo n.º 16
0
module.exports = function loadDocument(args) {
  var browser = args.browser;
  var history = args.history;

  assert(browser && browser.visit, "Missing parameter browser");
  assert(history && history.reload, "Missing parameter history");

  var url = args.url;

  if (url && browser.site) {
    var site = /^(https?:|file:)/i.test(browser.site) ? browser.site : "http://" + browser.site;
    url = Utils.resolveHref(site, URL.format(url));
  }
  url = url || "about:blank";

  var document = createDocument(_core.Object.assign({ url: url }, args));
  var window = document.parentWindow;

  if (args.html) {
    window._eventQueue.enqueue(function () {
      document.write(args.html); // jshint ignore:line
      document.close();
      browser.emit("loaded", document);
    });
    return document;
  }

  // Let's handle the specifics of each protocol

  var _URL$parse = URL.parse(url);

  var protocol = _URL$parse.protocol;
  var pathname = _URL$parse.pathname;

  switch (protocol) {
    case "about:":
      {
        window._eventQueue.enqueue(function () {
          document.close();
          browser.emit("loaded", document);
        });
        break;
      }

    case "javascript:":
      {
        window._eventQueue.enqueue(function () {
          document.close();
          try {
            window._evaluate(pathname, "javascript:");
            browser.emit("loaded", document);
          } catch (error) {
            browser.emit("error", error);
          }
        });
        break;
      }

    default:
      {
        var method = (args.method || "GET").toUpperCase();
        // Proceeed to load resource ...
        var headers = args.headers || {};
        // HTTP header Referer, but Document property referrer
        headers.referer = headers.referer || args.referrer || browser.referrer || browser.referer || history.url || "";
        // Tell the browser we're looking for an HTML document
        headers.accept = headers.accept || "text/html,*/*";
        // Forms require content type
        if (method === "POST") headers["content-type"] = args.encoding || "application/x-www-form-urlencoded";

        window._eventQueue.http(method, url, { headers: headers, params: args.params, target: document }, function (error, response) {
          if (response) {
            history.updateLocation(window, response.url);
            window._response = response;
          }

          if (response && response.statusCode >= 400) error = new Error("Server returned status code " + response.statusCode + " from " + url);
          if (error) {

            // 4xx/5xx we get an error with an HTTP response
            // Error in body of page helps with debugging
            var message = response && response.body || error.message || error;
            document.write("<html><body>" + message + "</body></html>"); //jshint ignore:line
            document.close();
            browser.emit("error", error);
          } else {
            (function () {

              document.write(response.body); //jshint ignore:line
              document.close();

              // Handle meta refresh.  Automatically reloads new location and counts
              // as a redirect.
              //
              // If you need to check the page before refresh takes place, use this:
              //   browser.wait({
              //     function: function() {
              //       return browser.query('meta[http-equiv="refresh"]');
              //     }
              //   });
              var refreshURL = getMetaRefreshURL(document);
              if (refreshURL)
                // Allow completion function to run
                window._eventQueue.enqueue(function () {
                  // Count a meta-refresh in the redirects count.
                  history.replace(refreshURL || document.location.href);
                  // This results in a new window getting loaded
                  var newWindow = history.current.window;
                  newWindow.addEventListener("load", function () {
                    newWindow._response.redirects++;
                  });
                });else if (document.documentElement) browser.emit("loaded", document);else browser.emit("error", new Error("Could not parse document at " + response.url));
            })();
          }
        });
        break;
      }
  }

  return document;
};
Ejemplo n.º 17
0
      return _regeneratorRuntime.async(function handleRedirect$(context$2$0) {
        while (1) switch (context$2$0.prev = context$2$0.next) {
          case 0:
            status = response.status;

            if (!(status === 301 || status === 302 || status === 303 || status === 307 || status === 308)) {
              context$2$0.next = 19;
              break;
            }

            if (!(request.redirect === 'error')) {
              context$2$0.next = 4;
              break;
            }

            return context$2$0.abrupt('return', Fetch.Response.error());

          case 4:
            _location = response.headers.get('Location');

            if (!(_location === null)) {
              context$2$0.next = 7;
              break;
            }

            return context$2$0.abrupt('return', response);

          case 7:
            if (!(request._redirectCount >= 20)) {
              context$2$0.next = 9;
              break;
            }

            return context$2$0.abrupt('return', Fetch.Response.error());

          case 9:

            browser.emit('redirect', request, response, _location);
            ++request._redirectCount;
            if (status !== 307) {
              request.method = 'GET';
              request.headers['delete']('Content-Type');
              request.headers['delete']('Content-Length');
              request.headers['delete']('Content-Transfer-Encoding');
            }

            // This request is referer for next
            request.headers.set('Referer', request.url);
            request.url = Utils.resolveHref(request.url, _location);
            context$2$0.next = 16;
            return browser.pipeline._runPipeline(request);

          case 16:
            return context$2$0.abrupt('return', context$2$0.sent);

          case 19:
            return context$2$0.abrupt('return', response);

          case 20:
          case 'end':
            return context$2$0.stop();
        }
      }, null, this);
Ejemplo n.º 18
0
 patterns.forEach(function(pattern) {
   assert.equal(Utils.resolveHref(pattern[0], pattern[1]), pattern[2]);
 });