UNPKG

ember-cli-yadda-opinionated

Version:

A radical take on Cucumber to solve your test maintenance woes.

342 lines (260 loc) 12.1 kB
/* global server */ import { expect } from 'chai'; import { assert } from '@ember/debug'; import { currentURL, pauseTest, settled } from '@ember/test-helpers'; import { isVisible, pause } from 'ember-cli-yadda-opinionated/test-support/-private/helpers'; import { findEditable, findInputForLabelWithText } from 'ember-cli-yadda-opinionated/test-support/-private/dom-helpers'; import { camelize } from '@ember/string'; import { pluralize } from 'ember-inflector'; import isSubset from 'is-subset/module'; import { STR_STRING_WITH_ESCAPE as opinonatedString } from '../regex'; const steps = { "Then pause(?: for ?(\\d+) ?ms)?"(countRaw) { if (countRaw) { const count = parseInt(countRaw, 10); return pause(count); } else { return pauseTest(); } }, "Then debug(?:ger)?"() { debugger; // eslint-disable-line no-debugger }, async "Then I should (?:still )?be (?:at|on) URL $opinionatedString"(url) { await settled(); expect(currentURL()).to.equal(url); }, async "Then current URL's pathname should be $opinionatedString"(pathname) { await settled(); const url = new URL(currentURL(), location.origin); expect(url.pathname).to.equal(pathname); }, async "Then current URL should (not |NOT )?have query param $opinionatedString"(not, key) { await settled(); const url = new URL(currentURL(), location.origin); expect(url.searchParams.has(key)).to.equal(!!not); }, async "Then current URL should (not |NOT )?have query param $opinionatedString with value $opinionatedString"(not, key, expectedValue) { await settled(); const url = new URL(currentURL(), location.origin); const actualValue = url.searchParams.get(key); not ? expect(actualValue).not.to.equal(expectedValue) : expect(actualValue).to.equal(expectedValue); }, "Then there should be (NO |no )?(?:(\\d+) )?$opinionatedElement"(no, countRaw, [collection/* , label, selector */]) { assert(`Don't use NO and number at the same time`, !(no && countRaw)); let count = no ? 0 : countRaw ? parseInt(countRaw, 10) : 1; expect(collection).to.have.length(count); }, "Then (?:(\\d+) )?$opinionatedElement should (not |NOT )?be visible"(countRaw, [collection/* , label, selector */], no) { assert(`Don't use NOT and number at the same time`, !(no && countRaw)); let count = no ? 0 : countRaw ? parseInt(countRaw, 10) : 1; let m = `Element count`; expect(collection, m).to.have.length(count); collection.forEach((element, i) => { m = `Element #${i} (zero-indexed) visibility`; expect(isVisible(element), m).to.be.true; }); }, "Then I should see (NO |no )?(?:(\\d+) )?$opinionatedElement"(no, countRaw, [collection, label, selector]) { return steps["Then (?:(\\d+) )?$opinionatedElement should (not |NOT )?be visible"](countRaw, [collection, label, selector], no); }, "Then $opinionatedElement should (not |NOT )?(?:have text|say|be) \"(.*)\""([collection/* , label, selector */], not, text) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); const [element] = collection; if (element.matches("input, textarea")) { not ? expect(element).not.to.have.value(text) : expect(element).to.have.value(text); } else { not ? expect(element).not.to.have.trimmed.text(text) : expect(element).to.have.trimmed.text(text); } }, "Then $opinionatedElement should (not |NOT )?(?:match|have text matching) /(.*)/"([collection/* , label, selector */], not, regexString) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); const regex = new RegExp(regexString); const [element] = collection; const text = element.matches("input, textarea") ? element.value : element.textContent.trim(); not ? expect(regex.test(text)).false : expect(regex.test(text)).true; }, "Then $opinionatedElement should (not |NOT )?have the following text:\n$opinionatedText"() { return steps["Then $opinionatedElement should (not |NOT )?(?:have text|say|be) \"(.*)\""](...arguments); }, "Then $opinionatedElement should (not |NOT )?have the following text with collapsed whitespace: $opinionatedString"([collection/* , label, selector */], not, expectedText) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); const [element] = collection; const actualText = element.textContent.trim().replace(/\s+/g, ' '); not ? expect(actualText).not.equal(expectedText) : expect(actualText).equal(expectedText); }, "Then $opinionatedElement should (not |NOT )?have the following text with collapsed whitespace:\n$opinionatedText"([collection/* , label, selector */], not, expectedText) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); const [element] = collection; const actualText = element.textContent.trim().replace(/\s+/g, ' '); expectedText = expectedText.trim().replace(/\s+/g, ' '); not ? expect(actualText).not.equal(expectedText.trim()) : expect(actualText).equal(expectedText.trim()); }, "Then $opinionatedElement should (not |NOT )?have value \"(.*)\""([collection/* , label, selector */], not, value) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); const element = collection[0]; const target = findEditable(element, false); not ? expect(target).not.to.have.value(value) : expect(target).to.have.value(value); }, "Then $opinionatedElement should (not |NOT )?have HTML class \"(.*)\""([collection/* , label, selector */], not, text) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found`, collection.length === 1); not ? expect(collection[0]).not.to.have.class(text) : expect(collection[0]).to.have.class(text); }, [`Then $opinionatedElement should (not |NOT )?have HTML attr $opinionatedString(?: with value ${opinonatedString})?`]([collection/* , label, selector */], not, attrName, attrValue) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1); not ? expect(collection[0]).not.to.have.attr(attrName, attrValue) : expect(collection[0]).to.have.attr(attrName, attrValue); }, [`Then $opinionatedElement should (not |NOT )?have HTML attr $opinionatedString with value matching /(.*)/`]([collection/* , label, selector */], not, attrName, regexString) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1); const regex = new RegExp(regexString); const [element] = collection; const text = element.getAttribute(attrName); if (not && text == null) { return; } not ? expect(regex.test(text)).false : expect(regex.test(text)).true; }, "Then $opinionatedElement should (not |NOT )?have CSS property $opinionatedString with value $opinionatedString"([collection/* , label, selector */], not, propName, expectedValue) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1); const actualValue = collection[0].style[camelize(propName)]; not ? expect(actualValue).not.equal(expectedValue) : expect(actualValue).equal(expectedValue); }, "Then record of type $opinionatedString and id $opinionatedString should have attribute $opinionatedString with value $opinionatedJSON"(typeRaw, idStr, key, value) { const typePlural = pluralize(camelize(typeRaw)); const collection = server.db[typePlural]; assert(`Collection ${typeRaw} does not exist in Mirage DB`, collection); const record = collection.find(idStr); assert(`Record of type ${typeRaw} with id ${idStr} not found in Mirage DB`, record); expect(record[key]).deep.equal(value); }, "Then (?:the )?(?:radio button|checkbox) $opinionatedElement should (not |NOT )?be selected"([collection/* , label, selector */], not) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1); const [element] = collection; let input; if (element.type === 'checkbox' || element.type === 'radio') { input = element; } else { const inputs = element.querySelectorAll('input[type="radio"], input[type="checkbox"]'); assert(`Expected one checkbox/radio, but ${inputs.length} found`, inputs.length === 1); [input] = inputs; } not ? expect(input.checked).to.be.false : expect(input.checked).to.be.true; }, "Then (?:the )?(?:radio button|checkbox) $opinionatedString should (not |NOT )?be selected in $opinionatedElement"(text, not, [collection/* , label, selector */]) { if (not && !collection.length) { return; } assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1); const [element] = collection; const input = findInputForLabelWithText(text, element); assert('Expected input to exist', input) assert('Expected input to be a checkbox or radio button', input.type === 'checkbox' || input.type === 'radio'); not ? expect(input.checked).to.be.false : expect(input.checked).to.be.true; }, "Then local storage value for $opinionatedString should (not |NOT )?be equal to $opinionatedString"(key, not, expectedValue) { const actualValue = window.localStorage.getItem(key); not ? expect(actualValue).not.to.equal(expectedValue) : expect(actualValue).to.equal(expectedValue); }, "Then local storage value for $opinionatedString should (not |NOT )be equal to the following value:\n$opinionatedText": "Then local storage value for $opinionatedString should (not |NOT )?be equal to $opinionatedString", "Then local storage value for $opinionatedString should (not |NOT )be deeply equal to the following JSON:\n$opinionatedJSON"(key, not, expectedJSON) { const actualJSON = JSON.parse(window.localStorage.getItem(key)); not ? expect(actualJSON).not.to.deep.equal(expectedJSON) : expect(actualJSON).to.deep.equal(expectedJSON); }, "Then local storage value for $opinionatedString should (not |NOT )be a subset of the following JSON:\n$opinionatedJSON"(key, not, superset) { const subset = JSON.parse(window.localStorage.getItem(key)); const result = isSubset(superset, subset); not ? expect(result).to.be.false : expect(result).to.be.true; }, "Then local storage value for $opinionatedString should (not |NOT )be a superset of the following JSON:\n$opinionatedJSON"(key, not, subset) { const superset = JSON.parse(window.localStorage.getItem(key)); const result = isSubset(superset, subset); not ? expect(result).to.be.false : expect(result).to.be.true; }, "Then local storage key $opinionatedString should (not |NOT )?exist"(key, not) { const result = window.localStorage.getItem(key); not ? expect(result).to.be.null : expect(result).not.to.be.null; }, "Then local storage should (not |NOT )?be empty"(not) { const result = window.localStorage.key(0); not ? expect(result).not.to.be.null : expect(result).to.be.null; }, }; export default steps;