Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: search parent folders for split file #157

Merged
merged 3 commits into from Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -173,6 +173,23 @@ jobs:
with:
command: npm run timings-no-file

test-find-timings-file:
runs-on: ubuntu-22.04
steps:
- name: Checkout 🛎
uses: actions/checkout@v4
- name: Needs to find the timings file 🧪
# https://github.com/cypress-io/github-action
uses: cypress-io/github-action@v5
with:
project: examples/timings-file/tests/cypress-tests
env:
SPLIT: 1
SPLIT_INDEX: 0
# the timings file is not next to the config file
# but in the project folder
SPLIT_FILE: timings.json

test-workflow-e2e:
# https://github.com/bahmutov/cypress-workflows
uses: bahmutov/cypress-workflows/.github/workflows/split.yml@v1
Expand Down Expand Up @@ -220,6 +237,7 @@ jobs:
test-timings,
test-timings-no-file,
test-merge-timings,
test-find-timings-file,
]
runs-on: ubuntu-22.04
steps:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -268,6 +268,8 @@ If the timings file does not exist yet, the timings will be written into the fil

See example [bahmutov/cypress-split-timings-example](https://github.com/bahmutov/cypress-split-timings-example).

**Note 2:** during Cypress execution, the working directory is set to the folder with the Cypress config file. This module tries its best to find the split file by searching the parent folders to the Git repo or root folder.

## Merging timings files

This module includes a bin utility to merge multiple timings files into one. Example:
Expand Down
17 changes: 17 additions & 0 deletions examples/timings-file/tests/cypress-tests/cypress.config.js
@@ -0,0 +1,17 @@
const { defineConfig } = require('cypress')
const cypressSplit = require('../../../../src')

module.exports = defineConfig({
e2e: {
// baseUrl, etc
supportFile: false,
fixturesFolder: false,
specPattern: 'e2e/*.cy.js',
setupNodeEvents(on, config) {
console.log('cwd is', process.cwd())
cypressSplit(on, config)
// IMPORTANT: return the config object
return config
},
},
})
1 change: 1 addition & 0 deletions examples/timings-file/tests/cypress-tests/e2e/spec-a.cy.js
@@ -0,0 +1 @@
it('works A', () => {})
1 change: 1 addition & 0 deletions examples/timings-file/tests/cypress-tests/e2e/spec-b.cy.js
@@ -0,0 +1 @@
it('works B', () => {})
1 change: 1 addition & 0 deletions examples/timings-file/tests/cypress-tests/e2e/spec-c.cy.js
@@ -0,0 +1 @@
it('works C', () => {})
16 changes: 16 additions & 0 deletions examples/timings-file/timings.json
@@ -0,0 +1,16 @@
{
"durations": [
{
"spec": "cypress/e2e/spec-a.cy.js",
"duration": 100
},
{
"spec": "cypress/e2e/spec-b.cy.js",
"duration": 100
},
{
"spec": "cypress/e2e/spec-c.cy.js",
"duration": 1000
}
]
}
50 changes: 50 additions & 0 deletions src/find-file.js
@@ -0,0 +1,50 @@
// @ts-check

const debug = require('debug')('cypress-split')
const exists = require('fs').existsSync
const { join, normalize } = require('path')

function isGitRootFolder(folder) {
const gitRoot = '.git'
const full = join(folder, gitRoot)
return exists(full)
}

/**
* Finds the file using the current working directory or its parent
* directories up to the Git root folder.
* @param {string} filename File to find
* @returns {string|undefined} found file path or undefined
*/
function findFile(filename) {
if (!filename) {
throw new Error('Missing the filename')
}

let currentFolder = process.cwd()
let found

while (true) {
const maybePath = join(currentFolder, filename)
if (exists(maybePath)) {
found = maybePath
debug('found file %s', found)
break
}
if (isGitRootFolder(currentFolder)) {
debug('reached git root folder %s', currentFolder)
debug('but could not find %s', filename)
break
}
const parent = normalize(join(currentFolder, '..'))
if (parent === currentFolder) {
debug('reached top level folder %s', currentFolder)
debug('but could not find tool %s', filename)
break
}
currentFolder = parent
}
return found
}

module.exports = { findFile }
19 changes: 14 additions & 5 deletions src/index.js
Expand Up @@ -5,6 +5,7 @@ const debug = require('debug')('cypress-split')
const { getSpecs } = require('find-cypress-specs')
const ghCore = require('@actions/core')
const { getChunk } = require('./chunk')
const { findFile } = require('./find-file')
const {
splitByDuration,
hasTimeDifferences,
Expand Down Expand Up @@ -172,10 +173,17 @@ function cypressSplit(on, config) {
const cwd = process.cwd()
console.log('%s specs from the current directory %s', label, cwd)

let foundSplitFile
if (SPLIT_FILE) {
debug('loading split file %s', SPLIT_FILE)
try {
const splitFile = JSON.parse(fs.readFileSync(SPLIT_FILE, 'utf8'))
foundSplitFile = findFile(SPLIT_FILE)
if (!foundSplitFile) {
throw new Error(
`Could not find ${SPLIT_FILE} based on the current working directory ${cwd}`,
)
}
const splitFile = JSON.parse(fs.readFileSync(foundSplitFile, 'utf8'))
const previousDurations = splitFile.durations
const averageDuration =
previousDurations
Expand Down Expand Up @@ -309,11 +317,11 @@ function cypressSplit(on, config) {
const timingsString = JSON.stringify(timings, null, 2)
console.log(timingsString)

if (!fs.existsSync(SPLIT_FILE)) {
if (!foundSplitFile) {
console.log('%s writing out timings file %s', label, SPLIT_FILE)
fs.writeFileSync(SPLIT_FILE, timingsString + '\n', 'utf8')
} else {
const splitFile = JSON.parse(fs.readFileSync(SPLIT_FILE, 'utf8'))
const splitFile = JSON.parse(fs.readFileSync(foundSplitFile, 'utf8'))
const hasUpdatedTimings = hasTimeDifferences(splitFile, timings, 0.1)
if (hasUpdatedTimings) {
// TODO: merge split file with new timings
Expand All @@ -328,10 +336,11 @@ function cypressSplit(on, config) {
debug('previous timings has %d entries', splitFile.durations.length)
debug('current timings has %d entries', timings.durations.length)
debug(
'merged timings has %d entries',
'merged timings has %d entries written to %s',
mergedTimings.durations.length,
foundSplitFile,
)
fs.writeFileSync(SPLIT_FILE, mergedText + '\n', 'utf8')
fs.writeFileSync(foundSplitFile, mergedText + '\n', 'utf8')
} else {
console.log('%s spec timings unchanged', label)
}
Expand Down