mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-24 16:09:32 -06:00
* remove experimentalSkipDomainInjection, add and deprecate injectDocumentDomain * remove experimentalSkipDomainInjection, add injectDocumentDomain * begin rethreading domain injection * complete document domain transition * move some cookie specs to separate test run * origin and privileged commands with default docdom inject * fix privileged channel when injecting document domain * rm unnecessary .getOrigin abstraction in cors lib * move remote-states in prep for refactor Replace Conditional with Polymorphism * refactor remote states to strategy pattern * cookie commands work as expected w cross origin bridge on different origins * some origin tests updated * run tests with document domain enabled * run tests actually * use correct config, swap conditional * check-ts * inject documetn domain for webkit tests * do not exec injectDocumetnDomain in parallel * fix ServerBase construction in tests to include cfg now * pass cfg to ServerBase * improved integration tests * remove document domain checks for all server integration specs - will add injectDocumentDomain cases * tests for injecting document domain when configured to * square away server integration tests * ensure cookies are set correctly, potentially * errors pkg snapshots * fix config tests * fixing config tests * somewhat improves tests for cors policies in packages/network * fix ts err in server-base * enable injectDocumentDomain for cy in cy tests * fix Policy type ref * refactor cypress-schematic ct spec to be less prone to timeouts * run vite-dev-server tests with injectDocumentDomain * rm document domain assertion from page_loading system test * add system tests that test with injectDocumentDomain and others that test with cy.origin * fix results_spec snapshot * update experimentalSkipDomainInjection system test * different behavior for certain net_stubbing tests based on injectDocumentDomain or not * fix ts * extract origin key logic from remote states, for now * move server-base and response-middleware over to new pattern * WIP - reentry * fix build, remove console.log * check-ts * fix spec frame injection * remove injection for localhost * mostly fix vite-dev-server app integration tests * fix codeframe in certain cases in chrome * drop internal stack frames from stacks intended for determining code frame data * some improvements to vite ct error codeframes * fix proxy unit tests to use document domain injection util class * rm .only * fix all vite ct error specs * rm console.log * slight refactor to util class to make easier to test * fix refactor - missing rename in files.js * several tests do not set testingtype in config, so just check against component instead of checking for e2e * revert changes to getInvocationDetails to see if that breaks tests * re-enable stack stripping in invocation details for chrome * new snapshots with more accurate invocation details * test for same-site cross-origin cookie behavior * ignore window.top ts errors * revert forcing injectDocumentDomain in vite-dev-server cy config * fix normalized whitespace for firefox "loading_failed" error * always trim trailing wsp from stack before appending additional content * force normalization of whitespace to three \n when adding additional stack details * normalize wsp between stack and additional stack to "\n \n" in firefox * remove stack_utils attempt at normalizing wsp * various cleanup: remove commented console logs, add more detailed comments * add on links to error messages * remove experimentalSkipDomainInjection from exported type defs * Update system-tests/test/experimental_skip_domain_injection_spec.ts Co-authored-by: Bill Glesias <bglesias@gmail.com> * Update packages/driver/cypress/e2e/e2e/origin/cookie_misc.cy.ts Co-authored-by: Bill Glesias <bglesias@gmail.com> * no need to coerce a boolean value to a booleanc * export base config from primary cypress config in driver for use in inject-document-domain test subset * lift experimentalSkipDomainInjection breaking option to root * rollback config/options changes * rm invalid comment * use hostname instead of origin to create cookie from automation cookie * clarify stack regex in results_spec * lint * take a stab at the changelog entries for this * Update cli/CHANGELOG.md Co-authored-by: Ryan Manuel <ryanm@cypress.io> * Update cli/CHANGELOG.md Co-authored-by: Ryan Manuel <ryanm@cypress.io> * reenable locally-failing test * changelog * snapshot updatesfor experimental skip domain injection err msg * remove packageManager declaration in package.json --------- Co-authored-by: Bill Glesias <bglesias@gmail.com> Co-authored-by: Jennifer Shehane <jennifer@cypress.io> Co-authored-by: Ryan Manuel <ryanm@cypress.io>
1645 lines
55 KiB
JavaScript
1645 lines
55 KiB
JavaScript
require('../spec_helper')
|
|
|
|
const _ = require('lodash')
|
|
const http = require('http')
|
|
const rp = require('@cypress/request-promise')
|
|
const Promise = require('bluebird')
|
|
const evilDns = require('evil-dns')
|
|
const { setupFullConfigWithDefaults } = require('@packages/config')
|
|
const httpsServer = require(`@packages/https-proxy/test/helpers/https_server`)
|
|
const config = require(`../../lib/config`)
|
|
const { ServerBase } = require(`../../lib/server-base`)
|
|
const { SocketE2E } = require(`../../lib/socket-e2e`)
|
|
const Fixtures = require('@tooling/system-tests')
|
|
const { createRoutes } = require(`../../lib/routes`)
|
|
const { getCtx } = require('../../lib/makeDataContext')
|
|
|
|
const s3StaticHtmlUrl = 'https://s3.amazonaws.com/internal-test-runner-assets.cypress.io/index.html'
|
|
|
|
const expectToEqDetails = function (actual, expected) {
|
|
actual = _.omit(actual, 'totalTime')
|
|
|
|
expect(actual).to.deep.eq(expected)
|
|
}
|
|
|
|
describe('Server', () => {
|
|
require('mocha-banner').register()
|
|
|
|
beforeEach(() => {
|
|
return sinon.stub(ServerBase.prototype, 'reset')
|
|
})
|
|
|
|
context('resolving url', () => {
|
|
beforeEach(function () {
|
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
|
|
|
nock.enableNetConnect()
|
|
|
|
this.automationRequest = sinon.stub()
|
|
this.automationRequest.withArgs('get:cookies').resolves([])
|
|
this.automationRequest.withArgs('set:cookie').resolves({})
|
|
|
|
this.setup = (initialUrl, obj = {}) => {
|
|
if (_.isObject(initialUrl)) {
|
|
obj = initialUrl
|
|
initialUrl = null
|
|
}
|
|
|
|
// get all the config defaults
|
|
// and allow us to override them
|
|
// for each test
|
|
return setupFullConfigWithDefaults(obj, getCtx().file.getFilesByGlob)
|
|
.then((cfg) => {
|
|
// use a jar for each test
|
|
// but reset it automatically
|
|
// between test
|
|
const jar = rp.jar()
|
|
|
|
// use a custom request promise
|
|
// to automatically backfill these
|
|
// options including our proxy
|
|
this.rp = (options = {}) => {
|
|
let url
|
|
|
|
if (_.isString(options)) {
|
|
url = options
|
|
options = {}
|
|
}
|
|
|
|
_.defaults(options, {
|
|
url,
|
|
proxy: this.proxy,
|
|
jar,
|
|
simple: false,
|
|
followRedirect: false,
|
|
resolveWithFullResponse: true,
|
|
})
|
|
|
|
return rp(options)
|
|
}
|
|
|
|
return Promise.all([
|
|
// open our https server
|
|
httpsServer.start(8443),
|
|
|
|
// and open our cypress server
|
|
(this.server = new ServerBase(cfg)),
|
|
|
|
this.server.open(cfg, {
|
|
SocketCtor: SocketE2E,
|
|
createRoutes,
|
|
testingType: 'e2e',
|
|
getCurrentBrowser: () => null,
|
|
})
|
|
.spread(async (port) => {
|
|
const automationStub = {
|
|
use: () => { },
|
|
}
|
|
|
|
await this.server.startWebsockets(automationStub, config, {})
|
|
if (initialUrl) {
|
|
this.server.remoteStates.set(initialUrl)
|
|
}
|
|
|
|
this.srv = this.server.getHttpServer()
|
|
|
|
this.proxy = `http://localhost:${port}`
|
|
|
|
this.buffers = this.server._networkProxy.http.buffers
|
|
|
|
this.fileServer = this.server._fileServer.address()
|
|
}),
|
|
])
|
|
})
|
|
}
|
|
})
|
|
|
|
afterEach(function () {
|
|
nock.cleanAll()
|
|
|
|
evilDns.clear()
|
|
|
|
return Promise.join(
|
|
this.server.close(),
|
|
httpsServer.stop(),
|
|
)
|
|
})
|
|
|
|
describe('file', () => {
|
|
beforeEach(function () {
|
|
Fixtures.scaffold('no-server')
|
|
|
|
return this.setup({
|
|
projectRoot: Fixtures.projectPath('no-server'),
|
|
config: {
|
|
port: 2000,
|
|
fileServerFolder: 'dev',
|
|
supportFile: false,
|
|
},
|
|
})
|
|
})
|
|
|
|
it('can serve static assets', async function () {
|
|
const obj = await this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
|
|
await expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
const res = await this.rp('http://localhost:2000/index.html')
|
|
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.headers['etag']).to.exist
|
|
expect(res.headers['set-cookie']).not.to.match(/initial=;/)
|
|
expect(res.headers['cache-control']).to.eq('no-cache, no-store, must-revalidate')
|
|
expect(res.body).to.include('index.html content')
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script>\n </head>')
|
|
})
|
|
|
|
it('sends back the content type', async function () {
|
|
const obj = await this.server._onResolveUrl('/assets/foo.json', {}, this.automationRequest)
|
|
|
|
await expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: false,
|
|
contentType: 'application/json',
|
|
url: 'http://localhost:2000/assets/foo.json',
|
|
originalUrl: '/assets/foo.json',
|
|
filePath: Fixtures.projectPath('no-server/dev/assets/foo.json'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
|
|
it('buffers the response', function () {
|
|
sinon.spy(this.server.request, 'sendStream')
|
|
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
expect(this.buffers.buffer).to.include({ url: 'http://localhost:2000/index.html' })
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
expect(this.server.request.sendStream).to.be.calledTwice
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('Cypress')
|
|
|
|
expect(this.buffers.buffer).to.be.undefined
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can follow static file redirects', function () {
|
|
return this.server._onResolveUrl('/sub', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/sub/',
|
|
originalUrl: '/sub',
|
|
filePath: Fixtures.projectPath('no-server/dev/sub/'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: ['301: http://localhost:2000/sub/'],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/sub/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
props: null,
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
it('gracefully handles 404', function () {
|
|
return this.server._onResolveUrl('/does-not-exist', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: false,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/does-not-exist',
|
|
originalUrl: '/does-not-exist',
|
|
filePath: Fixtures.projectPath('no-server/dev/does-not-exist'),
|
|
status: 404,
|
|
statusText: 'Not Found',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp({
|
|
url: 'http://localhost:2000/does-not-exist',
|
|
headers: {
|
|
'Accept-Encoding': 'identity',
|
|
},
|
|
})
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(404)
|
|
expect(res.body).to.include('Cypress errored trying to serve this file from your system:')
|
|
expect(res.body).to.include('does-not-exist')
|
|
|
|
expect(res.body).to.include('The file was not found')
|
|
})
|
|
})
|
|
})
|
|
|
|
it('handles urls with hashes', function () {
|
|
return this.server._onResolveUrl('/index.html#/foo/bar', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
expect(this.buffers.buffer).to.include({ url: 'http://localhost:2000/index.html' })
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
|
|
expect(this.buffers.buffer).to.be.undefined
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('http', () => {
|
|
beforeEach(function () {
|
|
return this.setup({
|
|
projectRoot: '/foo/bar/',
|
|
config: {
|
|
port: 2000,
|
|
supportFile: false,
|
|
},
|
|
})
|
|
})
|
|
|
|
context('only having one request in flight at a time', () => {
|
|
beforeEach(function (done) {
|
|
this.httpServer = http.createServer((req, res) => {
|
|
const [path, ms] = req.url.split('/').slice(1)
|
|
|
|
switch (path) {
|
|
case 'pause-before-body':
|
|
res.writeHead(200, { 'content-type': 'text/html' })
|
|
|
|
return setTimeout(() => {
|
|
res.write('ok')
|
|
|
|
return res.end()
|
|
}
|
|
, Number(ms))
|
|
case 'pause-before-headers':
|
|
return setTimeout(() => {
|
|
res.writeHead(200, { 'content-type': 'text/html' })
|
|
res.write('ok')
|
|
|
|
return res.end()
|
|
}
|
|
, Number(ms))
|
|
default:
|
|
}
|
|
})
|
|
|
|
this.httpServer.listen(() => {
|
|
this.httpPort = this.httpServer.address().port
|
|
|
|
return done()
|
|
})
|
|
|
|
this.runOneReqTest = (path) => {
|
|
// put the first request in flight
|
|
const p1 = this.server._onResolveUrl(`http://localhost:${this.httpPort}/${path}/1000`, {}, this.automationRequest)
|
|
|
|
return Promise.delay(100)
|
|
.then(() => {
|
|
// the p1 should not have a current promise phase or reqStream until it's canceled
|
|
expect(p1).not.to.have.property('currentPromisePhase')
|
|
expect(p1).not.to.have.property('reqStream')
|
|
|
|
// fire the 2nd request now that the first one has had some time to reach out
|
|
return this.server._onResolveUrl(`http://localhost:${this.httpPort}/${path}/100`, {}, this.automationRequest)
|
|
}).then((obj) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: `http://localhost:${this.httpPort}/${path}/100`,
|
|
originalUrl: `http://localhost:${this.httpPort}/${path}/100`,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
expect(p1.isCancelled()).to.be.true
|
|
expect(p1).to.have.property('currentPromisePhase')
|
|
|
|
expect(p1.reqStream.aborted).to.be.true
|
|
})
|
|
}
|
|
})
|
|
|
|
it('cancels and aborts the 1st request when it hasn\'t loaded headers and a 2nd request is made', function () {
|
|
return this.runOneReqTest('pause-before-headers')
|
|
})
|
|
|
|
it('cancels and aborts the 1st request when it hasn\'t loaded body and a 2nd request is made', function () {
|
|
return this.runOneReqTest('pause-before-body')
|
|
})
|
|
})
|
|
|
|
it('can serve http requests', function () {
|
|
nock('http://getbootstrap.com')
|
|
.matchHeader('user-agent', 'foobarbaz')
|
|
.matchHeader('accept', 'text/html,*/*')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'X-Foo-Bar': 'true',
|
|
'Content-Type': 'text/html',
|
|
'Cache-Control': 'public, max-age=3600',
|
|
})
|
|
|
|
const userAgent = 'foobarbaz'
|
|
|
|
return this.server._onResolveUrl('http://getbootstrap.com/', userAgent, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://getbootstrap.com/',
|
|
originalUrl: 'http://getbootstrap.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://getbootstrap.com/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.headers['set-cookie']).not.to.match(/initial=;/)
|
|
expect(res.headers['x-foo-bar']).to.eq('true')
|
|
expect(res.headers['cache-control']).to.eq('no-cache, no-store, must-revalidate')
|
|
expect(res.body).to.include('content')
|
|
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</head>content</html>')
|
|
})
|
|
})
|
|
})
|
|
|
|
it('sends back the content type', function () {
|
|
nock('http://getbootstrap.com')
|
|
.get('/user.json')
|
|
.reply(200, {})
|
|
|
|
return this.server._onResolveUrl('http://getbootstrap.com/user.json', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: false,
|
|
isHtml: false,
|
|
contentType: 'application/json',
|
|
url: 'http://getbootstrap.com/user.json',
|
|
originalUrl: 'http://getbootstrap.com/user.json',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
})
|
|
|
|
// @see https://github.com/cypress-io/cypress/issues/8506
|
|
it('yields isHtml true for unconventional HTML content-types', async function () {
|
|
const scope = nock('http://example.com')
|
|
.get('/a').reply(200, 'notHtml')
|
|
.get('/b').reply(200, 'notHtml', { 'content-type': 'Text/Html' })
|
|
.get('/c').reply(200, 'notHtml', { 'content-type': 'text/html;charset=utf-8' })
|
|
// invalid, but let's be tolerant
|
|
.get('/d').reply(200, 'notHtml', { 'content-type': 'text/html;' })
|
|
.get('/e').reply(200, 'notHtml', { 'content-type': 'application/xhtml+xml' })
|
|
|
|
const bad = await this.server._onResolveUrl('http://example.com/a', {}, this.automationRequest)
|
|
|
|
expect(bad.isHtml).to.be.false
|
|
|
|
for (const path of ['/b', '/c', '/d', '/e']) {
|
|
const details = await this.server._onResolveUrl(`http://example.com${path}`, {}, this.automationRequest)
|
|
|
|
expect(details.isHtml).to.be.true
|
|
}
|
|
|
|
scope.done()
|
|
})
|
|
|
|
it('yields isHtml true for HTML-shaped responses', function () {
|
|
nock('http://example.com')
|
|
.get('/')
|
|
.reply(200, '<html>foo</html>')
|
|
|
|
return this.server._onResolveUrl('http://example.com', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: undefined,
|
|
url: 'http://example.com/',
|
|
originalUrl: 'http://example.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
})
|
|
|
|
it('yields isHtml false for non-HTML-shaped responses', function () {
|
|
nock('http://example.com')
|
|
.get('/')
|
|
.reply(200, '{ foo: "bar" }')
|
|
|
|
return this.server._onResolveUrl('http://example.com', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: false,
|
|
isHtml: false,
|
|
contentType: undefined,
|
|
url: 'http://example.com/',
|
|
originalUrl: 'http://example.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can follow multiple http redirects', function () {
|
|
nock('http://espn.com')
|
|
.get('/')
|
|
.reply(301, undefined, {
|
|
'Location': '/foo',
|
|
})
|
|
.get('/foo')
|
|
.reply(302, undefined, {
|
|
'Location': 'http://espn.go.com/',
|
|
})
|
|
|
|
nock('http://espn.go.com')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://espn.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://espn.go.com/',
|
|
originalUrl: 'http://espn.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
cookies: [],
|
|
redirects: [
|
|
'301: http://espn.com/foo',
|
|
'302: http://espn.go.com/',
|
|
],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://espn.go.com/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('content')
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</head>content</html>')
|
|
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://espn.go.com',
|
|
strategy: 'http',
|
|
domainName: 'go.com',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'go',
|
|
tld: 'com',
|
|
port: '80',
|
|
subdomain: 'espn',
|
|
protocol: 'http:',
|
|
},
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
it('buffers the http response', function () {
|
|
sinon.spy(this.server.request, 'sendStream')
|
|
|
|
nock('http://espn.com')
|
|
.get('/')
|
|
.times(2)
|
|
.reply(301, undefined, {
|
|
'Location': '/foo',
|
|
})
|
|
.get('/foo')
|
|
.times(2)
|
|
.reply(302, undefined, {
|
|
'Location': 'http://espn.go.com/',
|
|
})
|
|
|
|
nock('http://espn.go.com')
|
|
.get('/')
|
|
.times(2)
|
|
.reply(200, '<html><head></head><body>espn</body></html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://espn.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://espn.go.com/',
|
|
originalUrl: 'http://espn.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
cookies: [],
|
|
redirects: [
|
|
'301: http://espn.com/foo',
|
|
'302: http://espn.go.com/',
|
|
],
|
|
})
|
|
|
|
expect(this.buffers.buffer).to.include({ url: 'http://espn.go.com/' })
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('http://espn.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://espn.go.com/',
|
|
originalUrl: 'http://espn.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
cookies: [],
|
|
redirects: [
|
|
'301: http://espn.com/foo',
|
|
'302: http://espn.go.com/',
|
|
],
|
|
})
|
|
|
|
expect(this.server.request.sendStream).to.be.calledTwice
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://espn.go.com/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script></head><body>espn</body></html>')
|
|
|
|
expect(this.buffers.buffer).to.be.undefined
|
|
})
|
|
})
|
|
})
|
|
|
|
it('does not buffer \'bad\' responses', function () {
|
|
sinon.spy(this.server.request, 'sendStream')
|
|
|
|
nock('http://espn.com')
|
|
.get('/')
|
|
.reply(404, undefined)
|
|
.get('/')
|
|
.reply(301, undefined, {
|
|
'Location': '/foo',
|
|
})
|
|
.get('/foo')
|
|
.reply(301, undefined, {
|
|
'Location': 'http://espn.go.com/',
|
|
})
|
|
|
|
nock('http://espn.go.com')
|
|
.get('/')
|
|
.reply(200, 'content', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://espn.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: false,
|
|
isPrimarySuperDomainOrigin: false,
|
|
isHtml: false,
|
|
contentType: undefined,
|
|
url: 'http://espn.com/',
|
|
originalUrl: 'http://espn.com/',
|
|
status: 404,
|
|
statusText: 'Not Found',
|
|
cookies: [],
|
|
redirects: [],
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://espn.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://espn.go.com/',
|
|
originalUrl: 'http://espn.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
cookies: [],
|
|
redirects: [
|
|
'301: http://espn.com/foo',
|
|
'301: http://espn.go.com/',
|
|
],
|
|
})
|
|
|
|
expect(this.server.request.sendStream).to.be.calledTwice
|
|
})
|
|
})
|
|
})
|
|
|
|
it('gracefully handles 500', function () {
|
|
nock('http://mlb.com')
|
|
.get('/')
|
|
.reply(307, undefined, {
|
|
'Location': 'http://mlb.mlb.com/',
|
|
})
|
|
|
|
nock('http://mlb.mlb.com')
|
|
.get('/')
|
|
.reply(500, undefined, {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://mlb.com/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: false,
|
|
isPrimarySuperDomainOrigin: false,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://mlb.mlb.com/',
|
|
originalUrl: 'http://mlb.com/',
|
|
status: 500,
|
|
statusText: 'Internal Server Error',
|
|
cookies: [],
|
|
redirects: ['307: http://mlb.mlb.com/'],
|
|
})
|
|
})
|
|
})
|
|
|
|
it('gracefully handles http errors', function () {
|
|
return this.server._onResolveUrl('http://localhost:64646', {}, this.automationRequest)
|
|
.catch((err) => {
|
|
expect(err.message).to.eq('connect ECONNREFUSED 127.0.0.1:64646')
|
|
expect(err.port).to.eq(64646)
|
|
|
|
expect(err.code).to.eq('ECONNREFUSED')
|
|
})
|
|
})
|
|
|
|
it('handles url hashes', function () {
|
|
nock('http://getbootstrap.com')
|
|
.get('/')
|
|
.reply(200, 'content page', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://getbootstrap.com/#/foo', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://getbootstrap.com/',
|
|
originalUrl: 'http://getbootstrap.com/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
|
|
expect(this.buffers.buffer).to.include({ url: 'http://getbootstrap.com/' })
|
|
}).then(() => {
|
|
return this.rp('http://getbootstrap.com/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
|
|
expect(this.buffers.buffer).to.be.undefined
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can serve non 2xx status code requests when option set', function () {
|
|
nock('http://cypress.io')
|
|
.matchHeader('user-agent', 'foobarbaz')
|
|
.matchHeader('accept', 'text/html,*/*')
|
|
.get('/foo')
|
|
.reply(404, '<html>content</html>', {
|
|
'X-Foo-Bar': 'true',
|
|
'Content-Type': 'text/html',
|
|
'Cache-Control': 'public, max-age=3600',
|
|
})
|
|
|
|
const userAgent = 'foobarbaz'
|
|
|
|
return this.server._onResolveUrl('http://cypress.io/foo', userAgent, this.automationRequest, { failOnStatusCode: false })
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://cypress.io/foo',
|
|
originalUrl: 'http://cypress.io/foo',
|
|
status: 404,
|
|
statusText: 'Not Found',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://cypress.io/foo')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(404)
|
|
expect(res.headers['set-cookie']).not.to.match(/initial=;/)
|
|
expect(res.headers['x-foo-bar']).to.eq('true')
|
|
expect(res.headers['cache-control']).to.eq('no-cache, no-store, must-revalidate')
|
|
expect(res.body).to.include('content')
|
|
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</head>content</html>')
|
|
})
|
|
})
|
|
})
|
|
|
|
it('passes auth through', function () {
|
|
const username = 'u'
|
|
const password = 'p'
|
|
|
|
const base64 = Buffer.from(`${username}:${password}`).toString('base64')
|
|
|
|
const auth = {
|
|
username,
|
|
password,
|
|
}
|
|
|
|
nock('http://google.com')
|
|
.get('/index')
|
|
.matchHeader('authorization', `Basic ${base64}`)
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
.get('/index2')
|
|
.matchHeader('authorization', `Basic ${base64}`)
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
const userAgent = 'foobarbaz'
|
|
|
|
return this.server._onResolveUrl('http://google.com/index', userAgent, this.automationRequest, { auth })
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://google.com/index',
|
|
originalUrl: 'http://google.com/index',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://google.com/index2')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth,
|
|
origin: 'http://google.com',
|
|
strategy: 'http',
|
|
domainName: 'google.com',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'google',
|
|
tld: 'com',
|
|
port: '80',
|
|
subdomain: null,
|
|
protocol: 'http:',
|
|
},
|
|
})
|
|
})
|
|
})
|
|
|
|
context('cross-origin', () => {
|
|
it('adds a remote state and buffers the response when the request is from within cy.origin and the origins match', function () {
|
|
nock('http://www.cypress.io/')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: null,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
})
|
|
|
|
this.server.remoteStates.set('http://cypress.io', {}, false)
|
|
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: {
|
|
domain: 'cypress',
|
|
port: '80',
|
|
tld: 'io',
|
|
subdomain: null,
|
|
protocol: 'http:',
|
|
},
|
|
origin: 'http://cypress.io',
|
|
strategy: 'http',
|
|
domainName: 'cypress.io',
|
|
fileServer: null,
|
|
})
|
|
|
|
expect(this.server.remoteStates.isPrimarySuperDomainOrigin('http://cypress.io')).to.be.false
|
|
|
|
return this.server._onResolveUrl('http://www.cypress.io/', {}, this.automationRequest, { isFromSpecBridge: true })
|
|
.then((obj = {}) => {
|
|
expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: false,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://www.cypress.io/',
|
|
originalUrl: 'http://www.cypress.io/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
cookies: [],
|
|
redirects: [],
|
|
})
|
|
|
|
// Verify the cross origin request was buffered
|
|
const buffer = this.buffers.take('http://www.cypress.io/')
|
|
|
|
expect(buffer).to.not.be.empty
|
|
expect(buffer.urlDoesNotMatchPolicyBasedOnDomain).to.be.true
|
|
|
|
// Verify the secondary remote state is returned
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: {
|
|
domain: 'cypress',
|
|
port: '80',
|
|
tld: 'io',
|
|
subdomain: 'www',
|
|
protocol: 'http:',
|
|
},
|
|
origin: 'http://www.cypress.io',
|
|
strategy: 'http',
|
|
domainName: 'cypress.io',
|
|
fileServer: null,
|
|
})
|
|
})
|
|
})
|
|
|
|
it('adds a remote state and buffers the response when a url has already been visited and the origins match', function () {
|
|
nock('http://localhost:3500/')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
// this will be the current origin
|
|
this.server.remoteStates.set('http://localhost:3500/')
|
|
|
|
return this.server._onResolveUrl('http://localhost:3500/', {}, this.automationRequest, { hasAlreadyVisitedUrl: true })
|
|
.then((obj = {}) => {
|
|
// Verify the cross origin request was buffered
|
|
const buffer = this.buffers.take('http://localhost:3500/')
|
|
|
|
expect(buffer).to.not.be.empty
|
|
|
|
// Verify the secondary remote state is returned
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: {
|
|
domain: '',
|
|
port: '3500',
|
|
tld: 'localhost',
|
|
subdomain: null,
|
|
protocol: 'http:',
|
|
},
|
|
origin: 'http://localhost:3500',
|
|
strategy: 'http',
|
|
domainName: 'localhost',
|
|
fileServer: null,
|
|
})
|
|
})
|
|
})
|
|
|
|
it('does set a remote state and buffer the response when a url has already been visited and the origins don\'t match', function () {
|
|
nock('http://localhost:3500/')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
this.server.remoteStates.set('http://localhost:3500/')
|
|
|
|
// this will be the current origin
|
|
this.server.remoteStates.set('http://cypress.io', {}, false)
|
|
|
|
return this.server._onResolveUrl('http://localhost:3500/', {}, this.automationRequest, { hasAlreadyVisitedUrl: true })
|
|
.then(() => {
|
|
// Verify the remote state was not updated
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: {
|
|
domain: '',
|
|
port: '3500',
|
|
tld: 'localhost',
|
|
subdomain: null,
|
|
protocol: 'http:',
|
|
},
|
|
origin: 'http://localhost:3500',
|
|
strategy: 'http',
|
|
domainName: 'localhost',
|
|
fileServer: null,
|
|
})
|
|
|
|
// Verify the cross origin request was buffered
|
|
const buffer = this.buffers.take('http://localhost:3500/')
|
|
|
|
expect(buffer).to.not.be.empty
|
|
})
|
|
})
|
|
|
|
it('does set a remote state or buffer the response when the request is from within cy.origin and the origins don\'t match', function () {
|
|
nock('http://localhost:3500/')
|
|
.get('/')
|
|
.reply(200, '<html>content</html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
this.server.remoteStates.set('http://localhost:3500/')
|
|
|
|
// this will be the current origin
|
|
this.server.remoteStates.set('http://cypress.io', {}, false)
|
|
|
|
return this.server._onResolveUrl('http://localhost:3500/', {}, this.automationRequest, { isFromSpecBridge: true })
|
|
.then(() => {
|
|
// Verify the remote state was not updated
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
props: {
|
|
domain: '',
|
|
port: '3500',
|
|
tld: 'localhost',
|
|
subdomain: null,
|
|
protocol: 'http:',
|
|
},
|
|
origin: 'http://localhost:3500',
|
|
strategy: 'http',
|
|
domainName: 'localhost',
|
|
fileServer: null,
|
|
})
|
|
|
|
// Verify the cross origin request was buffered
|
|
const buffer = this.buffers.take('http://localhost:3500/')
|
|
|
|
expect(buffer).to.not.be.empty
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('http with injectDocumentDomain enabled', () => {
|
|
const superDomain = 'cypress.io'
|
|
const secondSuperDomain = 'google.com'
|
|
const origin = `http://www.${superDomain}`
|
|
const sameSuperdomainOrigin = `http://docs.${superDomain}`
|
|
const differentSuperdomainOrigin = `http://www.${secondSuperDomain}`
|
|
|
|
const statusCode = 200
|
|
const contentText = 'content'
|
|
const path = '/'
|
|
|
|
beforeEach(async function () {
|
|
await this.setup(origin, {
|
|
projectRoot: '/foo/bar/',
|
|
config: {
|
|
port: 2000,
|
|
supportFile: false,
|
|
|
|
injectDocumentDomain: true,
|
|
|
|
},
|
|
})
|
|
|
|
;[origin, sameSuperdomainOrigin, differentSuperdomainOrigin].forEach((originToMock) => {
|
|
nock(originToMock).get(path).reply(statusCode, `<html>${contentText}</html>`, {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('when navigating to a different subdomain of the same superdomain without cy.origin', function () {
|
|
it('injects document.domain', async function () {
|
|
const url = `${sameSuperdomainOrigin}${path}`
|
|
|
|
await this.server._onResolveUrl(url, {}, this.automationRequest)
|
|
const res = await this.rp(url)
|
|
|
|
expect(res.body).to.include(`document.domain = \'${superDomain}\'`)
|
|
})
|
|
})
|
|
|
|
describe('when navigating to a different superdomain with cy.origin', function () {
|
|
it('injects document.domain', async function () {
|
|
const url = `${differentSuperdomainOrigin}${path}`
|
|
|
|
this.server.remoteStates.set(differentSuperdomainOrigin, {}, false)
|
|
await this.server._onResolveUrl(url, {}, this.automationRequest)
|
|
const res = await this.rp(url)
|
|
|
|
expect(res.body).to.include(`document.domain = \'${secondSuperDomain}\'`)
|
|
})
|
|
})
|
|
|
|
describe('when navigating to the same origin', function () {
|
|
it('injects document.domain', async function () {
|
|
const url = `${origin}${path}`
|
|
|
|
this.server.remoteStates.set(differentSuperdomainOrigin)
|
|
await this.server._onResolveUrl(url, {}, this.automationRequest)
|
|
const res = await this.rp(url)
|
|
|
|
expect(res.body).to.include(`document.domain = \'${superDomain}\'`)
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('both', () => {
|
|
beforeEach(function () {
|
|
Fixtures.scaffold('no-server')
|
|
|
|
return this.setup({
|
|
projectRoot: Fixtures.projectPath('no-server'),
|
|
config: {
|
|
port: 2000,
|
|
fileServerFolder: 'dev',
|
|
supportFile: false,
|
|
},
|
|
})
|
|
})
|
|
|
|
it('can go from file -> http -> file', function () {
|
|
nock('http://www.cypress.io')
|
|
.get('/')
|
|
.reply(200, 'content page', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('http://www.cypress.io/', {}, this.automationRequest)
|
|
}).then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://www.cypress.io/',
|
|
originalUrl: 'http://www.cypress.io/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://www.cypress.io/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://www.cypress.io',
|
|
strategy: 'http',
|
|
domainName: 'cypress.io',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'cypress',
|
|
tld: 'io',
|
|
port: '80',
|
|
subdomain: 'www',
|
|
protocol: 'http:',
|
|
},
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
props: null,
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can go from http -> file -> http', function () {
|
|
nock('http://www.cypress.io')
|
|
.get('/')
|
|
.reply(200, '<html><head></head><body>cypress</body></html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
.get('/')
|
|
.reply(200, '<html><head></head><body>cypress</body></html>', {
|
|
'Content-Type': 'text/html',
|
|
})
|
|
|
|
return this.server._onResolveUrl('http://www.cypress.io/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://www.cypress.io/',
|
|
originalUrl: 'http://www.cypress.io/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://www.cypress.io/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script></head><body>cypress</body></html>')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://www.cypress.io',
|
|
strategy: 'http',
|
|
domainName: 'cypress.io',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'cypress',
|
|
tld: 'io',
|
|
port: '80',
|
|
subdomain: 'www',
|
|
protocol: 'http:',
|
|
},
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
props: null,
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('http://www.cypress.io/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://www.cypress.io/',
|
|
originalUrl: 'http://www.cypress.io/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://www.cypress.io/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script></head><body>cypress</body></html>')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://www.cypress.io',
|
|
strategy: 'http',
|
|
domainName: 'cypress.io',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'cypress',
|
|
tld: 'io',
|
|
port: '80',
|
|
subdomain: 'www',
|
|
protocol: 'http:',
|
|
},
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can go from https -> file -> https', function () {
|
|
evilDns.add('*.foobar.com', '127.0.0.1')
|
|
|
|
return this.server._onResolveUrl('https://www.foobar.com:8443/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'https://www.foobar.com:8443/',
|
|
originalUrl: 'https://www.foobar.com:8443/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('https://www.foobar.com:8443/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script></head><body>https server</body></html>')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'https://www.foobar.com:8443',
|
|
strategy: 'http',
|
|
domainName: 'foobar.com',
|
|
fileServer: null,
|
|
props: {
|
|
domain: 'foobar',
|
|
tld: 'com',
|
|
port: '8443',
|
|
subdomain: 'www',
|
|
protocol: 'https:',
|
|
},
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
props: null,
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('https://www.foobar.com:8443/', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'https://www.foobar.com:8443/',
|
|
originalUrl: 'https://www.foobar.com:8443/',
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
return this.rp('https://www.foobar.com:8443/')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
expect(res.body).to.include('</script></head><body>https server</body></html>')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'https://www.foobar.com:8443',
|
|
strategy: 'http',
|
|
fileServer: null,
|
|
domainName: 'foobar.com',
|
|
props: {
|
|
domain: 'foobar',
|
|
tld: 'com',
|
|
port: '8443',
|
|
subdomain: 'www',
|
|
protocol: 'https:',
|
|
},
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
it('can go from https -> file -> https without a port', function () {
|
|
this.timeout(5000)
|
|
|
|
return this.server._onResolveUrl(s3StaticHtmlUrl, {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: s3StaticHtmlUrl,
|
|
originalUrl: s3StaticHtmlUrl,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
// @server.onRequest (req, res) ->
|
|
// console.log "ON REQUEST!!!!!!!!!!!!!!!!!!!!!!"
|
|
|
|
// nock("https://s3.amazonaws.com")
|
|
// .get("/internal-test-runner-assets.cypress.io/index.html")
|
|
// .reply 200, "<html><head></head><body>jsonplaceholder</body></html>", {
|
|
// "Content-Type": "text/html"
|
|
// }
|
|
|
|
return this.rp(s3StaticHtmlUrl)
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('Cypress')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'https://s3.amazonaws.com',
|
|
strategy: 'http',
|
|
domainName: 's3.amazonaws.com',
|
|
fileServer: null,
|
|
props: {
|
|
domain: '',
|
|
tld: 's3.amazonaws.com',
|
|
port: '443',
|
|
subdomain: null,
|
|
protocol: 'https:',
|
|
},
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl('/index.html', {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: 'http://localhost:2000/index.html',
|
|
originalUrl: '/index.html',
|
|
filePath: Fixtures.projectPath('no-server/dev/index.html'),
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
})
|
|
}).then(() => {
|
|
return this.rp('http://localhost:2000/index.html')
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('.action("app:window:before:load",window)')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'http://localhost:2000',
|
|
strategy: 'file',
|
|
domainName: 'localhost',
|
|
fileServer: this.fileServer,
|
|
props: null,
|
|
})
|
|
}).then(() => {
|
|
return this.server._onResolveUrl(s3StaticHtmlUrl, {}, this.automationRequest)
|
|
.then((obj = {}) => {
|
|
return expectToEqDetails(obj, {
|
|
isOkStatusCode: true,
|
|
isPrimarySuperDomainOrigin: true,
|
|
isHtml: true,
|
|
contentType: 'text/html',
|
|
url: s3StaticHtmlUrl,
|
|
originalUrl: s3StaticHtmlUrl,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
redirects: [],
|
|
cookies: [],
|
|
})
|
|
}).then(() => {
|
|
// @server.onNextRequest (req, res) ->
|
|
// nock("https://s3.amazonaws.com")
|
|
// .get("/internal-test-runner-assets.cypress.io/index.html")
|
|
// .reply 200, "<html><head></head><body>jsonplaceholder</body></html>", {
|
|
// "Content-Type": "text/html"
|
|
// }
|
|
|
|
return this.rp(s3StaticHtmlUrl)
|
|
.then((res) => {
|
|
expect(res.statusCode).to.eq(200)
|
|
expect(res.body).to.include('Cypress')
|
|
})
|
|
}).then(() => {
|
|
expect(this.server.remoteStates.current()).to.deep.eq({
|
|
auth: undefined,
|
|
origin: 'https://s3.amazonaws.com',
|
|
strategy: 'http',
|
|
fileServer: null,
|
|
domainName: 's3.amazonaws.com',
|
|
props: {
|
|
domain: '',
|
|
tld: 's3.amazonaws.com',
|
|
port: '443',
|
|
subdomain: null,
|
|
protocol: 'https:',
|
|
},
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|