diff --git a/lib/tasks/tests/visual/run.js b/lib/tasks/tests/visual/run.js index f955fc652..1c09af9e3 100644 --- a/lib/tasks/tests/visual/run.js +++ b/lib/tasks/tests/visual/run.js @@ -91,8 +91,7 @@ export default (gulp, config, args) => { /* Start Gemini and return runner upon finish */ return new Gemini(gemini).test(`${config.tests.visual}/suites`, { - reporters: [process.env.CI ? "flat" : "html"], - grep: args.grep ? new RegExp(args.grep, "i") : null, + reporters: ["flat"].concat(process.env.CI ? [] : ["html"]), browsers: args.browsers ? [].concat(args.browsers) : null }) diff --git a/scripts/build b/scripts/build index 1f77f8097..8037cbda3 100755 --- a/scripts/build +++ b/scripts/build @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp build --clean --optimize --revision $@ +`npm bin`/gulp build --clean --optimize --revision "$@" diff --git a/scripts/clean b/scripts/clean index 9cb9d0f33..309567950 100755 --- a/scripts/clean +++ b/scripts/clean @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp clean $@ +`npm bin`/gulp clean "$@" diff --git a/scripts/start b/scripts/start index 385e72923..0dc23e37c 100755 --- a/scripts/start +++ b/scripts/start @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp watch --no-lint $@ +`npm bin`/gulp watch --no-lint "$@" diff --git a/scripts/test/visual/run b/scripts/test/visual/run index a5691bb5d..04c45871e 100755 --- a/scripts/test/visual/run +++ b/scripts/test/visual/run @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp tests:visual:run --clean $@ +`npm bin`/gulp tests:visual:run --clean "$@" diff --git a/scripts/test/visual/session b/scripts/test/visual/session index 61803861c..5d30bd2e1 100755 --- a/scripts/test/visual/session +++ b/scripts/test/visual/session @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp tests:visual:session $@ +`npm bin`/gulp tests:visual:session "$@" diff --git a/scripts/test/visual/update b/scripts/test/visual/update index eabae85b3..61789f24d 100755 --- a/scripts/test/visual/update +++ b/scripts/test/visual/update @@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then fi # Run command -`npm bin`/gulp tests:visual:update $@ +`npm bin`/gulp tests:visual:update "$@" diff --git a/tests/visual/helpers/spec.js b/tests/visual/helpers/spec.js index 760ca5ba4..2ab6eeadd 100644 --- a/tests/visual/helpers/spec.js +++ b/tests/visual/helpers/spec.js @@ -22,6 +22,14 @@ import config from "../config.json" import path from "path" +import yargs from "yargs" + +/* ---------------------------------------------------------------------------- + * Configuration and arguments + * ------------------------------------------------------------------------- */ + +/* Parse arguments from command line */ +const args = yargs.argv /* ---------------------------------------------------------------------------- * Functions @@ -61,7 +69,50 @@ const resolve = (breakpoints, expr) => { } /** - * Generate a Gemini test suite for the component + * Filter a set of test suites using a regular expression + * + * @param {Array.} components - Component specifications + * @param {Array.} parent - Parent test suite names + * @return {boolean} Whether at least one suite was kept + */ +const filter = (components, parent = []) => { + const regexp = new RegExp(args.grep.replace(" ", ".*?"), "i") + return Object.keys(components).reduce((match, name) => { + const component = components[name] + + /* Deep-copy current path and call recursive */ + const temp = parent.slice(0).concat(name) + const keep = filter(component.suite || {}, temp) + + /* Remove all states that do not match the regular expression */ + component.states = (component.states || [{ name: "", wait: 0 }]).reduce( + (states, state) => { + const fullname = temp.slice(0) + .concat(state.name.length ? [state.name] : []) + .join(" ") + if (regexp.test(fullname)) + states.push(state) + return states + }, []) + + /* Keep komponent, if there is at least one state or the component has + matching subsuites, so it needs to be kept */ + if (component.states.length || keep) { + if (keep) { + delete component.capture + delete component.break + } + return true + } + + /* Otherwise, delete component */ + delete components[name] + return match + }, false) +} + +/** + * Generate Gemini test suites for the given components * * @param {string} dirname - Directory of the test suite * @param {Array.} components - Component specifications // TODO: document syntax and specificagtion @@ -81,11 +132,11 @@ const generate = (dirname, components) => { "_", component.url ? component.url : "")) /* The capture selector is assumed to exist */ - suite.setCaptureElements(component.capture) + if (component.capture) + suite.setCaptureElements(component.capture) /* Generate a subsuite for every state */ - const states = component.states || [{ name: "", wait: 0 }] - for (const state of states) { + for (const state of component.states) { const test = subsuite => { /* Resolve and apply relevant breakpoints */ @@ -129,10 +180,22 @@ const generate = (dirname, components) => { } } +/** + * Register Gemini test suites for the given components + * + * @param {string} dirname - Directory of the test suite + * @param {Array.} components - Component specifications + */ +const register = (dirname, components) => { + if (args.grep) + filter(components) + generate(dirname, components) +} + /* ---------------------------------------------------------------------------- * Exports * ------------------------------------------------------------------------- */ export default { - generate + register } diff --git a/tests/visual/suites/extensions/admonition/suite.js b/tests/visual/suites/extensions/admonition/suite.js index 42b5fd3cb..7bdbb33c5 100644 --- a/tests/visual/suites/extensions/admonition/suite.js +++ b/tests/visual/suites/extensions/admonition/suite.js @@ -32,7 +32,7 @@ import spec from "~/tests/visual/helpers/spec" * The admonition block looks the same on everything above tablet * portrait, so we can save a few test cases. */ -spec.generate(__dirname, { +spec.register(__dirname, { "admonition": { "url": "/", "capture": "#default + .admonition", diff --git a/tests/visual/suites/layout/nav/suite.js b/tests/visual/suites/layout/nav/suite.js index 29d272aa5..aea23679c 100644 --- a/tests/visual/suites/layout/nav/suite.js +++ b/tests/visual/suites/layout/nav/suite.js @@ -41,7 +41,7 @@ const open = () => { /* * Main navigation */ -spec.generate(__dirname, { +spec.register(__dirname, { "md-nav--primary": { "url": "/", "capture": ".md-nav--primary", @@ -84,7 +84,7 @@ spec.generate(__dirname, { /* Last list item */ ":last-child": { "capture": - ".md-nav--primary > .md-nav__list >" + + ".md-nav--primary > .md-nav__list > " + ".md-nav__item:last-child", "break": "+@tablet-landscape", "states": [