1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  */
    
  9. 
    
  10. 'use strict';
    
  11. 
    
  12. import {defaultBrowserChromeSize} from '../constants';
    
  13. 
    
  14. import {
    
  15.   createEventTarget,
    
  16.   describeWithPointerEvent,
    
  17.   testWithPointerType,
    
  18.   resetActivePointers,
    
  19. } from '../index';
    
  20. 
    
  21. /**
    
  22.  * Unit test helpers
    
  23.  */
    
  24. describeWithPointerEvent('describeWithPointerEvent', pointerEvent => {
    
  25.   test('provides boolean to tests', () => {
    
  26.     expect(pointerEvent).toMatchSnapshot();
    
  27.   });
    
  28. 
    
  29.   testWithPointerType('testWithPointerType', pointerType => {
    
  30.     expect(pointerType).toMatchSnapshot();
    
  31.   });
    
  32. });
    
  33. 
    
  34. /**
    
  35.  * createEventTarget
    
  36.  */
    
  37. describe('createEventTarget', () => {
    
  38.   let node;
    
  39.   beforeEach(() => {
    
  40.     node = document.createElement('div');
    
  41.   });
    
  42. 
    
  43.   afterEach(() => {
    
  44.     node = null;
    
  45.     resetActivePointers();
    
  46.   });
    
  47. 
    
  48.   test('returns expected API', () => {
    
  49.     const target = createEventTarget(node);
    
  50.     expect(target.node).toEqual(node);
    
  51.     expect(Object.keys(target)).toMatchInlineSnapshot(`
    
  52.       [
    
  53.         "node",
    
  54.         "blur",
    
  55.         "click",
    
  56.         "focus",
    
  57.         "keydown",
    
  58.         "keyup",
    
  59.         "scroll",
    
  60.         "virtualclick",
    
  61.         "contextmenu",
    
  62.         "pointercancel",
    
  63.         "pointerdown",
    
  64.         "pointerhover",
    
  65.         "pointermove",
    
  66.         "pointerenter",
    
  67.         "pointerexit",
    
  68.         "pointerup",
    
  69.         "tap",
    
  70.         "setBoundingClientRect",
    
  71.       ]
    
  72.     `);
    
  73.   });
    
  74. 
    
  75.   /**
    
  76.    * Simple events
    
  77.    */
    
  78. 
    
  79.   describe('.blur()', () => {
    
  80.     test('default', () => {
    
  81.       const target = createEventTarget(node);
    
  82.       node.addEventListener('blur', e => {
    
  83.         expect(e.relatedTarget).toMatchInlineSnapshot(`null`);
    
  84.       });
    
  85.       target.blur();
    
  86.     });
    
  87. 
    
  88.     test('custom payload', () => {
    
  89.       const target = createEventTarget(node);
    
  90.       node.addEventListener('blur', e => {
    
  91.         expect(e.relatedTarget).toMatchInlineSnapshot(`null`);
    
  92.       });
    
  93.       target.blur();
    
  94.     });
    
  95.   });
    
  96. 
    
  97.   describe('.click()', () => {
    
  98.     test('default', () => {
    
  99.       const target = createEventTarget(node);
    
  100.       node.addEventListener('click', e => {
    
  101.         expect(e.altKey).toEqual(false);
    
  102.         expect(e.button).toEqual(0);
    
  103.         expect(e.buttons).toEqual(0);
    
  104.         expect(e.clientX).toEqual(0);
    
  105.         expect(e.clientY).toEqual(0);
    
  106.         expect(e.ctrlKey).toEqual(false);
    
  107.         expect(e.detail).toEqual(1);
    
  108.         expect(typeof e.getModifierState).toEqual('function');
    
  109.         expect(e.metaKey).toEqual(false);
    
  110.         expect(e.movementX).toEqual(0);
    
  111.         expect(e.movementY).toEqual(0);
    
  112.         expect(e.offsetX).toEqual(0);
    
  113.         expect(e.offsetY).toEqual(0);
    
  114.         expect(e.pageX).toEqual(0);
    
  115.         expect(e.pageY).toEqual(0);
    
  116.         expect(typeof e.preventDefault).toEqual('function');
    
  117.         expect(e.screenX).toEqual(0);
    
  118.         expect(e.screenY).toEqual(defaultBrowserChromeSize);
    
  119.         expect(e.shiftKey).toEqual(false);
    
  120.         expect(typeof e.timeStamp).toEqual('number');
    
  121.       });
    
  122.       target.click();
    
  123.     });
    
  124. 
    
  125.     test('custom payload', () => {
    
  126.       const target = createEventTarget(node);
    
  127.       node.addEventListener('click', e => {
    
  128.         expect(e.altKey).toEqual(true);
    
  129.         expect(e.button).toEqual(1);
    
  130.         expect(e.buttons).toEqual(4);
    
  131.         expect(e.clientX).toEqual(10);
    
  132.         expect(e.clientY).toEqual(20);
    
  133.         expect(e.ctrlKey).toEqual(true);
    
  134.         expect(e.metaKey).toEqual(true);
    
  135.         expect(e.movementX).toEqual(1);
    
  136.         expect(e.movementY).toEqual(2);
    
  137.         expect(e.offsetX).toEqual(5);
    
  138.         expect(e.offsetY).toEqual(5);
    
  139.         expect(e.pageX).toEqual(50);
    
  140.         expect(e.pageY).toEqual(50);
    
  141.         expect(e.screenX).toEqual(10);
    
  142.         expect(e.screenY).toEqual(20 + defaultBrowserChromeSize);
    
  143.         expect(e.shiftKey).toEqual(true);
    
  144.       });
    
  145.       target.click({
    
  146.         altKey: true,
    
  147.         button: 1,
    
  148.         buttons: 4,
    
  149.         x: 10,
    
  150.         y: 20,
    
  151.         ctrlKey: true,
    
  152.         metaKey: true,
    
  153.         movementX: 1,
    
  154.         movementY: 2,
    
  155.         offsetX: 5,
    
  156.         offsetY: 5,
    
  157.         pageX: 50,
    
  158.         pageY: 50,
    
  159.         shiftKey: true,
    
  160.       });
    
  161.     });
    
  162.   });
    
  163. 
    
  164.   describe('.focus()', () => {
    
  165.     test('default', () => {
    
  166.       const target = createEventTarget(node);
    
  167.       node.addEventListener('focus', e => {
    
  168.         expect(e.relatedTarget).toMatchInlineSnapshot(`null`);
    
  169.       });
    
  170.       target.blur();
    
  171.     });
    
  172. 
    
  173.     test('custom payload', () => {
    
  174.       const target = createEventTarget(node);
    
  175.       node.addEventListener('focus', e => {
    
  176.         expect(e.relatedTarget).toMatchInlineSnapshot(`null`);
    
  177.       });
    
  178.       target.blur();
    
  179.     });
    
  180.   });
    
  181. 
    
  182.   describe('.keydown()', () => {
    
  183.     test('default', () => {
    
  184.       const target = createEventTarget(node);
    
  185.       node.addEventListener('keydown', e => {
    
  186.         expect(e.altKey).toEqual(false);
    
  187.         expect(e.ctrlKey).toEqual(false);
    
  188.         expect(typeof e.getModifierState).toEqual('function');
    
  189.         expect(e.key).toEqual('');
    
  190.         expect(e.metaKey).toEqual(false);
    
  191.         expect(typeof e.preventDefault).toEqual('function');
    
  192.         expect(e.shiftKey).toEqual(false);
    
  193.         expect(typeof e.timeStamp).toEqual('number');
    
  194.       });
    
  195.       target.keydown();
    
  196.     });
    
  197. 
    
  198.     test('custom payload', () => {
    
  199.       const target = createEventTarget(node);
    
  200.       node.addEventListener('keydown', e => {
    
  201.         expect(e.altKey).toEqual(true);
    
  202.         expect(e.ctrlKey).toEqual(true);
    
  203.         expect(e.isComposing).toEqual(true);
    
  204.         expect(e.key).toEqual('Enter');
    
  205.         expect(e.metaKey).toEqual(true);
    
  206.         expect(e.shiftKey).toEqual(true);
    
  207.       });
    
  208.       target.keydown({
    
  209.         altKey: true,
    
  210.         ctrlKey: true,
    
  211.         isComposing: true,
    
  212.         key: 'Enter',
    
  213.         metaKey: true,
    
  214.         shiftKey: true,
    
  215.       });
    
  216.     });
    
  217.   });
    
  218. 
    
  219.   describe('.keyup()', () => {
    
  220.     test('default', () => {
    
  221.       const target = createEventTarget(node);
    
  222.       node.addEventListener('keyup', e => {
    
  223.         expect(e.altKey).toEqual(false);
    
  224.         expect(e.ctrlKey).toEqual(false);
    
  225.         expect(typeof e.getModifierState).toEqual('function');
    
  226.         expect(e.key).toEqual('');
    
  227.         expect(e.metaKey).toEqual(false);
    
  228.         expect(typeof e.preventDefault).toEqual('function');
    
  229.         expect(e.shiftKey).toEqual(false);
    
  230.         expect(typeof e.timeStamp).toEqual('number');
    
  231.       });
    
  232.       target.keydown();
    
  233.     });
    
  234. 
    
  235.     test('custom payload', () => {
    
  236.       const target = createEventTarget(node);
    
  237.       node.addEventListener('keyup', e => {
    
  238.         expect(e.altKey).toEqual(true);
    
  239.         expect(e.ctrlKey).toEqual(true);
    
  240.         expect(e.isComposing).toEqual(true);
    
  241.         expect(e.key).toEqual('Enter');
    
  242.         expect(e.metaKey).toEqual(true);
    
  243.         expect(e.shiftKey).toEqual(true);
    
  244.       });
    
  245.       target.keyup({
    
  246.         altKey: true,
    
  247.         ctrlKey: true,
    
  248.         isComposing: true,
    
  249.         key: 'Enter',
    
  250.         metaKey: true,
    
  251.         shiftKey: true,
    
  252.       });
    
  253.     });
    
  254.   });
    
  255. 
    
  256.   describe('.scroll()', () => {
    
  257.     test('default', () => {
    
  258.       const target = createEventTarget(node);
    
  259.       node.addEventListener('scroll', e => {
    
  260.         expect(e.type).toEqual('scroll');
    
  261.       });
    
  262.       target.scroll();
    
  263.     });
    
  264.   });
    
  265. 
    
  266.   describe('.virtualclick()', () => {
    
  267.     test('default', () => {
    
  268.       const target = createEventTarget(node);
    
  269.       node.addEventListener('click', e => {
    
  270.         expect(e.altKey).toEqual(false);
    
  271.         expect(e.button).toEqual(0);
    
  272.         expect(e.buttons).toEqual(0);
    
  273.         expect(e.clientX).toEqual(0);
    
  274.         expect(e.clientY).toEqual(0);
    
  275.         expect(e.ctrlKey).toEqual(false);
    
  276.         expect(e.detail).toEqual(0);
    
  277.         expect(typeof e.getModifierState).toEqual('function');
    
  278.         expect(e.metaKey).toEqual(false);
    
  279.         expect(e.movementX).toEqual(0);
    
  280.         expect(e.movementY).toEqual(0);
    
  281.         expect(e.offsetX).toEqual(0);
    
  282.         expect(e.offsetY).toEqual(0);
    
  283.         expect(e.pageX).toEqual(0);
    
  284.         expect(e.pageY).toEqual(0);
    
  285.         expect(typeof e.preventDefault).toEqual('function');
    
  286.         expect(e.screenX).toEqual(0);
    
  287.         expect(e.screenY).toEqual(0);
    
  288.         expect(e.shiftKey).toEqual(false);
    
  289.         expect(typeof e.timeStamp).toEqual('number');
    
  290.       });
    
  291.       target.virtualclick();
    
  292.     });
    
  293. 
    
  294.     test('custom payload', () => {
    
  295.       const target = createEventTarget(node);
    
  296.       node.addEventListener('click', e => {
    
  297.         // expect most of the custom payload to be ignored
    
  298.         expect(e.altKey).toEqual(true);
    
  299.         expect(e.button).toEqual(1);
    
  300.         expect(e.buttons).toEqual(0);
    
  301.         expect(e.clientX).toEqual(0);
    
  302.         expect(e.clientY).toEqual(0);
    
  303.         expect(e.ctrlKey).toEqual(true);
    
  304.         expect(e.detail).toEqual(0);
    
  305.         expect(e.metaKey).toEqual(true);
    
  306.         expect(e.pageX).toEqual(0);
    
  307.         expect(e.pageY).toEqual(0);
    
  308.         expect(e.screenX).toEqual(0);
    
  309.         expect(e.screenY).toEqual(0);
    
  310.         expect(e.shiftKey).toEqual(true);
    
  311.       });
    
  312.       target.virtualclick({
    
  313.         altKey: true,
    
  314.         button: 1,
    
  315.         buttons: 4,
    
  316.         x: 10,
    
  317.         y: 20,
    
  318.         ctrlKey: true,
    
  319.         metaKey: true,
    
  320.         pageX: 50,
    
  321.         pageY: 50,
    
  322.         shiftKey: true,
    
  323.       });
    
  324.     });
    
  325.   });
    
  326. 
    
  327.   /**
    
  328.    * Complex event sequences
    
  329.    *
    
  330.    * ...coming soon
    
  331.    */
    
  332. 
    
  333.   /**
    
  334.    * Other APIs
    
  335.    */
    
  336. 
    
  337.   test('.setBoundingClientRect()', () => {
    
  338.     const target = createEventTarget(node);
    
  339.     expect(node.getBoundingClientRect()).toMatchInlineSnapshot(`
    
  340.       {
    
  341.         "bottom": 0,
    
  342.         "height": 0,
    
  343.         "left": 0,
    
  344.         "right": 0,
    
  345.         "top": 0,
    
  346.         "width": 0,
    
  347.         "x": 0,
    
  348.         "y": 0,
    
  349.       }
    
  350.     `);
    
  351.     target.setBoundingClientRect({x: 10, y: 20, width: 100, height: 200});
    
  352.     expect(node.getBoundingClientRect()).toMatchInlineSnapshot(`
    
  353.       {
    
  354.         "bottom": 220,
    
  355.         "height": 200,
    
  356.         "left": 10,
    
  357.         "right": 110,
    
  358.         "top": 20,
    
  359.         "width": 100,
    
  360.       }
    
  361.     `);
    
  362.   });
    
  363. });