Added tests for navigation and improved test generation logic

This commit is contained in:
squidfunk 2017-02-01 23:56:57 +01:00
parent 87c440c003
commit 8a7d9001fd
18 changed files with 324 additions and 215 deletions

2
.gitignore vendored
View File

@ -23,7 +23,7 @@
# NPM-related # NPM-related
/node_modules /node_modules
/npm-debug.log /npm-debug.log*
# Files generated by build # Files generated by build
/build /build

View File

@ -34,6 +34,13 @@ let server = null
* Functions * Functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/**
* Start static file server
*
* @param {string} directory - Directory to serve
* @param {number} port - Port to listen on
* @param {Function} done - Resolve callback
*/
export const start = (directory, port, done) => { export const start = (directory, port, done) => {
server = http.createServer(ecstatic({ server = http.createServer(ecstatic({
root: directory root: directory
@ -45,6 +52,11 @@ export const start = (directory, port, done) => {
process.on(signal, stop) process.on(signal, stop)
} }
/**
* Stop static file server
*
* @param {Function} done - Resolve callback
*/
export const stop = done => { export const stop = done => {
server.close(done) server.close(done)
} }

View File

@ -33,6 +33,11 @@ let server = null
* Definition * Definition
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/**
* Start Selenium
*
* @param {Function} done - Resolve callback
*/
export const start = done => { export const start = done => {
selenium.start({}, (err, proc) => { selenium.start({}, (err, proc) => {
@ -67,13 +72,16 @@ export const start = done => {
}) })
} }
/**
* Stop Selenium
*
* @param {Function} done - Resolve callback
*/
export const stop = done => { export const stop = done => {
if (server) { if (server) {
if (typeof done === "function") if (typeof done === "function")
server.on("exit", done) server.on("exit", done)
server.kill() server.kill()
/* Unset, so we don't try to kill the server twice */
server = null server = null
} }
} }

View File

@ -56,7 +56,9 @@ export default (gulp, config, args) => {
autoprefixer(), autoprefixer(),
mqpacker mqpacker
].concat(!args.optimize ? [ ].concat(!args.optimize ? [
pseudoclasses() pseudoclasses({
"restrictTo": ["hover", "focus"]
})
] : []))) ] : [])))
/* Minify sources */ /* Minify sources */

View File

@ -29,9 +29,8 @@ import util from "gulp-util"
* Task: generate visual tests * Task: generate visual tests
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
export default (gulp, config, args) => { export default (gulp, config) => {
const theme = path.resolve(process.cwd(), config.views.build) const theme = path.resolve(process.cwd(), config.views.build)
const match = new RegExp(args.grep || "", "i")
return () => { return () => {
return gulp.src(`${config.tests.visual}/suites/**/mkdocs.yml`) return gulp.src(`${config.tests.visual}/suites/**/mkdocs.yml`)
.pipe( .pipe(
@ -46,7 +45,6 @@ export default (gulp, config, args) => {
`${config.tests.visual}/data`, name, "_") `${config.tests.visual}/data`, name, "_")
/* Generate test fixtures with freshly built theme */ /* Generate test fixtures with freshly built theme */
if (match.test(name)) {
const proc = child.spawnSync("mkdocs", [ const proc = child.spawnSync("mkdocs", [
"build", "--site-dir", site, "--theme-dir", theme "build", "--site-dir", site, "--theme-dir", theme
], { ], {
@ -57,7 +55,6 @@ export default (gulp, config, args) => {
if (proc.status) if (proc.status)
this.emit("error", new util.PluginError("mkdocs", this.emit("error", new util.PluginError("mkdocs",
`Terminated with errors: ${proc.stderr.toString()}`)) `Terminated with errors: ${proc.stderr.toString()}`))
}
/* Terminate */ /* Terminate */
done() done()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@
{% else %} {% else %}
<link rel="shortcut icon" href="{{ base_url }}/assets/images/favicon.ico"> <link rel="shortcut icon" href="{{ base_url }}/assets/images/favicon.ico">
{% endif %} {% endif %}
<meta name="generator" content="mkdocs+mkdocs-material#1.0.3"> <meta name="generator" content="mkdocs-{{ mkdocs_version }}, mkdocs-material-1.0.3">
{% endblock %} {% endblock %}
{% block htmltitle %} {% block htmltitle %}
{% if page.title %} {% if page.title %}
@ -45,7 +45,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
{% endblock %} {% endblock %}
{% block styles %} {% block styles %}
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-e21055ee85.css"> <link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-180dae0b60.css">
{% if config.extra.palette %} {% if config.extra.palette %}
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css"> <link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css">
{% endif %} {% endif %}

View File

@ -84,7 +84,7 @@
} }
} }
// Icon buttons // Button with logo
&__button { &__button {
@extend %md-icon, %md-icon__button; @extend %md-icon, %md-icon__button;
@ -140,7 +140,8 @@
color: $md-color-primary; color: $md-color-primary;
} }
// Hovered item // Focused or hovered item
&:focus,
&:hover { &:hover {
color: $md-color-accent; color: $md-color-accent;
} }

View File

@ -56,7 +56,8 @@
{% endif %} {% endif %}
<!-- Generator banner --> <!-- Generator banner -->
<meta name="generator" content="mkdocs+$theme-name$#$theme-version$" /> <meta name="generator"
content="mkdocs-{{ mkdocs_version }}, $theme-name$-$theme-version$" />
{% endblock %} {% endblock %}
<!-- Block: site title --> <!-- Block: site title -->

View File

@ -1,29 +1,30 @@
/* /*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com> * Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import config from "../config.json" import config from "../config.json"
import path from "path"
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Helper * Functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/** /**
@ -59,14 +60,14 @@ const resolve = (breakpoints, expr) => {
return breakpoints.slice(from, to) return breakpoints.slice(from, to)
} }
/* ---------------------------------------------------------------------------- /**
* Functions * Generate a Gemini test suite for the component
* ------------------------------------------------------------------------- */ *
* @param {string} dirname - Directory of the test suite
/* * @param {Array.<object>} components - Component specifications // TODO: document syntax and specificagtion
* TODO
*/ */
const generate = components => { const generate = (dirname, components) => {
const base = path.relative(`${__dirname}/../suites`, dirname)
/* Generate a suite for every component */ /* Generate a suite for every component */
for (const name of Object.keys(components)) { for (const name of Object.keys(components)) {
@ -75,78 +76,61 @@ const generate = components => {
/* Create suite */ /* Create suite */
gemini.suite(name, suite => { gemini.suite(name, suite => {
if (component.url) if (component.url)
suite.setUrl(component.url) suite.setUrl(path.join(base, component.url, "_"))
/* The capture selector is assumed to exist */ /* The capture selector is assumed to exist */
suite.setCaptureElements(component.capture) suite.setCaptureElements(component.capture)
/* Generate a subsuite for every state */
const states = component.states || [{ name: "", wait: 0 }]
for (const state of states) {
const test = subsuite => {
/* Resolve and apply relevant breakpoints */ /* Resolve and apply relevant breakpoints */
const breakpoints = resolve(config.breakpoints, component.break) const breakpoints = resolve(config.breakpoints, component.break)
for (const breakpoint of breakpoints) { for (const breakpoint of breakpoints) {
suite.capture(`@${breakpoint.name}`, actions => { subsuite.capture(`@${breakpoint.name}`, actions => {
actions.setWindowSize(breakpoint.size.width, breakpoint.size.height)
/* Set window size according to breakpoint */
actions.setWindowSize(
breakpoint.size.width, breakpoint.size.height)
/* Add the name as a CSS class to the captured element */
if (state.name)
actions.executeJS(new Function(`
document.querySelector(
"${component.capture}"
).classList.add("${state.name}")
`))
/* Execute function inside an IIFE */
if (state.exec)
actions.executeJS(new Function(`(${state.exec})()`))
/* Wait the specified time before taking a screenshot */
if (state.wait)
actions.wait(state.wait)
}) })
} }
}
/* No state sub-suite if the name is empty */
if (state.name.length > 0)
gemini.suite(state.name, subsuite => test(subsuite))
else
test(suite)
}
/* Generate sub-suites */ /* Generate sub-suites */
generate(component.suite || {}) generate(dirname, component.suite || {})
}) })
/* Set component states to default, if none given */
// const states = component.states
// ? component.states
// : [{ name: "", wait: 0 }]
//
// let done = 0
// for (const state of states) {
// gemini.suite(`${name}${state.name}`, suite => {
//
// /* Set URL of page to capture */
// if (component.url)
// suite.setUrl(component.url)
//
// /* Set elements to capture */
// if (component.capture)
// suite.setCaptureElements(component.capture)
//
// // TODO: otherwise throw error
// if (component.break) {
// const breakpoints = resolve(config.breakpoints, component.break)
//
// // iterate breakpoints
// for (const breakpoint of breakpoints) {
// suite.capture(`@${breakpoint.name}`, actions => {
// actions.setWindowSize(
// breakpoint.size.width, breakpoint.size.height)
// if (state.wait)
// actions.wait(state.wait)
// if (state.name) {
// // eval, as its executed at the frontend
// if (typeof state.name === "string") {
// actions.executeJS(new Function(`
// document.querySelector(
// "${component.capture}"
// ).classList.add("${state.name}")
// `)
// )
// } else {
// actions.executeJS(state.name)
// }
// }
// })
// }
// }
//
// // nested suites
// if (!done && component.suite) {
// done = 1
// generate(component.suite)
// }
// })
// }
} }
} }
/* ----------------------------------------------------------------------------
* Exports
* ------------------------------------------------------------------------- */
export default { export default {
generate generate
} }

View File

@ -1,24 +1,24 @@
/* /*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com> * Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import spec from "~/tests/visual/helpers/spec" import spec from "~/tests/visual/helpers/spec"
@ -27,14 +27,14 @@ import spec from "~/tests/visual/helpers/spec"
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/* /*
* Admonition block * Admonition extension
* *
* The admonition block looks the same on everything above tablet * The admonition block looks the same on everything above tablet
* portrait, so we can save a few test cases. * portrait, so we can save a few test cases.
*/ */
spec.generate({ spec.generate(__dirname, {
"admonition": { "admonition": {
"url": "/extensions/admonition/_", "url": "/",
"capture": "#default + .admonition", "capture": "#default + .admonition",
"break": "-@tablet-portrait", "break": "-@tablet-portrait",
"suite": { "suite": {

View File

@ -0,0 +1 @@
# Suite

View File

@ -0,0 +1,28 @@
# Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# Test suite
site_name: Pneumonoultramicroscopicsilicovolcanoconiosis
pages:
- Pneumonoultramicroscopicsilicovolcanoconiosis: index.md
- Supercalifragilisticexpialidocious:
- Pseudopseudohypoparathyroidism: empty.md
- Floccinaucinihilipilification: empty.md
- Antidisestablishmentarianism: empty.md

View File

@ -1,58 +1 @@
# Suite # Suite
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam condimentum
lacinia urna id vestibulum. Maecenas tincidunt nulla dui, a dapibus turpis
iaculis at. Donec tortor sem, scelerisque ut congue id, pretium ac risus.
Vivamus ac quam semper, elementum neque nec, dictum sem. Nullam porttitor in
ipsum quis sagittis. Cras viverra egestas purus ullamcorper eleifend. Nunc id
facilisis magna, id sagittis metus. Suspendisse egestas, ipsum sed consectetur
pretium, mauris tortor eleifend sem, vel cursus diam augue at diam. Nullam
accumsan id sapien feugiat ultrices. Cras tempor nulla a maximus dignissim.
Aliquam sed orci et elit tempor bibendum ac non neque. Aliquam erat volutpat.
Duis eu ligula ullamcorper, tristique libero in, eleifend turpis. Cras
fermentum iaculis ipsum, vitae viverra enim posuere vel. Phasellus non
fermentum arcu. Donec pulvinar erat non tellus rhoncus, bibendum interdum
libero ornare.
Etiam vel commodo turpis. Proin imperdiet ante eu suscipit ullamcorper.
Vivamus pharetra, mauris nec bibendum suscipit, dui velit vehicula purus,
sit amet pretium ex felis quis tellus. Nunc urna purus, dignissim in justo
quis, tempus sollicitudin odio. Morbi in commodo leo. Vestibulum fringilla
arcu quis venenatis venenatis. Phasellus vitae est at magna aliquam hendrerit.
Sed egestas, dui sit amet convallis porttitor, velit lectus molestie ipsum,
non ullamcorper erat elit vitae purus. In pulvinar nisl sed nulla placerat,
ac sollicitudin felis varius. Nunc orci quam, cursus ut fermentum eu,
interdum id dolor. Etiam tincidunt est elit, at tempus ligula pretium quis.
In vitae leo ullamcorper, lobortis nibh at, varius risus. Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Sed risus neque, mattis a urna in, gravida
bibendum odio. Quisque enim nunc, auctor id justo a, viverra tempor dolor.
Duis molestie sagittis justo, id euismod mauris volutpat et. Suspendisse sed
leo vitae eros pulvinar scelerisque ut eu dolor. Nam at sapien dui. Integer
mattis faucibus metus. Pellentesque habitant morbi tristique senectus et netus
et malesuada fames ac turpis egestas. Mauris non sapien eleifend, eleifend
lectus at, elementum metus. Maecenas in tortor ut dui venenatis venenatis
sed id erat. Duis felis leo, eleifend a orci a, iaculis hendrerit arcu.
Praesent eget tellus tellus. Mauris eleifend mauris vitae porta laoreet. Morbi
venenatis, eros consectetur faucibus sodales, sapien purus interdum erat, quis
ultricies lacus odio sit amet tellus. Sed tincidunt est vitae sapien tempor
elementum.
Morbi ac eros ultrices, pulvinar ante ut, gravida risus. Integer id dolor
rhoncus odio scelerisque vestibulum. Integer justo felis, finibus congue felis
in, efficitur bibendum libero. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Aenean dignissim enim ac justo cursus condimentum. Class
aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Morbi euismod pulvinar lacus sit amet egestas. Praesent in ex
molestie, scelerisque diam id, malesuada mauris. Vivamus at magna eu tellus
cursus hendrerit eu nec felis. Suspendisse ut hendrerit ex. Nulla semper quam
nec tincidunt vestibulum. Donec non nibh elit. Donec neque lacus, consequat
vitae nibh et, faucibus mollis dolor.
Nunc tempus lectus odio, sed laoreet elit suscipit et. Cras rutrum nibh eget
tellus tempus, et sodales sapien varius. Nam quis mi sagittis lacus commodo
cursus et viverra nibh. Vivamus ut egestas ante. Proin scelerisque tortor
turpis, at facilisis tortor feugiat mollis. Suspendisse neque odio, efficitur
quis ipsum a, tristique rutrum purus. Fusce ac tellus in magna eleifend
aliquet. Aliquam lectus libero, varius id nibh a, gravida fermentum est.
Aliquam erat volutpat.

View File

@ -19,8 +19,13 @@
# IN THE SOFTWARE. # IN THE SOFTWARE.
# Test suite # Test suite
site_name: Navigation Test site_name: Test/Navigation
pages: pages:
- Lorem ipsum dolor sit amet: index.md - Lorem ipsum dolor sit amet: index.md
- Consectetur adipiscing elit: empty.md - Consectetur adipiscing elit: empty.md
- Etiam condimentum lacinia urna id vestibulum: empty.md - Etiam condimentum lacinia urna id vestibulum: empty.md
- Maecenas tincidunt nulla dui: empty.md
- A dapibus turpis iaculis at:
- Donec tortor sem: empty.md
- Scelerisque ut congue id: empty.md
- Pretium ac risus: empty.md

View File

@ -1,37 +1,164 @@
/* /*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com> * Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import spec from "~/tests/visual/helpers/spec" import spec from "~/tests/visual/helpers/spec"
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Open the drawer
*/
const open = () => {
const drawer = document.querySelector("[data-md-toggle=\"drawer\"]")
drawer.checked = true
}
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Tests * Tests
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/* /*
* TODO * Main navigation
*/ */
spec.generate({ spec.generate(__dirname, {
"md-nav--primary": { "md-nav--primary": {
"url": "/layout/nav/_", "url": "/",
"capture": ".md-nav--primary" "capture": ".md-nav--primary",
"states": [
{ "name": "", "wait": 250, "exec": open }
],
"suite": {
/* List title */
"md-nav__title": {
"capture": ".md-nav--primary .md-nav__title",
"states": [
{ "name": "", "wait": 250, "exec": open }
],
"suite": {
/* Long list title with ellipsis */
"~overflow": {
"url": "/_overflow",
"capture": ".md-nav--primary .md-nav__title",
"states": [
{ "name": "", "wait": 250, "exec": open }
]
}
}
},
/* List of items */
"md-nav__list": {
"capture": ".md-nav--primary .md-nav__list",
"states": [
{ "name": "", "wait": 250, "exec": open }
]
},
/* List item */
"md-nav__item": {
"capture": ".md-nav--primary .md-nav__item",
"states": [
{ "name": "", "wait": 250, "exec": open }
],
"suites": {
/* Last list item */
":last-child": {
"capture":
".md-nav--primary > .md-nav__list >" +
".md-nav__item:last-child",
"states": [
{ "name": "", "wait": 250, "exec": open }
]
}
}
},
/* Item contains a nested list */
"md-nav__item--nested": {
"capture": ".md-nav--primary .md-nav__item--nested",
"states": [
{ "name": "", "wait": 250, "exec": open }
],
"suites": {
/* Link inside item that contains a nested list */
"md-nav__link": {
"capture":
".md-nav--primary .md-nav__item--nested " +
".md-nav__link",
"states": [
{ "name": "", "wait": 250, "exec": open },
{ "name": ":focus", "wait": 250, "exec": open },
{ "name": ":hover", "wait": 250, "exec": open }
]
},
/* Active link inside item that contains a nested list */
"md-nav__link--active": {
"capture":
".md-nav--primary .md-nav__item--nested " +
".md-nav__link--active",
"states": [
{ "name": "", "wait": 250, "exec": open },
{ "name": ":focus", "wait": 250, "exec": open },
{ "name": ":hover", "wait": 250, "exec": open }
]
}
}
},
/* Button with logo */
"md-nav__button": {
"capture": ".md-nav--primary .md-nav__button",
"break": "-@tablet-landscape",
"states": [
{ "name": "", "wait": 250, "exec": open }
]
},
/* Link inside item */
"md-nav__link": {
"capture": ".md-nav--primary .md-nav__item:nth-child(2) .md-nav__link",
"states": [
{ "name": "", "wait": 250, "exec": open },
{ "name": ":focus", "wait": 250, "exec": open },
{ "name": ":hover", "wait": 250, "exec": open }
]
},
/* Active link */
"md-nav__link--active": {
"capture": ".md-nav--primary .md-nav__link--active",
"states": [
{ "name": "", "wait": 250, "exec": open },
{ "name": ":focus", "wait": 250, "exec": open },
{ "name": ":hover", "wait": 250, "exec": open }
]
}
}
} }
}) })