mirror of https://github.com/status-im/consul.git
UI: Add ember steps:list command for listing available steps (#5255)
* ui: Add ember steps:list command for listing available steps 1. Adds `command` addon to house the new command 2. Start to organize out the steps themselves, bring a bit more order to things ready to dedupe and cleanup
This commit is contained in:
parent
cb0c5309c9
commit
cfa4bc264e
|
@ -25,6 +25,9 @@ lint: deps
|
||||||
format: deps
|
format: deps
|
||||||
yarn run format:js
|
yarn run format:js
|
||||||
|
|
||||||
|
steps:
|
||||||
|
yarn run steps:list
|
||||||
|
|
||||||
node_modules: yarn.lock package.json
|
node_modules: yarn.lock package.json
|
||||||
yarn install
|
yarn install
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
/* eslint-env node */
|
||||||
|
'use strict';
|
||||||
|
module.exports = {
|
||||||
|
name: 'commands',
|
||||||
|
includedCommands: function() {
|
||||||
|
return {
|
||||||
|
'steps:list': {
|
||||||
|
name: 'steps:list',
|
||||||
|
run: function(config, args) {
|
||||||
|
require('./lib/list.js')(`${process.cwd()}/tests/steps.js`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
isDevelopingAddon() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
/* eslint-env node */
|
||||||
|
'use strict';
|
||||||
|
const babel = require('@babel/core');
|
||||||
|
const read = require('fs').readFileSync;
|
||||||
|
const path = require('path');
|
||||||
|
const vm = require('vm');
|
||||||
|
const color = require('chalk');
|
||||||
|
|
||||||
|
const out = function(prefix, step, desc) {
|
||||||
|
if (!Array.isArray(step)) {
|
||||||
|
step = [step];
|
||||||
|
}
|
||||||
|
step.forEach(function(item) {
|
||||||
|
const str =
|
||||||
|
prefix +
|
||||||
|
item.replace('\n', ' | ').replace(/\$\w+/g, function(match) {
|
||||||
|
return color.cyan(match);
|
||||||
|
});
|
||||||
|
console.log(color.green(str));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const library = {
|
||||||
|
given: function(step, cb, desc) {
|
||||||
|
out('Given ', step, desc);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
desc: function(desc) {
|
||||||
|
console.log(color.yellow(`- ${desc.trim()}`));
|
||||||
|
},
|
||||||
|
section: function() {
|
||||||
|
console.log(color.yellow(`##`));
|
||||||
|
},
|
||||||
|
then: function(step, cb, desc) {
|
||||||
|
out('Then ', step, desc);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
when: function(step, cb, desc) {
|
||||||
|
out('When ', step, desc);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const exec = function(filename) {
|
||||||
|
const js = read(filename);
|
||||||
|
const code = babel.transform(js.toString(), {
|
||||||
|
filename: filename,
|
||||||
|
presets: [require('babel-preset-env')],
|
||||||
|
}).code;
|
||||||
|
const exports = {};
|
||||||
|
vm.runInNewContext(
|
||||||
|
code,
|
||||||
|
{
|
||||||
|
exports: exports,
|
||||||
|
require: function(str) {
|
||||||
|
return exec(path.resolve(`${process.cwd()}/tests`, `${str}.js`)).default;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename: filename,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = function(filename) {
|
||||||
|
exec(filename).default(function() {}, library, {}, {}, {}, function() {});
|
||||||
|
};
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "commands",
|
||||||
|
"keywords": [
|
||||||
|
"ember-addon"
|
||||||
|
]
|
||||||
|
}
|
|
@ -20,7 +20,8 @@
|
||||||
"test-parallel": "EMBER_EXAM_PARALLEL=true ember exam --split=4 --parallel",
|
"test-parallel": "EMBER_EXAM_PARALLEL=true ember exam --split=4 --parallel",
|
||||||
"test:view": "ember test --server --test-port=${EMBER_TEST_PORT:-7357}",
|
"test:view": "ember test --server --test-port=${EMBER_TEST_PORT:-7357}",
|
||||||
"test:coverage": "COVERAGE=true ember test --test-port=${EMBER_TEST_PORT:-7357}",
|
"test:coverage": "COVERAGE=true ember test --test-port=${EMBER_TEST_PORT:-7357}",
|
||||||
"test:view:coverage": "COVERAGE=true ember test --server --test-port=${EMBER_TEST_PORT:-7357}"
|
"test:view:coverage": "COVERAGE=true ember test --server --test-port=${EMBER_TEST_PORT:-7357}",
|
||||||
|
"steps:list": "node ./lib/commands/bin/list.js"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
@ -38,11 +39,13 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.2.2",
|
||||||
"@hashicorp/consul-api-double": "^2.0.1",
|
"@hashicorp/consul-api-double": "^2.0.1",
|
||||||
"@hashicorp/ember-cli-api-double": "^1.3.0",
|
"@hashicorp/ember-cli-api-double": "^1.3.0",
|
||||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||||
"base64-js": "^1.3.0",
|
"base64-js": "^1.3.0",
|
||||||
"broccoli-asset-rev": "^2.4.5",
|
"broccoli-asset-rev": "^2.4.5",
|
||||||
|
"chalk": "^2.4.2",
|
||||||
"dart-sass": "^1.14.1",
|
"dart-sass": "^1.14.1",
|
||||||
"ember-ajax": "^3.0.0",
|
"ember-ajax": "^3.0.0",
|
||||||
"ember-browserify": "^1.2.2",
|
"ember-browserify": "^1.2.2",
|
||||||
|
@ -104,7 +107,8 @@
|
||||||
"ember-addon": {
|
"ember-addon": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"lib/startup",
|
"lib/startup",
|
||||||
"lib/block-slots"
|
"lib/block-slots",
|
||||||
|
"lib/commands"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,83 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
import Inflector from 'ember-inflector';
|
||||||
|
import utils from '@ember/test-helpers';
|
||||||
|
import getDictionary from '@hashicorp/ember-cli-api-double/dictionary';
|
||||||
|
|
||||||
|
import yadda from 'consul-ui/tests/helpers/yadda';
|
||||||
|
import pages from 'consul-ui/tests/pages';
|
||||||
|
import api from 'consul-ui/tests/helpers/api';
|
||||||
|
|
||||||
import steps from 'consul-ui/tests/steps';
|
import steps from 'consul-ui/tests/steps';
|
||||||
export default steps;
|
|
||||||
|
const pluralize = function(str) {
|
||||||
|
return Inflector.inflector.pluralize(str);
|
||||||
|
};
|
||||||
|
export default function(assert) {
|
||||||
|
const library = yadda.localisation.English.library(
|
||||||
|
getDictionary(function(model, cb) {
|
||||||
|
switch (model) {
|
||||||
|
case 'datacenter':
|
||||||
|
case 'datacenters':
|
||||||
|
case 'dcs':
|
||||||
|
model = 'dc';
|
||||||
|
break;
|
||||||
|
case 'services':
|
||||||
|
model = 'service';
|
||||||
|
break;
|
||||||
|
case 'nodes':
|
||||||
|
model = 'node';
|
||||||
|
break;
|
||||||
|
case 'kvs':
|
||||||
|
model = 'kv';
|
||||||
|
break;
|
||||||
|
case 'acls':
|
||||||
|
model = 'acl';
|
||||||
|
break;
|
||||||
|
case 'sessions':
|
||||||
|
model = 'session';
|
||||||
|
break;
|
||||||
|
case 'intentions':
|
||||||
|
model = 'intention';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cb(null, model);
|
||||||
|
}, yadda)
|
||||||
|
);
|
||||||
|
const create = function(number, name, value) {
|
||||||
|
// don't return a promise here as
|
||||||
|
// I don't need it to wait
|
||||||
|
api.server.createList(name, number, value);
|
||||||
|
};
|
||||||
|
const respondWith = function(url, data) {
|
||||||
|
api.server.respondWith(url.split('?')[0], data);
|
||||||
|
};
|
||||||
|
const setCookie = function(key, value) {
|
||||||
|
api.server.setCookie(key, value);
|
||||||
|
};
|
||||||
|
const getLastNthRequest = function(arr) {
|
||||||
|
return function(n, method) {
|
||||||
|
let requests = arr.slice(0).reverse();
|
||||||
|
if (method) {
|
||||||
|
requests = requests.filter(function(item) {
|
||||||
|
return item.method === method;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (n == null) {
|
||||||
|
return requests;
|
||||||
|
}
|
||||||
|
return requests[n];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return steps(assert, library, pages, {
|
||||||
|
pluralize: pluralize,
|
||||||
|
triggerKeyEvent: utils.triggerKeyEvent,
|
||||||
|
currentURL: utils.currentURL,
|
||||||
|
click: utils.click,
|
||||||
|
fillIn: utils.fillIn,
|
||||||
|
find: utils.find,
|
||||||
|
lastNthRequest: getLastNthRequest(api.server.history),
|
||||||
|
respondWith: respondWith,
|
||||||
|
create: create,
|
||||||
|
set: setCookie,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,521 +1,38 @@
|
||||||
/* eslint no-console: "off" */
|
import models from './steps/doubles/model';
|
||||||
import Inflector from 'ember-inflector';
|
import http from './steps/doubles/http';
|
||||||
import yadda from './helpers/yadda';
|
import visit from './steps/interactions/visit';
|
||||||
import { currentURL, click, triggerKeyEvent, fillIn, find } from '@ember/test-helpers';
|
import click from './steps/interactions/click';
|
||||||
import getDictionary from '@hashicorp/ember-cli-api-double/dictionary';
|
import form from './steps/interactions/form';
|
||||||
import pages from 'consul-ui/tests/pages';
|
import debug from './steps/debug/index';
|
||||||
import api from 'consul-ui/tests/helpers/api';
|
import assertHttp from './steps/assertions/http';
|
||||||
|
import assertModel from './steps/assertions/model';
|
||||||
|
import assertPage from './steps/assertions/page';
|
||||||
|
import assertDom from './steps/assertions/dom';
|
||||||
|
|
||||||
// const dont = `( don't| shouldn't| can't)?`;
|
// const dont = `( don't| shouldn't| can't)?`;
|
||||||
const pluralize = function(str) {
|
|
||||||
return Inflector.inflector.pluralize(str);
|
export default function(assert, library, pages, utils) {
|
||||||
};
|
var currentPage;
|
||||||
const create = function(number, name, value) {
|
const getCurrentPage = function() {
|
||||||
// don't return a promise here as
|
return currentPage;
|
||||||
// I don't need it to wait
|
};
|
||||||
api.server.createList(name, number, value);
|
const setCurrentPage = function(page) {
|
||||||
};
|
currentPage = page;
|
||||||
const lastRequest = function(method) {
|
|
||||||
return api.server.history
|
|
||||||
.slice(0)
|
|
||||||
.reverse()
|
|
||||||
.find(function(item) {
|
|
||||||
return item.method === method;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const fillInElement = function(page, name, value) {
|
|
||||||
const cm = document.querySelector(`textarea[name="${name}"] + .CodeMirror`);
|
|
||||||
if (cm) {
|
|
||||||
cm.CodeMirror.setValue(value);
|
|
||||||
return page;
|
return page;
|
||||||
} else {
|
};
|
||||||
return page.fillIn(name, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var currentPage;
|
|
||||||
export default function(assert) {
|
|
||||||
return (
|
|
||||||
yadda.localisation.English.library(
|
|
||||||
getDictionary(function(model, cb) {
|
|
||||||
switch (model) {
|
|
||||||
case 'datacenter':
|
|
||||||
case 'datacenters':
|
|
||||||
case 'dcs':
|
|
||||||
model = 'dc';
|
|
||||||
break;
|
|
||||||
case 'services':
|
|
||||||
model = 'service';
|
|
||||||
break;
|
|
||||||
case 'nodes':
|
|
||||||
model = 'node';
|
|
||||||
break;
|
|
||||||
case 'kvs':
|
|
||||||
model = 'kv';
|
|
||||||
break;
|
|
||||||
case 'acls':
|
|
||||||
model = 'acl';
|
|
||||||
break;
|
|
||||||
case 'sessions':
|
|
||||||
model = 'session';
|
|
||||||
break;
|
|
||||||
case 'intentions':
|
|
||||||
model = 'intention';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cb(null, model);
|
|
||||||
}, yadda)
|
|
||||||
)
|
|
||||||
// doubles
|
|
||||||
.given(['an external edit results in $number $model model[s]?'], function(number, model) {
|
|
||||||
return create(number, model);
|
|
||||||
})
|
|
||||||
.given(['$number $model model[s]?'], function(number, model) {
|
|
||||||
return create(number, model);
|
|
||||||
})
|
|
||||||
.given(['$number $model model[s]? with the value "$value"'], function(number, model, value) {
|
|
||||||
return create(number, model, value);
|
|
||||||
})
|
|
||||||
.given(
|
|
||||||
['$number $model model[s]? from yaml\n$yaml', '$number $model model[s]? from json\n$json'],
|
|
||||||
function(number, model, data) {
|
|
||||||
return create(number, model, data);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.given(['settings from yaml\n$yaml'], function(data) {
|
|
||||||
return Object.keys(data).forEach(function(key) {
|
|
||||||
window.localStorage[key] = JSON.stringify(data[key]);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.given('a network latency of $number', function(number) {
|
|
||||||
api.server.setCookie('CONSUL_LATENCY', number);
|
|
||||||
})
|
|
||||||
.given(["I'm using a legacy token"], function() {
|
|
||||||
window.localStorage['consul:token'] = JSON.stringify({ AccessorID: null, SecretID: 'id' });
|
|
||||||
})
|
|
||||||
// TODO: Abstract this away from HTTP
|
|
||||||
.given(['the url "$url" responds with a $status status'], function(url, status) {
|
|
||||||
return api.server.respondWithStatus(url.split('?')[0], parseInt(status));
|
|
||||||
})
|
|
||||||
.given(['the url "$url" responds with from yaml\n$yaml'], function(url, data) {
|
|
||||||
api.server.respondWith(url.split('?')[0], data);
|
|
||||||
})
|
|
||||||
// interactions
|
|
||||||
.when('I visit the $name page', function(name) {
|
|
||||||
currentPage = pages[name];
|
|
||||||
return currentPage.visit();
|
|
||||||
})
|
|
||||||
.when('I visit the $name page for the "$id" $model', function(name, id, model) {
|
|
||||||
currentPage = pages[name];
|
|
||||||
return currentPage.visit({
|
|
||||||
[model]: id,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.when(
|
|
||||||
['I visit the $name page for yaml\n$yaml', 'I visit the $name page for json\n$json'],
|
|
||||||
function(name, data) {
|
|
||||||
currentPage = pages[name];
|
|
||||||
// TODO: Consider putting an assertion here for testing the current url
|
|
||||||
// do I absolutely definitely need that all the time?
|
|
||||||
return pages[name].visit(data);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.when('I click "$selector"', function(selector) {
|
|
||||||
return click(selector);
|
|
||||||
})
|
|
||||||
// TODO: Probably nicer to think of better vocab than having the 'without " rule'
|
|
||||||
.when('I click (?!")$property(?!")', function(property) {
|
|
||||||
try {
|
|
||||||
return currentPage[property]();
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
throw new Error(`The '${property}' property on the page object doesn't exist`);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.when('I click $prop on the $component', function(prop, component) {
|
|
||||||
// Collection
|
|
||||||
var obj;
|
|
||||||
if (typeof currentPage[component].objectAt === 'function') {
|
|
||||||
obj = currentPage[component].objectAt(0);
|
|
||||||
} else {
|
|
||||||
obj = currentPage[component];
|
|
||||||
}
|
|
||||||
const func = obj[prop].bind(obj);
|
|
||||||
try {
|
|
||||||
return func();
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(
|
|
||||||
`The '${prop}' property on the '${component}' page object doesn't exist.\n${e.message}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.when('I submit', function(selector) {
|
|
||||||
return currentPage.submit();
|
|
||||||
})
|
|
||||||
.then('I fill in "$name" with "$value"', function(name, value) {
|
|
||||||
return currentPage.fillIn(name, value);
|
|
||||||
})
|
|
||||||
.then(['I fill in with yaml\n$yaml', 'I fill in with json\n$json'], function(data) {
|
|
||||||
return Object.keys(data).reduce(function(prev, item, i, arr) {
|
|
||||||
return fillInElement(prev, item, data[item]);
|
|
||||||
}, currentPage);
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
['I fill in the $form form with yaml\n$yaml', 'I fill in the $form with json\n$json'],
|
|
||||||
function(form, data) {
|
|
||||||
return Object.keys(data).reduce(function(prev, item, i, arr) {
|
|
||||||
const name = `${form}[${item}]`;
|
|
||||||
return fillInElement(prev, name, data[item]);
|
|
||||||
}, currentPage);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(['I type "$text" into "$selector"'], function(text, selector) {
|
|
||||||
return fillIn(selector, text);
|
|
||||||
})
|
|
||||||
.then(['I type with yaml\n$yaml'], function(data) {
|
|
||||||
const keys = Object.keys(data);
|
|
||||||
return keys
|
|
||||||
.reduce(function(prev, item, i, arr) {
|
|
||||||
return prev.fillIn(item, data[item]);
|
|
||||||
}, currentPage)
|
|
||||||
.then(function() {
|
|
||||||
return Promise.all(
|
|
||||||
keys.map(function(item) {
|
|
||||||
return triggerKeyEvent(`[name="${item}"]`, 'keyup', 83); // TODO: This is 's', be more generic
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// debugging helpers
|
|
||||||
.then('print the current url', function(url) {
|
|
||||||
console.log(currentURL());
|
|
||||||
return Promise.resolve();
|
|
||||||
})
|
|
||||||
.then('log the "$text"', function(text) {
|
|
||||||
console.log(text);
|
|
||||||
return Promise.resolve();
|
|
||||||
})
|
|
||||||
.then('pause for $milliseconds', function(milliseconds) {
|
|
||||||
return new Promise(function(resolve) {
|
|
||||||
setTimeout(resolve, milliseconds);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// assertions
|
|
||||||
.then('pause until I see $number $model model[s]?', function(num, model) {
|
|
||||||
return new Promise(function(resolve) {
|
|
||||||
let count = 0;
|
|
||||||
const interval = setInterval(function() {
|
|
||||||
if (++count >= 50) {
|
|
||||||
clearInterval(interval);
|
|
||||||
assert.ok(false);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
const len = currentPage[`${pluralize(model)}`].filter(function(item) {
|
|
||||||
return item.isVisible;
|
|
||||||
}).length;
|
|
||||||
if (len === num) {
|
|
||||||
clearInterval(interval);
|
|
||||||
assert.equal(len, num, `Expected ${num} ${model}s, saw ${len}`);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then('a $method request is made to "$url" with the body from yaml\n$yaml', function(
|
|
||||||
method,
|
|
||||||
url,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
const request = api.server.history[api.server.history.length - 2];
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
const body = JSON.parse(request.requestBody);
|
|
||||||
Object.keys(data).forEach(function(key, i, arr) {
|
|
||||||
assert.deepEqual(
|
|
||||||
body[key],
|
|
||||||
data[key],
|
|
||||||
`Expected the payload to contain ${key} equaling ${data[key]}, ${key} was ${body[key]}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
// TODO: This one can replace the above one, it covers more use cases
|
|
||||||
// also DRY it out a bit
|
|
||||||
.then('a $method request is made to "$url" from yaml\n$yaml', function(method, url, yaml) {
|
|
||||||
const request = api.server.history[api.server.history.length - 2];
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
let data = yaml.body || {};
|
|
||||||
const body = JSON.parse(request.requestBody);
|
|
||||||
Object.keys(data).forEach(function(key, i, arr) {
|
|
||||||
assert.equal(
|
|
||||||
body[key],
|
|
||||||
data[key],
|
|
||||||
`Expected the payload to contain ${key} to equal ${body[key]}, ${key} was ${data[key]}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
data = yaml.headers || {};
|
|
||||||
const headers = request.requestHeaders;
|
|
||||||
Object.keys(data).forEach(function(key, i, arr) {
|
|
||||||
assert.equal(
|
|
||||||
headers[key],
|
|
||||||
data[key],
|
|
||||||
`Expected the payload to contain ${key} to equal ${headers[key]}, ${key} was ${
|
|
||||||
data[key]
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then('a $method request is made to "$url" with the body "$body"', function(
|
|
||||||
method,
|
|
||||||
url,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
const request = api.server.history[api.server.history.length - 2];
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
const body = request.requestBody;
|
|
||||||
assert.equal(body, data, `Expected the request body to be ${data}, was ${body}`);
|
|
||||||
})
|
|
||||||
.then('a $method request is made to "$url" with no body', function(method, url) {
|
|
||||||
const request = api.server.history[api.server.history.length - 2];
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
const body = request.requestBody;
|
|
||||||
assert.equal(body, null, `Expected the request body to be null, was ${body}`);
|
|
||||||
})
|
|
||||||
|
|
||||||
.then('a $method request is made to "$url"', function(method, url) {
|
models(library, utils.create);
|
||||||
const request = api.server.history[api.server.history.length - 2];
|
http(library, utils.respondWith, utils.set);
|
||||||
assert.equal(
|
visit(library, pages, setCurrentPage);
|
||||||
request.method,
|
click(library, utils.click, getCurrentPage);
|
||||||
method,
|
form(library, utils.fillIn, utils.triggerKeyEvent, getCurrentPage);
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
debug(library, assert, utils.currentURL);
|
||||||
);
|
assertHttp(library, assert, utils.lastNthRequest);
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
assertModel(library, assert, getCurrentPage, utils.pluralize);
|
||||||
})
|
assertPage(library, assert, getCurrentPage);
|
||||||
.then('the last $method request was made to "$url"', function(method, url) {
|
assertDom(library, assert, utils.find, utils.currentURL);
|
||||||
const request = lastRequest(method);
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
})
|
|
||||||
.then('the last $method request was made to "$url" with the body from yaml\n$yaml', function(
|
|
||||||
method,
|
|
||||||
url,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
const request = lastRequest(method);
|
|
||||||
assert.ok(request, `Expected a ${method} request`);
|
|
||||||
assert.equal(
|
|
||||||
request.method,
|
|
||||||
method,
|
|
||||||
`Expected the request method to be ${method}, was ${request.method}`
|
|
||||||
);
|
|
||||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
|
||||||
const body = JSON.parse(request.requestBody);
|
|
||||||
Object.keys(data).forEach(function(key, i, arr) {
|
|
||||||
assert.deepEqual(
|
|
||||||
body[key],
|
|
||||||
data[key],
|
|
||||||
`Expected the payload to contain ${key} equaling ${data[key]}, ${key} was ${body[key]}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then('the last $method requests were like yaml\n$yaml', function(method, data) {
|
|
||||||
const requests = api.server.history.reverse().filter(function(item) {
|
|
||||||
return item.method === method;
|
|
||||||
});
|
|
||||||
data.reverse().forEach(function(item, i, arr) {
|
|
||||||
assert.equal(
|
|
||||||
requests[i].url,
|
|
||||||
item,
|
|
||||||
`Expected the request url to be ${item}, was ${requests[i].url}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then('the url should be $url', function(url) {
|
|
||||||
// TODO: nice! $url should be wrapped in ""
|
|
||||||
if (url === "''") {
|
|
||||||
url = '';
|
|
||||||
}
|
|
||||||
const current = currentURL() || '';
|
|
||||||
assert.equal(current, url, `Expected the url to be ${url} was ${current}`);
|
|
||||||
})
|
|
||||||
.then(['I see $num $model', 'I see $num $model model', 'I see $num $model models'], function(
|
|
||||||
num,
|
|
||||||
model
|
|
||||||
) {
|
|
||||||
const len = currentPage[pluralize(model)].filter(function(item) {
|
|
||||||
return item.isVisible;
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
assert.equal(len, num, `Expected ${num} ${pluralize(model)}, saw ${len}`);
|
return library.given(["I'm using a legacy token"], function(number, model, data) {
|
||||||
})
|
window.localStorage['consul:token'] = JSON.stringify({ AccessorID: null, SecretID: 'id' });
|
||||||
// TODO: I${ dont } see
|
});
|
||||||
.then([`I see $num $model model[s]? with the $property "$value"`], function(
|
|
||||||
// negate,
|
|
||||||
num,
|
|
||||||
model,
|
|
||||||
property,
|
|
||||||
value
|
|
||||||
) {
|
|
||||||
const len = currentPage[pluralize(model)].filter(function(item) {
|
|
||||||
return item.isVisible && item[property] == value;
|
|
||||||
}).length;
|
|
||||||
assert.equal(
|
|
||||||
len,
|
|
||||||
num,
|
|
||||||
`Expected ${num} ${pluralize(model)} with ${property} set to "${value}", saw ${len}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
// TODO: Make this accept a 'contains' word so you can search for text containing also
|
|
||||||
.then('I have settings like yaml\n$yaml', function(data) {
|
|
||||||
// TODO: Inject this
|
|
||||||
const settings = window.localStorage;
|
|
||||||
// TODO: this and the setup should probably use consul:
|
|
||||||
// as we are talking about 'settings' here not localStorage
|
|
||||||
// so the prefix should be hidden
|
|
||||||
Object.keys(data).forEach(function(prop) {
|
|
||||||
const actual = settings.getItem(prop);
|
|
||||||
const expected = data[prop];
|
|
||||||
assert.strictEqual(actual, expected, `Expected settings to be ${expected} was ${actual}`);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then('I see $property on the $component like yaml\n$yaml', function(
|
|
||||||
property,
|
|
||||||
component,
|
|
||||||
yaml
|
|
||||||
) {
|
|
||||||
const _component = currentPage[component];
|
|
||||||
const iterator = new Array(_component.length).fill(true);
|
|
||||||
// this will catch if we get aren't managing to select a component
|
|
||||||
assert.ok(iterator.length > 0);
|
|
||||||
iterator.forEach(function(item, i, arr) {
|
|
||||||
const actual =
|
|
||||||
typeof _component.objectAt(i)[property] === 'undefined'
|
|
||||||
? null
|
|
||||||
: _component.objectAt(i)[property];
|
|
||||||
|
|
||||||
// anything coming from the DOM is going to be text/strings
|
|
||||||
// if the yaml has numbers, cast them to strings
|
|
||||||
// TODO: This would get problematic for deeper objects
|
|
||||||
// will have to look to do this recursively
|
|
||||||
const expected = typeof yaml[i] === 'number' ? yaml[i].toString() : yaml[i];
|
|
||||||
|
|
||||||
assert.deepEqual(
|
|
||||||
actual,
|
|
||||||
expected,
|
|
||||||
`Expected to see ${property} on ${component}[${i}] as ${JSON.stringify(
|
|
||||||
expected
|
|
||||||
)}, was ${JSON.stringify(actual)}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(['I see $property on the $component'], function(property, component) {
|
|
||||||
// TODO: Time to work on repetition
|
|
||||||
// Collection
|
|
||||||
var obj;
|
|
||||||
if (typeof currentPage[component].objectAt === 'function') {
|
|
||||||
obj = currentPage[component].objectAt(0);
|
|
||||||
} else {
|
|
||||||
obj = currentPage[component];
|
|
||||||
}
|
|
||||||
let _component;
|
|
||||||
if (typeof obj === 'function') {
|
|
||||||
const func = obj[property].bind(obj);
|
|
||||||
try {
|
|
||||||
_component = func();
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
throw new Error(
|
|
||||||
`The '${property}' property on the '${component}' page object doesn't exist`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_component = obj;
|
|
||||||
}
|
|
||||||
assert.ok(_component[property], `Expected to see ${property} on ${component}`);
|
|
||||||
})
|
|
||||||
.then(["I don't see $property on the $component"], function(property, component) {
|
|
||||||
// Collection
|
|
||||||
var obj;
|
|
||||||
if (typeof currentPage[component].objectAt === 'function') {
|
|
||||||
obj = currentPage[component].objectAt(0);
|
|
||||||
} else {
|
|
||||||
obj = currentPage[component];
|
|
||||||
}
|
|
||||||
const func = obj[property].bind(obj);
|
|
||||||
assert.throws(
|
|
||||||
function() {
|
|
||||||
func();
|
|
||||||
},
|
|
||||||
function(e) {
|
|
||||||
return e.toString().indexOf('Element not found') !== -1;
|
|
||||||
},
|
|
||||||
`Expected to not see ${property} on ${component}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then(["I don't see $property"], function(property) {
|
|
||||||
assert.throws(
|
|
||||||
function() {
|
|
||||||
currentPage[property]();
|
|
||||||
},
|
|
||||||
function(e) {
|
|
||||||
return e.toString().indexOf('Element not found') !== -1;
|
|
||||||
},
|
|
||||||
`Expected to not see ${property}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then(['I see $property'], function(property) {
|
|
||||||
assert.ok(currentPage[property], `Expected to see ${property}`);
|
|
||||||
})
|
|
||||||
.then(['I see $property like "$value"'], function(property, value) {
|
|
||||||
assert.equal(
|
|
||||||
currentPage[property],
|
|
||||||
value,
|
|
||||||
`Expected to see ${property}, was ${currentPage[property]}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then(['I see the text "$text" in "$selector"'], function(text, selector) {
|
|
||||||
assert.ok(
|
|
||||||
find(selector).textContent.indexOf(text) !== -1,
|
|
||||||
`Expected to see "${text}" in "${selector}"`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
// TODO: Think of better language
|
|
||||||
// TODO: These should be mergeable
|
|
||||||
.then(['"$selector" has the "$class" class'], function(selector, cls) {
|
|
||||||
// because `find` doesn't work, guessing its sandboxed to ember's container
|
|
||||||
assert.ok(
|
|
||||||
document.querySelector(selector).classList.contains(cls),
|
|
||||||
`Expected [class] to contain ${cls} on ${selector}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then(['"$selector" doesn\'t have the "$class" class'], function(selector, cls) {
|
|
||||||
assert.ok(
|
|
||||||
!document.querySelector(selector).classList.contains(cls),
|
|
||||||
`Expected [class] not to contain ${cls} on ${selector}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.then('ok', function() {
|
|
||||||
assert.ok(true);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
export default function(scenario, assert, find, currentURL) {
|
||||||
|
scenario
|
||||||
|
.then(['I see the text "$text" in "$selector"'], function(text, selector) {
|
||||||
|
assert.ok(
|
||||||
|
find(selector).textContent.indexOf(text) !== -1,
|
||||||
|
`Expected to see "${text}" in "${selector}"`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
// TODO: Think of better language
|
||||||
|
// TODO: These should be mergeable
|
||||||
|
.then(['"$selector" has the "$class" class'], function(selector, cls) {
|
||||||
|
// because `find` doesn't work, guessing its sandboxed to ember's container
|
||||||
|
assert.ok(
|
||||||
|
document.querySelector(selector).classList.contains(cls),
|
||||||
|
`Expected [class] to contain ${cls} on ${selector}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(['"$selector" doesn\'t have the "$class" class'], function(selector, cls) {
|
||||||
|
assert.ok(
|
||||||
|
!document.querySelector(selector).classList.contains(cls),
|
||||||
|
`Expected [class] not to contain ${cls} on ${selector}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
// TODO: Make this accept a 'contains' word so you can search for text containing also
|
||||||
|
.then('I have settings like yaml\n$yaml', function(data) {
|
||||||
|
// TODO: Inject this
|
||||||
|
const settings = window.localStorage;
|
||||||
|
// TODO: this and the setup should probably use consul:
|
||||||
|
// as we are talking about 'settings' here not localStorage
|
||||||
|
// so the prefix should be hidden
|
||||||
|
Object.keys(data).forEach(function(prop) {
|
||||||
|
const actual = settings.getItem(prop);
|
||||||
|
const expected = data[prop];
|
||||||
|
assert.strictEqual(actual, expected, `Expected settings to be ${expected} was ${actual}`);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then('the url should be $url', function(url) {
|
||||||
|
// TODO: nice! $url should be wrapped in ""
|
||||||
|
if (url === "''") {
|
||||||
|
url = '';
|
||||||
|
}
|
||||||
|
const current = currentURL() || '';
|
||||||
|
assert.equal(current, url, `Expected the url to be ${url} was ${current}`);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
export default function(scenario, assert, lastNthRequest) {
|
||||||
|
// lastNthRequest should return a
|
||||||
|
// {
|
||||||
|
// method: '',
|
||||||
|
// requestBody: '',
|
||||||
|
// requestHeaders: ''
|
||||||
|
// }
|
||||||
|
const assertRequest = function(request, method, url) {
|
||||||
|
assert.equal(
|
||||||
|
request.method,
|
||||||
|
method,
|
||||||
|
`Expected the request method to be ${method}, was ${request.method}`
|
||||||
|
);
|
||||||
|
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
||||||
|
};
|
||||||
|
scenario
|
||||||
|
.then('a $method request is made to "$url" with the body from yaml\n$yaml', function(
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
data
|
||||||
|
) {
|
||||||
|
const request = lastNthRequest(1);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
const body = JSON.parse(request.requestBody);
|
||||||
|
Object.keys(data).forEach(function(key, i, arr) {
|
||||||
|
assert.deepEqual(
|
||||||
|
body[key],
|
||||||
|
data[key],
|
||||||
|
`Expected the payload to contain ${key} equaling ${data[key]}, ${key} was ${body[key]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
// TODO: This one can replace the above one, it covers more use cases
|
||||||
|
// also DRY it out a bit
|
||||||
|
.then('a $method request is made to "$url" from yaml\n$yaml', function(method, url, yaml) {
|
||||||
|
const request = lastNthRequest(1);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
let data = yaml.body || {};
|
||||||
|
const body = JSON.parse(request.requestBody);
|
||||||
|
Object.keys(data).forEach(function(key, i, arr) {
|
||||||
|
assert.equal(
|
||||||
|
body[key],
|
||||||
|
data[key],
|
||||||
|
`Expected the payload to contain ${key} to equal ${body[key]}, ${key} was ${data[key]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
data = yaml.headers || {};
|
||||||
|
const headers = request.requestHeaders;
|
||||||
|
Object.keys(data).forEach(function(key, i, arr) {
|
||||||
|
assert.equal(
|
||||||
|
headers[key],
|
||||||
|
data[key],
|
||||||
|
`Expected the payload to contain ${key} to equal ${headers[key]}, ${key} was ${data[key]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then('a $method request is made to "$url" with the body "$body"', function(method, url, data) {
|
||||||
|
const request = lastNthRequest(1);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
assert.equal(
|
||||||
|
request.requestBody,
|
||||||
|
data,
|
||||||
|
`Expected the request body to be ${data}, was ${request.requestBody}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then('a $method request is made to "$url" with no body', function(method, url) {
|
||||||
|
const request = lastNthRequest(1);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
assert.equal(
|
||||||
|
request.requestBody,
|
||||||
|
null,
|
||||||
|
`Expected the request body to be null, was ${request.requestBody}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
|
.then('a $method request is made to "$url"', function(method, url) {
|
||||||
|
const request = lastNthRequest(1);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
})
|
||||||
|
.then('the last $method request was made to "$url"', function(method, url) {
|
||||||
|
const request = lastNthRequest(0, method);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
})
|
||||||
|
.then('the last $method request was made to "$url" with the body from yaml\n$yaml', function(
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
data
|
||||||
|
) {
|
||||||
|
const request = lastNthRequest(0, method);
|
||||||
|
const body = JSON.parse(request.requestBody);
|
||||||
|
assert.ok(request, `Expected a ${method} request`);
|
||||||
|
assertRequest(request, method, url);
|
||||||
|
Object.keys(data).forEach(function(key, i, arr) {
|
||||||
|
assert.deepEqual(
|
||||||
|
body[key],
|
||||||
|
data[key],
|
||||||
|
`Expected the payload to contain ${key} equaling ${data[key]}, ${key} was ${body[key]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then('the last $method requests were like yaml\n$yaml', function(method, data) {
|
||||||
|
const requests = lastNthRequest(null, method);
|
||||||
|
data.reverse().forEach(function(item, i, arr) {
|
||||||
|
assert.equal(
|
||||||
|
requests[i].url,
|
||||||
|
item,
|
||||||
|
`Expected the request url to be ${item}, was ${requests[i].url}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
export default function(scenario, assert, currentPage, pluralize) {
|
||||||
|
scenario
|
||||||
|
.then('pause until I see $number $model model[s]?', function(num, model) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
let count = 0;
|
||||||
|
const interval = setInterval(function() {
|
||||||
|
if (++count >= 50) {
|
||||||
|
clearInterval(interval);
|
||||||
|
assert.ok(false);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
const len = currentPage()[pluralize(model)].filter(function(item) {
|
||||||
|
return item.isVisible;
|
||||||
|
}).length;
|
||||||
|
if (len === num) {
|
||||||
|
clearInterval(interval);
|
||||||
|
assert.equal(len, num, `Expected ${num} ${model}s, saw ${len}`);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(['I see $num $model', 'I see $num $model model', 'I see $num $model models'], function(
|
||||||
|
num,
|
||||||
|
model
|
||||||
|
) {
|
||||||
|
const len = currentPage()[pluralize(model)].filter(function(item) {
|
||||||
|
return item.isVisible;
|
||||||
|
}).length;
|
||||||
|
|
||||||
|
assert.equal(len, num, `Expected ${num} ${pluralize(model)}, saw ${len}`);
|
||||||
|
})
|
||||||
|
// TODO: I${ dont } see
|
||||||
|
.then([`I see $num $model model[s]? with the $property "$value"`], function(
|
||||||
|
// negate,
|
||||||
|
num,
|
||||||
|
model,
|
||||||
|
property,
|
||||||
|
value
|
||||||
|
) {
|
||||||
|
const len = currentPage()[pluralize(model)].filter(function(item) {
|
||||||
|
return item.isVisible && item[property] == value;
|
||||||
|
}).length;
|
||||||
|
assert.equal(
|
||||||
|
len,
|
||||||
|
num,
|
||||||
|
`Expected ${num} ${pluralize(model)} with ${property} set to "${value}", saw ${len}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
export default function(scenario, assert, currentPage) {
|
||||||
|
scenario
|
||||||
|
.then('I see $property on the $component like yaml\n$yaml', function(
|
||||||
|
property,
|
||||||
|
component,
|
||||||
|
yaml
|
||||||
|
) {
|
||||||
|
const _component = currentPage()[component];
|
||||||
|
const iterator = new Array(_component.length).fill(true);
|
||||||
|
// this will catch if we get aren't managing to select a component
|
||||||
|
assert.ok(iterator.length > 0);
|
||||||
|
iterator.forEach(function(item, i, arr) {
|
||||||
|
const actual =
|
||||||
|
typeof _component.objectAt(i)[property] === 'undefined'
|
||||||
|
? null
|
||||||
|
: _component.objectAt(i)[property];
|
||||||
|
|
||||||
|
// anything coming from the DOM is going to be text/strings
|
||||||
|
// if the yaml has numbers, cast them to strings
|
||||||
|
// TODO: This would get problematic for deeper objects
|
||||||
|
// will have to look to do this recursively
|
||||||
|
const expected = typeof yaml[i] === 'number' ? yaml[i].toString() : yaml[i];
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
actual,
|
||||||
|
expected,
|
||||||
|
`Expected to see ${property} on ${component}[${i}] as ${JSON.stringify(
|
||||||
|
expected
|
||||||
|
)}, was ${JSON.stringify(actual)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(['I see $property on the $component'], function(property, component) {
|
||||||
|
// TODO: Time to work on repetition
|
||||||
|
// Collection
|
||||||
|
var obj;
|
||||||
|
if (typeof currentPage()[component].objectAt === 'function') {
|
||||||
|
obj = currentPage()[component].objectAt(0);
|
||||||
|
} else {
|
||||||
|
obj = currentPage()[component];
|
||||||
|
}
|
||||||
|
let _component;
|
||||||
|
if (typeof obj === 'function') {
|
||||||
|
const func = obj[property].bind(obj);
|
||||||
|
try {
|
||||||
|
_component = func();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
throw new Error(
|
||||||
|
`The '${property}' property on the '${component}' page object doesn't exist`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_component = obj;
|
||||||
|
}
|
||||||
|
assert.ok(_component[property], `Expected to see ${property} on ${component}`);
|
||||||
|
})
|
||||||
|
.then(["I don't see $property on the $component"], function(property, component) {
|
||||||
|
// Collection
|
||||||
|
var obj;
|
||||||
|
if (typeof currentPage()[component].objectAt === 'function') {
|
||||||
|
obj = currentPage()[component].objectAt(0);
|
||||||
|
} else {
|
||||||
|
obj = currentPage()[component];
|
||||||
|
}
|
||||||
|
const func = obj[property].bind(obj);
|
||||||
|
assert.throws(
|
||||||
|
function() {
|
||||||
|
func();
|
||||||
|
},
|
||||||
|
function(e) {
|
||||||
|
return e.toString().indexOf('Element not found') !== -1;
|
||||||
|
},
|
||||||
|
`Expected to not see ${property} on ${component}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(["I don't see $property"], function(property) {
|
||||||
|
assert.throws(
|
||||||
|
function() {
|
||||||
|
currentPage()[property]();
|
||||||
|
},
|
||||||
|
function(e) {
|
||||||
|
return e.toString().indexOf('Element not found') !== -1;
|
||||||
|
},
|
||||||
|
`Expected to not see ${property}`
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(['I see $property'], function(property) {
|
||||||
|
assert.ok(currentPage()[property], `Expected to see ${property}`);
|
||||||
|
})
|
||||||
|
.then(['I see $property like "$value"'], function(property, value) {
|
||||||
|
assert.equal(
|
||||||
|
currentPage()[property],
|
||||||
|
value,
|
||||||
|
`Expected to see ${property}, was ${currentPage()[property]}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
export default function(scenario, assert, currentURL) {
|
||||||
|
scenario
|
||||||
|
.then('print the current url', function(url) {
|
||||||
|
console.log(currentURL());
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
.then('log the "$text"', function(text) {
|
||||||
|
console.log(text);
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
.then('pause for $milliseconds', function(milliseconds) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
setTimeout(resolve, milliseconds);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then('ok', function() {
|
||||||
|
assert.ok(true);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
export default function(scenario, respondWith, set) {
|
||||||
|
// respondWith should set the url to return a certain response shape
|
||||||
|
scenario
|
||||||
|
.given(['the url "$url" responds with a $status status'], function(url, status) {
|
||||||
|
respondWith(url, {
|
||||||
|
status: parseInt(status),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.given(['the url "$url" responds with from yaml\n$yaml'], function(url, data) {
|
||||||
|
respondWith(url, data);
|
||||||
|
})
|
||||||
|
.given('a network latency of $number', function(number) {
|
||||||
|
set('CONSUL_LATENCY', number);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
export default function(scenario, create) {
|
||||||
|
scenario
|
||||||
|
.given(['an external edit results in $number $model model[s]?'], function(number, model) {
|
||||||
|
return create(number, model);
|
||||||
|
})
|
||||||
|
.given(['$number $model model[s]?'], function(number, model) {
|
||||||
|
return create(number, model);
|
||||||
|
})
|
||||||
|
.given(['$number $model model[s]? with the value "$value"'], function(number, model, value) {
|
||||||
|
return create(number, model, value);
|
||||||
|
})
|
||||||
|
.given(
|
||||||
|
['$number $model model[s]? from yaml\n$yaml', '$number $model model[s]? from json\n$json'],
|
||||||
|
function(number, model, data) {
|
||||||
|
return create(number, model, data);
|
||||||
|
}
|
||||||
|
).given(['settings from yaml\n$yaml'], function(data) {
|
||||||
|
return Object.keys(data).forEach(function(key) {
|
||||||
|
window.localStorage[key] = JSON.stringify(data[key]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* eslint no-console: "off" */
|
||||||
|
export default function(scenario, click, currentPage) {
|
||||||
|
scenario
|
||||||
|
.when('I click "$selector"', function(selector) {
|
||||||
|
return click(selector);
|
||||||
|
})
|
||||||
|
// TODO: Probably nicer to think of better vocab than having the 'without " rule'
|
||||||
|
.when('I click (?!")$property(?!")', function(property) {
|
||||||
|
try {
|
||||||
|
return currentPage()[property]();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
throw new Error(`The '${property}' property on the page object doesn't exist`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.when('I click $prop on the $component', function(prop, component) {
|
||||||
|
// Collection
|
||||||
|
var obj;
|
||||||
|
if (typeof currentPage()[component].objectAt === 'function') {
|
||||||
|
obj = currentPage()[component].objectAt(0);
|
||||||
|
} else {
|
||||||
|
obj = currentPage()[component];
|
||||||
|
}
|
||||||
|
const func = obj[prop].bind(obj);
|
||||||
|
try {
|
||||||
|
return func();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(
|
||||||
|
`The '${prop}' property on the '${component}' page object doesn't exist.\n${e.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
export default function(scenario, fillIn, triggerKeyEvent, currentPage) {
|
||||||
|
const fillInElement = function(page, name, value) {
|
||||||
|
const cm = document.querySelector(`textarea[name="${name}"] + .CodeMirror`);
|
||||||
|
if (cm) {
|
||||||
|
cm.CodeMirror.setValue(value);
|
||||||
|
return page;
|
||||||
|
} else {
|
||||||
|
return page.fillIn(name, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
scenario
|
||||||
|
.when('I submit', function(selector) {
|
||||||
|
return currentPage().submit();
|
||||||
|
})
|
||||||
|
.then('I fill in "$name" with "$value"', function(name, value) {
|
||||||
|
return currentPage().fillIn(name, value);
|
||||||
|
})
|
||||||
|
.then(['I fill in with yaml\n$yaml', 'I fill in with json\n$json'], function(data) {
|
||||||
|
return Object.keys(data).reduce(function(prev, item, i, arr) {
|
||||||
|
return fillInElement(prev, item, data[item]);
|
||||||
|
}, currentPage());
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
['I fill in the $form form with yaml\n$yaml', 'I fill in the $form with json\n$json'],
|
||||||
|
function(form, data) {
|
||||||
|
return Object.keys(data).reduce(function(prev, item, i, arr) {
|
||||||
|
const name = `${form}[${item}]`;
|
||||||
|
return fillInElement(prev, name, data[item]);
|
||||||
|
}, currentPage());
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(['I type "$text" into "$selector"'], function(text, selector) {
|
||||||
|
return fillIn(selector, text);
|
||||||
|
})
|
||||||
|
.then(['I type with yaml\n$yaml'], function(data) {
|
||||||
|
const keys = Object.keys(data);
|
||||||
|
return keys
|
||||||
|
.reduce(function(prev, item, i, arr) {
|
||||||
|
return prev.fillIn(item, data[item]);
|
||||||
|
}, currentPage())
|
||||||
|
.then(function() {
|
||||||
|
return Promise.all(
|
||||||
|
keys.map(function(item) {
|
||||||
|
return triggerKeyEvent(`[name="${item}"]`, 'keyup', 83); // TODO: This is 's', be more generic
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
export default function(scenario, pages, set) {
|
||||||
|
scenario
|
||||||
|
.when('I visit the $name page', function(name) {
|
||||||
|
return set(pages[name]).visit();
|
||||||
|
})
|
||||||
|
.when('I visit the $name page for the "$id" $model', function(name, id, model) {
|
||||||
|
return set(pages[name]).visit({
|
||||||
|
[model]: id,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.when(
|
||||||
|
['I visit the $name page for yaml\n$yaml', 'I visit the $name page for json\n$json'],
|
||||||
|
function(name, data) {
|
||||||
|
// TODO: Consider putting an assertion here for testing the current url
|
||||||
|
// do I absolutely definitely need that all the time?
|
||||||
|
return set(pages[name]).visit(data);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -27,6 +27,26 @@
|
||||||
semver "^5.4.1"
|
semver "^5.4.1"
|
||||||
source-map "^0.5.0"
|
source-map "^0.5.0"
|
||||||
|
|
||||||
|
"@babel/core@^7.2.2":
|
||||||
|
version "7.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947"
|
||||||
|
integrity sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/generator" "^7.3.3"
|
||||||
|
"@babel/helpers" "^7.2.0"
|
||||||
|
"@babel/parser" "^7.3.3"
|
||||||
|
"@babel/template" "^7.2.2"
|
||||||
|
"@babel/traverse" "^7.2.2"
|
||||||
|
"@babel/types" "^7.3.3"
|
||||||
|
convert-source-map "^1.1.0"
|
||||||
|
debug "^4.1.0"
|
||||||
|
json5 "^2.1.0"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
resolve "^1.3.2"
|
||||||
|
semver "^5.4.1"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
|
||||||
"@babel/generator@^7.0.0", "@babel/generator@^7.1.2":
|
"@babel/generator@^7.0.0", "@babel/generator@^7.1.2":
|
||||||
version "7.1.2"
|
version "7.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.2.tgz#fde75c072575ce7abbd97322e8fef5bae67e4630"
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.2.tgz#fde75c072575ce7abbd97322e8fef5bae67e4630"
|
||||||
|
@ -37,6 +57,17 @@
|
||||||
source-map "^0.5.0"
|
source-map "^0.5.0"
|
||||||
trim-right "^1.0.1"
|
trim-right "^1.0.1"
|
||||||
|
|
||||||
|
"@babel/generator@^7.2.2", "@babel/generator@^7.3.3":
|
||||||
|
version "7.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e"
|
||||||
|
integrity sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.3.3"
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
trim-right "^1.0.1"
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.0.0":
|
"@babel/helper-annotate-as-pure@^7.0.0":
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
|
||||||
|
@ -181,6 +212,15 @@
|
||||||
"@babel/traverse" "^7.1.0"
|
"@babel/traverse" "^7.1.0"
|
||||||
"@babel/types" "^7.1.2"
|
"@babel/types" "^7.1.2"
|
||||||
|
|
||||||
|
"@babel/helpers@^7.2.0":
|
||||||
|
version "7.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9"
|
||||||
|
integrity sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.1.2"
|
||||||
|
"@babel/traverse" "^7.1.5"
|
||||||
|
"@babel/types" "^7.3.0"
|
||||||
|
|
||||||
"@babel/highlight@^7.0.0":
|
"@babel/highlight@^7.0.0":
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
|
||||||
|
@ -193,6 +233,11 @@
|
||||||
version "7.1.2"
|
version "7.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.2.tgz#85c5c47af6d244fab77bce6b9bd830e38c978409"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.2.tgz#85c5c47af6d244fab77bce6b9bd830e38c978409"
|
||||||
|
|
||||||
|
"@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.3.3":
|
||||||
|
version "7.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87"
|
||||||
|
integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==
|
||||||
|
|
||||||
"@babel/plugin-proposal-async-generator-functions@^7.1.0":
|
"@babel/plugin-proposal-async-generator-functions@^7.1.0":
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce"
|
||||||
|
@ -503,6 +548,15 @@
|
||||||
"@babel/parser" "^7.1.2"
|
"@babel/parser" "^7.1.2"
|
||||||
"@babel/types" "^7.1.2"
|
"@babel/types" "^7.1.2"
|
||||||
|
|
||||||
|
"@babel/template@^7.2.2":
|
||||||
|
version "7.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907"
|
||||||
|
integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/parser" "^7.2.2"
|
||||||
|
"@babel/types" "^7.2.2"
|
||||||
|
|
||||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0":
|
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0":
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2"
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2"
|
||||||
|
@ -517,6 +571,21 @@
|
||||||
globals "^11.1.0"
|
globals "^11.1.0"
|
||||||
lodash "^4.17.10"
|
lodash "^4.17.10"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2":
|
||||||
|
version "7.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8"
|
||||||
|
integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/generator" "^7.2.2"
|
||||||
|
"@babel/helper-function-name" "^7.1.0"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.0.0"
|
||||||
|
"@babel/parser" "^7.2.3"
|
||||||
|
"@babel/types" "^7.2.2"
|
||||||
|
debug "^4.1.0"
|
||||||
|
globals "^11.1.0"
|
||||||
|
lodash "^4.17.10"
|
||||||
|
|
||||||
"@babel/types@^7.0.0", "@babel/types@^7.1.2":
|
"@babel/types@^7.0.0", "@babel/types@^7.1.2":
|
||||||
version "7.1.2"
|
version "7.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.2.tgz#183e7952cf6691628afdc2e2b90d03240bac80c0"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.2.tgz#183e7952cf6691628afdc2e2b90d03240bac80c0"
|
||||||
|
@ -525,6 +594,15 @@
|
||||||
lodash "^4.17.10"
|
lodash "^4.17.10"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
|
||||||
|
version "7.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436"
|
||||||
|
integrity sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==
|
||||||
|
dependencies:
|
||||||
|
esutils "^2.0.2"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@ember/ordered-set@^1.0.0":
|
"@ember/ordered-set@^1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@ember/ordered-set/-/ordered-set-1.0.0.tgz#cf9ab5fd7510bcad370370ebcded705f6d1c542b"
|
resolved "https://registry.yarnpkg.com/@ember/ordered-set/-/ordered-set-1.0.0.tgz#cf9ab5fd7510bcad370370ebcded705f6d1c542b"
|
||||||
|
@ -1231,6 +1309,7 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
|
||||||
babel-core@^6.14.0, babel-core@^6.26.0, babel-core@^6.26.3:
|
babel-core@^6.14.0, babel-core@^6.26.0, babel-core@^6.26.3:
|
||||||
version "6.26.3"
|
version "6.26.3"
|
||||||
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
|
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
|
||||||
|
integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-code-frame "^6.26.0"
|
babel-code-frame "^6.26.0"
|
||||||
babel-generator "^6.26.0"
|
babel-generator "^6.26.0"
|
||||||
|
@ -2821,6 +2900,15 @@ chalk@^2.4.1:
|
||||||
escape-string-regexp "^1.0.5"
|
escape-string-regexp "^1.0.5"
|
||||||
supports-color "^5.3.0"
|
supports-color "^5.3.0"
|
||||||
|
|
||||||
|
chalk@^2.4.2:
|
||||||
|
version "2.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
|
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^3.2.1"
|
||||||
|
escape-string-regexp "^1.0.5"
|
||||||
|
supports-color "^5.3.0"
|
||||||
|
|
||||||
chalk@~0.4.0:
|
chalk@~0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
|
resolved "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
|
||||||
|
@ -6989,6 +7077,13 @@ json5@^0.5.0, json5@^0.5.1:
|
||||||
version "0.5.1"
|
version "0.5.1"
|
||||||
resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
resolved "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||||
|
|
||||||
|
json5@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
|
||||||
|
integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.0"
|
||||||
|
|
||||||
jsonfile@^2.1.0:
|
jsonfile@^2.1.0:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
|
||||||
|
@ -7594,9 +7689,10 @@ lodash@^4.14.0, lodash@^4.17.4:
|
||||||
version "4.17.10"
|
version "4.17.10"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||||
|
|
||||||
lodash@^4.17.10, lodash@^4.17.5, lodash@~4.17.10:
|
lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5, lodash@~4.17.10:
|
||||||
version "4.17.11"
|
version "4.17.11"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||||
|
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
||||||
|
|
||||||
log-symbols@^1.0.2:
|
log-symbols@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
|
Loading…
Reference in New Issue