Extract and set form values through the DOM—no frameworks required! https://github.com/TheoryOfNekomata/formxtra
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

144 rivejä
3.7 KiB

  1. /// <reference types="cypress" />
  2. import JSDOMDummyCypress from './jsdom-compat'
  3. type ExpectedSearchValue = any
  4. type RetrieveSubmitterFn = (wrapper: typeof cy | JSDOMDummyCypress) => any
  5. type HTMLSubmitterElement = HTMLButtonElement | HTMLInputElement
  6. type TestFn = (form: HTMLFormElement, submitter: HTMLSubmitterElement, after: ExpectedSearchValue) => unknown
  7. export const setup = (template: string) => {
  8. if (typeof cy !== 'undefined') {
  9. return () => {
  10. cy.intercept({ url: '/' }, { body: template }).as('loaded');
  11. cy.intercept({ url: '/?*' }, { body: template }).as('submitted');
  12. }
  13. }
  14. return () => {
  15. // @ts-ignore
  16. window.document.open(undefined, undefined, undefined, true)
  17. window.document.write(template)
  18. window.document.close()
  19. }
  20. }
  21. type TestOptions = {
  22. actionBeforeSubmit: RetrieveSubmitterFn,
  23. onSubmitted: TestFn,
  24. expectedStaticValue?: ExpectedSearchValue,
  25. onLoaded?: Function,
  26. }
  27. export const test = (options: TestOptions) => {
  28. const {
  29. actionBeforeSubmit: retrieveSubmitterFn,
  30. onSubmitted: testFn,
  31. expectedStaticValue,
  32. onLoaded,
  33. } = options;
  34. let form: HTMLFormElement
  35. let submitter: HTMLButtonElement | HTMLInputElement
  36. let r: any
  37. if (typeof cy !== 'undefined') {
  38. cy
  39. .visit('/')
  40. .get('form')
  41. .then((formResult: any) => {
  42. [form] = Array.from(formResult);
  43. if (typeof onLoaded === 'function') {
  44. onLoaded(form);
  45. }
  46. })
  47. r = retrieveSubmitterFn(cy)
  48. .then((submitterQueryEl: any) => {
  49. [submitter] = Array.from(submitterQueryEl as any[])
  50. })
  51. if (typeof expectedStaticValue !== 'undefined') {
  52. r.click()
  53. cy
  54. .wait('@submitted')
  55. .location('search')
  56. .then((search: any) => {
  57. setTimeout(() => {
  58. testFn(form, submitter, search)
  59. }, 0)
  60. })
  61. } else {
  62. cy
  63. .location('search')
  64. .then((search: any) => {
  65. setTimeout(() => {
  66. testFn(form, submitter, search)
  67. }, 0);
  68. })
  69. }
  70. } else {
  71. r = retrieveSubmitterFn(new JSDOMDummyCypress())
  72. .then((submitterQueryEl: any) => {
  73. [submitter] = Array.from(submitterQueryEl as any[]);
  74. [form] = Array.from(window.document.getElementsByTagName('form'))
  75. if (typeof onLoaded === 'function') {
  76. onLoaded(form);
  77. }
  78. testFn(form, submitter, expectedStaticValue)
  79. })
  80. if (typeof expectedStaticValue !== 'undefined') {
  81. r.click()
  82. }
  83. }
  84. }
  85. export const makeSearchParams = (beforeValues: Record<string, unknown> | string) => {
  86. switch (typeof (beforeValues as unknown)) {
  87. case 'string':
  88. return new URLSearchParams(beforeValues as string)
  89. case 'object':
  90. return Object
  91. .entries(beforeValues)
  92. .filter(([k]) => k.trim().length > 0)
  93. .reduce(
  94. (beforeSearchParams, [key, value]) => {
  95. const theValue = !Array.isArray(value) ? [value] : value
  96. theValue.forEach(v => {
  97. let processedLineBreaks = v
  98. if (typeof v === 'object' && v.__proto__.constructor.name === 'TextualValueString') {
  99. beforeSearchParams.append(key, v);
  100. const vStr = v as Record<string, string>;
  101. beforeSearchParams.append(vStr.dirName, vStr.dir);
  102. return;
  103. }
  104. if (typeof cy !== 'undefined' && typeof v === 'string') {
  105. let forceLineBreaks: string;
  106. // TODO make this foolproof
  107. if (navigator.platform.indexOf("Mac") === 0 ||
  108. navigator.platform === "iPhone") {
  109. forceLineBreaks = '\n';
  110. } else if (navigator.platform === 'Win32') {
  111. forceLineBreaks = '\r\n';
  112. }
  113. processedLineBreaks = processedLineBreaks
  114. .replace(/(\r\n|\r|\n)/g, forceLineBreaks)
  115. }
  116. beforeSearchParams.append(key, processedLineBreaks)
  117. })
  118. return beforeSearchParams
  119. },
  120. new URLSearchParams()
  121. )
  122. default:
  123. break
  124. }
  125. throw new TypeError('Invalid parameter.')
  126. }