CopyToClipboard.js 5.7 KB

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