From 3b46b6724787cf2a2580ff482c9e41497bbe0b63 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Tue, 11 May 2021 10:15:20 +0800 Subject: [PATCH] Unify tests Attempt to unify tests for Jest and Cypress. --- cypress.json | 2 +- jest.config.js | 2 +- package.json | 5 +- src/index.test.ts | 90 ---------------- src/index.ts | 84 ++------------- test/fixtures/templates/blank.html | 4 +- test/integration/blank.test.ts | 23 ++++ test/integration/everything.test.ts | 42 ++++++++ test/integration/single.test.ts | 114 ++++++++++++++++++++ test/integrations/blank.e2e.ts | 29 ----- test/integrations/everything.e2e.ts | 104 ------------------ test/integrations/single.e2e.ts | 162 ---------------------------- test/support/index.ts | 1 + test/utils/index.ts | 70 +++++++++++- test/utils/search.ts | 12 --- yarn.lock | 145 ++++++++++++++++++++++++- 16 files changed, 402 insertions(+), 487 deletions(-) delete mode 100644 src/index.test.ts create mode 100644 test/integration/blank.test.ts create mode 100644 test/integration/everything.test.ts create mode 100644 test/integration/single.test.ts delete mode 100644 test/integrations/blank.e2e.ts delete mode 100644 test/integrations/everything.e2e.ts delete mode 100644 test/integrations/single.e2e.ts diff --git a/cypress.json b/cypress.json index 1681f1d..d9bbdde 100644 --- a/cypress.json +++ b/cypress.json @@ -1,6 +1,6 @@ { "fixturesFolder": "test/fixtures", - "integrationFolder": "test/integrations", + "integrationFolder": "test/integration", "pluginsFile": "test/plugins/index.ts", "supportFile": "test/support/index.ts" } diff --git a/jest.config.js b/jest.config.js index 25c9bac..4931934 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,3 @@ module.exports = { - testEnvironment: 'node', + testEnvironment: 'jsdom', }; diff --git a/package.json b/package.json index d01413b..791a4f2 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "scripts": { "start": "tsdx watch", "build": "tsdx build", - "test": "tsdx test", + "test:jsdom": "tsdx test", + "test:dom": "cypress open", "lint": "tsdx lint", - "e2e": "cypress open", "prepare": "tsdx build", "size": "size-limit", "analyze": "size-limit --why" @@ -49,6 +49,7 @@ "@size-limit/preset-small-lib": "^4.10.2", "@types/jsdom": "^16.2.10", "cypress": "^7.2.0", + "cypress-jest-adapter": "^0.1.1", "husky": "^6.0.0", "jsdom": "^16.5.3", "size-limit": "^4.10.2", diff --git a/src/index.test.ts b/src/index.test.ts deleted file mode 100644 index 08081bc..0000000 --- a/src/index.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as fixtures from '../test/utils' -import getFormValues from '.' -import {DOMWindow, JSDOM} from 'jsdom'; - -describe('blank template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('blank')).window - }) - it('should have blank form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({}) - }) -}) - -describe('single input template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('single-input')).window - }) - it('should have a single form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({ hello: 'Hi' }) - }) -}) - -describe('single disabled input template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('single-disabled-input')).window - }) - it('should have blank form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({}) - }) -}) - -describe('single readonly input template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('single-readonly-input')).window - }) - it('should have a single form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({ hello: 'Hi' }) - }) -}) - -describe('single input with double button submitters template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('single-input-with-double-button-submitters')).window - }) - it('should have a single form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({ hello: 'Hi' }) - }) - - it('should include the submitter\'s value when provided', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const [submitter] = Array.from(window.document.getElementsByTagName('button')) - const values = getFormValues(form, submitter) - expect(values).toEqual({ hello: 'Hi', [submitter.name]: submitter.value }) - }) -}) - -describe('single input with double input submitters template', () => { - let window: DOMWindow - beforeEach(async () => { - window = new JSDOM(await fixtures.loadTemplate('single-input-with-double-input-submitters')).window - }) - - it('should have a single form value', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const values = getFormValues(form) - expect(values).toEqual({ hello: 'Hi' }) - }) - - it('should include the submitter\'s value when provided', () => { - const [form] = Array.from(window.document.getElementsByTagName('form')) - const [,submitter] = Array.from(window.document.getElementsByTagName('input')).filter(i => i.type === 'submit') - const values = getFormValues(form, submitter) - expect(values).toEqual({ hello: 'Hi', [submitter.name]: submitter.value }) - }) -}) diff --git a/src/index.ts b/src/index.ts index 0b957b0..d1684b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,26 +1,14 @@ -const RadioNodeList = global.RadioNodeList || class RadioNodeList { - name: string = '' - disabled: boolean = false -} - type HTMLFieldElement = HTMLInputElement | HTMLButtonElement | HTMLSelectElement | HTMLTextAreaElement -type FieldNode - = typeof RadioNodeList - | HTMLFieldElement - type HTMLSubmitterElement = HTMLButtonElement | HTMLInputElement -const isFormFieldElement = (el: FieldNode) => { - if ((el as unknown) instanceof RadioNodeList) { - return true - } +const isFormFieldElement = (el: HTMLFieldElement) => { const htmlEl = el as HTMLElement const tagName = htmlEl.tagName if (['SELECT', 'TEXTAREA'].includes(tagName)) { @@ -41,71 +29,11 @@ const isFormFieldElement = (el: FieldNode) => { return Boolean(inputEl.name) } -const isValidFieldNode = (submitter?: HTMLSubmitterElement) => (fieldNode: Node) => { - const fieldEl = fieldNode as HTMLElement - const fieldElTagName = fieldEl.tagName - - if (fieldElTagName === 'BUTTON' && Boolean(submitter as HTMLSubmitterElement)) { - const buttonEl = fieldEl as HTMLButtonElement - if (buttonEl.type === 'reset' || buttonEl.type === 'button') { - return false - } - - return ( - buttonEl.name === submitter!.name - && buttonEl.value === submitter!.value - ) - } - - if (fieldElTagName === 'INPUT') { - const inputEl = fieldEl as HTMLInputElement - if (inputEl.type === 'radio') { - return inputEl.checked - } - - if (inputEl.type === 'submit' && Boolean(submitter as HTMLSubmitterElement)) { - return ( - inputEl.name === submitter!.name - && inputEl.value === submitter!.value - ) - } - - if (inputEl.type === 'reset' || inputEl.type === 'button') { - return false - } - } - - return true -} - -const getRadioNodeListResolvedValue = (radioNodeList: RadioNodeList, submitter?: HTMLSubmitterElement) => { - const isValid = isValidFieldNode(submitter) - const validFieldElements: Node[] = Array.from(radioNodeList).filter(isValid) - - if (validFieldElements.length > 1) { - return validFieldElements.map((fieldNode: Node) => (fieldNode as HTMLFieldElement).value) - } - - if (validFieldElements.length > 0) { - const [validFieldElement] = (validFieldElements as HTMLFieldElement[]) - if (validFieldElement) { - return validFieldElement.value - } - } - - return null -} - /** * Gets the value of a field element. * @param el - The field element node. - * @param submitter - The element which triggered the enclosing form's submit event, if said form is submitted. */ -const getFieldValue = (el: FieldNode, submitter?: HTMLSubmitterElement) => { - if ((el as unknown) instanceof RadioNodeList) { - return getRadioNodeListResolvedValue(el as unknown as RadioNodeList, submitter) - } - +const getFieldValue = (el: HTMLFieldElement) => { const fieldEl = el as HTMLFieldElement const tagName = fieldEl.tagName const type = fieldEl.type @@ -149,7 +77,7 @@ const getFieldValue = (el: FieldNode, submitter?: HTMLSubmitterElement) => { * Returns only named form field elements. * @param el - The element */ -const isValidFormField = (el: FieldNode) => { +const isValidFormField = (el: HTMLFieldElement) => { return ( 'name' in el && typeof el['name'] === 'string' @@ -166,8 +94,8 @@ const getFormValues = (form: HTMLFormElement, submitter?: HTMLSubmitterElement) if (!form) { throw new TypeError('Invalid form element.') } - const formElements = form.elements as unknown as Record - const allFormFieldElements = Object.entries(formElements) + const formElements = form.elements as unknown as Record + const allFormFieldElements = Object.entries(formElements) const formFieldElements = allFormFieldElements.filter(([k, el]) => { return ( // get only indexed forms @@ -177,7 +105,7 @@ const getFormValues = (form: HTMLFormElement, submitter?: HTMLSubmitterElement) }) const fieldValues = formFieldElements.reduce( (theFormValues, [,el]) => { - const fieldValue = getFieldValue(el, submitter) + const fieldValue = getFieldValue(el) if (fieldValue === null) { return theFormValues } diff --git a/test/fixtures/templates/blank.html b/test/fixtures/templates/blank.html index e54c614..c5f859f 100644 --- a/test/fixtures/templates/blank.html +++ b/test/fixtures/templates/blank.html @@ -5,6 +5,8 @@ Title -
+
+ +
diff --git a/test/integration/blank.test.ts b/test/integration/blank.test.ts new file mode 100644 index 0000000..bd49c92 --- /dev/null +++ b/test/integration/blank.test.ts @@ -0,0 +1,23 @@ +/// +/// + +import getFormValues from '../../src' +import * as utils from '../utils' + +describe('blank template', () => { + beforeEach(utils.setup('blank')) + + it('should have blank form value', () => { + utils.test( + (cy: any) => { + cy.get('[type="submit"]').click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + {} + ); + }); +}) diff --git a/test/integration/everything.test.ts b/test/integration/everything.test.ts new file mode 100644 index 0000000..12c518e --- /dev/null +++ b/test/integration/everything.test.ts @@ -0,0 +1,42 @@ +/// +/// + +import getFormValues from '../../src' +import * as utils from '../utils'; + +describe('blank template', () => { + beforeEach(utils.setup('everything')) + + it('should have blank form value', () => { + let submitter: HTMLButtonElement + utils.test( + (cy) => { + cy.get('[name="first_name"]').type('John') + cy.get('[name="middle_name"]').type('Marcelo') + cy.get('[name="last_name"]').type('Dela Cruz') + cy.get('[name="gender"][value="m"]').check() + cy.get('[name="civil_status"]').select('Married') + cy.get('[name="new_registration"]').check() + cy.get('[name="nationality"][value="filipino"]').check() + cy.get('[name="dependent"][value="Jun"]').check() + cy.get('button.dependents').click() + cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Juana') + cy.get('button.dependents').click() + cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Jane') + cy.get('button.dependents').click() + cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Josh') + cy.get('[name="notes"]').type('Test content\n\nNew line\n\nAnother line') + cy.get('[name="submit"][value="Hi"]').then((submitterEl: any) => { + [submitter] = Array.from(submitterEl) as HTMLButtonElement[]; + submitterEl.trigger('click'); + }) + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form, submitter)).toString(); + const after = new URLSearchParams(search).toString(); + expect(before).toEqual(after); + }, + {} + ); + }); +}) diff --git a/test/integration/single.test.ts b/test/integration/single.test.ts new file mode 100644 index 0000000..e86059c --- /dev/null +++ b/test/integration/single.test.ts @@ -0,0 +1,114 @@ +/// + +import getFormValues from '../../src' +import * as utils from '../utils'; + +describe('single input template', () => { + beforeEach(utils.setup('single-input')) + + it('should have single form value', () => { + utils.test( + (cy: any) => { + cy.get('[type="submit"]').click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + { + hello: 'Hi', + } + ); + }); +}) + +describe('single readonly template', () => { + beforeEach(utils.setup('single-readonly-input')) + + it('should have single form value', () => { + utils.test( + (cy: any) => { + cy.get('[type="submit"]').click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + { + hello: 'Hi', + } + ); + }); +}) + +describe('single disabled template', () => { + beforeEach(utils.setup('single-disabled-input')) + + it('should have blank form value', () => { + utils.test( + (cy: any) => { + cy.get('[type="submit"]').click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + {} + ); + }); +}) + +describe('single input with double button submitters template', () => { + beforeEach(utils.setup('single-input-with-double-button-submitters')) + + it('should have double form values', () => { + let submitter: HTMLButtonElement + utils.test( + (cy: any) => { + cy.get('[name="action"][value="Foo"]') + .then((result: any) => { + [submitter] = Array.from(result) + }) + .click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form, submitter)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + { + hello: 'Hi', + action: 'Foo', + } + ); + }); +}) + +describe('single input with double input submitters template', () => { + beforeEach(utils.setup('single-input-with-double-input-submitters')) + + it('should have double form values', () => { + let submitter: HTMLInputElement + utils.test( + (cy: any) => { + cy.get('[name="action"][value="Bar"]') + .then((result: any) => { + [submitter] = Array.from(result) + }) + .click() + }, + (form: HTMLFormElement, search: any) => { + const before = utils.makeSearchParams(getFormValues(form, submitter)).toString(); + const after = utils.makeSearchParams(search).toString(); + expect(before).toEqual(after); + }, + { + hello: 'Hi', + action: 'Bar', + } + ); + }); +}) diff --git a/test/integrations/blank.e2e.ts b/test/integrations/blank.e2e.ts deleted file mode 100644 index af58ac4..0000000 --- a/test/integrations/blank.e2e.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// - -import getFormValues from '../../src' -import {makeSearchParams} from '../utils/search'; - -describe('blank template', () => { - beforeEach(() => { - cy.intercept({ url: '/' }, { fixture: 'templates/blank.html' }); - cy.intercept({ url: '/?*' }, { fixture: 'templates/blank.html' }).as('submitted'); - }) - - it('should have blank form value', () => { - let form; - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .submit() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }); -}) diff --git a/test/integrations/everything.e2e.ts b/test/integrations/everything.e2e.ts deleted file mode 100644 index b0fb4fd..0000000 --- a/test/integrations/everything.e2e.ts +++ /dev/null @@ -1,104 +0,0 @@ -/// - -import getFormValues from '../../src' -import {makeSearchParams} from '../utils/search'; - -describe('default template', () => { - beforeEach(() => { - cy.intercept({ url: '/' }, { fixture: 'templates/everything.html' }); - cy.intercept({ url: '/?*' }, { fixture: 'templates/everything.html' }).as('submitted'); - }) - - it('should have a single form value', () => { - let form; - let submitter; - - cy - .visit('/') - - cy - .get('[name="first_name"]') - .type('John') - - cy - .get('[name="middle_name"]') - .type('Marcelo') - - cy - .get('[name="last_name"]') - .type('Dela Cruz') - - cy - .get('[name="gender"][value="m"]') - .check() - - cy - .get('[name="civil_status"]') - .select('Married') - - cy - .get('[name="new_registration"]') - .check() - - cy - .get('[name="nationality"][value="filipino"]') - .check() - - cy - .get('[name="dependent"][value="Jun"]') - .check() - - cy - .get('button.dependents') - .click() - - cy - .get('.additional-dependent [name="dependent"][type="text"]') - .last() - .type('Juana') - - cy - .get('button.dependents') - .click() - - cy - .get('.additional-dependent [name="dependent"][type="text"]') - .last() - .type('Jane') - - cy - .get('button.dependents') - .click() - - cy - .get('.additional-dependent [name="dependent"][type="text"]') - .last() - .type('Josh') - - cy - .get('[name="notes"]') - .type('Test content\n\nNew line\n\nAnother line') - - cy - .get('form') - .then((theForm) => { - [form] = Array.from(theForm) - }) - - cy - .get('[name="submit"][value="Hi"]') - .then((submitterEl) => { - [submitter] = Array.from(submitterEl) as HTMLButtonElement[]; - submitterEl.trigger('click'); - }) - - cy - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form, submitter)); - const after = new URLSearchParams(search) - expect(before.toString()).to.equal(after.toString()); - }) - }) -}); diff --git a/test/integrations/single.e2e.ts b/test/integrations/single.e2e.ts deleted file mode 100644 index 6309a91..0000000 --- a/test/integrations/single.e2e.ts +++ /dev/null @@ -1,162 +0,0 @@ -/// - -import getFormValues from '../../src' -import {makeSearchParams} from '../utils/search'; - -describe('single input template', () => { - beforeEach(() => { - cy.intercept({ url: '/' }, { fixture: 'templates/single-input.html' }); - cy.intercept({ url: '/?*' }, { fixture: 'templates/single-input.html' }).as('submitted'); - }) - - it('should have a single form value', () => { - let form - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .get('[type="submit"]') - .click() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }) -}); - -describe('single readonly template', () => { - beforeEach(() => { - cy.intercept({ url: '/' }, { fixture: 'templates/single-readonly-input.html' }); - cy.intercept({ url: '/?*' }, { fixture: 'templates/single-readonly-input.html' }).as('submitted'); - }) - - it('should have a single form value', () => { - let form - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .get('[type="submit"]') - .click() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }) -}); - -describe('single disabled template', () => { - beforeEach(() => { - cy.intercept({ url: '/' }, { fixture: 'templates/single-disabled-input.html' }); - cy.intercept({ url: '/?*' }, { fixture: 'templates/single-disabled-input.html' }).as('submitted'); - }) - - it('should have a single form value', () => { - let form - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .get('[type="submit"]') - .click() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }) -}); - -describe('single input with double button submitters template', () => { - beforeEach(() => { - cy - .intercept( - { url: '/' }, - { fixture: 'templates/single-input-with-double-button-submitters.html' } - ); - - cy - .intercept( - { url: '/?*' }, - { fixture: 'templates/single-input-with-double-button-submitters.html' } - ) - .as('submitted'); - }) - - it('should have a single form value', () => { - let submitter; - let form; - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .get('[name="action"][value="Bar"]') - .then((submitterEl) => { - [submitter] = Array.from(submitterEl) - }) - .click() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form, submitter as HTMLInputElement)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }) -}); - -describe('single input with double input submitters template', () => { - beforeEach(() => { - cy - .intercept( - { url: '/' }, - { fixture: 'templates/single-input-with-double-input-submitters.html' } - ); - - cy - .intercept( - { url: '/?*' }, - { fixture: 'templates/single-input-with-double-input-submitters.html' } - ) - .as('submitted'); - }) - - it('should have a single form value', () => { - let submitter; - let form; - cy - .visit('/') - .get('form') - .then((formResult) => { - [form] = Array.from(formResult); - }) - .get('[name="action"][value="Foo"]') - .then((submitterEl) => { - [submitter] = Array.from(submitterEl) - }) - .click() - .wait('@submitted') - .location('search') - .then(search => { - const before = makeSearchParams(getFormValues(form, submitter as HTMLInputElement)).toString(); - const after = new URLSearchParams(search).toString(); - expect(before).to.equal(after); - }) - }) -}); diff --git a/test/support/index.ts b/test/support/index.ts index bd55847..ed026ad 100644 --- a/test/support/index.ts +++ b/test/support/index.ts @@ -15,6 +15,7 @@ // Import commands.ts using ES2015 syntax: import './commands' +import 'cypress-jest-adapter' // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/test/utils/index.ts b/test/utils/index.ts index a0e9b02..8459b24 100644 --- a/test/utils/index.ts +++ b/test/utils/index.ts @@ -1,8 +1,70 @@ +/// +/// + import fs from 'fs' import path from 'path' -export const loadTemplate = async (templateName: string): Promise => { - const templatePath = path.join('test', 'fixtures', 'templates', `${templateName}.html`) - const templateRaw = await fs.promises.readFile(templatePath) - return templateRaw.toString('utf-8') +type TestFn = (form: HTMLFormElement, after: Record | string) => unknown + +export const setup = (template: string) => { + if (typeof cy !== 'undefined') { + return () => { + cy.intercept({ url: '/' }, { fixture: `templates/${template}.html` }); + cy.intercept({ url: '/?*' }, { fixture: `templates/${template}.html` }).as('submitted'); + } + } + return async () => { + const templatePath = path.join('test', 'fixtures', 'templates', `${template}.html`) + const templateRaw = await fs.promises.readFile(templatePath) + window.document.open() + window.document.write(templateRaw.toString('utf-8')) + window.document.close() + } +} + +export const test = (opFn: (wrapper: any) => unknown, testFn: TestFn, expectedValue: Record | string) => { + let form: HTMLFormElement + if (typeof cy !== 'undefined') { + cy + .visit('/') + .get('form') + .then((formResult) => { + [form] = Array.from(formResult); + }) + + opFn(cy) + + cy + .wait('@submitted') + .location('search') + .then(search => { + testFn(form, search) + }) + } else { + [form] = Array.from(window.document.getElementsByTagName('form')) + testFn(form, expectedValue) + } +} + +export const makeSearchParams = (beforeValues: Record | string) => { + switch (typeof (beforeValues as unknown)) { + case 'string': + return new URLSearchParams(beforeValues as string) + case 'object': + return Object + .entries(beforeValues) + .reduce( + (beforeSearchParams, [key, value]) => { + const theValue = !Array.isArray(value) ? [value] : value + theValue.forEach(v => { + beforeSearchParams.append(key, v) + }) + return beforeSearchParams + }, + new URLSearchParams() + ) + default: + break + } + throw new TypeError('Invalid parameter.') } diff --git a/test/utils/search.ts b/test/utils/search.ts index 2f5cc3c..e69de29 100644 --- a/test/utils/search.ts +++ b/test/utils/search.ts @@ -1,12 +0,0 @@ -export const makeSearchParams = (beforeValues) => Object - .entries(beforeValues) - .reduce( - (beforeSearchParams, [key, value]) => { - const theValue = !Array.isArray(value) ? [value] : value - theValue.forEach(v => { - beforeSearchParams.append(key, v) - }) - return beforeSearchParams - }, - new URLSearchParams() - ) diff --git a/yarn.lock b/yarn.lock index f41f940..340fb3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -976,6 +976,15 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== +"@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + "@jest/console@^25.5.0": version "25.5.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.5.0.tgz#770800799d510f37329c508a9edd0b7b447d9abb" @@ -1082,6 +1091,15 @@ optionalDependencies: node-notifier "^6.0.0" +"@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + "@jest/source-map@^25.5.0": version "25.5.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.5.0.tgz#df5c20d6050aa292c2c6d3f0d2c7606af315bd1b" @@ -1091,6 +1109,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@jest/test-result@^25.5.0": version "25.5.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.5.0.tgz#139a043230cdeffe9ba2d8341b27f2efc77ce87c" @@ -1134,6 +1161,15 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + "@jest/types@^25.5.0": version "25.5.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" @@ -1442,6 +1478,13 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== +"@types/yargs@^13.0.0": + version "13.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.11.tgz#def2f0c93e4bdf2c61d7e34899b17e34be28d3b1" + integrity sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^15.0.0": version "15.0.13" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" @@ -1755,7 +1798,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -2506,7 +2549,7 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, 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== @@ -3139,6 +3182,16 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +cypress-jest-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/cypress-jest-adapter/-/cypress-jest-adapter-0.1.1.tgz#d1aa9d84393b6a5007022d1d33b3cdd3ce9672af" + integrity sha512-5dSB03utqDTBG5pi1LaAvYQD5uSMtSwurSzodpM+3XS/RdrjR/644oPnFUxPRvX4FVBaIY8avRs/f/GmIAiu8w== + dependencies: + expect "^24.5.0" + jest-get-type "^24.3.0" + jest-jquery-matchers "^2.1.0" + jquery "^3.4.0" + cypress@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/cypress/-/cypress-7.2.0.tgz#6a3364e18972f898fff1fb12c1ff747939e45ddc" @@ -3331,6 +3384,11 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + diff-sequences@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" @@ -3940,6 +3998,18 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect@^24.5.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + expect@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/expect/-/expect-25.5.0.tgz#f07f848712a2813bb59167da3fb828ca21f58bba" @@ -5209,6 +5279,16 @@ jest-config@^25.5.4: pretty-format "^25.5.0" realpath-native "^2.0.0" +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-diff@^25.2.1, jest-diff@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" @@ -5261,6 +5341,11 @@ jest-environment-node@^25.5.0: jest-util "^25.5.0" semver "^6.3.0" +jest-get-type@^24.3.0, jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + jest-get-type@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" @@ -5309,6 +5394,11 @@ jest-jasmine2@^25.5.4: pretty-format "^25.5.0" throat "^5.0.0" +jest-jquery-matchers@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/jest-jquery-matchers/-/jest-jquery-matchers-2.1.0.tgz#b56d19c460f6e57b17e6ddcce6f905d28b0ec532" + integrity sha512-gbCptZOPFv4m7CJenRJcp7OTmQ432yakCDGup6gExrIwbNq8hBfxU+llXO2IXOpFuLmI0c8A+JdGMUNXe6LV9A== + jest-leak-detector@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz#2291c6294b0ce404241bb56fe60e2d0c3e34f0bb" @@ -5317,6 +5407,16 @@ jest-leak-detector@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-matcher-utils@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" @@ -5327,6 +5427,20 @@ jest-matcher-utils@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-message-util@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" @@ -5353,6 +5467,11 @@ jest-pnp-resolver@^1.2.1: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== +jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + jest-regex-util@^25.2.1, jest-regex-util@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" @@ -5545,6 +5664,11 @@ jpjs@^1.2.1: resolved "https://registry.yarnpkg.com/jpjs/-/jpjs-1.2.1.tgz#f343833de8838a5beba1f42d5a219be0114c44b7" integrity sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw== +jquery@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -7210,6 +7334,16 @@ pretty-bytes@^5.6.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-format@^25.2.1, pretty-format@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" @@ -7374,7 +7508,7 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -react-is@^16.12.0, react-is@^16.8.1: +react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -8043,6 +8177,11 @@ size-limit@^4.10.2: ora "^5.4.0" read-pkg-up "^7.0.1" +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"