Socket
Socket
Sign inDemoInstall

@isaac.frontend/testcafe-scaffolding

Package Overview
Dependencies
Maintainers
8
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@isaac.frontend/testcafe-scaffolding - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

examples/page-models/about-page.js

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",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc