Skip to content

Commit

Permalink
make sure to use correct path in windows if no cypress public path is…
Browse files Browse the repository at this point in the history
… provided [run ci]
  • Loading branch information
AtofStryker committed May 15, 2024
1 parent 5927129 commit f9cdf77
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 6 deletions.
24 changes: 18 additions & 6 deletions npm/vite-dev-server/client/initCypressTests.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// This file is merged in a <script type=module> into index.html
// it will be used to load and kick start the selected spec

const CypressInstance = window.Cypress = parent.Cypress

const importsToLoad = []
Expand All @@ -13,30 +12,43 @@ const supportFile = CypressInstance.config('supportFile')
const projectRoot = CypressInstance.config('projectRoot')
const devServerPublicPathRoute = CypressInstance.config('devServerPublicPathRoute')

let devServerPublicPathBase = devServerPublicPathRoute

if (devServerPublicPathRoute === '') {
devServerPublicPathBase = '.'
}

if (supportFile) {
let supportRelativeToProjectRoot = supportFile.replace(projectRoot, '')

if (CypressInstance.config('platform') === 'win32') {
const platformProjectRoot = projectRoot.replaceAll('/', '\\')

supportRelativeToProjectRoot = supportFile.replace(platformProjectRoot, '')

// Support Relative path (as well as in some cases absolute path) lookup is done with unix style operators.
supportRelativeToProjectRoot = supportRelativeToProjectRoot.replaceAll('\\', '/')
}

// We need a slash before /cypress/supportFile.js, this happens by default
// with the current string replacement logic.
// We need a slash before /cypress/supportFile.js if the devServerPublicPathRoute is populated, this happens by default
// with the current string replacement logic. Otherwise, we need to specify the relative path to look up if devServerPublicPathRoute
// if not defined as it would be in the base directory

const relativeUrl = `${devServerPublicPathBase}${supportRelativeToProjectRoot}`

importsToLoad.push({
load: () => import(`${devServerPublicPathRoute}${supportRelativeToProjectRoot}`),
load: () => import(relativeUrl),
absolute: supportFile,
relative: supportRelativeToProjectRoot,
relativeUrl: `${devServerPublicPathRoute}${supportRelativeToProjectRoot}`,
relativeUrl,
})
}

// Using relative path wouldn't allow to load tests outside Vite project root folder
// So we use the "@fs" bit to load the test file using its absolute path
// Normalize path to not include a leading slash (different on Win32 vs Unix)
const normalizedAbsolutePath = CypressInstance.spec.absolute.replace(/^\//, '')
const testFileAbsolutePathRoute = `${devServerPublicPathRoute}/@fs/${normalizedAbsolutePath}`
const testFileAbsolutePathRoute = `${devServerPublicPathBase}/@fs/${normalizedAbsolutePath}`

/* Spec file import logic */
// We need a slash before /src/my-spec.js, this does not happen by default.
Expand Down
1 change: 1 addition & 0 deletions npm/vite-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"devDependencies": {
"chai": "^4.3.6",
"decache": "^4.6.2",
"dedent": "^0.7.0",
"mocha": "^9.2.2",
"sinon": "^13.0.1",
Expand Down
207 changes: 207 additions & 0 deletions npm/vite-dev-server/test/initCypressTests.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import Chai, { expect } from 'chai'
import sinon from 'sinon'
import decache from 'decache'
import SinonChai from 'sinon-chai'

Chai.use(SinonChai)

describe('initCypressTests', () => {
let mockSupportFile: string | undefined
// relative "/cypress/support/component.js"
let mockProjectRoot: string | undefined = ''
let mockPlatform: 'darwin' | 'win32' | 'linux' = 'linux'
let mockDevServerPublicPathRoute: string = ''
let mockAbsolutePath: string = ''
let mockRelativePath: string = ''
let mockViewportWidth: number
let mockViewportHeight: number

const createMockCypress = () => {
return {
on: sinon.stub(),
onSpecWindow: sinon.stub(),
action: sinon.stub(),
config: sinon.stub().callsFake((key) => {
switch (key) {
case 'supportFile':
return mockSupportFile
case 'projectRoot':
return mockProjectRoot
case 'platform':
return mockPlatform
case 'devServerPublicPathRoute':
return mockDevServerPublicPathRoute
case 'viewportWidth':
return mockViewportWidth
case 'viewportHeight':
return mockViewportHeight
default:
return undefined
}
}),
spec: {
absolute: mockAbsolutePath,
relative: mockRelativePath,
},
}
}

let mockCypressInstance = createMockCypress()

beforeEach(() => {
mockSupportFile = '/users/mock_dir/mock_project/cypress/support/component.js'
// relative "/cypress/support/component.js"
mockProjectRoot = '/users/mock_dir/mock_project'
mockPlatform = 'linux'
mockDevServerPublicPathRoute = '/__cypress/src'
mockAbsolutePath = '/users/mock_dir/mock_project/src/Test.cy.jsx'
mockRelativePath = 'src/Test.cy.jsx'
mockViewportWidth = 800
mockViewportHeight = 500

mockCypressInstance = createMockCypress()

global.import = sinon.stub()
// @ts-expect-error
global.window = {}
// @ts-expect-error
global.parent = {}
// @ts-expect-error
global.parent.Cypress = mockCypressInstance
})

afterEach(() => {
// @ts-expect-error
delete global.window
// @ts-expect-error
delete global.parent

decache('../client/initCypressTests.js')
})

describe('support file / spec file loading', () => {
it('doesn\'t load the support file if one is not provided', () => {
mockSupportFile = undefined
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(global.window, [
{
load: sinon.match.func,
absolute: mockAbsolutePath,
relative: mockRelativePath,
relativeUrl: `${mockDevServerPublicPathRoute}/@fs${mockAbsolutePath}`,
},
])
})

it('load the support file along with the spec', () => {
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(global.window, [
{
load: sinon.match.func,
absolute: '/users/mock_dir/mock_project/cypress/support/component.js',
relative: '/cypress/support/component.js',
relativeUrl: '/__cypress/src/cypress/support/component.js',
},
{
load: sinon.match.func,
absolute: '/users/mock_dir/mock_project/src/Test.cy.jsx',
relative: 'src/Test.cy.jsx',
relativeUrl: '/__cypress/src/@fs/users/mock_dir/mock_project/src/Test.cy.jsx',
},
])
})

describe('empty devServerPublicPathRoute', () => {
it('load the support file along with the spec', () => {
mockDevServerPublicPathRoute = ''
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(global.window, [
{
load: sinon.match.func,
absolute: '/users/mock_dir/mock_project/cypress/support/component.js',
relative: '/cypress/support/component.js',
relativeUrl: './cypress/support/component.js',
},
{
load: sinon.match.func,
absolute: '/users/mock_dir/mock_project/src/Test.cy.jsx',
relative: 'src/Test.cy.jsx',
relativeUrl: './@fs/users/mock_dir/mock_project/src/Test.cy.jsx',
},
])
})
})

describe('windows', () => {
beforeEach(() => {
mockPlatform = 'win32'
mockProjectRoot = 'C:\\users\\mock_user\\mock_dir\\mock_project'
mockSupportFile = 'C:\\users\\mock_user\\mock_dir\\mock_project\\cypress\\support\\component.js'
// even though we are still in windows, this is the expected / passed in public path
mockDevServerPublicPathRoute = '/__cypress/src'
mockAbsolutePath = 'C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx'
mockRelativePath = 'src\\Test.cy.jsx'
mockCypressInstance.spec.absolute = mockAbsolutePath
mockCypressInstance.spec.relative = mockRelativePath
})

it('doesn\'t load the support file if one is not provided', () => {
mockSupportFile = undefined
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(sinon.match.any, [
{
load: sinon.match.func,
absolute: 'C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
relative: 'src\\Test.cy.jsx',
relativeUrl: '/__cypress/src/@fs/C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
},
])
})

it('load the support file along with the spec', () => {
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(global.window, [
{
load: sinon.match.func,
absolute: 'C:\\users\\mock_user\\mock_dir\\mock_project\\cypress\\support\\component.js',
relative: '/cypress/support/component.js',
relativeUrl: '/__cypress/src/cypress/support/component.js',
},
{
load: sinon.match.func,
absolute: 'C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
relative: 'src\\Test.cy.jsx',
relativeUrl: '/__cypress/src/@fs/C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
},
])
})

describe('empty devServerPublicPathRoute', () => {
it('load the support file along with the spec', () => {
mockDevServerPublicPathRoute = ''
require('../client/initCypressTests.js')
// just includes the spec import
expect(mockCypressInstance.onSpecWindow).to.be.calledWith(global.window, [
{
load: sinon.match.func,
absolute: 'C:\\users\\mock_user\\mock_dir\\mock_project\\cypress\\support\\component.js',
relative: '/cypress/support/component.js',
relativeUrl: './cypress/support/component.js',
},
{
load: sinon.match.func,
absolute: 'C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
relative: 'src\\Test.cy.jsx',
relativeUrl: './@fs/C:/users/mock_user/mock_dir/mock_project/src/Test.cy.jsx',
},
])
})
})
})
})
})
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11534,6 +11534,11 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bin
get-intrinsic "^1.2.4"
set-function-length "^1.2.1"

callsite@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==

callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
Expand Down Expand Up @@ -13575,6 +13580,13 @@ debuglog@^1.0.1:
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=

decache@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.2.tgz#c1df1325a2f36d53922e08f33380f083148199cd"
integrity sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==
dependencies:
callsite "^1.0.0"

decamelize-keys@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
Expand Down

0 comments on commit f9cdf77

Please sign in to comment.