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

Override generated scenarios #31

Closed
wants to merge 6 commits into from
Closed
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: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ $ npm install --global backstop-crawl
--limit-similar[=3] Limits the number of similar URLs to a set number
Defaults to 3
e.g /blog/1, /blog/2, /blog/3
--reference-url Allows a reference URL to be used in testing
--reference-url Allows a reference URL to be used in testing
--template Specify the template file to use
Defaults to backstop.template.json

Examples
$ backstop-crawl http://localhost
Expand Down Expand Up @@ -62,6 +64,10 @@ For example:
}
```

After generating your `backstop.json`, you can modify scenarios and copy them into `scenarios` in your template. The next time you run `backstop crawl`, these scenarios will override generated scenarios with a matching label.

Ex. One of your pages takes a little more time to load, so you need to increase the delay. Rather than increasing the delay in the `defaultScenario` (which would impact all tests) you can override just that one case by copying it into `scenarios` in your template and modifying the value for `delay`.

## License

MIT © fffunction [fffunction.co](https://fffunction.co)
16 changes: 15 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

'use strict';

const fs = require('fs');
const meow = require('meow');
const validurl = require('valid-url').is_web_uri;
const updateNotifier = require('update-notifier');
Expand Down Expand Up @@ -30,7 +31,9 @@ const cli = meow(
--limit-similar[=3] Limits the number of similar URLs to a set number
Defaults to 3
e.g /blog/1, /blog/2, /blog/3
--reference-url Allows a reference URL to be used in testing
--reference-url Allows a reference URL to be used in testing
--template Specify the template file to use
Defaults to backstop.template.json

Examples
$ backstop-crawl http://localhost
Expand Down Expand Up @@ -59,6 +62,17 @@ if (cli.flags.referenceUrl) {
}
}

if (cli.flags.template) {
fs.access(cli.flags.template, fs.F_OK, (err) => {
if (err) {
console.error(
`> Error: "${cli.flags.template}" doesn't exist`
);
process.exit(1);
}
})
}

if (cli.input.length > 0) {
if (validurl(cli.input[0])) {
crawl(cli.input[0], cli.flags);
Expand Down
43 changes: 29 additions & 14 deletions lib/crawl.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,11 @@ const jsonfile = require('jsonfile');
const cheerio = require('cheerio');
const normalurl = require('normalize-url');
const limitSimilar = require('./limit-similar');
const processOverrides = require('./process-overrides');

const dirname = path.dirname;
const confPath = path.resolve(process.cwd(), 'backstop.template.json');
const defaultConf = fs.existsSync(confPath)
? JSON.parse(fs.readFileSync(confPath))
: require('./backstop.template.json');

/**
* Stash the default scenario from the template then delete it
* as defaultScenario isn't a valid key for backstop.json
*/
const defaultScenario = defaultConf.defaultScenario;
delete defaultConf.defaultScenario;

let overriddenScenarios = [];

const EXT_BLACKLIST = /\.pdf|\.js|\.css|\.png|\.jpg|\.jpeg|\.gif|\.json|\.xml|\.txt$/i;
const SPINNER_WIDTH = 2;
Expand All @@ -35,6 +27,8 @@ function crawl(url, flags) {
const spinner = ora('Crawling...');
let outfile = './backstop.json';

let confPath = path.resolve(process.cwd(), 'backstop.template.json');

crawler.discoverResources = function(buffer) {
const $ = cheerio.load(buffer.toString('utf8'));

Expand Down Expand Up @@ -80,6 +74,24 @@ function crawl(url, flags) {
crawler.scanSubdomains = true;
}

if (flags.template) {
confPath = flags.template;
}

const defaultConf = fs.existsSync(confPath)
? JSON.parse(fs.readFileSync(confPath))
: require('./backstop.template.json');

/**
* Stash the default scenario from the template then delete it
* as defaultScenario isn't a valid key for backstop.json
*/
const defaultScenario = defaultConf.defaultScenario;
delete defaultConf.defaultScenario;

// Grab any scenarios defined in the template.
overriddenScenarios = defaultConf.scenarios;
This conversation was marked as resolved.
Show resolved Hide resolved

// Skip this small blacklist of extensions
crawler.addFetchCondition(
queueItem => !queueItem.path.match(EXT_BLACKLIST)
Expand All @@ -104,11 +116,11 @@ function crawl(url, flags) {

if (flags.referenceUrl) {
// Normalize the URL to remove duplicate slashes. See #25
currentScenario.referenceUrl = normalurl(
currentScenario.referenceUrl = normalurl(
queueItem.url.replace(
url,
flags.referenceUrl
)
)
);

// Add a trailing slash to referenceUrl if url has a trailing slash and referenceUrl does not
Expand Down Expand Up @@ -138,6 +150,9 @@ function crawl(url, flags) {
});
urls = limitSimilar(urls, flags.limitSimilar);
}

urls = processOverrides(urls, overriddenScenarios);
This conversation was marked as resolved.
Show resolved Hide resolved

defaultConf.scenarios = urls;
const outPath = dirname(outfile);
mkpath(outPath, mkpathErr => {
Expand All @@ -154,7 +169,7 @@ function crawl(url, flags) {
spinner.text = jsonfileErr;
spinner.fail();
} else {
spinner.text = 'backstop.js generated';
spinner.text = `${outfile} generated`;
spinner.succeed();
}
}
Expand Down
13 changes: 13 additions & 0 deletions lib/process-overrides.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = processOverrides;
function processOverrides(urls, scenarios) {

scenarios.forEach((scenario, scenarioKey) => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that doing a forEach inside another forEach isn't ideal, but I haven't yet figured out a more efficient way to do this.

urls.forEach((url, urlKey) => {
if (url.label === scenario.label) {
urls[urlKey] = scenarios[scenarioKey];
}
});
});

return urls;
}
Loading