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.
 
 
 

115 lines
2.4 KiB

  1. /// <reference types="node" />
  2. import { readFileSync, statSync } from 'fs'
  3. import { join, basename } from 'path'
  4. class JSDOMJQuery {
  5. private selectedElements: Node[]
  6. constructor(elements: NodeList) {
  7. this.selectedElements = Array.from(elements)
  8. }
  9. type(s: string) {
  10. this.selectedElements.forEach((el: any) => {
  11. if (el.tagName === 'TEXTAREA') {
  12. el.innerText = s
  13. el.value = s
  14. return
  15. }
  16. if (el.type === 'datetime-local') {
  17. el.value = new Date(`${s}:00.000Z`).toISOString().slice(0, 'yyyy-MM-DDTHH:mm'.length)
  18. return
  19. }
  20. el.setAttribute('value', s)
  21. el.value = s
  22. })
  23. return this
  24. }
  25. check() {
  26. this.selectedElements.forEach((el: any) => {
  27. el.setAttribute('checked', '')
  28. el.checked = true
  29. })
  30. return this
  31. }
  32. select(v: string) {
  33. this.selectedElements.forEach((el: any) => {
  34. const option: any = Array.from(el.querySelectorAll('option')).find((o: any) => o.textContent === v)
  35. option.setAttribute('selected', '')
  36. el.value = option.value
  37. })
  38. return this
  39. }
  40. last() {
  41. this.selectedElements = this.selectedElements.slice(-1)
  42. return this
  43. }
  44. then(fn: (...args: unknown[]) => unknown) {
  45. fn(this.selectedElements)
  46. return this
  47. }
  48. click() {
  49. return this
  50. }
  51. submit() {
  52. return this
  53. }
  54. invoke(key: string, value: unknown) {
  55. if (key === 'val') {
  56. this.selectedElements.forEach((el) => (el as unknown as Record<string, unknown>).valueAsNumber = value);
  57. }
  58. return this
  59. }
  60. trigger(which: string) {
  61. return this
  62. }
  63. attachFile(filename: string | string[]) {
  64. const { File, FileList } = window;
  65. const theFilenames = Array.isArray(filename) ? filename : [filename];
  66. const theFiles = theFilenames.map((f) => {
  67. const filePath = join('cypress', 'fixtures', f);
  68. const { mtimeMs: lastModified } = statSync(filePath);
  69. const contents = readFileSync(filePath);
  70. return new File(
  71. [contents],
  72. basename(filePath),
  73. {
  74. lastModified,
  75. type: '',
  76. },
  77. );
  78. });
  79. (theFiles as unknown as Record<string, unknown>).__proto__ = Object.create(FileList.prototype);
  80. this.selectedElements.forEach((el) => {
  81. Object.defineProperty(el, 'files', {
  82. value: theFiles,
  83. writable: false,
  84. })
  85. });
  86. return this;
  87. }
  88. }
  89. export default class JSDOMDummyCypress {
  90. private currentElement = window.document;
  91. wait(time: number) {
  92. return this;
  93. }
  94. get(q: string) {
  95. return new JSDOMJQuery(this.currentElement.querySelectorAll(q));
  96. }
  97. }