Better organisation of e2e tests

This commit is contained in:
Josh Johnson 2018-10-13 12:18:02 +01:00
parent 5b68505b1a
commit 2f96c239ff
9 changed files with 355 additions and 288 deletions

View file

@ -1,3 +1,3 @@
{
"baseUrl": "http://localhost:3001"
"baseUrl": "http://localhost:3001/test"
}

View file

@ -1,169 +0,0 @@
describe('Choices', () => {
beforeEach(() => {
cy.visit('/test.html');
});
describe('text element', () => {
const textInput = 'testing';
describe('choices enabled', () => {
describe('adding choices', () => {
it('allows me to input choices', () => {
cy.get('.choices')
.first()
.find('.choices__input--cloned')
.type(textInput)
.type('{enter}');
cy.get('.choices')
.first()
.find('.choices__list .choices__item')
.last()
.should($el => {
expect($el).to.contain(textInput);
});
});
describe('inputting data', () => {
it('shows a dropdown prompt', () => {
cy.get('.choices')
.first()
.find('.choices__input--cloned')
.type(textInput);
cy.get('.choices')
.first()
.find('.choices__list--dropdown')
.should('be.visible')
.should($dropdown => {
const dropdownText = $dropdown.text().trim();
expect(dropdownText).to.equal(
`Press Enter to add "${textInput}"`,
);
});
});
});
describe('input limit', () => {
beforeEach(() => {
for (let index = 0; index < 6; index++) {
cy.get('.choices')
.first()
.find('.choices__input--cloned')
.type(`${textInput} + ${index}`)
.type('{enter}');
}
});
it('does not let me input more than 5 choices', () => {
cy.get('.choices')
.first()
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(5);
});
});
it('hides dropdown prompt once limit has been reached', () => {
cy.get('.choices')
.first()
.find('.choices__list--dropdown')
.should('not.be.visible');
});
});
describe('unique values', () => {
beforeEach(() => {
cy.get('.choices')
.eq(1) // second choices instance
.find('.choices__input--cloned')
.type(`${textInput}`)
.type('{enter}')
.type(`${textInput}`)
.type('{enter}');
});
it('only allows me to input unique values', () => {
cy.get('.choices')
.eq(1)
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(1);
});
});
describe('inputting a non-unique value', () => {
it('displays dropdown prompt', () => {
cy.get('.choices')
.eq(1)
.find('.choices__list--dropdown')
.should('be.visible')
.should($dropdown => {
const dropdownText = $dropdown.text().trim();
expect(dropdownText).to.equal(
'Only unique values can be added.',
);
});
});
});
});
});
describe('removing choices', () => {
beforeEach(() => {
cy.get('.choices')
.first() // second choices instance
.find('.choices__input--cloned')
.type(`${textInput}`)
.type('{enter}')
.type(`${textInput}`)
.type('{enter}');
});
it('allows me to remove inputted choices', () => {
cy.get('.choices')
.first()
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(2);
});
cy.get('.choices')
.first()
.find('.choices__list--multiple .choices__item')
.last()
.find('.choices__button')
.focus()
.click();
cy.get('.choices')
.first()
.find('.choices__list--multiple')
.first()
.should($items => {
expect($items.length).to.equal(1);
});
});
});
});
describe('choices disabled', () => {
it('does not allow me to input data', () => {
cy.get('.choices')
.eq(3)
.find('.choices__input--cloned')
.should('be.disabled');
});
});
});
describe('select-one element', () => {});
describe('select-multiple element', () => {});
});

View file

@ -0,0 +1,213 @@
describe('Choices - text element', () => {
beforeEach(() => {
cy.visit('/text.html');
});
describe('configs', () => {
const textInput = 'testing';
describe('basic', () => {
describe('adding choices', () => {
it('allows me to input choices', () => {
cy.get('[data-test-hook=basic]')
.find('.choices__input--cloned')
.type(textInput)
.type('{enter}');
cy.get('[data-test-hook=basic]')
.find('.choices__list--multiple .choices__item')
.last()
.should($el => {
expect($el).to.contain(textInput);
});
});
it('updates the value of the original input', () => {
cy.get('[data-test-hook=basic]')
.find('.choices__input--cloned')
.type(textInput)
.type('{enter}');
cy.get('[data-test-hook=basic]')
.find('.choices__input.is-hidden')
.should('have.value', textInput);
});
describe('inputting data', () => {
it('shows a dropdown prompt', () => {
cy.get('[data-test-hook=basic]')
.find('.choices__input--cloned')
.type(textInput);
cy.get('[data-test-hook=basic]')
.find('.choices__list--dropdown')
.should('be.visible')
.should($dropdown => {
const dropdownText = $dropdown.text().trim();
expect(dropdownText).to.equal(
`Press Enter to add "${textInput}"`,
);
});
});
});
});
describe('removing choices', () => {
beforeEach(() => {
cy.get('[data-test-hook=basic]')
.find('.choices__input--cloned')
.type(`${textInput}`)
.type('{enter}')
.type(`${textInput}`)
.type('{enter}');
});
it('allows me to remove inputted choices', () => {
cy.get('[data-test-hook=basic]')
.find('.choices__list--multiple')
.children()
.should($items => {
expect($items.length).to.equal(2);
});
cy.get('[data-test-hook=basic]')
.find('.choices__list--multiple .choices__item')
.last()
.find('.choices__button')
.focus()
.click();
cy.get('[data-test-hook=basic]')
.find('.choices__list--multiple')
.first()
.should($items => {
expect($items.length).to.equal(1);
});
});
});
});
describe('unique values only', () => {
describe('unique values', () => {
beforeEach(() => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__input--cloned')
.type(`${textInput}`)
.type('{enter}')
.type(`${textInput}`)
.type('{enter}');
});
it('only allows me to input unique values', () => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(1);
});
});
describe('inputting a non-unique value', () => {
it('displays dropdown prompt', () => {
cy.get('[data-test-hook=unique-values]')
.find('.choices__list--dropdown')
.should('be.visible')
.should($dropdown => {
const dropdownText = $dropdown.text().trim();
expect(dropdownText).to.equal(
'Only unique values can be added.',
);
});
});
});
});
});
describe('input limit', () => {
beforeEach(() => {
for (let index = 0; index < 6; index++) {
cy.get('[data-test-hook=input-limit]')
.find('.choices__input--cloned')
.type(`${textInput} + ${index}`)
.type('{enter}');
}
});
it('does not let me input more than 5 choices', () => {
cy.get('[data-test-hook=input-limit]')
.find('.choices__list--multiple')
.first()
.children()
.should($items => {
expect($items.length).to.equal(5);
});
});
it('hides dropdown prompt once limit has been reached', () => {
cy.get('[data-test-hook=input-limit]')
.find('.choices__list--dropdown')
.should('not.be.visible');
});
});
describe('regex filter', () => {
describe('a valid that satisfies regex', () => {
const input = 'joe@bloggs.com';
it('allows me to add choice', () => {
cy.get('[data-test-hook=regex-filter]')
.find('.choices__input--cloned')
.type(input)
.type('{enter}');
cy.get('[data-test-hook=regex-filter]')
.find('.choices__list .choices__item')
.last()
.should($choice => {
expect($choice).to.contain(input);
});
});
});
describe('inputting a value that does not satisfy the regex', () => {
it('displays dropdown prompt', () => {
cy.get('[data-test-hook=regex-filter]')
.find('.choices__input--cloned')
.type(`this is not an email address`)
.type('{enter}');
cy.get('[data-test-hook=regex-filter]')
.find('.choices__list--dropdown')
.should('not.be.visible');
});
});
});
describe('prepend/append', () => {
beforeEach(() => {
cy.get('[data-test-hook=prepend-append]')
.find('.choices__input--cloned')
.type(textInput)
.type('{enter}');
});
it('prepends and appends value to inputted value', () => {
cy.get('[data-test-hook=prepend-append]')
.find('.choices__list--multiple .choices__item')
.last()
.should($choice => {
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
});
});
});
describe('disabled', () => {
it('does not allow me to input data', () => {
cy.get('[data-test-hook=disabled]')
.find('.choices__input--cloned')
.should('be.disabled');
});
});
});
});

View file

@ -5,7 +5,7 @@
"main": "./public/assets/scripts/choices.min.js",
"types": "./types/index.d.ts",
"scripts": {
"start": "NODE_ENV=development node server.js",
"start": "run-p js:watch css:watch",
"build": "npm run js:build && npm run css:build",
"lint": "eslint assets/**/*.js",
"coverage": "nyc npm run test",
@ -14,6 +14,8 @@
"test:unit": "mocha --require ./config/test.js --compilers js:babel-core/register \"./src/**/**/**/**/*.test.js\" --exit",
"test:unit:watch": "npm run test -- --watch --inspect=5556",
"test:e2e": "run-p --race start cypress:run",
"test": "run-p test:unit test:e2e",
"js:watch": "NODE_ENV=development node server.js",
"js:build:minimised": "webpack --env.minimize --config webpack.config.prod.js",
"js:build:unminimised": "webpack --config webpack.config.prod.js",
"js:build": "run-p js:build:minimised js:build:unminimised",
@ -67,7 +69,7 @@
"husky": "^0.14.3",
"jsdom": "^11.5.1",
"mocha": "^3.4.2",
"node-sass": "^3.4.2",
"node-sass": "^4.9.3",
"nodemon": "^1.9.1",
"npm-run-all": "^4.1.3",
"nyc": "^11.0.3",

View file

@ -172,4 +172,8 @@ h6,
display: none;
}
[data-test-hook] {
margin-bottom: 24px;
}
/*===== End of Section comment block ======*/

View file

@ -1 +1 @@
*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,:after,:before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label{margin-bottom:8px;font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#00bcd4}.logo{display:block;margin-bottom:12px}.logo__img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}.is-hidden{display:none}
*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,:after,:before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label{margin-bottom:8px;font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#00bcd4}.logo{display:block;margin-bottom:12px}.logo__img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}.is-hidden{display:none}[data-test-hook]{margin-bottom:24px}

View file

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>Choices</title>
<meta name=description itemprop=description content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.">
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/apple-touch-icon.png">
<link rel="icon" type="image/png" href="assets/images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="assets/images/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="assets/images/manifest.json">
<link rel="mask-icon" href="assets/images/safari-pinned-tab.svg" color="#00bcd4">
<link rel="shortcut icon" href="assets/images/favicon.ico">
<meta name="msapplication-config" content="/assets/images/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<!-- Ignore these -->
<link rel="stylesheet" href="assets/styles/base.min.css?version=3.0.2">
<!-- End ignore these -->
<!-- Optional includes -->
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=es5,fetch,Element.prototype.classList,requestAnimationFrame,Node.insertBefore,Node.firstChild,Object.assign"></script>
<!-- End optional includes -->
<!-- Choices includes -->
<link rel="stylesheet" href="assets/styles/choices.min.css?version=3.0.2">
<script src="assets/scripts/choices.min.js?version=2.8.8"></script>
<!-- End Choices includes -->
<!--[if lt IE 9]>
<style>
.hidden-ie { display: none; }
.visible-ie { display: block; }
</style>
<![endif]-->
</head>
<body>
<div class="container">
<div class="section">
<a href="https://github.com/jshjohnson/Choices" class="logo">
<img src="assets/images/logo.svg" alt="Choices.js logo" class="logo__img hidden-ie">
<h1 class="visible-ie">Choices.js</h1>
</a>
<h2>Text inputs</h2>
<label for="choices-text-remove-button">Limited to 5 values with remove button</label>
<input class="form-control" id="choices-text-remove-button" type="text" placeholder="Enter something">
<label for="choices-text-unique-values">Unique values only, no pasting</label>
<input class="form-control" id="choices-text-unique-values" type="text" placeholder="This is a placeholder"
class="custom class">
<label for="choices-text-email-filter">Email addresses only</label>
<input class="form-control" id="choices-text-email-filter" type="text" placeholder="This is a placeholder">
<label for="choices-text-disabled">Disabled</label>
<input class="form-control" id="choices-text-disabled" type="text" placeholder="This is a placeholder">
<label for="choices-text-prepend-append-value">Prepends and appends a value to each items return value</label>
<input class="form-control" id="choices-text-prepend-append-value" type="text" placeholder="This is a placeholder">
<hr>
<h2>Multiple select input</h2>
<hr>
<h2>Single select input</h2>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var textRemove = new Choices('#choices-text-remove-button', {
delimiter: ',',
editItems: true,
maxItemCount: 5,
removeItemButton: true,
});
var textUniqueVals = new Choices('#choices-text-unique-values', {
paste: false,
duplicateItemsAllowed: false,
editItems: true,
});
var textEmailFilter = new Choices('#choices-text-email-filter', {
editItems: true,
regexFilter: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
});
var textDisabled = new Choices('#choices-text-disabled', {
addItems: false,
removeItems: false,
}).disable();
var textPrependAppendVal = new Choices('#choices-text-prepend-append-value', {
prependValue: 'item-',
appendValue: '-' + Date.now(),
}).removeActiveItems();
});
</script>
<!-- Google Analytics - Ignore me -->
<script>
window.ga = window.ga || function() { (ga.q = ga.q || []).push(arguments) }; ga.l = +new Date;
ga('create', 'UA-31575166-1', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
</body>
</html>

128
public/test/text.html Normal file
View file

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>Choices</title>
<meta name=description itemprop=description content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.">
<link rel="apple-touch-icon" sizes="180x180" href="../assets/images/apple-touch-icon.png">
<link rel="icon" type="image/png" href="../assets/images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="../assets/images/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="../assets/images/manifest.json">
<link rel="mask-icon" href="../assets/images/safari-pinned-tab.svg" color="#00bcd4">
<link rel="shortcut icon" href="../assets/images/favicon.ico">
<meta name="msapplication-config" content="../assets/images/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<!-- Ignore these -->
<link rel="stylesheet" href="../assets/styles/base.min.css?version=3.0.2">
<!-- End ignore these -->
<!-- Optional includes -->
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=es5,fetch,Element.prototype.classList,requestAnimationFrame,Node.insertBefore,Node.firstChild,Object.assign"></script>
<!-- End optional includes -->
<!-- Choices includes -->
<link rel="stylesheet" href="../assets/styles/choices.min.css?version=3.0.2">
<script src="../assets/scripts/choices.min.js?version=2.8.8"></script>
<!-- End Choices includes -->
<!--[if lt IE 9]>
<style>
.hidden-ie { display: none; }
.visible-ie { display: block; }
</style>
<![endif]-->
</head>
<body>
<div class="container">
<div class="section">
<a href="https://github.com/jshjohnson/Choices" class="logo">
<img src="../assets/images/logo.svg" alt="Choices.js logo" class="logo__img hidden-ie">
<h1 class="visible-ie">Choices.js</h1>
</a>
<h2>Text inputs</h2>
<div data-test-hook="basic">
<label for="choices-basic">Basic</label>
<input class="form-control" id="choices-basic" type="text" placeholder="Enter something">
</div>
<div data-test-hook="unique-values">
<label for="choices-unique-values">Unique values</label>
<input class="form-control" id="choices-unique-values" type="text" placeholder="This is a placeholder">
</div>
<div data-test-hook="input-limit">
<label for="choices-input-limit">Input limit</label>
<input class="form-control" id="choices-input-limit" type="text" placeholder="This is a placeholder">
</div>
<div data-test-hook="regex-filter">
<label for="choices-regex-filter">Regex filter</label>
<input class="form-control" id="choices-regex-filter" type="text" placeholder="This is a placeholder">
</div>
<div data-test-hook="disabled">
<label for="choices-disabled">Disabled</label>
<input class="form-control" id="choices-disabled" type="text" placeholder="This is a placeholder">
</div>
<div data-test-hook="prepend-append">
<label for="choices-prepend-append">Prepend/append</label>
<input class="form-control" id="choices-prepend-append" type="text" placeholder="This is a placeholder">
</div>
<hr>
<h2>Multiple select input</h2>
<hr>
<h2>Single select input</h2>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
new Choices('#choices-basic', {
editItems: true,
removeItemButton: true,
});
new Choices('#choices-unique-values', {
duplicateItemsAllowed: false,
});
new Choices('#choices-input-limit', {
maxItemCount: 5,
});
new Choices('#choices-regex-filter', {
regexFilter: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
});
new Choices('#choices-disabled', {
addItems: false,
removeItems: false,
}).disable();
new Choices('#choices-prepend-append', {
prependValue: 'before-',
appendValue: '-after',
});
});
</script>
<!-- Google Analytics - Ignore me -->
<script>
window.ga = window.ga || function() { (ga.q = ga.q || []).push(arguments) }; ga.l = +new Date;
ga('create', 'UA-31575166-1', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
</body>
</html>

View file

@ -176,4 +176,8 @@ h6,
display: none;
}
[data-test-hook] {
margin-bottom: $global-guttering;
}
/*===== End of Section comment block ======*/