@@ -1,6 +1,6 @@ | |||||
{ | { | ||||
"fixturesFolder": "test/fixtures", | "fixturesFolder": "test/fixtures", | ||||
"integrationFolder": "test/integrations", | |||||
"integrationFolder": "test/integration", | |||||
"pluginsFile": "test/plugins/index.ts", | "pluginsFile": "test/plugins/index.ts", | ||||
"supportFile": "test/support/index.ts" | "supportFile": "test/support/index.ts" | ||||
} | } |
@@ -1,3 +1,3 @@ | |||||
module.exports = { | module.exports = { | ||||
testEnvironment: 'node', | |||||
testEnvironment: 'jsdom', | |||||
}; | }; |
@@ -13,9 +13,9 @@ | |||||
"scripts": { | "scripts": { | ||||
"start": "tsdx watch", | "start": "tsdx watch", | ||||
"build": "tsdx build", | "build": "tsdx build", | ||||
"test": "tsdx test", | |||||
"test:jsdom": "tsdx test", | |||||
"test:dom": "cypress open", | |||||
"lint": "tsdx lint", | "lint": "tsdx lint", | ||||
"e2e": "cypress open", | |||||
"prepare": "tsdx build", | "prepare": "tsdx build", | ||||
"size": "size-limit", | "size": "size-limit", | ||||
"analyze": "size-limit --why" | "analyze": "size-limit --why" | ||||
@@ -49,6 +49,7 @@ | |||||
"@size-limit/preset-small-lib": "^4.10.2", | "@size-limit/preset-small-lib": "^4.10.2", | ||||
"@types/jsdom": "^16.2.10", | "@types/jsdom": "^16.2.10", | ||||
"cypress": "^7.2.0", | "cypress": "^7.2.0", | ||||
"cypress-jest-adapter": "^0.1.1", | |||||
"husky": "^6.0.0", | "husky": "^6.0.0", | ||||
"jsdom": "^16.5.3", | "jsdom": "^16.5.3", | ||||
"size-limit": "^4.10.2", | "size-limit": "^4.10.2", | ||||
@@ -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 }) | |||||
}) | |||||
}) |
@@ -1,26 +1,14 @@ | |||||
const RadioNodeList = global.RadioNodeList || class RadioNodeList { | |||||
name: string = '' | |||||
disabled: boolean = false | |||||
} | |||||
type HTMLFieldElement | type HTMLFieldElement | ||||
= HTMLInputElement | = HTMLInputElement | ||||
| HTMLButtonElement | | HTMLButtonElement | ||||
| HTMLSelectElement | | HTMLSelectElement | ||||
| HTMLTextAreaElement | | HTMLTextAreaElement | ||||
type FieldNode | |||||
= typeof RadioNodeList | |||||
| HTMLFieldElement | |||||
type HTMLSubmitterElement | type HTMLSubmitterElement | ||||
= HTMLButtonElement | = HTMLButtonElement | ||||
| HTMLInputElement | | HTMLInputElement | ||||
const isFormFieldElement = (el: FieldNode) => { | |||||
if ((el as unknown) instanceof RadioNodeList) { | |||||
return true | |||||
} | |||||
const isFormFieldElement = (el: HTMLFieldElement) => { | |||||
const htmlEl = el as HTMLElement | const htmlEl = el as HTMLElement | ||||
const tagName = htmlEl.tagName | const tagName = htmlEl.tagName | ||||
if (['SELECT', 'TEXTAREA'].includes(tagName)) { | if (['SELECT', 'TEXTAREA'].includes(tagName)) { | ||||
@@ -41,71 +29,11 @@ const isFormFieldElement = (el: FieldNode) => { | |||||
return Boolean(inputEl.name) | 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. | * Gets the value of a field element. | ||||
* @param el - The field element node. | * @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 fieldEl = el as HTMLFieldElement | ||||
const tagName = fieldEl.tagName | const tagName = fieldEl.tagName | ||||
const type = fieldEl.type | const type = fieldEl.type | ||||
@@ -149,7 +77,7 @@ const getFieldValue = (el: FieldNode, submitter?: HTMLSubmitterElement) => { | |||||
* Returns only named form field elements. | * Returns only named form field elements. | ||||
* @param el - The element | * @param el - The element | ||||
*/ | */ | ||||
const isValidFormField = (el: FieldNode) => { | |||||
const isValidFormField = (el: HTMLFieldElement) => { | |||||
return ( | return ( | ||||
'name' in el | 'name' in el | ||||
&& typeof el['name'] === 'string' | && typeof el['name'] === 'string' | ||||
@@ -166,8 +94,8 @@ const getFormValues = (form: HTMLFormElement, submitter?: HTMLSubmitterElement) | |||||
if (!form) { | if (!form) { | ||||
throw new TypeError('Invalid form element.') | throw new TypeError('Invalid form element.') | ||||
} | } | ||||
const formElements = form.elements as unknown as Record<string | number, FieldNode> | |||||
const allFormFieldElements = Object.entries<FieldNode>(formElements) | |||||
const formElements = form.elements as unknown as Record<string | number, HTMLFieldElement> | |||||
const allFormFieldElements = Object.entries<HTMLFieldElement>(formElements) | |||||
const formFieldElements = allFormFieldElements.filter(([k, el]) => { | const formFieldElements = allFormFieldElements.filter(([k, el]) => { | ||||
return ( | return ( | ||||
// get only indexed forms | // get only indexed forms | ||||
@@ -177,7 +105,7 @@ const getFormValues = (form: HTMLFormElement, submitter?: HTMLSubmitterElement) | |||||
}) | }) | ||||
const fieldValues = formFieldElements.reduce( | const fieldValues = formFieldElements.reduce( | ||||
(theFormValues, [,el]) => { | (theFormValues, [,el]) => { | ||||
const fieldValue = getFieldValue(el, submitter) | |||||
const fieldValue = getFieldValue(el) | |||||
if (fieldValue === null) { | if (fieldValue === null) { | ||||
return theFormValues | return theFormValues | ||||
} | } | ||||
@@ -5,6 +5,8 @@ | |||||
<title>Title</title> | <title>Title</title> | ||||
</head> | </head> | ||||
<body> | <body> | ||||
<form></form> | |||||
<form> | |||||
<button type="submit">Submit</button> | |||||
</form> | |||||
</body> | </body> | ||||
</html> | </html> |
@@ -0,0 +1,23 @@ | |||||
/// <reference types="cypress" /> | |||||
/// <reference types="cypress-jest-adapter" /> | |||||
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); | |||||
}, | |||||
{} | |||||
); | |||||
}); | |||||
}) |
@@ -0,0 +1,42 @@ | |||||
/// <reference types="cypress" /> | |||||
/// <reference types="cypress-jest-adapter" /> | |||||
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); | |||||
}, | |||||
{} | |||||
); | |||||
}); | |||||
}) |
@@ -0,0 +1,114 @@ | |||||
/// <reference types="cypress" /> | |||||
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', | |||||
} | |||||
); | |||||
}); | |||||
}) |
@@ -1,29 +0,0 @@ | |||||
/// <reference types="cypress" /> | |||||
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); | |||||
}) | |||||
}); | |||||
}) |
@@ -1,104 +0,0 @@ | |||||
/// <reference types="cypress" /> | |||||
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()); | |||||
}) | |||||
}) | |||||
}); |
@@ -1,162 +0,0 @@ | |||||
/// <reference types="cypress" /> | |||||
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); | |||||
}) | |||||
}) | |||||
}); |
@@ -15,6 +15,7 @@ | |||||
// Import commands.ts using ES2015 syntax: | // Import commands.ts using ES2015 syntax: | ||||
import './commands' | import './commands' | ||||
import 'cypress-jest-adapter' | |||||
// Alternatively you can use CommonJS syntax: | // Alternatively you can use CommonJS syntax: | ||||
// require('./commands') | // require('./commands') |
@@ -1,8 +1,70 @@ | |||||
/// <reference types="cypress" /> | |||||
/// <reference types="cypress-jest-adapter" /> | |||||
import fs from 'fs' | import fs from 'fs' | ||||
import path from 'path' | import path from 'path' | ||||
export const loadTemplate = async (templateName: string): Promise<string> => { | |||||
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, string> | 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, string> | 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, unknown> | 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.') | |||||
} | } |
@@ -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() | |||||
) |
@@ -976,6 +976,15 @@ | |||||
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" | ||||
integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== | 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": | "@jest/console@^25.5.0": | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.5.0.tgz#770800799d510f37329c508a9edd0b7b447d9abb" | resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.5.0.tgz#770800799d510f37329c508a9edd0b7b447d9abb" | ||||
@@ -1082,6 +1091,15 @@ | |||||
optionalDependencies: | optionalDependencies: | ||||
node-notifier "^6.0.0" | 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": | "@jest/source-map@^25.5.0": | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.5.0.tgz#df5c20d6050aa292c2c6d3f0d2c7606af315bd1b" | resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.5.0.tgz#df5c20d6050aa292c2c6d3f0d2c7606af315bd1b" | ||||
@@ -1091,6 +1109,15 @@ | |||||
graceful-fs "^4.2.4" | graceful-fs "^4.2.4" | ||||
source-map "^0.6.0" | 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": | "@jest/test-result@^25.5.0": | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.5.0.tgz#139a043230cdeffe9ba2d8341b27f2efc77ce87c" | resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.5.0.tgz#139a043230cdeffe9ba2d8341b27f2efc77ce87c" | ||||
@@ -1134,6 +1161,15 @@ | |||||
source-map "^0.6.1" | source-map "^0.6.1" | ||||
write-file-atomic "^3.0.0" | 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": | "@jest/types@^25.5.0": | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" | 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" | resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" | ||||
integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== | 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": | "@types/yargs@^15.0.0": | ||||
version "15.0.13" | version "15.0.13" | ||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" | 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" | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" | ||||
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= | ||||
ansi-regex@^4.1.0: | |||||
ansi-regex@^4.0.0, ansi-regex@^4.1.0: | |||||
version "4.1.0" | version "4.1.0" | ||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" | ||||
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== | ||||
@@ -2506,7 +2549,7 @@ chalk@^1.0.0, chalk@^1.1.3: | |||||
strip-ansi "^3.0.0" | strip-ansi "^3.0.0" | ||||
supports-color "^2.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" | version "2.4.2" | ||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" | ||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== | 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" | resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" | ||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= | 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: | cypress@^7.2.0: | ||||
version "7.2.0" | version "7.2.0" | ||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-7.2.0.tgz#6a3364e18972f898fff1fb12c1ff747939e45ddc" | 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" | resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" | ||||
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== | 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: | diff-sequences@^25.2.6: | ||||
version "25.2.6" | version "25.2.6" | ||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" | 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" | snapdragon "^0.8.1" | ||||
to-regex "^3.0.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: | expect@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/expect/-/expect-25.5.0.tgz#f07f848712a2813bb59167da3fb828ca21f58bba" | 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" | pretty-format "^25.5.0" | ||||
realpath-native "^2.0.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: | jest-diff@^25.2.1, jest-diff@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" | 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" | jest-util "^25.5.0" | ||||
semver "^6.3.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: | jest-get-type@^25.2.6: | ||||
version "25.2.6" | version "25.2.6" | ||||
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" | 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" | pretty-format "^25.5.0" | ||||
throat "^5.0.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: | jest-leak-detector@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz#2291c6294b0ce404241bb56fe60e2d0c3e34f0bb" | 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" | jest-get-type "^25.2.6" | ||||
pretty-format "^25.5.0" | 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: | jest-matcher-utils@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" | 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" | jest-get-type "^25.2.6" | ||||
pretty-format "^25.5.0" | 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: | jest-message-util@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" | 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" | resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" | ||||
integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== | 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: | jest-regex-util@^25.2.1, jest-regex-util@^25.2.6: | ||||
version "25.2.6" | version "25.2.6" | ||||
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" | 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" | resolved "https://registry.yarnpkg.com/jpjs/-/jpjs-1.2.1.tgz#f343833de8838a5beba1f42d5a219be0114c44b7" | ||||
integrity sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw== | 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: | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: | ||||
version "4.0.0" | version "4.0.0" | ||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" | 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" | resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" | ||||
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== | 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: | pretty-format@^25.2.1, pretty-format@^25.5.0: | ||||
version "25.5.0" | version "25.5.0" | ||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" | 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" | randombytes "^2.0.5" | ||||
safe-buffer "^5.1.0" | 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" | version "16.13.1" | ||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" | ||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== | ||||
@@ -8043,6 +8177,11 @@ size-limit@^4.10.2: | |||||
ora "^5.4.0" | ora "^5.4.0" | ||||
read-pkg-up "^7.0.1" | 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: | slash@^3.0.0: | ||||
version "3.0.0" | version "3.0.0" | ||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" | ||||