From e08778dd897968541948c00a43067547fec43010 Mon Sep 17 00:00:00 2001 From: Brian Mann Date: Sun, 4 Feb 2018 17:28:33 -0500 Subject: [PATCH] Issue 1175 (#1257) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * server: fixes #802 and fixes #380 and fixes #402 and fixes #493 and fixes #1161 - use the public suffix when parsing tld’s so that document.domain is set correctly * driver: move location spec back into cypress tests * server, driver: fixes: #600 and fixes #1175 use public suffix for parsing tld, handle multiple different subdomains on cy.visit --- packages/driver/package.json | 1 + packages/driver/src/cypress/location.coffee | 46 +++++++++++------ .../integration}/cypress/location_spec.coffee | 50 +++++++++++-------- .../__snapshots__/subdomain_spec.coffee | 8 +-- .../server/test/e2e/subdomain_spec.coffee | 3 ++ .../cypress/integration/subdomain_spec.coffee | 7 +++ 6 files changed, 74 insertions(+), 41 deletions(-) rename packages/driver/test/{unit => cypress/integration}/cypress/location_spec.coffee (87%) diff --git a/packages/driver/package.json b/packages/driver/package.json index c266c83e94..47377f379b 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -48,6 +48,7 @@ "moment": "^2.14.1", "morgan": "^1.3.0", "npm-install-version": "^6.0.2", + "parse-domain": "2.0.0", "setimmediate": "^1.0.2", "sinon": "3.2.0", "underscore": "^1.8.3", diff --git a/packages/driver/src/cypress/location.coffee b/packages/driver/src/cypress/location.coffee index e294dc50ad..b75b59e951 100644 --- a/packages/driver/src/cypress/location.coffee +++ b/packages/driver/src/cypress/location.coffee @@ -9,6 +9,14 @@ _ = require("lodash") UrlParse = require("url-parse") +## TODO: this adds 70kb gzipped +## and we need to move this to use +## node over websockets so we dont +## have to send it to the client +parseDomain = require("parse-domain") + +localHostOrIpAddressRe = /.?localhost|\.local|^[\d\.]+$/ + reHttp = /^https?:\/\// reWww = /^www/ @@ -65,24 +73,30 @@ class $Location getSuperDomain: -> hostname = @getHostName() - parts = hostname.split(".") - ## if this is an ip address then - ## just return it straight up - if ipAddressRe.test(hostname) - return hostname + ## TODO: this code is almost identical to + ## the code in server/util/cors + ## refactor this to share it together - switch parts.length - when 1 - ## localhost => localhost - hostname - when 2 - ## stackoverflow.com => stackoverflow.com - hostname - else - ## mail.google.com => google.com - ## cart.shopping.co.uk => shopping.co.uk - parts.slice(1).join(".") + ## if we couldn't get a parsed domain + if not parsed = parseDomain(hostname, { + privateTlds: true ## use the public suffix + customTlds: localHostOrIpAddressRe + }) + + ## then just fall back to a dumb check + ## based on assumptions that the tld + ## is the last segment after the final + ## '.' and that the domain is the segment + ## before that + segments = hostname.split(".") + + parsed = { + tld: segments[segments.length - 1] + domain: segments[segments.length - 2] + } + + return _.compact([parsed.domain, parsed.tld]).join(".") getToString: -> @remote.toString() diff --git a/packages/driver/test/unit/cypress/location_spec.coffee b/packages/driver/test/cypress/integration/cypress/location_spec.coffee similarity index 87% rename from packages/driver/test/unit/cypress/location_spec.coffee rename to packages/driver/test/cypress/integration/cypress/location_spec.coffee index 7f006f588c..3f4e8b9908 100644 --- a/packages/driver/test/unit/cypress/location_spec.coffee +++ b/packages/driver/test/cypress/integration/cypress/location_spec.coffee @@ -1,8 +1,4 @@ -require("../../support/unit_spec_helper") - -_ = require("lodash") -Promise = require("bluebird") -$Location = require("#{src}/cypress/location") +{ _, Location, Promise } = Cypress urls = { blank: "about:blank" @@ -18,12 +14,15 @@ urls = { stack: "https://stackoverflow.com/" trailHash:"http://localhost:3500/index.html?foo=bar#" email: "http://localhost:3500/?email=brian@cypress.io" + heroku: "https://example.herokuapp.com" + herokuSub:"https://foo.example.herokuapp.com" + unknown: "http://what.is.so.unknown" } describe "src/cypress/location", -> beforeEach -> @setup = (remote) => - new $Location(urls[remote]) + new Location(urls[remote]) context "#getHash", -> it "returns the hash fragment prepended with #", -> @@ -145,20 +144,32 @@ describe "src/cypress/location", -> str = @setup("email").getOriginPolicy() expect(str).to.eq("http://localhost:3500") + it "handles private tlds in the public suffix", -> + str = @setup("heroku").getOriginPolicy() + expect(str).to.eq("https://example.herokuapp.com") + + it "handles subdomains of private tlds in the public suffix", -> + str = @setup("herokuSub").getOriginPolicy() + expect(str).to.eq("https://example.herokuapp.com") + + it "falls back to dumb check when invalid tld", -> + str = @setup("unknown").getOriginPolicy() + expect(str).to.eq("http://so.unknown") + context ".create", -> it "returns an object literal", -> - obj = $Location.create(urls.cypress, urls.signin) + obj = Location.create(urls.cypress, urls.signin) keys = ["hash", "href", "host", "hostname", "origin", "pathname", "port", "protocol", "search", "toString", "originPolicy", "superDomain"] expect(obj).to.have.keys(keys) it "can invoke toString function", -> - obj = $Location.create(urls.signin) + obj = Location.create(urls.signin) expect(obj.toString()).to.eq("http://localhost:2020/signin") context ".normalize", -> beforeEach -> @url = (source, expected) -> - url = $Location.normalize(source) + url = Location.normalize(source) expect(url).to.eq(expected) describe "http urls", -> @@ -210,44 +221,39 @@ describe "src/cypress/location", -> context ".fullyQualifyUrl", -> beforeEach -> - ## TODO: might be easier to stub out something on - ## the $Location object -> or refactor for it - ## to use a location getter module - jsdom.reconfigure({url: "http://localhost:3500"}) - @normalize = (url) -> - $Location.normalize(url) + Location.normalize(url) it "does not append trailing slash on a sub directory", -> url = @normalize("http://localhost:4200/app") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://localhost:4200/app" it "does not append a trailing slash to url with hash", -> url = @normalize("http://localhost:4000/#/home") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://localhost:4000/#/home" it "does not append a trailing slash to protocol-less url with hash", -> url = @normalize("www.github.com/#/home") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://www.github.com/#/home" it "handles urls without a host", -> url = @normalize("index.html") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://localhost:3500/index.html" it "does not insert trailing slash without a host", -> - url = $Location.fullyQualifyUrl("index.html") + url = Location.fullyQualifyUrl("index.html") expect(url).to.eq "http://localhost:3500/index.html" it "handles no host + query params", -> url = @normalize("timeout?ms=1000") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://localhost:3500/timeout?ms=1000" it "does not strip off path", -> url = @normalize("fixtures/sinon.html") - url = $Location.fullyQualifyUrl(url) + url = Location.fullyQualifyUrl(url) expect(url).to.eq "http://localhost:3500/fixtures/sinon.html" diff --git a/packages/server/__snapshots__/subdomain_spec.coffee b/packages/server/__snapshots__/subdomain_spec.coffee index af699db9d1..78694a8742 100644 --- a/packages/server/__snapshots__/subdomain_spec.coffee +++ b/packages/server/__snapshots__/subdomain_spec.coffee @@ -13,16 +13,17 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4 - sets a hostOnly cookie by default ✓ issue #361: incorrect cookie synchronization between cy.request redirects ✓ issue #362: incorrect cookie synchronization between cy.visit redirects + ✓ issue #600 can visit between nested subdomains - 6 passing + 7 passing 2 pending (Tests Finished) - - Tests: 8 - - Passes: 6 + - Tests: 9 + - Passes: 7 - Failures: 0 - Pending: 2 - Duration: 10 seconds @@ -40,3 +41,4 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4 (All Done) ` + diff --git a/packages/server/test/e2e/subdomain_spec.coffee b/packages/server/test/e2e/subdomain_spec.coffee index c62e649f61..3723785db5 100644 --- a/packages/server/test/e2e/subdomain_spec.coffee +++ b/packages/server/test/e2e/subdomain_spec.coffee @@ -86,6 +86,9 @@ onServer = (app) -> getText("Domain") + when "qa.sub.foobar.com:2292", "staging.sub.foobar.com:2292" + getText("Nested Subdomains") + else throw new Error("Host: '#{h}' not recognized") diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/integration/subdomain_spec.coffee b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/subdomain_spec.coffee index f70e308a11..10abee2177 100644 --- a/packages/server/test/support/fixtures/projects/e2e/cypress/integration/subdomain_spec.coffee +++ b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/subdomain_spec.coffee @@ -106,3 +106,10 @@ describe "subdomains", -> .visit("http://domain.foobar.com:2292/domainRedirect") .get("#cookie") .should("have.text", "foobar=1") + + it "issue #600 can visit between nested subdomains", -> + cy + .visit("http://qa.sub.foobar.com:2292") + .contains("Nested Subdomains") + .visit("http://staging.sub.foobar.com:2292") + .contains("Nested Subdomains")