Extract and set form values through the DOM—no frameworks required! https://github.com/TheoryOfNekomata/formxtra
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. querySubmitter: RetrieveSubmitterFn,
  23. onSubmitted?: TestFn,
  24. expectedStaticValue?: ExpectedSearchValue,
  25. onLoaded?: TestFn,
  26. onBeforeSubmit?: RetrieveSubmitterFn,
  27. }
  28. export const test = (options: TestOptions) => {
  29. const {
  30. querySubmitter,
  31. onSubmitted,
  32. expectedStaticValue,
  33. onLoaded,
  34. onBeforeSubmit,
  35. } = options;
  36. let form: HTMLFormElement
  37. let submitter: HTMLButtonElement | HTMLInputElement
  38. let r: any
  39. if (typeof cy !== 'undefined') {
  40. cy
  41. .visit('/')
  42. .get('form')
  43. .then((formResult: any) => {
  44. [form] = Array.from(formResult);
  45. onLoaded?.(form);
  46. })
  47. onBeforeSubmit?.(cy);
  48. r = querySubmitter(cy).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. onSubmitted?.(form, submitter, search)
  59. }, 0)
  60. })
  61. } else {
  62. cy
  63. .location('search')
  64. .then((search: any) => {
  65. setTimeout(() => {
  66. onSubmitted?.(form, submitter, search)
  67. }, 0);
  68. })
  69. }
  70. } else {
  71. const jsdomCy = new JSDOMDummyCypress()
  72. onBeforeSubmit?.(jsdomCy);
  73. r = querySubmitter(jsdomCy)
  74. .then((submitterQueryEl: any) => {
  75. [submitter] = Array.from(submitterQueryEl as any[]);
  76. [form] = Array.from(window.document.getElementsByTagName('form'))
  77. onLoaded?.(form);
  78. onSubmitted?.(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. }