Ver código fonte

Organize tests

Both the JSDOM and the Cypress tests are organized.
master
TheoryOfNekomata 3 anos atrás
pai
commit
d6553006a1
15 arquivos alterados com 327 adições e 239 exclusões
  1. +14
    -13
      src/index.test.ts
  2. +22
    -21
      src/index.ts
  3. +0
    -0
      test/fixtures/templates/everything.html
  4. +0
    -0
      test/fixtures/templates/single-input-with-double-button-submitters.html
  5. +11
    -11
      test/integrations/blank.e2e.ts
  6. +0
    -49
      test/integrations/default.e2e.ts
  7. +104
    -0
      test/integrations/everything.e2e.ts
  8. +0
    -28
      test/integrations/single-disabled-input.e2e.ts
  9. +0
    -28
      test/integrations/single-input-with-double-input-submitters.e2e.ts
  10. +0
    -28
      test/integrations/single-input-with-double-submitters.e2e.ts
  11. +0
    -28
      test/integrations/single-input.e2e.ts
  12. +0
    -28
      test/integrations/single-readonly-input.e2e.ts
  13. +162
    -0
      test/integrations/single.e2e.ts
  14. +2
    -5
      test/utils/index.ts
  15. +12
    -0
      test/utils/search.ts

+ 14
- 13
src/index.test.ts Ver arquivo

@@ -1,10 +1,11 @@
import * as fixtures from '../test/utils'
import getFormValues from '.'
import {DOMWindow, JSDOM} from 'jsdom';

describe('blank template', () => {
let window: fixtures.Window
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('blank')
window = new JSDOM(await fixtures.loadTemplate('blank')).window
})
it('should have blank form value', () => {
const [form] = Array.from(window.document.getElementsByTagName('form'))
@@ -14,9 +15,9 @@ describe('blank template', () => {
})

describe('single input template', () => {
let window: fixtures.Window
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('single-input')
window = new JSDOM(await fixtures.loadTemplate('single-input')).window
})
it('should have a single form value', () => {
const [form] = Array.from(window.document.getElementsByTagName('form'))
@@ -26,9 +27,9 @@ describe('single input template', () => {
})

describe('single disabled input template', () => {
let window: fixtures.Window
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('single-disabled-input')
window = new JSDOM(await fixtures.loadTemplate('single-disabled-input')).window
})
it('should have blank form value', () => {
const [form] = Array.from(window.document.getElementsByTagName('form'))
@@ -38,9 +39,9 @@ describe('single disabled input template', () => {
})

describe('single readonly input template', () => {
let window: fixtures.Window
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('single-readonly-input')
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'))
@@ -49,10 +50,10 @@ describe('single readonly input template', () => {
})
})

describe('single input with double submitters template', () => {
let window: fixtures.Window
describe('single input with double button submitters template', () => {
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('single-input-with-double-submitters')
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'))
@@ -69,9 +70,9 @@ describe('single input with double submitters template', () => {
})

describe('single input with double input submitters template', () => {
let window: fixtures.Window
let window: DOMWindow
beforeEach(async () => {
window = await fixtures.loadTemplate('single-input-with-double-input-submitters')
window = new JSDOM(await fixtures.loadTemplate('single-input-with-double-input-submitters')).window
})

it('should have a single form value', () => {


+ 22
- 21
src/index.ts Ver arquivo

@@ -168,40 +168,41 @@ const getFormValues = (form: HTMLFormElement, submitter?: HTMLSubmitterElement)
}
const formElements = form.elements as unknown as Record<string | number, FieldNode>
const allFormFieldElements = Object.entries<FieldNode>(formElements)
const formFieldElements = allFormFieldElements.filter(([, el]) => isValidFormField(el))
const formFieldElements = allFormFieldElements.filter(([k, el]) => {
return (
// get only indexed forms
!isNaN(Number(k))
&& isValidFormField(el)
)
})
const fieldValues = formFieldElements.reduce(
(theFormValues, [,el]) => {
const inputEl = el as HTMLInputElement
if (inputEl.tagName === 'INPUT' && inputEl.type === 'radio' && !inputEl.checked) {
return theFormValues
}

const fieldValue = getFieldValue(el, submitter)
if (fieldValue === null) {
return theFormValues
}

const fieldName = el['name'] as string;
// const { [fieldName]: oldFormValue = null } = theFormValues;
const { [fieldName]: oldFormValue = null } = theFormValues;

// if (oldFormValue === null) {
if (oldFormValue === null) {
return {
...theFormValues,
[fieldName]: fieldValue,
}
// }
//
// if (!Array.isArray(oldFormValue)) {
// return {
// ...theFormValues,
// [fieldName]: [oldFormValue, fieldValue],
// }
// }
//
// return {
// ...theFormValues,
// [fieldName]: [...oldFormValue, fieldValue],
// }
}
if (!Array.isArray(oldFormValue)) {
return {
...theFormValues,
[fieldName]: [oldFormValue, fieldValue],
}
}
return {
...theFormValues,
[fieldName]: [...oldFormValue, fieldValue],
}
},
{} as any
)


test/fixtures/templates/default.html → test/fixtures/templates/everything.html Ver arquivo


test/fixtures/templates/single-input-with-double-submitters.html → test/fixtures/templates/single-input-with-double-button-submitters.html Ver arquivo


+ 11
- 11
test/integrations/blank.e2e.ts Ver arquivo

@@ -1,6 +1,7 @@
/// <reference types="cypress" />

import getFormValues from '../../src'
import {makeSearchParams} from '../utils/search';

describe('blank template', () => {
beforeEach(() => {
@@ -9,21 +10,20 @@ describe('blank template', () => {
})

it('should have blank form value', () => {
let beforeValues;
let form;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
console.log(beforeValues)
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
[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);
})
});
})

+ 0
- 49
test/integrations/default.e2e.ts Ver arquivo

@@ -1,49 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

describe('single input template', () => {
beforeEach(() => {
cy.intercept({ url: '/' }, { fixture: 'templates/default.html' });
cy.intercept({ url: '/?*' }, { fixture: 'templates/default.html' }).as('submitted');
})

it('should have a single form value', () => {
let beforeValues;
cy
.visit('/')
.then(() => {
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"]').eq(0).type('Juana')
// cy.get('button.dependents').click()
// cy.get('.additional-dependent [name="dependent"][type="text"]').eq(1).type('Jane')
// cy.get('button.dependents').click()
// cy.get('.additional-dependent [name="dependent"][type="text"]').eq(2).type('Josh')
cy.get('[name="notes"]').type('Test content\n\nNew line\n\nAnother line').as('filled')
})
.get('form')
.then((theForm) => {
cy
.get('[name="submit"][value="Hi"]')
.then((submitterEl) => {
const [submitter] = Array.from(submitterEl) as HTMLButtonElement[];
beforeValues = getFormValues(theForm[0], submitter);
submitterEl.trigger('click');
cy.wait('@submitted')
cy.location('search').then(search => {
const before = JSON.stringify(new URLSearchParams(beforeValues).toString().split('&'));
const after = JSON.stringify(new URLSearchParams(search).toString().split('&'));
expect(before).to.equal(after);
})
})
})
})
});

+ 104
- 0
test/integrations/everything.e2e.ts Ver arquivo

@@ -0,0 +1,104 @@
/// <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());
})
})
});

+ 0
- 28
test/integrations/single-disabled-input.e2e.ts Ver arquivo

@@ -1,28 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

describe('single input 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 beforeValues;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
})
})
});

+ 0
- 28
test/integrations/single-input-with-double-input-submitters.e2e.ts Ver arquivo

@@ -1,28 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

describe('single input 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 beforeValues;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
})
})
});

+ 0
- 28
test/integrations/single-input-with-double-submitters.e2e.ts Ver arquivo

@@ -1,28 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

describe('single input template', () => {
beforeEach(() => {
cy.intercept({ url: '/' }, { fixture: 'templates/single-input-with-double-submitters.html' });
cy.intercept({ url: '/?*' }, { fixture: 'templates/single-input-with-double-submitters.html' }).as('submitted');
})

it('should have a single form value', () => {
let beforeValues;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
})
})
});

+ 0
- 28
test/integrations/single-input.e2e.ts Ver arquivo

@@ -1,28 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

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 beforeValues;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
})
})
});

+ 0
- 28
test/integrations/single-readonly-input.e2e.ts Ver arquivo

@@ -1,28 +0,0 @@
/// <reference types="cypress" />

import getFormValues from '../../src'

describe('single input 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 beforeValues;
cy
.visit('/')
.get('form')
.then((formResult) => {
const [form] = Array.from(formResult);
beforeValues = getFormValues(form);
form.submit();
cy.wait('@submitted')
cy.location('search').then(search => {
const before = new URLSearchParams(beforeValues).toString();
const after = new URLSearchParams(search).toString();
expect(before).to.equal(after);
})
})
})
});

+ 162
- 0
test/integrations/single.e2e.ts Ver arquivo

@@ -0,0 +1,162 @@
/// <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);
})
})
});

+ 2
- 5
test/utils/index.ts Ver arquivo

@@ -1,11 +1,8 @@
import fs from 'fs'
import path from 'path'
import {DOMWindow, JSDOM} from 'jsdom'

export type Window = DOMWindow

export const loadTemplate = async (templateName: string): Promise<Window> => {
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 new JSDOM(templateRaw.toString('utf-8')).window
return templateRaw.toString('utf-8')
}

+ 12
- 0
test/utils/search.ts Ver arquivo

@@ -0,0 +1,12 @@
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()
)

Carregando…
Cancelar
Salvar