1
0

CopyToClipboard.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. 'use strict';
  2. const common = require('../common');
  3. const fc = require('fast-check');
  4. describe('CopyToClipboard', function () {
  5. afterEach(() => {
  6. globalThis.cleanup();
  7. });
  8. describe('Copy document to clipboard', function () {
  9. it('Copy with button click', async function () {
  10. await fc.assert(fc.asyncProperty(
  11. common.fcFormats(),
  12. fc.string({minLength: 1}),
  13. async function (format, text) {
  14. common.enableClipboard();
  15. document.body.innerHTML = (
  16. '<div id="status" class="hidden"></div>' +
  17. '<div id="errormessage" class="hidden"></div>' +
  18. '<div id="placeholder" class="hidden">+++ no document text ' +
  19. '+++</div><div id="prettymessage" class="hidden">' +
  20. '<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
  21. '<svg id="copySuccessIcon"></svg></button><pre ' +
  22. 'id="prettyprint" class="prettyprint linenums:1"></pre>' +
  23. '</div><div id="plaintext" class="hidden"></div>' +
  24. '<h5 id="copyShortcutHint" class="hidden">' +
  25. '<button type="button" id="copyShortcutHintBtn"></button>' +
  26. '</h5>'
  27. );
  28. PrivateBin.Alert.init();
  29. PrivateBin.PasteViewer.init();
  30. PrivateBin.PasteViewer.setFormat(format);
  31. PrivateBin.PasteViewer.setText(text);
  32. PrivateBin.PasteViewer.run();
  33. PrivateBin.CopyToClipboard.init();
  34. document.getElementById('copyShortcutHintBtn').click();
  35. const savedToClipboardText = await navigator.clipboard.readText();
  36. return text === savedToClipboardText;
  37. }
  38. ));
  39. });
  40. /**
  41. * Unfortunately, in JSVerify impossible to check if copy with shortcut when user selected some text on the page
  42. * (the copy document to clipboard should not work in this case) due to lacking window.getSelection() in jsdom.
  43. */
  44. it('Copy with keyboard shortcut', async function () {
  45. await fc.assert(fc.asyncProperty(
  46. common.fcFormats(),
  47. fc.string({minLength: 1}),
  48. async function (format, text) {
  49. common.enableClipboard();
  50. document.body.innerHTML = (
  51. '<div id="status" class="hidden"></div>' +
  52. '<div id="errormessage" class="hidden"></div>' +
  53. '<div id="placeholder">+++ no document text ' +
  54. '+++</div><div id="prettymessage" class="hidden">' +
  55. '<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
  56. '<svg id="copySuccessIcon"></svg></button><pre ' +
  57. 'id="prettyprint" class="prettyprint linenums:1"></pre>' +
  58. '</div><div id="plaintext" class="hidden"></div>' +
  59. '<h5 id="copyShortcutHint" class="hidden">' +
  60. '<button type="button" id="copyShortcutHintBtn"></button>' +
  61. '</h5>'
  62. );
  63. PrivateBin.Alert.init();
  64. PrivateBin.PasteViewer.init();
  65. PrivateBin.PasteViewer.setFormat(format);
  66. PrivateBin.PasteViewer.setText(text);
  67. PrivateBin.PasteViewer.run();
  68. PrivateBin.CopyToClipboard.init();
  69. document.body.dispatchEvent(getClipboardEvent());
  70. const copiedTextWithoutSelectedText = await navigator.clipboard.readText();
  71. return copiedTextWithoutSelectedText === text;
  72. }
  73. ));
  74. });
  75. /**
  76. * ClipboardEvent is not supported in jsdom yet, so this creates a mock event to trigger the copy event listener.
  77. *
  78. * See https://github.com/jsdom/jsdom/issues/1568
  79. *
  80. * @returns {ClipboardEvent}
  81. */
  82. function getClipboardEvent() {
  83. /** {@type ClipboardEvent} */
  84. const clipboardEvent = new Event('copy', {
  85. bubbles: true,
  86. cancelable: true,
  87. composed: true
  88. });
  89. clipboardEvent['clipboardData'] = {
  90. getData: function () {
  91. return '';
  92. }
  93. }
  94. return clipboardEvent;
  95. }
  96. });
  97. it('Copy link to clipboard', async function () {
  98. await fc.assert(fc.asyncProperty(fc.string(),
  99. async function (text) {
  100. common.enableClipboard();
  101. document.body.innerHTML = (
  102. '<div id="status" class="hidden"></div>' +
  103. '<div id="errormessage" class="hidden"></div>' +
  104. '<button id="copyLink"></button>'
  105. );
  106. PrivateBin.Alert.init();
  107. PrivateBin.CopyToClipboard.init();
  108. PrivateBin.CopyToClipboard.setUrl(text);
  109. document.getElementById('copyLink').click();
  110. const copiedText = await navigator.clipboard.readText();
  111. return text === copiedText;
  112. })
  113. );
  114. });
  115. describe('Keyboard shortcut hint', function () {
  116. it('shows hint', () => {
  117. fc.assert(fc.property(fc.string(),
  118. function () {
  119. document.body.innerHTML = '<h5 id="copyShortcutHint" class="hidden"></h5>';
  120. PrivateBin.CopyToClipboard.init();
  121. PrivateBin.CopyToClipboard.showKeyboardShortcutHint();
  122. return !document.getElementById('copyShortcutHint').classList.contains('hidden');
  123. }
  124. ));
  125. });
  126. });
  127. it('Hide hint', () => {
  128. fc.assert(fc.property(
  129. fc.string({minLength: 1}),
  130. function () {
  131. document.body.innerHTML = '<h5 id="copyShortcutHint"></h5>';
  132. PrivateBin.CopyToClipboard.init();
  133. PrivateBin.CopyToClipboard.hideKeyboardShortcutHint();
  134. return document.getElementById('copyShortcutHint').classList.contains('hidden');
  135. }
  136. ));
  137. });
  138. });