@isaac.frontend/testcafe-scaffolding
Advanced tools
Comparing version 2.1.0 to 3.0.0
407
bin/init.js
@@ -5,35 +5,35 @@ #!/usr/bin/env node | ||
require('colors') | ||
const readlineSync = require('readline-sync') | ||
const fs = require('fs') | ||
const fx = require('mkdir-recursive') | ||
const path = require('path') | ||
const execSync = require('child_process').exec | ||
const util = require('util') | ||
const yarnOrNpm = require('yarn-or-npm') | ||
require("colors"); | ||
const readlineSync = require("readline-sync"); | ||
const fs = require("fs"); | ||
const fx = require("mkdir-recursive"); | ||
const path = require("path"); | ||
const execSync = require("child_process").exec; | ||
const util = require("util"); | ||
const yarnOrNpm = require("yarn-or-npm"); | ||
const hasYarn = yarnOrNpm() === 'yarn' | ||
const pkg = path.resolve('package.json') | ||
const hasYarn = yarnOrNpm() === "yarn"; | ||
const pkg = path.resolve("package.json"); | ||
// eslint-disable-next-line import/no-dynamic-require | ||
const pkgObject = require(pkg) | ||
const defaultTestSuitePath = 'tests/e2e' | ||
const pkgObject = require(pkg); | ||
const defaultTestSuitePath = "tests/e2e"; | ||
const exec = async (command, { verbose } = { verbose: true }) => { | ||
const execAsync = util.promisify(execSync) | ||
const { stdout, stderr } = await execAsync(command) | ||
if (verbose) console.log(stdout.gray) | ||
console.error(stderr.gray) | ||
} | ||
const execAsync = util.promisify(execSync); | ||
const { stdout, stderr } = await execAsync(command); | ||
if (verbose) console.log(stdout.gray); | ||
console.error(stderr.gray); | ||
}; | ||
const findAndReplaceInFile = ({ file, find, replace }) => fs.readFile(file, 'utf8', (err, data) => { | ||
if (err) return console.log(`Cannot read file ${file}`) | ||
const findAndReplaceInFile = ({ file, find, replace }) => | ||
fs.readFile(file, "utf8", (err, data) => { | ||
if (err) return console.log(`Cannot read file ${file}`); | ||
const regex = new RegExp(find, 'g') | ||
const result = data.replace(regex, replace) | ||
const regex = new RegExp(find, "g"); | ||
const result = data.replace(regex, replace); | ||
fs.writeFile(file, result, 'utf8', (error) => { | ||
if (error) return console.log(err) | ||
}) | ||
}) | ||
fs.writeFile(file, result, "utf8", (error) => { | ||
if (error) return console.log(err); | ||
}); | ||
}); | ||
@@ -43,29 +43,36 @@ /** | ||
*/ | ||
const createPageModels = ({ testSuitePath, isInstallExampleTests, isInstallDSLExample }) => { | ||
const paths = ['dsl', 'tests', 'page-models'] | ||
const createPageModels = ({ testSuitePath, isInstallExampleTests }) => { | ||
const paths = ["tests", "page-models"]; | ||
fx.mkdirSync(path.resolve(testSuitePath)) | ||
fx.mkdirSync(path.resolve(testSuitePath)); | ||
paths.forEach((subDirectory) => { | ||
const dstPath = path.join(testSuitePath, subDirectory) | ||
const dstPath = path.join(testSuitePath, subDirectory); | ||
if (fs.existsSync(dstPath)) { | ||
console.log(`Directory ${dstPath} already exists. Ignoring`.blue) | ||
return | ||
console.log(`Directory ${dstPath} already exists. Ignoring`.blue); | ||
return; | ||
} else { | ||
fx.mkdirSync(path.join(testSuitePath, subDirectory)); | ||
} | ||
if (subDirectory !== 'dsl' | ||
|| (subDirectory === 'dsl' && isInstallDSLExample)) fs.mkdirSync(dstPath) | ||
// add .gitkeep files to the directories when no example tests are chosen | ||
if (!isInstallExampleTests && subDirectory !== 'dsl') { | ||
fs.closeSync(fs.openSync(path.join(dstPath, '.gitkeep'), 'w')) | ||
if (!isInstallExampleTests) { | ||
fs.closeSync(fs.openSync(path.join(dstPath, ".gitkeep"), "w")); | ||
} | ||
// Copy example data: | ||
if (isInstallExampleTests | ||
&& (subDirectory !== 'dsl' | ||
|| (subDirectory === 'dsl' && isInstallDSLExample))) { | ||
const sourcePath = path.join(__dirname, '..', 'examples', subDirectory) | ||
if (isInstallExampleTests) { | ||
const sourcePath = path.join( | ||
__dirname, | ||
"..", | ||
"examples", | ||
subDirectory | ||
); | ||
console.log({ sourcePath }); | ||
fs.readdirSync(`${sourcePath}`).forEach((file) => { | ||
if (/\.js$/.test(file)) { | ||
fs.copyFileSync(path.join(sourcePath, file), path.join(dstPath, file)) | ||
console.log({ file }); | ||
fs.copyFileSync( | ||
path.join(sourcePath, file), | ||
path.join(dstPath, file) | ||
); | ||
findAndReplaceInFile({ | ||
@@ -75,12 +82,15 @@ file: path.join(dstPath, file), | ||
replace: testSuitePath, | ||
}) | ||
}); | ||
} | ||
}) | ||
}); | ||
} | ||
// Copy utilities | ||
fx.mkdirSync(path.join(testSuitePath, 'utils')) | ||
fs.copyFileSync(path.join(__dirname, '..', 'examples', 'utils', 'browser.js'), path.join(testSuitePath, 'utils', 'browser.js')) | ||
}) | ||
} | ||
fx.mkdirSync(path.join(testSuitePath, "utils")); | ||
fs.copyFileSync( | ||
path.join(__dirname, "..", "examples", "utils", "browser.js"), | ||
path.join(testSuitePath, "utils", "browser.js") | ||
); | ||
}); | ||
}; | ||
@@ -90,22 +100,35 @@ /** | ||
*/ | ||
const createRunner = ({ testSuitePath, isInstallAllureReporting, isInstallBrowserstack }) => { | ||
const date = new Date() | ||
const dateString = `${date.getUTCFullYear()}${date.getUTCMonth() + 1}${date.getUTCDate()}` | ||
const createRunner = ({ | ||
testSuitePath, | ||
isInstallAllureReporting, | ||
isInstallBrowserstack, | ||
}) => { | ||
const date = new Date(); | ||
const dateString = `${date.getUTCFullYear()}${ | ||
date.getUTCMonth() + 1 | ||
}${date.getUTCDate()}`; | ||
const doesRunnerAlreadyExist = fs.existsSync(path.join(testSuitePath, 'runner.js')) | ||
const doesRunnerAlreadyExist = fs.existsSync( | ||
path.join(testSuitePath, "runner.js") | ||
); | ||
const runnerFile = `${[ | ||
'testcafe', | ||
...(isInstallAllureReporting ? ['allure'] : []), | ||
...(isInstallBrowserstack ? ['browserstack'] : []), | ||
].join('-')}.js` | ||
const sourcePath = path.join(__dirname, '..', 'examples') | ||
const runnerFileSourcePath = path.join(sourcePath, runnerFile) | ||
const runnerFileDestinationPath = doesRunnerAlreadyExist ? path.join(testSuitePath, `runner-${dateString}.js`) : path.join(testSuitePath, 'runner.js') | ||
"testcafe", | ||
...(isInstallAllureReporting ? ["allure"] : []), | ||
...(isInstallBrowserstack ? ["browserstack"] : []), | ||
].join("-")}.js`; | ||
const sourcePath = path.join(__dirname, "..", "examples"); | ||
const runnerFileSourcePath = path.join(sourcePath, runnerFile); | ||
const runnerFileDestinationPath = doesRunnerAlreadyExist | ||
? path.join(testSuitePath, `runner-${dateString}.js`) | ||
: path.join(testSuitePath, "runner.js"); | ||
if (doesRunnerAlreadyExist) { | ||
console.log(`runner.js already exists. Created a new runner named "runner-${dateString}.js".`.yellow) | ||
console.log( | ||
`runner.js already exists. Created a new runner named "runner-${dateString}.js".` | ||
.yellow | ||
); | ||
} | ||
fs.copyFileSync(runnerFileSourcePath, runnerFileDestinationPath) | ||
fs.copyFileSync(runnerFileSourcePath, runnerFileDestinationPath); | ||
findAndReplaceInFile({ | ||
@@ -115,6 +138,5 @@ file: runnerFileDestinationPath, | ||
replace: testSuitePath, | ||
}) | ||
} | ||
}); | ||
}; | ||
/** | ||
@@ -125,3 +147,4 @@ * Testcafe allure-config needs forward slashes as | ||
const createAllureConfig = ({ testSuitePath }) => { | ||
if (fs.existsSync('allure.config.js')) return console.log('allure.config.js already defined. Ignoring.'.blue) | ||
if (fs.existsSync("allure.config.js")) | ||
return console.log("allure.config.js already defined. Ignoring.".blue); | ||
const allureDocConfig = `module.exports = { | ||
@@ -134,10 +157,12 @@ RESULT_DIR: '${testSuitePath}/allure/allure-results', | ||
} | ||
};` | ||
fs.writeFileSync('allure.config.js', allureDocConfig, (err) => { | ||
if (err) throw console.error('allure.config.js could not be created!'.bgRed.white.bold) | ||
console.log('allure.config.js created.'.green) | ||
}) | ||
} | ||
};`; | ||
fs.writeFileSync("allure.config.js", allureDocConfig, (err) => { | ||
if (err) | ||
throw console.error( | ||
"allure.config.js could not be created!".bgRed.white.bold | ||
); | ||
console.log("allure.config.js created.".green); | ||
}); | ||
}; | ||
/** | ||
@@ -151,53 +176,78 @@ * Update the package.json with new dependencies | ||
}) => { | ||
console.log(['', 'Updating package.json...', ''].join('\n').gray) | ||
console.log(["", "Updating package.json...", ""].join("\n").gray); | ||
const packages = [ | ||
'testcafe', | ||
...(isInstallAllureReporting ? ['testcafe-reporter-allure@npm:@isaac.frontend/testcafe-reporter-allure'] : []), | ||
...(isInstallBrowserstack ? ['testcafe-browser-provider-browserstack'] : []), | ||
].join(' ') | ||
"testcafe", | ||
...(isInstallAllureReporting | ||
? [ | ||
"testcafe-reporter-allure@npm:@isaac.frontend/testcafe-reporter-allure", | ||
] | ||
: []), | ||
...(isInstallBrowserstack | ||
? ["testcafe-browser-provider-browserstack"] | ||
: []), | ||
].join(" "); | ||
const addScriptToPkgJson = (script) => { | ||
// eslint-disable-next-line import/no-dynamic-require, global-require | ||
const currentPkgObject = require(pkg) | ||
const currentPkgObject = require(pkg); | ||
try { | ||
if (!currentPkgObject.scripts) currentPkgObject.scripts = {} | ||
if (!currentPkgObject.scripts) currentPkgObject.scripts = {}; | ||
if (currentPkgObject.scripts[script.key]) { | ||
console.log(`${script.key} already exists in the package.json. We won't override previously declared scripts`.yellow) | ||
console.log(`The value of the script would have been: ${script.value}`) | ||
console.log( | ||
`${script.key} already exists in the package.json. We won't override previously declared scripts` | ||
.yellow | ||
); | ||
console.log( | ||
`The value of the script would have been: ${script.value}` | ||
); | ||
} else { | ||
currentPkgObject.scripts[script.key] = script.value | ||
currentPkgObject.scripts[script.key] = script.value; | ||
fs.writeFileSync(pkg, JSON.stringify(currentPkgObject, null, 2), { encoding: 'utf8' }) | ||
fs.writeFileSync( | ||
pkg, | ||
JSON.stringify(currentPkgObject, null, 2), | ||
{ encoding: "utf8" } | ||
); | ||
} | ||
} catch (e) { | ||
console.error(`Script could not be added: ${e}`.bgRed.white.bold) | ||
console.error(`Script could not be added: ${e}`.bgRed.white.bold); | ||
} | ||
} | ||
}; | ||
addScriptToPkgJson({ | ||
key: 'test:e2e', | ||
key: "test:e2e", | ||
value: `node ${testSuitePath}/runner.js`, | ||
}) | ||
}); | ||
console.log(['', 'installing packages...', ''].join('\n').gray) | ||
console.log(["", "installing packages...", ""].join("\n").gray); | ||
if (hasYarn) { | ||
await exec(`yarn add -D ${packages}`) | ||
await exec(`yarn add -D ${packages}`); | ||
} else { | ||
await exec(`npm install -D --force ${packages}`) | ||
await exec(`npm install -D --force ${packages}`); | ||
} | ||
console.log(['', 'package.json updated and new dependencies installed.', ''].join('\n').green) | ||
} | ||
console.log( | ||
["", "package.json updated and new dependencies installed.", ""].join( | ||
"\n" | ||
).green | ||
); | ||
}; | ||
const removeScaffoldingPkg = async () => { | ||
if (hasYarn) { | ||
await exec('yarn remove @isaac.frontend/testcafe-scaffolding', { verbose: false }) | ||
await exec("yarn remove @isaac.frontend/testcafe-scaffolding", { | ||
verbose: false, | ||
}); | ||
} else { | ||
await exec('npm rm @isaac.frontend/testcafe-scaffolding', { verbose: false }) | ||
await exec("npm rm @isaac.frontend/testcafe-scaffolding", { | ||
verbose: false, | ||
}); | ||
} | ||
console.log('Removed @isaac.frontend/testcafe-scaffolding dependency'.green) | ||
} | ||
console.log( | ||
"Removed @isaac.frontend/testcafe-scaffolding dependency".green | ||
); | ||
}; | ||
@@ -209,10 +259,10 @@ const addFoldersToGitIgnore = ({ testSuitePath }) => { | ||
${testSuitePath}/screenshots | ||
` | ||
`; | ||
try { | ||
fs.appendFileSync('.gitignore', ignoreTemplateString) | ||
console.log('test report folders added to .gitignore'.gray) | ||
fs.appendFileSync(".gitignore", ignoreTemplateString); | ||
console.log("test report folders added to .gitignore".gray); | ||
} catch (e) { | ||
console.error(`Script could not be added: ${e}`.bgRed.white.bold) | ||
console.error(`Script could not be added: ${e}`.bgRed.white.bold); | ||
} | ||
} | ||
}; | ||
@@ -223,45 +273,83 @@ /** | ||
(async () => { | ||
console.clear() | ||
console.log(['-'.repeat(100).gray, 'Welcome to the initialization process'.bold, '-'.repeat(100).gray, ''].join('\n')) | ||
console.clear(); | ||
console.log( | ||
[ | ||
"-".repeat(100).gray, | ||
"Welcome to the initialization process".bold, | ||
"-".repeat(100).gray, | ||
"", | ||
].join("\n") | ||
); | ||
// Makes the script crash on unhandled rejections instead of silently ignoring them. | ||
process.on('unhandledRejection', (err) => { throw err }) | ||
process.on("unhandledRejection", (err) => { | ||
throw err; | ||
}); | ||
if (!fs.existsSync(pkg)) { | ||
console.error('No package.json found. Please run this command in the root of your project or run "npm init" / "yarn init"!'.bgRed.white.bold) | ||
process.exit(1) | ||
console.error( | ||
'No package.json found. Please run this command in the root of your project or run "npm init" / "yarn init"!' | ||
.bgRed.white.bold | ||
); | ||
process.exit(1); | ||
} | ||
const testSuitePath = readlineSync.question('In which directory do you want to keep your test suite? (default: $<defaultInput>): ', { | ||
defaultInput: defaultTestSuitePath, | ||
}) | ||
const testSuitePath = readlineSync | ||
.question( | ||
"In which directory do you want to keep your test suite? (default: $<defaultInput>): ", | ||
{ | ||
defaultInput: defaultTestSuitePath, | ||
} | ||
) | ||
// Always use forward slashes as it will be running in package.json scripts | ||
.replace(/\\/, '/').replace(/^\/|\/$/, '') | ||
.replace(/\\/, "/") | ||
.replace(/^\/|\/$/, ""); | ||
const isInstallExampleTests = readlineSync.keyInYN('Install example tests?') | ||
const isInstallDSLExample = isInstallExampleTests | ||
? readlineSync.keyInYN('Install Domain Specific Language (DSL) folder? https://github.com/isaaceindhoven/testcafe-scaffolding/blob/master/docs/writing-the-testsuite.md') | ||
: false | ||
const isInstallExampleTests = readlineSync.keyInYN( | ||
"Install example tests?" | ||
); | ||
const isInstallAllureReporting = readlineSync.keyInYN('Install Allure reporting?') | ||
const isInstallBrowserstack = readlineSync.keyInYN('Install BrowserStack integration?') | ||
const isRemovingTestcafeScaffolding = pkgObject && pkgObject.devDependencies && pkgObject.devDependencies['@isaac.frontend/testcafe-scaffolding'] | ||
? readlineSync.keyInYN( | ||
'After running this initialization, you no longer need this tool as a dependency. Do you want to remove it after this script has ran?', | ||
) | ||
: undefined | ||
const isInstallAllureReporting = readlineSync.keyInYN( | ||
"Install Allure reporting?" | ||
); | ||
const isInstallBrowserstack = readlineSync.keyInYN( | ||
"Install BrowserStack integration?" | ||
); | ||
const isRemovingTestcafeScaffolding = | ||
pkgObject && | ||
pkgObject.devDependencies && | ||
pkgObject.devDependencies["@isaac.frontend/testcafe-scaffolding"] | ||
? readlineSync.keyInYN( | ||
"After running this initialization, you no longer need this tool as a dependency. Do you want to remove it after this script has ran?" | ||
) | ||
: undefined; | ||
console.log([ | ||
'', | ||
'The following will be installed:'.gray, | ||
`Test suite path : ${`${testSuitePath}`.bold}`, | ||
`Example data : ${`${isInstallExampleTests}`.bold}`, | ||
...(isInstallExampleTests ? [`Example DSL : ${`${isInstallDSLExample}`.bold}`] : []), | ||
`Allure reporting : ${`${isInstallAllureReporting}`.bold}`, | ||
`Browserstack integration : ${`${isInstallBrowserstack}`.bold}`, | ||
...(typeof isRemovingTestcafeScaffolding !== 'undefined' ? [`Remove @isaac.frontend/testcafe-scaffolding : ${`${isRemovingTestcafeScaffolding}`.bold}`] : []), | ||
'', | ||
].join('\n')) | ||
console.log( | ||
[ | ||
"", | ||
"The following will be installed:".gray, | ||
`Test suite path : ${`${testSuitePath}`.bold}`, | ||
`Example data : ${`${isInstallExampleTests}`.bold}`, | ||
`Allure reporting : ${`${isInstallAllureReporting}`.bold}`, | ||
`Browserstack integration : ${`${isInstallBrowserstack}`.bold}`, | ||
...(typeof isRemovingTestcafeScaffolding !== "undefined" | ||
? [ | ||
`Remove @isaac.frontend/testcafe-scaffolding : ${ | ||
`${isRemovingTestcafeScaffolding}`.bold | ||
}`, | ||
] | ||
: []), | ||
"", | ||
].join("\n") | ||
); | ||
if (readlineSync.keyInYN('Is this correct?')) { | ||
console.log(['', '-'.repeat(100).gray, '', 'Starting initialization process'.cyan, ''].join('\n')) | ||
if (readlineSync.keyInYN("Is this correct?")) { | ||
console.log( | ||
[ | ||
"", | ||
"-".repeat(100).gray, | ||
"", | ||
"Starting initialization process".cyan, | ||
"", | ||
].join("\n") | ||
); | ||
@@ -273,30 +361,37 @@ const context = { | ||
isInstallExampleTests, | ||
isInstallDSLExample, | ||
} | ||
}; | ||
try { | ||
createPageModels(context) | ||
createRunner(context) | ||
addFoldersToGitIgnore(context) | ||
if (isInstallAllureReporting) createAllureConfig(context) | ||
await updatePackageJson(context) | ||
if (typeof isRemovingTestcafeScaffolding !== 'undefined' && isRemovingTestcafeScaffolding === true) await removeScaffoldingPkg() | ||
createPageModels(context); | ||
createRunner(context); | ||
addFoldersToGitIgnore(context); | ||
if (isInstallAllureReporting) createAllureConfig(context); | ||
await updatePackageJson(context); | ||
if ( | ||
typeof isRemovingTestcafeScaffolding !== "undefined" && | ||
isRemovingTestcafeScaffolding === true | ||
) | ||
await removeScaffoldingPkg(); | ||
} catch (err) { | ||
console.error('Something went horribly wrong!'.bgRed.white.bold) | ||
console.error(err.toString().red) | ||
process.exit(1) | ||
console.error("Something went horribly wrong!".bgRed.white.bold); | ||
console.error(err.toString().red); | ||
process.exit(1); | ||
} | ||
console.log([ | ||
'-'.repeat(100).gray, | ||
`All done. Your TestCafé test suite is now available in ${testSuitePath}`.green, | ||
'See https://github.com/isaaceindhoven/testcafe-scaffolding.git for more details and examples.', | ||
'', | ||
'To run your test suite, type: `npm run test:e2e` or `yarn test:e2e`'.bold, | ||
'-'.repeat(100).gray, | ||
].join('\n')) | ||
console.log( | ||
[ | ||
"-".repeat(100).gray, | ||
`All done. Your TestCafé test suite is now available in ${testSuitePath}` | ||
.green, | ||
"See https://github.com/isaaceindhoven/testcafe-scaffolding.git for more details and examples.", | ||
"", | ||
"To run your test suite, type: `npm run test:e2e` or `yarn test:e2e`" | ||
.bold, | ||
"-".repeat(100).gray, | ||
].join("\n") | ||
); | ||
} else { | ||
console.log('Aborting') | ||
process.exit(0) | ||
console.log("Aborting"); | ||
process.exit(0); | ||
} | ||
})() | ||
})(); |
@@ -47,9 +47,8 @@ [Home](../README.md) | ||
```html | ||
<img data-testid="logo" class="lazy-load logo" alt="ISAAC" src="/global/images/v4/logo.svg"> | ||
<img data-testid="logo-inverse" class="lazy-load logo-inverse" alt="ISAAC" src="/global/images/v4/logo-white.svg"> | ||
<a aria-label="Io logo" class="relative transition-opacity duration-500 Header_lightLogo__onWdF opacity-100 pointer-events-auto" href="/nl"> | ||
``` | ||
With the html in place we can easily make selectors like: | ||
```js | ||
const logo = Selector('[data-testid="logo"]') | ||
const logoInverse = Selector('[data-testid="logo-inverse"]') | ||
const logo = Selector('[aria-label="Io logo"]') | ||
``` | ||
@@ -56,0 +55,0 @@ This will make it clear for any other developer who looks at the code at a later point in time that this attribute is used for testing. |
/** | ||
* This example test checks whether clicking the ISAAC logo navigates to the homepage. | ||
* Note that this test may fail when the ISAAC homepage changes. | ||
* This example test checks whether clicking the iO logo navigates to the homepage. | ||
* Note that this test may fail when the iO homepage changes. | ||
*/ | ||
import browser from '../utils/browser' | ||
import isaacHomePage from '../page-models/isaac-website' | ||
import { Browser } from "../utils/browser"; | ||
import { HomePage } from "../page-models/home-page"; | ||
import { AboutPage } from "../page-models/about-page"; | ||
import { CookieWall } from "../page-models/cookie-wall"; | ||
fixture('ISAAC website logo') | ||
.page(isaacHomePage.home) | ||
fixture("iO website logo").page(HomePage().homeURL); | ||
test('Logo existence', async (t) => { | ||
await t | ||
.expect(isaacHomePage.logo.exists).eql(true) | ||
}) | ||
test.before(async () => { | ||
await CookieWall().acceptCookies(); | ||
})("Logo existence", async (t) => { | ||
await t.expect(HomePage().logo.exists).eql(true); | ||
}); | ||
test('Clicking the logo navigates to home', async (t) => { | ||
test.before(async () => { | ||
await CookieWall().acceptCookies(); | ||
})("Clicking the logo navigates to home", async (t) => { | ||
await t | ||
.navigateTo(isaacHomePage.about) | ||
.click(isaacHomePage.logo) | ||
.expect(browser.getUrl()).eql(isaacHomePage.home) | ||
}) | ||
.navigateTo(AboutPage().aboutUrl) | ||
.click(AboutPage().logo) | ||
.expect(Browser().getUrl()) | ||
.eql(HomePage().homeURL); | ||
}); |
@@ -1,9 +0,7 @@ | ||
import { ClientFunction } from 'testcafe' | ||
import { ClientFunction } from "testcafe"; | ||
class Browser { | ||
constructor() { | ||
this.getUrl = ClientFunction(() => document.location.href) | ||
} | ||
} | ||
export default new Browser(); | ||
export const Browser = () => { | ||
return { | ||
getUrl: ClientFunction(() => document.location.href), | ||
}; | ||
}; |
{ | ||
"name": "@isaac.frontend/testcafe-scaffolding", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"description": "TestCafe scaffolding tool to setup your repository for end-to-end testing with TestCafe", | ||
@@ -5,0 +5,0 @@ "author": "ISAAC E-commerce Solutions BV", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
123191
594
1