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: add concurrently & wait-on command #34

Merged
merged 5 commits into from
May 7, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@
},
"dependencies": {
"@dhis2/cli-helpers-engine": "^1.5.0",
"concurrently": "^5.2.0",
"cross-spawn": "^7.0.1",
"cypress": "^4.0.2",
"cypress-cucumber-preprocessor": "^2.0.1",
"fs-extra": "^8.1.0",
"inquirer": "^7.0.4"
"inquirer": "^7.0.4",
"wait-on": "^4.0.2"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@dhis2/cli-style": "^6.0.0",
"@dhis2/cli-utils-docsite": "^1.3.0",
"concurrently": "^5.1.0",
"wait-on": "^4.0.0"
"@dhis2/cli-utils-docsite": "^1.3.0"
}
}
16 changes: 16 additions & 0 deletions src/commands/common/sharedCLIOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const appStart = {
describe: 'Command to start app (disabled with empty string)',
type: 'string',
default: 'yarn start',
}

const waitOn = {
describe: 'Url to wait for before running cypress',
type: 'string',
default: 'http-get://localhost:3000',
}

module.exports = {
appStart,
waitOn,
}
253 changes: 15 additions & 238 deletions src/commands/install.js
Original file line number Diff line number Diff line change
@@ -1,112 +1,17 @@
const path = require('path')
const fs = require('fs-extra')

const inquirer = require('inquirer')

const log = require('@dhis2/cli-helpers-engine').reporter

const { createCucumberConfigs } = require('./install/createCucumberConfigs.js')
const { createCypressConfig } = require('./install/createCypressConfig.js')
const {
CONSUMING_ROOT,
CYPRESS_ROOT,
CYPRESS_FIXTURES,
CYPRESS_INTEGRATION,
CYPRESS_PLUGINS,
CYPRESS_SUPPORT,
} = require('../utils/paths.js')

const extractOrgName = moduleName => {
const matches = moduleName.match(/^@[^/]+(?=\/)/)

if (!matches || !matches.length) {
return 'dhis2'
}

const [orgNameWithAtSymbol] = matches
return orgNameWithAtSymbol.replace('@', '')
}

const extractAppName = moduleName => {
const matches = moduleName.match(/^@[^/]+\/(.+)$/)
const appName = matches && matches.length > 1 ? matches[1] : moduleName

return appName
.replace(/-app$/, '') // dhis2 apps' names end with "app"
.replace(/\W/g, '')
}

const readJson = filename => {
const filepath = path.join(CONSUMING_ROOT, filename)
const exists = fs.existsSync(filepath)

if (!exists) {
log.warn(`File: '${filename}' does not exist`)
return
}

let content
try {
content = JSON.parse(fs.readFileSync(filepath))
} catch (e) {
log.error(`Could not parse contents of file: '${filename}'`)
return
}

return content
}

const addToJson = (filename, data, overwrite = false) => {
const filepath = path.join(CONSUMING_ROOT, filename)
const exists = fs.existsSync(filepath)

if (!exists) {
log.warn(`File: '${filename}' does not exist`)
return
}

if (overwrite) {
return write(filename, data, true)
}

const existingData = readJson(filename)
return write(filename, { ...existingData, ...data }, true)
}

const write = (filename, data, overwrite) => {
const filepath = path.join(CONSUMING_ROOT, filename)
const exists = fs.existsSync(filepath)
const content = JSON.stringify(data, null, 4)

if (exists && !overwrite) {
log.warn(`Existing file: '${filename}', use --force to overwrite.`)
return
}

fs.writeFileSync(filepath, content, { encoding: 'utf8' })
}

function copy(from, to, overwrite = true) {
try {
const exists = fs.existsSync(to)
const empty = exists ? fs.statSync(to).size === 0 : false

const replace = empty ? true : overwrite

if (exists && !replace) {
log.print(`Skip existing: ${path.relative(process.cwd(), to)}`)
} else {
log.print(`Installing: ${path.relative(process.cwd(), to)}`)
}
fs.ensureDirSync(path.dirname(to))
fs.copySync(from, to, { overwrite: replace })
} catch (err) {
log.error(`Failed to install configuration file: ${to}`, err)
}
}
createCypressEnvConfig,
} = require('./install/createCypressEnvConfig.js')
const {
createCypressSupportFile,
} = require('./install/createCypressSupportFile.js')
const { ensureDirectories } = require('./install/ensureDirectories.js')

exports.command = 'install'

exports.aliases = ['i']

exports.desc = 'Install DHIS2 Cypress configuration into project'

exports.builder = yargs =>
Expand Down Expand Up @@ -140,153 +45,25 @@ exports.builder = yargs =>
exports.handler = async argv => {
log.info('d2-utils-cypress > install')

const { force, cypressConfig, cypressEnv, cucumber, support } = argv
try {
const { force, cypressConfig, cypressEnv, cucumber, support } = argv

const prompt = inquirer.createPromptModule()
ensureDirectories()

try {
if (cypressConfig) {
const cypressAnswers = await prompt([
{
type: 'input',
name: 'baseUrl',
message: 'URL that Cypress should run tests against:',
default: 'http://localhost:3000',
},
{
type: 'input',
name: 'testFiles',
message: 'Glob pattern for the test files to run:',
default: '**/*.feature',
},
{
type: 'confirm',
name: 'video',
message: 'Record video?',
default: false,
},
{
type: 'input',
name: 'projectId',
message: 'The unique Cypress project ID:',
},
])

write(
'cypress.json',
{
baseUrl: cypressAnswers.baseUrl,
testFiles: cypressAnswers.testFiles,
video: cypressAnswers.video,
...(cypressAnswers.projectId
? [cypressAnswers.projectId]
: []),
},
force
)
await createCypressConfig(force)
}

if (cypressEnv) {
const envAnswers = await prompt([
{
type: 'input',
name: 'dhis2Url',
message: 'The DHIS2 instance URL to use as backend:',
default: 'http://localhost:8080',
},
{
type: 'input',
name: 'username',
message: 'DHIS2 Username:',
default: 'admin',
},
{
type: 'input',
name: 'password',
message: 'DHIS2 Username password:',
default: 'district',
},
])

write(
'cypress.env.json',
{
dhis2_base_url: envAnswers.dhis2Url,
dhis2_username: envAnswers.username,
dhis2_password: envAnswers.password,
},
force
)

log.info(
'Make sure to add `cypress.env.json` to the `.gitignore` file!'
)
await createCypressEnvConfig(force)
}

fs.ensureDirSync(CYPRESS_ROOT)
fs.ensureDirSync(CYPRESS_FIXTURES)
fs.ensureDirSync(CYPRESS_INTEGRATION)
fs.ensureDirSync(CYPRESS_PLUGINS)
fs.ensureDirSync(CYPRESS_SUPPORT)

if (cucumber) {
const cucFrom = path.join(
__dirname,
'..',
'..',
'templates',
'plugins.js'
)
const cucTo = path.join(CYPRESS_PLUGINS, 'index.js')
copy(cucFrom, cucTo, force)

const cucConfFrom = path.join(
__dirname,
'..',
'..',
'templates',
'cucumber-config.js'
)
const cucConfTo = path.join(
CONSUMING_ROOT,
'cypress-cucumber-preprocessor.config.js'
)
copy(cucConfFrom, cucConfTo, force)
await createCucumberConfigs(force)
}

if (support) {
const supFrom = path.join(
__dirname,
'..',
'..',
'templates',
'support.js'
)
const supTo = path.join(CYPRESS_SUPPORT, 'index.js')
copy(supFrom, supTo, force)

const packageJson = readJson('package.json')
const moduleName = packageJson ? packageJson.name : ''
const orgName = extractOrgName(moduleName)
const appName = extractAppName(moduleName)
const prefixDefault = [
...(orgName ? [orgName] : []),
...(appName ? [appName] : []),
].join('-')

const envAnswers = await prompt([
{
type: 'input',
name: 'dhis2DatatestPrefix',
message:
'The prefix for the cy.get data-test attributes of the app (e. g. "dhis2-appname-"):',
...(prefixDefault ? { default: prefixDefault } : {}),
},
])

addToJson('cypress.env.json', {
dhis2_datatest_prefix: envAnswers.dhis2DatatestPrefix,
})
await createCypressSupportFile(force)
}
} catch (e) {
log.error(e)
Expand Down
39 changes: 39 additions & 0 deletions src/commands/install/createCucumberConfigs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const inquirer = require('inquirer')
const { addToJson } = require('../../utils/fs.js')
const { copy } = require('../../utils/fs.js')
const {
CYPRESS_CONFIG_PATH,
CUCUMBER_PLUGIN_TEMPLATE_SOURCE,
CUCUMBER_PLUGIN_TEMPLATE_DESTINATION,
CUCUMBER_CONFIG_TEMPLATE_SOURCE,
CUCUMBER_CONFIG_TEMPLATE_DESTINATION,
} = require('../../utils/paths.js')

const createCucumberConfigs = async force => {
const prompt = inquirer.createPromptModule()

copy(
CUCUMBER_PLUGIN_TEMPLATE_SOURCE,
CUCUMBER_PLUGIN_TEMPLATE_DESTINATION,
force
)

copy(
CUCUMBER_CONFIG_TEMPLATE_SOURCE,
CUCUMBER_CONFIG_TEMPLATE_DESTINATION,
force
)

const { testFiles } = await prompt([
{
type: 'input',
name: 'testFiles',
message: 'Glob pattern for the test files to run:',
default: '**/*.feature',
},
])

addToJson(CYPRESS_CONFIG_PATH, { testFiles })
}

module.exports = { createCucumberConfigs }
Loading