How to use getInstanceFromNode method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ResponderEventPlugin-test.internal.js

Source:ResponderEventPlugin-test.internal.js Github

copy

Full Screen

...73 activeTouchObjects,74 changedTouchObjects,75 ),76 topLevelType: topType,77 targetInst: getInstanceFromNode(targetNodeHandle),78 };79};80/**81 * Creates test data for touch events using environment agnostic "node82 * handles".83 *84 * @param {NodeHandle} nodeHandle Environment agnostic handle to DOM node.85 * @param {Array<NodeHandle>} allTouchHandles Encoding of all "touches" in the86 * form of a mapping from integer (touch `identifier`) to touch target. This is87 * encoded in array form. Because of this, it is possible for two separate88 * touches (meaning two separate indices) to have the same touch target ID -89 * this corresponds to real world cases where two separate unique touches have90 * the same target. These touches don't just represent all active touches,91 * rather it also includes any touches that are not active, but are in the92 * process of being removed.93 * @param {Array<NodeHandle>} changedIndices Indices of `allTouchHandles` that94 * have changed.95 * @return {object} Config data used by test cases for extracting responder96 * events.97 */98const startConfig = function(nodeHandle, allTouchHandles, changedIndices) {99 return _touchConfig(100 'topTouchStart',101 nodeHandle,102 allTouchHandles,103 changedIndices,104 nodeHandle,105 );106};107/**108 * @see `startConfig`109 */110const moveConfig = function(nodeHandle, allTouchHandles, changedIndices) {111 return _touchConfig(112 'topTouchMove',113 nodeHandle,114 allTouchHandles,115 changedIndices,116 nodeHandle,117 );118};119/**120 * @see `startConfig`121 */122const endConfig = function(nodeHandle, allTouchHandles, changedIndices) {123 return _touchConfig(124 'topTouchEnd',125 nodeHandle,126 allTouchHandles,127 changedIndices,128 nodeHandle,129 );130};131/**132 * Test config for events that aren't negotiation related, but rather result of133 * a negotiation.134 *135 * Returns object of the form:136 *137 * {138 * responderReject: {139 * // Whatever "readableIDToID" was passed in.140 * grandParent: {order: NA, assertEvent: null, returnVal: blah},141 * ...142 * child: {order: NA, assertEvent: null, returnVal: blah},143 * }144 * responderGrant: {145 * grandParent: {order: NA, assertEvent: null, returnVal: blah},146 * ...147 * child: {order: NA, assertEvent: null, returnVal: blah}148 * }149 * ...150 * }151 *152 * After this is created, a test case would configure specific event orderings153 * and optional assertions. Anything left with an `order` of `NA` will be154 * required to never be invoked (the test runner will make sure it throws if155 * ever invoked).156 *157 */158const NA = -1;159const oneEventLoopTestConfig = function(readableIDToID) {160 const ret = {161 // Negotiation162 scrollShouldSetResponder: {bubbled: {}, captured: {}},163 startShouldSetResponder: {bubbled: {}, captured: {}},164 moveShouldSetResponder: {bubbled: {}, captured: {}},165 responderTerminationRequest: {},166 // Non-negotiation167 responderReject: {}, // These do not bubble capture.168 responderGrant: {},169 responderStart: {},170 responderMove: {},171 responderTerminate: {},172 responderEnd: {},173 responderRelease: {},174 };175 for (const eventName in ret) {176 for (const readableNodeName in readableIDToID) {177 if (ret[eventName].bubbled) {178 // Two phase179 ret[eventName].bubbled[readableNodeName] = {180 order: NA,181 assertEvent: null,182 returnVal: undefined,183 };184 ret[eventName].captured[readableNodeName] = {185 order: NA,186 assertEvent: null,187 returnVal: undefined,188 };189 } else {190 ret[eventName][readableNodeName] = {191 order: NA,192 assertEvent: null,193 returnVal: undefined,194 };195 }196 }197 }198 return ret;199};200/**201 * @param {object} eventTestConfig202 * @param {object} readableIDToID203 */204const registerTestHandlers = function(eventTestConfig, readableIDToID) {205 const runs = {dispatchCount: 0};206 const neverFire = function(readableID, registrationName) {207 runs.dispatchCount++;208 expect('').toBe(209 'Event type: ' +210 registrationName +211 '\nShould never occur on:' +212 readableID +213 '\nFor event test config:\n' +214 JSON.stringify(eventTestConfig) +215 '\n',216 );217 };218 const registerOneEventType = function(registrationName, eventTypeTestConfig) {219 for (const readableID in eventTypeTestConfig) {220 const nodeConfig = eventTypeTestConfig[readableID];221 const id = readableIDToID[readableID];222 const handler =223 nodeConfig.order === NA224 ? neverFire.bind(null, readableID, registrationName)225 : // We partially apply readableID and nodeConfig, as they change in the226 // parent closure across iterations.227 function(rID, config, e) {228 expect(229 rID +230 '->' +231 registrationName +232 ' index:' +233 runs.dispatchCount++,234 ).toBe(rID + '->' + registrationName + ' index:' + config.order);235 if (config.assertEvent) {236 config.assertEvent(e);237 }238 return config.returnVal;239 }.bind(null, readableID, nodeConfig);240 putListener(getInstanceFromNode(id), registrationName, handler);241 }242 };243 for (const eventName in eventTestConfig) {244 const oneEventTypeTestConfig = eventTestConfig[eventName];245 const hasTwoPhase = !!oneEventTypeTestConfig.bubbled;246 if (hasTwoPhase) {247 registerOneEventType(248 ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames249 .bubbled,250 oneEventTypeTestConfig.bubbled,251 );252 registerOneEventType(253 ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames254 .captured,255 oneEventTypeTestConfig.captured,256 );257 } else {258 registerOneEventType(259 ResponderEventPlugin.eventTypes[eventName].registrationName,260 oneEventTypeTestConfig,261 );262 }263 }264 return runs;265};266const run = function(config, hierarchyConfig, nativeEventConfig) {267 let max = NA;268 const searchForMax = function(nodeConfig) {269 for (const readableID in nodeConfig) {270 const order = nodeConfig[readableID].order;271 max = order > max ? order : max;272 }273 };274 for (const eventName in config) {275 const eventConfig = config[eventName];276 if (eventConfig.bubbled) {277 searchForMax(eventConfig.bubbled);278 searchForMax(eventConfig.captured);279 } else {280 searchForMax(eventConfig);281 }282 }283 // Register the handlers284 const runData = registerTestHandlers(config, hierarchyConfig);285 // Trigger the event286 const extractedEvents = ResponderEventPlugin.extractEvents(287 nativeEventConfig.topLevelType,288 nativeEventConfig.targetInst,289 nativeEventConfig.nativeEvent,290 nativeEventConfig.target,291 );292 // At this point the negotiation events have been dispatched as part of the293 // extraction process, but not the side effectful events. Below, we dispatch294 // side effectful events.295 EventPluginHub.runEventsInBatch(extractedEvents, true);296 // Ensure that every event that declared an `order`, was actually dispatched.297 expect('number of events dispatched:' + runData.dispatchCount).toBe(298 'number of events dispatched:' + (max + 1),299 ); // +1 for extra ++300};301const GRANDPARENT_HOST_NODE = {};302const PARENT_HOST_NODE = {};303const CHILD_HOST_NODE = {};304const CHILD_HOST_NODE2 = {};305// These intentionally look like Fibers. ReactTreeTraversal depends on their field names.306// TODO: we could test this with regular DOM nodes (and real fibers) instead.307const GRANDPARENT_INST = {308 return: null,309 tag: HostComponent,310 stateNode: GRANDPARENT_HOST_NODE,311 memoizedProps: {},312};313const PARENT_INST = {314 return: GRANDPARENT_INST,315 tag: HostComponent,316 stateNode: PARENT_HOST_NODE,317 memoizedProps: {},318};319const CHILD_INST = {320 return: PARENT_INST,321 tag: HostComponent,322 stateNode: CHILD_HOST_NODE,323 memoizedProps: {},324};325const CHILD_INST2 = {326 return: PARENT_INST,327 tag: HostComponent,328 stateNode: CHILD_HOST_NODE2,329 memoizedProps: {},330};331GRANDPARENT_HOST_NODE.testInstance = GRANDPARENT_INST;332PARENT_HOST_NODE.testInstance = PARENT_INST;333CHILD_HOST_NODE.testInstance = CHILD_INST;334CHILD_HOST_NODE2.testInstance = CHILD_INST2;335const three = {336 grandParent: GRANDPARENT_HOST_NODE,337 parent: PARENT_HOST_NODE,338 child: CHILD_HOST_NODE,339};340const siblings = {341 parent: PARENT_HOST_NODE,342 childOne: CHILD_HOST_NODE,343 childTwo: CHILD_HOST_NODE2,344};345function getInstanceFromNode(node) {346 return node.testInstance;347}348function getNodeFromInstance(inst) {349 return inst.stateNode;350}351function getFiberCurrentPropsFromNode(node) {352 return node.testInstance.memoizedProps;353}354function putListener(instance, registrationName, handler) {355 instance.memoizedProps[registrationName] = handler;356}357function deleteAllListeners(instance) {358 instance.memoizedProps = {};359}360describe('ResponderEventPlugin', () => {361 beforeEach(() => {362 jest.resetModules();363 const ReactDOM = require('react-dom');364 const ReactDOMUnstableNativeDependencies = require('react-dom/unstable-native-dependencies');365 EventPluginHub =366 ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED367 .EventPluginHub;368 const injectComponentTree =369 ReactDOMUnstableNativeDependencies.injectComponentTree;370 ResponderEventPlugin =371 ReactDOMUnstableNativeDependencies.ResponderEventPlugin;372 deleteAllListeners(GRANDPARENT_INST);373 deleteAllListeners(PARENT_INST);374 deleteAllListeners(CHILD_INST);375 deleteAllListeners(CHILD_INST2);376 injectComponentTree({377 getInstanceFromNode,378 getNodeFromInstance,379 getFiberCurrentPropsFromNode,380 });381 });382 it('should do nothing when no one wants to respond', () => {383 let config = oneEventLoopTestConfig(three);384 config.startShouldSetResponder.captured.grandParent = {385 order: 0,386 returnVal: false,387 };388 config.startShouldSetResponder.captured.parent = {389 order: 1,390 returnVal: false,391 };392 config.startShouldSetResponder.captured.child = {393 order: 2,394 returnVal: false,395 };396 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};397 config.startShouldSetResponder.bubbled.parent = {398 order: 4,399 returnVal: false,400 };401 config.startShouldSetResponder.bubbled.grandParent = {402 order: 5,403 returnVal: false,404 };405 run(config, three, startConfig(three.child, [three.child], [0]));406 expect(ResponderEventPlugin._getResponder()).toBe(null);407 // Now no handlers should be called on `touchEnd`.408 config = oneEventLoopTestConfig(three);409 run(config, three, endConfig(three.child, [three.child], [0]));410 expect(ResponderEventPlugin._getResponder()).toBe(null);411 });412 /**413 * Simple Start Granting414 * --------------------415 */416 it('should grant responder grandParent while capturing', () => {417 let config = oneEventLoopTestConfig(three);418 config.startShouldSetResponder.captured.grandParent = {419 order: 0,420 returnVal: true,421 };422 config.responderGrant.grandParent = {order: 1};423 config.responderStart.grandParent = {order: 2};424 run(config, three, startConfig(three.child, [three.child], [0]));425 expect(ResponderEventPlugin._getResponder()).toBe(426 getInstanceFromNode(three.grandParent),427 );428 config = oneEventLoopTestConfig(three);429 config.responderEnd.grandParent = {order: 0};430 config.responderRelease.grandParent = {order: 1};431 run(config, three, endConfig(three.child, [three.child], [0]));432 expect(ResponderEventPlugin._getResponder()).toBe(null);433 });434 it('should grant responder parent while capturing', () => {435 let config = oneEventLoopTestConfig(three);436 config.startShouldSetResponder.captured.grandParent = {437 order: 0,438 returnVal: false,439 };440 config.startShouldSetResponder.captured.parent = {441 order: 1,442 returnVal: true,443 };444 config.responderGrant.parent = {order: 2};445 config.responderStart.parent = {order: 3};446 run(config, three, startConfig(three.child, [three.child], [0]));447 expect(ResponderEventPlugin._getResponder()).toBe(448 getInstanceFromNode(three.parent),449 );450 config = oneEventLoopTestConfig(three);451 config.responderEnd.parent = {order: 0};452 config.responderRelease.parent = {order: 1};453 run(config, three, endConfig(three.child, [three.child], [0]));454 expect(ResponderEventPlugin._getResponder()).toBe(null);455 });456 it('should grant responder child while capturing', () => {457 let config = oneEventLoopTestConfig(three);458 config.startShouldSetResponder.captured.grandParent = {459 order: 0,460 returnVal: false,461 };462 config.startShouldSetResponder.captured.parent = {463 order: 1,464 returnVal: false,465 };466 config.startShouldSetResponder.captured.child = {order: 2, returnVal: true};467 config.responderGrant.child = {order: 3};468 config.responderStart.child = {order: 4};469 run(config, three, startConfig(three.child, [three.child], [0]));470 expect(ResponderEventPlugin._getResponder()).toBe(471 getInstanceFromNode(three.child),472 );473 config = oneEventLoopTestConfig(three);474 config.responderEnd.child = {order: 0};475 config.responderRelease.child = {order: 1};476 run(config, three, endConfig(three.child, [three.child], [0]));477 expect(ResponderEventPlugin._getResponder()).toBe(null);478 });479 it('should grant responder child while bubbling', () => {480 let config = oneEventLoopTestConfig(three);481 config.startShouldSetResponder.captured.grandParent = {482 order: 0,483 returnVal: false,484 };485 config.startShouldSetResponder.captured.parent = {486 order: 1,487 returnVal: false,488 };489 config.startShouldSetResponder.captured.child = {490 order: 2,491 returnVal: false,492 };493 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};494 config.responderGrant.child = {order: 4};495 config.responderStart.child = {order: 5};496 run(config, three, startConfig(three.child, [three.child], [0]));497 expect(ResponderEventPlugin._getResponder()).toBe(498 getInstanceFromNode(three.child),499 );500 config = oneEventLoopTestConfig(three);501 config.responderEnd.child = {order: 0};502 config.responderRelease.child = {order: 1};503 run(config, three, endConfig(three.child, [three.child], [0]));504 expect(ResponderEventPlugin._getResponder()).toBe(null);505 });506 it('should grant responder parent while bubbling', () => {507 let config = oneEventLoopTestConfig(three);508 config.startShouldSetResponder.captured.grandParent = {509 order: 0,510 returnVal: false,511 };512 config.startShouldSetResponder.captured.parent = {513 order: 1,514 returnVal: false,515 };516 config.startShouldSetResponder.captured.child = {517 order: 2,518 returnVal: false,519 };520 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};521 config.startShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};522 config.responderGrant.parent = {order: 5};523 config.responderStart.parent = {order: 6};524 run(config, three, startConfig(three.child, [three.child], [0]));525 expect(ResponderEventPlugin._getResponder()).toBe(526 getInstanceFromNode(three.parent),527 );528 config = oneEventLoopTestConfig(three);529 config.responderEnd.parent = {order: 0};530 config.responderRelease.parent = {order: 1};531 run(config, three, endConfig(three.child, [three.child], [0]));532 expect(ResponderEventPlugin._getResponder()).toBe(null);533 });534 it('should grant responder grandParent while bubbling', () => {535 let config = oneEventLoopTestConfig(three);536 config.startShouldSetResponder.captured.grandParent = {537 order: 0,538 returnVal: false,539 };540 config.startShouldSetResponder.captured.parent = {541 order: 1,542 returnVal: false,543 };544 config.startShouldSetResponder.captured.child = {545 order: 2,546 returnVal: false,547 };548 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};549 config.startShouldSetResponder.bubbled.parent = {550 order: 4,551 returnVal: false,552 };553 config.startShouldSetResponder.bubbled.grandParent = {554 order: 5,555 returnVal: true,556 };557 config.responderGrant.grandParent = {order: 6};558 config.responderStart.grandParent = {order: 7};559 run(config, three, startConfig(three.child, [three.child], [0]));560 expect(ResponderEventPlugin._getResponder()).toBe(561 getInstanceFromNode(three.grandParent),562 );563 config = oneEventLoopTestConfig(three);564 config.responderEnd.grandParent = {order: 0};565 config.responderRelease.grandParent = {order: 1};566 run(config, three, endConfig(three.child, [three.child], [0]));567 expect(ResponderEventPlugin._getResponder()).toBe(null);568 });569 /**570 * Simple Move Granting571 * --------------------572 */573 it('should grant responder grandParent while capturing move', () => {574 let config = oneEventLoopTestConfig(three);575 config.startShouldSetResponder.captured.grandParent = {order: 0};576 config.startShouldSetResponder.captured.parent = {order: 1};577 config.startShouldSetResponder.captured.child = {order: 2};578 config.startShouldSetResponder.bubbled.child = {order: 3};579 config.startShouldSetResponder.bubbled.parent = {order: 4};580 config.startShouldSetResponder.bubbled.grandParent = {order: 5};581 run(config, three, startConfig(three.child, [three.child], [0]));582 config = oneEventLoopTestConfig(three);583 config.moveShouldSetResponder.captured.grandParent = {584 order: 0,585 returnVal: true,586 };587 config.responderGrant.grandParent = {order: 1};588 config.responderMove.grandParent = {order: 2};589 run(config, three, moveConfig(three.child, [three.child], [0]));590 expect(ResponderEventPlugin._getResponder()).toBe(591 getInstanceFromNode(three.grandParent),592 );593 config = oneEventLoopTestConfig(three);594 config.responderEnd.grandParent = {order: 0};595 config.responderRelease.grandParent = {order: 1};596 run(config, three, endConfig(three.child, [three.child], [0]));597 expect(ResponderEventPlugin._getResponder()).toBe(null);598 });599 it('should grant responder parent while capturing move', () => {600 let config = oneEventLoopTestConfig(three);601 config.startShouldSetResponder.captured.grandParent = {order: 0};602 config.startShouldSetResponder.captured.parent = {order: 1};603 config.startShouldSetResponder.captured.child = {order: 2};604 config.startShouldSetResponder.bubbled.child = {order: 3};605 config.startShouldSetResponder.bubbled.parent = {order: 4};606 config.startShouldSetResponder.bubbled.grandParent = {order: 5};607 run(config, three, startConfig(three.child, [three.child], [0]));608 config = oneEventLoopTestConfig(three);609 config.moveShouldSetResponder.captured.grandParent = {610 order: 0,611 returnVal: false,612 };613 config.moveShouldSetResponder.captured.parent = {order: 1, returnVal: true};614 config.responderGrant.parent = {order: 2};615 config.responderMove.parent = {order: 3};616 run(config, three, moveConfig(three.child, [three.child], [0]));617 expect(ResponderEventPlugin._getResponder()).toBe(618 getInstanceFromNode(three.parent),619 );620 config = oneEventLoopTestConfig(three);621 config.responderEnd.parent = {order: 0};622 config.responderRelease.parent = {order: 1};623 run(config, three, endConfig(three.child, [three.child], [0]));624 expect(ResponderEventPlugin._getResponder()).toBe(null);625 });626 it('should grant responder child while capturing move', () => {627 let config = oneEventLoopTestConfig(three);628 config.startShouldSetResponder.captured.grandParent = {order: 0};629 config.startShouldSetResponder.captured.parent = {order: 1};630 config.startShouldSetResponder.captured.child = {order: 2};631 config.startShouldSetResponder.bubbled.child = {order: 3};632 config.startShouldSetResponder.bubbled.parent = {order: 4};633 config.startShouldSetResponder.bubbled.grandParent = {order: 5};634 run(config, three, startConfig(three.child, [three.child], [0]));635 config = oneEventLoopTestConfig(three);636 config.moveShouldSetResponder.captured.grandParent = {637 order: 0,638 returnVal: false,639 };640 config.moveShouldSetResponder.captured.parent = {641 order: 1,642 returnVal: false,643 };644 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: true};645 config.responderGrant.child = {order: 3};646 config.responderMove.child = {order: 4};647 run(config, three, moveConfig(three.child, [three.child], [0]));648 expect(ResponderEventPlugin._getResponder()).toBe(649 getInstanceFromNode(three.child),650 );651 config = oneEventLoopTestConfig(three);652 config.responderEnd.child = {order: 0};653 config.responderRelease.child = {order: 1};654 run(config, three, endConfig(three.child, [three.child], [0]));655 expect(ResponderEventPlugin._getResponder()).toBe(null);656 });657 it('should grant responder child while bubbling move', () => {658 let config = oneEventLoopTestConfig(three);659 config.startShouldSetResponder.captured.grandParent = {order: 0};660 config.startShouldSetResponder.captured.parent = {order: 1};661 config.startShouldSetResponder.captured.child = {order: 2};662 config.startShouldSetResponder.bubbled.child = {order: 3};663 config.startShouldSetResponder.bubbled.parent = {order: 4};664 config.startShouldSetResponder.bubbled.grandParent = {order: 5};665 run(config, three, startConfig(three.child, [three.child], [0]));666 config = oneEventLoopTestConfig(three);667 config.moveShouldSetResponder.captured.grandParent = {668 order: 0,669 returnVal: false,670 };671 config.moveShouldSetResponder.captured.parent = {672 order: 1,673 returnVal: false,674 };675 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};676 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: true};677 config.responderGrant.child = {order: 4};678 config.responderMove.child = {order: 5};679 run(config, three, moveConfig(three.child, [three.child], [0]));680 expect(ResponderEventPlugin._getResponder()).toBe(681 getInstanceFromNode(three.child),682 );683 config = oneEventLoopTestConfig(three);684 config.responderEnd.child = {order: 0};685 config.responderRelease.child = {order: 1};686 run(config, three, endConfig(three.child, [three.child], [0]));687 expect(ResponderEventPlugin._getResponder()).toBe(null);688 });689 it('should grant responder parent while bubbling move', () => {690 let config = oneEventLoopTestConfig(three);691 config.startShouldSetResponder.captured.grandParent = {order: 0};692 config.startShouldSetResponder.captured.parent = {order: 1};693 config.startShouldSetResponder.captured.child = {order: 2};694 config.startShouldSetResponder.bubbled.child = {order: 3};695 config.startShouldSetResponder.bubbled.parent = {order: 4};696 config.startShouldSetResponder.bubbled.grandParent = {order: 5};697 run(config, three, startConfig(three.child, [three.child], [0]));698 config = oneEventLoopTestConfig(three);699 config.moveShouldSetResponder.captured.grandParent = {700 order: 0,701 returnVal: false,702 };703 config.moveShouldSetResponder.captured.parent = {704 order: 1,705 returnVal: false,706 };707 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};708 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};709 config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};710 config.responderGrant.parent = {order: 5};711 config.responderMove.parent = {order: 6};712 run(config, three, moveConfig(three.child, [three.child], [0]));713 expect(ResponderEventPlugin._getResponder()).toBe(714 getInstanceFromNode(three.parent),715 );716 config = oneEventLoopTestConfig(three);717 config.responderEnd.parent = {order: 0};718 config.responderRelease.parent = {order: 1};719 run(config, three, endConfig(three.child, [three.child], [0]));720 expect(ResponderEventPlugin._getResponder()).toBe(null);721 });722 it('should grant responder grandParent while bubbling move', () => {723 let config = oneEventLoopTestConfig(three);724 config.startShouldSetResponder.captured.grandParent = {order: 0};725 config.startShouldSetResponder.captured.parent = {order: 1};726 config.startShouldSetResponder.captured.child = {order: 2};727 config.startShouldSetResponder.bubbled.child = {order: 3};728 config.startShouldSetResponder.bubbled.parent = {order: 4};729 config.startShouldSetResponder.bubbled.grandParent = {order: 5};730 run(config, three, startConfig(three.child, [three.child], [0]));731 config = oneEventLoopTestConfig(three);732 config.moveShouldSetResponder.captured.grandParent = {733 order: 0,734 returnVal: false,735 };736 config.moveShouldSetResponder.captured.parent = {737 order: 1,738 returnVal: false,739 };740 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};741 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};742 config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: false};743 config.moveShouldSetResponder.bubbled.grandParent = {744 order: 5,745 returnVal: true,746 };747 config.responderGrant.grandParent = {order: 6};748 config.responderMove.grandParent = {order: 7};749 run(config, three, moveConfig(three.child, [three.child], [0]));750 expect(ResponderEventPlugin._getResponder()).toBe(751 getInstanceFromNode(three.grandParent),752 );753 config = oneEventLoopTestConfig(three);754 config.responderEnd.grandParent = {order: 0};755 config.responderRelease.grandParent = {order: 1};756 run(config, three, endConfig(three.child, [three.child], [0]));757 expect(ResponderEventPlugin._getResponder()).toBe(null);758 });759 /**760 * Common ancestor tests761 * ---------------------762 */763 it('should bubble negotiation to first common ancestor of responder', () => {764 let config = oneEventLoopTestConfig(three);765 config.startShouldSetResponder.captured.grandParent = {766 order: 0,767 returnVal: false,768 };769 config.startShouldSetResponder.captured.parent = {770 order: 1,771 returnVal: true,772 };773 config.responderGrant.parent = {order: 2};774 config.responderStart.parent = {order: 3};775 run(config, three, startConfig(three.child, [three.child], [0]));776 expect(ResponderEventPlugin._getResponder()).toBe(777 getInstanceFromNode(three.parent),778 );779 // While `parent` is still responder, we create new handlers that verify780 // the ordering of propagation, restarting the count at `0`.781 config = oneEventLoopTestConfig(three);782 config.startShouldSetResponder.captured.grandParent = {783 order: 0,784 returnVal: false,785 };786 config.startShouldSetResponder.bubbled.grandParent = {787 order: 1,788 returnVal: false,789 };790 config.responderStart.parent = {order: 2};791 run(config, three, startConfig(three.child, [three.child], [0]));792 expect(ResponderEventPlugin._getResponder()).toBe(793 getInstanceFromNode(three.parent),794 );795 config = oneEventLoopTestConfig(three);796 config.responderEnd.parent = {order: 0};797 config.responderRelease.parent = {order: 1};798 run(config, three, endConfig(three.child, [three.child], [0]));799 expect(ResponderEventPlugin._getResponder()).toBe(null);800 });801 it('should bubble negotiation to first common ancestor of responder then transfer', () => {802 let config = oneEventLoopTestConfig(three);803 config.startShouldSetResponder.captured.grandParent = {804 order: 0,805 returnVal: false,806 };807 config.startShouldSetResponder.captured.parent = {808 order: 1,809 returnVal: true,810 };811 config.responderGrant.parent = {order: 2};812 config.responderStart.parent = {order: 3};813 run(config, three, startConfig(three.child, [three.child], [0]));814 expect(ResponderEventPlugin._getResponder()).toBe(815 getInstanceFromNode(three.parent),816 );817 config = oneEventLoopTestConfig(three);818 // Parent is responder, and responder is transferred by a second touch start819 config.startShouldSetResponder.captured.grandParent = {820 order: 0,821 returnVal: true,822 };823 config.responderGrant.grandParent = {order: 1};824 config.responderTerminationRequest.parent = {order: 2, returnVal: true};825 config.responderTerminate.parent = {order: 3};826 config.responderStart.grandParent = {order: 4};827 run(828 config,829 three,830 startConfig(three.child, [three.child, three.child], [1]),831 );832 expect(ResponderEventPlugin._getResponder()).toBe(833 getInstanceFromNode(three.grandParent),834 );835 config = oneEventLoopTestConfig(three);836 config.responderEnd.grandParent = {order: 0};837 // one remains\ /one ended \838 run(config, three, endConfig(three.child, [three.child, three.child], [1]));839 expect(ResponderEventPlugin._getResponder()).toBe(840 getInstanceFromNode(three.grandParent),841 );842 config = oneEventLoopTestConfig(three);843 config.responderEnd.grandParent = {order: 0};844 config.responderRelease.grandParent = {order: 1};845 run(config, three, endConfig(three.child, [three.child], [0]));846 expect(ResponderEventPlugin._getResponder()).toBe(null);847 });848 /**849 * If nothing is responder, then the negotiation should propagate directly to850 * the deepest target in the second touch.851 */852 it('should negotiate with deepest target on second touch if nothing is responder', () => {853 // Initially nothing wants to become the responder854 let config = oneEventLoopTestConfig(three);855 config.startShouldSetResponder.captured.grandParent = {856 order: 0,857 returnVal: false,858 };859 config.startShouldSetResponder.captured.parent = {860 order: 1,861 returnVal: false,862 };863 config.startShouldSetResponder.bubbled.parent = {864 order: 2,865 returnVal: false,866 };867 config.startShouldSetResponder.bubbled.grandParent = {868 order: 3,869 returnVal: false,870 };871 run(config, three, startConfig(three.parent, [three.parent], [0]));872 expect(ResponderEventPlugin._getResponder()).toBe(null);873 config = oneEventLoopTestConfig(three);874 // Now child wants to become responder. Negotiation should bubble as deep875 // as the target is because we don't find first common ancestor (with876 // current responder) because there is no current responder.877 // (Even if this is the second active touch).878 config.startShouldSetResponder.captured.grandParent = {879 order: 0,880 returnVal: false,881 };882 config.startShouldSetResponder.captured.parent = {883 order: 1,884 returnVal: false,885 };886 config.startShouldSetResponder.captured.child = {887 order: 2,888 returnVal: false,889 };890 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};891 config.responderGrant.child = {order: 4};892 config.responderStart.child = {order: 5};893 // / Two active touches \ /one of them new\894 run(895 config,896 three,897 startConfig(three.child, [three.parent, three.child], [1]),898 );899 expect(ResponderEventPlugin._getResponder()).toBe(900 getInstanceFromNode(three.child),901 );902 // Now we remove the original first touch, keeping the second touch that903 // started within the current responder (child). Nothing changes because904 // there's still touches that started inside of the current responder.905 config = oneEventLoopTestConfig(three);906 config.responderEnd.child = {order: 0};907 // / one ended\ /one remains \908 run(909 config,910 three,911 endConfig(three.child, [three.parent, three.child], [0]),912 );913 expect(ResponderEventPlugin._getResponder()).toBe(914 getInstanceFromNode(three.child),915 );916 // Okay, now let's add back that first touch (nothing should change) and917 // then we'll try peeling back the touches in the opposite order to make918 // sure that first removing the second touch instantly causes responder to919 // be released.920 config = oneEventLoopTestConfig(three);921 config.startShouldSetResponder.captured.grandParent = {922 order: 0,923 returnVal: false,924 };925 config.startShouldSetResponder.captured.parent = {926 order: 1,927 returnVal: false,928 };929 config.startShouldSetResponder.bubbled.parent = {930 order: 2,931 returnVal: false,932 };933 config.startShouldSetResponder.bubbled.grandParent = {934 order: 3,935 returnVal: false,936 };937 // Interesting: child still gets moves even though touch target is parent!938 // Current responder gets a `responderStart` for any touch while responder.939 config.responderStart.child = {order: 4};940 // / Two active touches \ /one of them new\941 run(942 config,943 three,944 startConfig(three.parent, [three.child, three.parent], [1]),945 );946 expect(ResponderEventPlugin._getResponder()).toBe(947 getInstanceFromNode(three.child),948 );949 // Now, move that new touch that had no effect, and did not start within950 // the current responder.951 config = oneEventLoopTestConfig(three);952 config.moveShouldSetResponder.captured.grandParent = {953 order: 0,954 returnVal: false,955 };956 config.moveShouldSetResponder.captured.parent = {957 order: 1,958 returnVal: false,959 };960 config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: false};961 config.moveShouldSetResponder.bubbled.grandParent = {962 order: 3,963 returnVal: false,964 };965 // Interesting: child still gets moves even though touch target is parent!966 // Current responder gets a `responderMove` for any touch while responder.967 config.responderMove.child = {order: 4};968 // / Two active touches \ /one of them moved\969 run(970 config,971 three,972 moveConfig(three.parent, [three.child, three.parent], [1]),973 );974 expect(ResponderEventPlugin._getResponder()).toBe(975 getInstanceFromNode(three.child),976 );977 config = oneEventLoopTestConfig(three);978 config.responderEnd.child = {order: 0};979 config.responderRelease.child = {order: 1};980 // /child end \ /parent remain\981 run(982 config,983 three,984 endConfig(three.child, [three.child, three.parent], [0]),985 );986 expect(ResponderEventPlugin._getResponder()).toBe(null);987 });988 /**989 * If nothing is responder, then the negotiation should propagate directly to990 * the deepest target in the second touch.991 */992 it('should negotiate until first common ancestor when there are siblings', () => {993 // Initially nothing wants to become the responder994 let config = oneEventLoopTestConfig(siblings);995 config.startShouldSetResponder.captured.parent = {996 order: 0,997 returnVal: false,998 };999 config.startShouldSetResponder.captured.childOne = {1000 order: 1,1001 returnVal: false,1002 };1003 config.startShouldSetResponder.bubbled.childOne = {1004 order: 2,1005 returnVal: true,1006 };1007 config.responderGrant.childOne = {order: 3};1008 config.responderStart.childOne = {order: 4};1009 run(1010 config,1011 siblings,1012 startConfig(siblings.childOne, [siblings.childOne], [0]),1013 );1014 expect(ResponderEventPlugin._getResponder()).toBe(1015 getInstanceFromNode(siblings.childOne),1016 );1017 // If the touch target is the sibling item, the negotiation should only1018 // propagate to first common ancestor of current responder and sibling (so1019 // the parent).1020 config = oneEventLoopTestConfig(siblings);1021 config.startShouldSetResponder.captured.parent = {1022 order: 0,1023 returnVal: false,1024 };1025 config.startShouldSetResponder.bubbled.parent = {1026 order: 1,1027 returnVal: false,1028 };1029 config.responderStart.childOne = {order: 2};1030 const touchConfig = startConfig(1031 siblings.childTwo,1032 [siblings.childOne, siblings.childTwo],1033 [1],1034 );1035 run(config, siblings, touchConfig);1036 expect(ResponderEventPlugin._getResponder()).toBe(1037 getInstanceFromNode(siblings.childOne),1038 );1039 // move childOne1040 config = oneEventLoopTestConfig(siblings);1041 config.moveShouldSetResponder.captured.parent = {1042 order: 0,1043 returnVal: false,1044 };1045 config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};1046 config.responderMove.childOne = {order: 2};1047 run(1048 config,1049 siblings,1050 moveConfig(1051 siblings.childOne,1052 [siblings.childOne, siblings.childTwo],1053 [0],1054 ),1055 );1056 expect(ResponderEventPlugin._getResponder()).toBe(1057 getInstanceFromNode(siblings.childOne),1058 );1059 // move childTwo: Only negotiates to `parent`.1060 config = oneEventLoopTestConfig(siblings);1061 config.moveShouldSetResponder.captured.parent = {1062 order: 0,1063 returnVal: false,1064 };1065 config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};1066 config.responderMove.childOne = {order: 2};1067 run(1068 config,1069 siblings,1070 moveConfig(1071 siblings.childTwo,1072 [siblings.childOne, siblings.childTwo],1073 [1],1074 ),1075 );1076 expect(ResponderEventPlugin._getResponder()).toBe(1077 getInstanceFromNode(siblings.childOne),1078 );1079 });1080 it('should notify of being rejected. responderStart/Move happens on current responder', () => {1081 // Initially nothing wants to become the responder1082 let config = oneEventLoopTestConfig(three);1083 config.startShouldSetResponder.captured.grandParent = {1084 order: 0,1085 returnVal: false,1086 };1087 config.startShouldSetResponder.captured.parent = {1088 order: 1,1089 returnVal: false,1090 };1091 config.startShouldSetResponder.captured.child = {1092 order: 2,1093 returnVal: false,1094 };1095 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1096 config.responderGrant.child = {order: 4};1097 config.responderStart.child = {order: 5};1098 run(config, three, startConfig(three.child, [three.child], [0]));1099 expect(ResponderEventPlugin._getResponder()).toBe(1100 getInstanceFromNode(three.child),1101 );1102 // Suppose parent wants to become responder on move, and is rejected1103 config = oneEventLoopTestConfig(three);1104 config.moveShouldSetResponder.captured.grandParent = {1105 order: 0,1106 returnVal: false,1107 };1108 config.moveShouldSetResponder.captured.parent = {1109 order: 1,1110 returnVal: false,1111 };1112 config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};1113 config.responderGrant.parent = {order: 3};1114 config.responderTerminationRequest.child = {order: 4, returnVal: false};1115 config.responderReject.parent = {order: 5};1116 // The start/move should occur on the original responder if new one is rejected1117 config.responderMove.child = {order: 6};1118 let touchConfig = moveConfig(three.child, [three.child], [0]);1119 run(config, three, touchConfig);1120 expect(ResponderEventPlugin._getResponder()).toBe(1121 getInstanceFromNode(three.child),1122 );1123 config = oneEventLoopTestConfig(three);1124 config.startShouldSetResponder.captured.grandParent = {1125 order: 0,1126 returnVal: false,1127 };1128 config.startShouldSetResponder.captured.parent = {1129 order: 1,1130 returnVal: false,1131 };1132 config.startShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};1133 config.responderGrant.parent = {order: 3};1134 config.responderTerminationRequest.child = {order: 4, returnVal: false};1135 config.responderReject.parent = {order: 5};1136 // The start/move should occur on the original responder if new one is rejected1137 config.responderStart.child = {order: 6};1138 touchConfig = startConfig(three.child, [three.child, three.child], [1]);1139 run(config, three, touchConfig);1140 expect(ResponderEventPlugin._getResponder()).toBe(1141 getInstanceFromNode(three.child),1142 );1143 });1144 it('should negotiate scroll', () => {1145 // Initially nothing wants to become the responder1146 let config = oneEventLoopTestConfig(three);1147 config.startShouldSetResponder.captured.grandParent = {1148 order: 0,1149 returnVal: false,1150 };1151 config.startShouldSetResponder.captured.parent = {1152 order: 1,1153 returnVal: false,1154 };1155 config.startShouldSetResponder.captured.child = {1156 order: 2,1157 returnVal: false,1158 };1159 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1160 config.responderGrant.child = {order: 4};1161 config.responderStart.child = {order: 5};1162 run(config, three, startConfig(three.child, [three.child], [0]));1163 expect(ResponderEventPlugin._getResponder()).toBe(1164 getInstanceFromNode(three.child),1165 );1166 // If the touch target is the sibling item, the negotiation should only1167 // propagate to first common ancestor of current responder and sibling (so1168 // the parent).1169 config = oneEventLoopTestConfig(three);1170 config.scrollShouldSetResponder.captured.grandParent = {1171 order: 0,1172 returnVal: false,1173 };1174 config.scrollShouldSetResponder.captured.parent = {1175 order: 1,1176 returnVal: false,1177 };1178 config.scrollShouldSetResponder.bubbled.parent = {1179 order: 2,1180 returnVal: true,1181 };1182 config.responderGrant.parent = {order: 3};1183 config.responderTerminationRequest.child = {order: 4, returnVal: false};1184 config.responderReject.parent = {order: 5};1185 run(config, three, {1186 topLevelType: 'topScroll',1187 targetInst: getInstanceFromNode(three.parent),1188 nativeEvent: {},1189 });1190 expect(ResponderEventPlugin._getResponder()).toBe(1191 getInstanceFromNode(three.child),1192 );1193 // Now lets let the scroll take control this time.1194 config = oneEventLoopTestConfig(three);1195 config.scrollShouldSetResponder.captured.grandParent = {1196 order: 0,1197 returnVal: false,1198 };1199 config.scrollShouldSetResponder.captured.parent = {1200 order: 1,1201 returnVal: false,1202 };1203 config.scrollShouldSetResponder.bubbled.parent = {1204 order: 2,1205 returnVal: true,1206 };1207 config.responderGrant.parent = {order: 3};1208 config.responderTerminationRequest.child = {order: 4, returnVal: true};1209 config.responderTerminate.child = {order: 5};1210 run(config, three, {1211 topLevelType: 'topScroll',1212 targetInst: getInstanceFromNode(three.parent),1213 nativeEvent: {},1214 });1215 expect(ResponderEventPlugin._getResponder()).toBe(1216 getInstanceFromNode(three.parent),1217 );1218 });1219 it('should cancel correctly', () => {1220 // Initially our child becomes responder1221 let config = oneEventLoopTestConfig(three);1222 config.startShouldSetResponder.captured.grandParent = {1223 order: 0,1224 returnVal: false,1225 };1226 config.startShouldSetResponder.captured.parent = {1227 order: 1,1228 returnVal: false,1229 };1230 config.startShouldSetResponder.captured.child = {1231 order: 2,1232 returnVal: false,1233 };1234 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1235 config.responderGrant.child = {order: 4};1236 config.responderStart.child = {order: 5};1237 run(config, three, startConfig(three.child, [three.child], [0]));1238 expect(ResponderEventPlugin._getResponder()).toBe(1239 getInstanceFromNode(three.child),1240 );1241 config = oneEventLoopTestConfig(three);1242 config.responderEnd.child = {order: 0};1243 config.responderTerminate.child = {order: 1};1244 const nativeEvent = _touchConfig(1245 'topTouchCancel',1246 three.child,1247 [three.child],1248 [0],1249 );1250 run(config, three, nativeEvent);1251 expect(ResponderEventPlugin._getResponder()).toBe(null);1252 });1253 it('should determine the first common ancestor correctly', () => {1254 // This test was moved here from the ReactTreeTraversal test since only the1255 // ResponderEventPlugin uses `getLowestCommonAncestor`1256 const React = require('react');1257 const ReactTestUtils = require('react-dom/test-utils');1258 const ReactTreeTraversal = require('shared/ReactTreeTraversal');1259 const ReactDOMComponentTree = require('../../react-dom/src/client/ReactDOMComponentTree');1260 class ChildComponent extends React.Component {1261 render() {1262 return (1263 <div ref="DIV" id={this.props.id + '__DIV'}>1264 <div ref="DIV_1" id={this.props.id + '__DIV_1'} />1265 <div ref="DIV_2" id={this.props.id + '__DIV_2'} />1266 </div>1267 );1268 }1269 }1270 class ParentComponent extends React.Component {1271 render() {1272 return (1273 <div ref="P" id="P">1274 <div ref="P_P1" id="P_P1">1275 <ChildComponent ref="P_P1_C1" id="P_P1_C1" />1276 <ChildComponent ref="P_P1_C2" id="P_P1_C2" />1277 </div>1278 <div ref="P_OneOff" id="P_OneOff" />1279 </div>1280 );1281 }1282 }1283 const parent = ReactTestUtils.renderIntoDocument(<ParentComponent />);1284 const ancestors = [1285 // Common ancestor with self is self.1286 {1287 one: parent.refs.P_P1_C1.refs.DIV_1,1288 two: parent.refs.P_P1_C1.refs.DIV_1,1289 com: parent.refs.P_P1_C1.refs.DIV_1,1290 },1291 // Common ancestor with self is self - even if topmost DOM.1292 {one: parent.refs.P, two: parent.refs.P, com: parent.refs.P},1293 // Siblings1294 {1295 one: parent.refs.P_P1_C1.refs.DIV_1,1296 two: parent.refs.P_P1_C1.refs.DIV_2,1297 com: parent.refs.P_P1_C1.refs.DIV,1298 },1299 // Common ancestor with parent is the parent.1300 {1301 one: parent.refs.P_P1_C1.refs.DIV_1,1302 two: parent.refs.P_P1_C1.refs.DIV,1303 com: parent.refs.P_P1_C1.refs.DIV,1304 },1305 // Common ancestor with grandparent is the grandparent.1306 {1307 one: parent.refs.P_P1_C1.refs.DIV_1,1308 two: parent.refs.P_P1,1309 com: parent.refs.P_P1,1310 },1311 // Grandparent across subcomponent boundaries.1312 {1313 one: parent.refs.P_P1_C1.refs.DIV_1,1314 two: parent.refs.P_P1_C2.refs.DIV_1,1315 com: parent.refs.P_P1,1316 },1317 // Something deep with something one-off.1318 {1319 one: parent.refs.P_P1_C1.refs.DIV_1,1320 two: parent.refs.P_OneOff,1321 com: parent.refs.P,1322 },1323 ];1324 let i;1325 for (i = 0; i < ancestors.length; i++) {1326 const plan = ancestors[i];1327 const firstCommon = ReactTreeTraversal.getLowestCommonAncestor(1328 ReactDOMComponentTree.getInstanceFromNode(plan.one),1329 ReactDOMComponentTree.getInstanceFromNode(plan.two),1330 );1331 expect(firstCommon).toBe(1332 ReactDOMComponentTree.getInstanceFromNode(plan.com),1333 );1334 }1335 });...

Full Screen

Full Screen

ResponderEventPlugin-test.js

Source:ResponderEventPlugin-test.js Github

copy

Full Screen

...74 activeTouchObjects,75 changedTouchObjects,76 ),77 topLevelType: topType,78 targetInst: getInstanceFromNode(targetNodeHandle),79 };80};81/**82 * Creates test data for touch events using environment agnostic "node83 * handles".84 *85 * @param {NodeHandle} nodeHandle Environment agnostic handle to DOM node.86 * @param {Array<NodeHandle>} allTouchHandles Encoding of all "touches" in the87 * form of a mapping from integer (touch `identifier`) to touch target. This is88 * encoded in array form. Because of this, it is possible for two separate89 * touches (meaning two separate indices) to have the same touch target ID -90 * this corresponds to real world cases where two separate unique touches have91 * the same target. These touches don't just represent all active touches,92 * rather it also includes any touches that are not active, but are in the93 * process of being removed.94 * @param {Array<NodeHandle>} changedIndices Indices of `allTouchHandles` that95 * have changed.96 * @return {object} Config data used by test cases for extracting responder97 * events.98 */99var startConfig = function(nodeHandle, allTouchHandles, changedIndices) {100 return _touchConfig(101 'topTouchStart',102 nodeHandle,103 allTouchHandles,104 changedIndices,105 nodeHandle,106 );107};108/**109 * @see `startConfig`110 */111var moveConfig = function(nodeHandle, allTouchHandles, changedIndices) {112 return _touchConfig(113 'topTouchMove',114 nodeHandle,115 allTouchHandles,116 changedIndices,117 nodeHandle,118 );119};120/**121 * @see `startConfig`122 */123var endConfig = function(nodeHandle, allTouchHandles, changedIndices) {124 return _touchConfig(125 'topTouchEnd',126 nodeHandle,127 allTouchHandles,128 changedIndices,129 nodeHandle,130 );131};132/**133 * Test config for events that aren't negotiation related, but rather result of134 * a negotiation.135 *136 * Returns object of the form:137 *138 * {139 * responderReject: {140 * // Whatever "readableIDToID" was passed in.141 * grandParent: {order: NA, assertEvent: null, returnVal: blah},142 * ...143 * child: {order: NA, assertEvent: null, returnVal: blah},144 * }145 * responderGrant: {146 * grandParent: {order: NA, assertEvent: null, returnVal: blah},147 * ...148 * child: {order: NA, assertEvent: null, returnVal: blah}149 * }150 * ...151 * }152 *153 * After this is created, a test case would configure specific event orderings154 * and optional assertions. Anything left with an `order` of `NA` will be155 * required to never be invoked (the test runner will make sure it throws if156 * ever invoked).157 *158 */159var NA = -1;160var oneEventLoopTestConfig = function(readableIDToID) {161 var ret = {162 // Negotiation163 scrollShouldSetResponder: {bubbled: {}, captured: {}},164 startShouldSetResponder: {bubbled: {}, captured: {}},165 moveShouldSetResponder: {bubbled: {}, captured: {}},166 responderTerminationRequest: {},167 // Non-negotiation168 responderReject: {}, // These do not bubble capture.169 responderGrant: {},170 responderStart: {},171 responderMove: {},172 responderTerminate: {},173 responderEnd: {},174 responderRelease: {},175 };176 for (var eventName in ret) {177 for (var readableNodeName in readableIDToID) {178 if (ret[eventName].bubbled) {179 // Two phase180 ret[eventName].bubbled[readableNodeName] = {181 order: NA,182 assertEvent: null,183 returnVal: undefined,184 };185 ret[eventName].captured[readableNodeName] = {186 order: NA,187 assertEvent: null,188 returnVal: undefined,189 };190 } else {191 ret[eventName][readableNodeName] = {192 order: NA,193 assertEvent: null,194 returnVal: undefined,195 };196 }197 }198 }199 return ret;200};201/**202 * @param {object} eventTestConfig203 * @param {object} readableIDToID204 */205var registerTestHandlers = function(eventTestConfig, readableIDToID) {206 var runs = {dispatchCount: 0};207 var neverFire = function(readableID, registrationName) {208 runs.dispatchCount++;209 expect('').toBe(210 'Event type: ' +211 registrationName +212 '\nShould never occur on:' +213 readableID +214 '\nFor event test config:\n' +215 JSON.stringify(eventTestConfig) +216 '\n',217 );218 };219 var registerOneEventType = function(registrationName, eventTypeTestConfig) {220 for (var readableID in eventTypeTestConfig) {221 var nodeConfig = eventTypeTestConfig[readableID];222 var id = readableIDToID[readableID];223 var handler = nodeConfig.order === NA224 ? neverFire.bind(null, readableID, registrationName)225 : // We partially apply readableID and nodeConfig, as they change in the226 // parent closure across iterations.227 function(rID, config, e) {228 expect(229 rID + '->' + registrationName + ' index:' + runs.dispatchCount++,230 ).toBe(rID + '->' + registrationName + ' index:' + config.order);231 if (config.assertEvent) {232 config.assertEvent(e);233 }234 return config.returnVal;235 }.bind(null, readableID, nodeConfig);236 putListener(getInstanceFromNode(id), registrationName, handler);237 }238 };239 for (var eventName in eventTestConfig) {240 var oneEventTypeTestConfig = eventTestConfig[eventName];241 var hasTwoPhase = !!oneEventTypeTestConfig.bubbled;242 if (hasTwoPhase) {243 registerOneEventType(244 ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames245 .bubbled,246 oneEventTypeTestConfig.bubbled,247 );248 registerOneEventType(249 ResponderEventPlugin.eventTypes[eventName].phasedRegistrationNames250 .captured,251 oneEventTypeTestConfig.captured,252 );253 } else {254 registerOneEventType(255 ResponderEventPlugin.eventTypes[eventName].registrationName,256 oneEventTypeTestConfig,257 );258 }259 }260 return runs;261};262var run = function(config, hierarchyConfig, nativeEventConfig) {263 var max = NA;264 var searchForMax = function(nodeConfig) {265 for (var readableID in nodeConfig) {266 var order = nodeConfig[readableID].order;267 max = order > max ? order : max;268 }269 };270 for (var eventName in config) {271 var eventConfig = config[eventName];272 if (eventConfig.bubbled) {273 searchForMax(eventConfig.bubbled);274 searchForMax(eventConfig.captured);275 } else {276 searchForMax(eventConfig);277 }278 }279 // Register the handlers280 var runData = registerTestHandlers(config, hierarchyConfig);281 // Trigger the event282 var extractedEvents = ResponderEventPlugin.extractEvents(283 nativeEventConfig.topLevelType,284 nativeEventConfig.targetInst,285 nativeEventConfig.nativeEvent,286 nativeEventConfig.target,287 );288 // At this point the negotiation events have been dispatched as part of the289 // extraction process, but not the side effectful events. Below, we dispatch290 // side effectful events.291 EventPluginHub.enqueueEvents(extractedEvents);292 EventPluginHub.processEventQueue(true);293 // Ensure that every event that declared an `order`, was actually dispatched.294 expect('number of events dispatched:' + runData.dispatchCount).toBe(295 'number of events dispatched:' + (max + 1),296 ); // +1 for extra ++297};298var GRANDPARENT_HOST_NODE = {};299var PARENT_HOST_NODE = {};300var CHILD_HOST_NODE = {};301var CHILD_HOST_NODE2 = {};302var GRANDPARENT_INST = {303 _hostParent: null,304 _rootNodeID: '1',305 _hostNode: GRANDPARENT_HOST_NODE,306 _currentElement: {props: {}},307};308var PARENT_INST = {309 _hostParent: GRANDPARENT_INST,310 _rootNodeID: '2',311 _hostNode: PARENT_HOST_NODE,312 _currentElement: {props: {}},313};314var CHILD_INST = {315 _hostParent: PARENT_INST,316 _rootNodeID: '3',317 _hostNode: CHILD_HOST_NODE,318 _currentElement: {props: {}},319};320var CHILD_INST2 = {321 _hostParent: PARENT_INST,322 _rootNodeID: '4',323 _hostNode: CHILD_HOST_NODE2,324 _currentElement: {props: {}},325};326GRANDPARENT_HOST_NODE._reactInstance = GRANDPARENT_INST;327PARENT_HOST_NODE._reactInstance = PARENT_INST;328CHILD_HOST_NODE._reactInstance = CHILD_INST;329CHILD_HOST_NODE2._reactInstance = CHILD_INST2;330var three = {331 grandParent: GRANDPARENT_HOST_NODE,332 parent: PARENT_HOST_NODE,333 child: CHILD_HOST_NODE,334};335var siblings = {336 parent: PARENT_HOST_NODE,337 childOne: CHILD_HOST_NODE,338 childTwo: CHILD_HOST_NODE2,339};340function getInstanceFromNode(node) {341 return node._reactInstance;342}343function getNodeFromInstance(inst) {344 return inst._hostNode;345}346function putListener(node, registrationName, handler) {347 node._currentElement.props[registrationName] = handler;348}349function deleteAllListeners(node) {350 node._currentElement.props = {};351}352describe('ResponderEventPlugin', () => {353 beforeEach(() => {354 jest.resetModules();355 EventPluginHub = require('EventPluginHub');356 EventPluginUtils = require('EventPluginUtils');357 ResponderEventPlugin = require('ResponderEventPlugin');358 deleteAllListeners(GRANDPARENT_INST);359 deleteAllListeners(PARENT_INST);360 deleteAllListeners(CHILD_INST);361 deleteAllListeners(CHILD_INST2);362 EventPluginUtils.injection.injectComponentTree({363 getInstanceFromNode,364 getNodeFromInstance,365 });366 });367 it('should do nothing when no one wants to respond', () => {368 var config = oneEventLoopTestConfig(three);369 config.startShouldSetResponder.captured.grandParent = {370 order: 0,371 returnVal: false,372 };373 config.startShouldSetResponder.captured.parent = {374 order: 1,375 returnVal: false,376 };377 config.startShouldSetResponder.captured.child = {378 order: 2,379 returnVal: false,380 };381 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};382 config.startShouldSetResponder.bubbled.parent = {383 order: 4,384 returnVal: false,385 };386 config.startShouldSetResponder.bubbled.grandParent = {387 order: 5,388 returnVal: false,389 };390 run(config, three, startConfig(three.child, [three.child], [0]));391 expect(ResponderEventPlugin._getResponder()).toBe(null);392 // Now no handlers should be called on `touchEnd`.393 config = oneEventLoopTestConfig(three);394 run(config, three, endConfig(three.child, [three.child], [0]));395 expect(ResponderEventPlugin._getResponder()).toBe(null);396 });397 /**398 * Simple Start Granting399 * --------------------400 */401 it('should grant responder grandParent while capturing', () => {402 var config = oneEventLoopTestConfig(three);403 config.startShouldSetResponder.captured.grandParent = {404 order: 0,405 returnVal: true,406 };407 config.responderGrant.grandParent = {order: 1};408 config.responderStart.grandParent = {order: 2};409 run(config, three, startConfig(three.child, [three.child], [0]));410 expect(ResponderEventPlugin._getResponder()).toBe(411 getInstanceFromNode(three.grandParent),412 );413 config = oneEventLoopTestConfig(three);414 config.responderEnd.grandParent = {order: 0};415 config.responderRelease.grandParent = {order: 1};416 run(config, three, endConfig(three.child, [three.child], [0]));417 expect(ResponderEventPlugin._getResponder()).toBe(null);418 });419 it('should grant responder parent while capturing', () => {420 var config = oneEventLoopTestConfig(three);421 config.startShouldSetResponder.captured.grandParent = {422 order: 0,423 returnVal: false,424 };425 config.startShouldSetResponder.captured.parent = {426 order: 1,427 returnVal: true,428 };429 config.responderGrant.parent = {order: 2};430 config.responderStart.parent = {order: 3};431 run(config, three, startConfig(three.child, [three.child], [0]));432 expect(ResponderEventPlugin._getResponder()).toBe(433 getInstanceFromNode(three.parent),434 );435 config = oneEventLoopTestConfig(three);436 config.responderEnd.parent = {order: 0};437 config.responderRelease.parent = {order: 1};438 run(config, three, endConfig(three.child, [three.child], [0]));439 expect(ResponderEventPlugin._getResponder()).toBe(null);440 });441 it('should grant responder child while capturing', () => {442 var config = oneEventLoopTestConfig(three);443 config.startShouldSetResponder.captured.grandParent = {444 order: 0,445 returnVal: false,446 };447 config.startShouldSetResponder.captured.parent = {448 order: 1,449 returnVal: false,450 };451 config.startShouldSetResponder.captured.child = {order: 2, returnVal: true};452 config.responderGrant.child = {order: 3};453 config.responderStart.child = {order: 4};454 run(config, three, startConfig(three.child, [three.child], [0]));455 expect(ResponderEventPlugin._getResponder()).toBe(456 getInstanceFromNode(three.child),457 );458 config = oneEventLoopTestConfig(three);459 config.responderEnd.child = {order: 0};460 config.responderRelease.child = {order: 1};461 run(config, three, endConfig(three.child, [three.child], [0]));462 expect(ResponderEventPlugin._getResponder()).toBe(null);463 });464 it('should grant responder child while bubbling', () => {465 var config = oneEventLoopTestConfig(three);466 config.startShouldSetResponder.captured.grandParent = {467 order: 0,468 returnVal: false,469 };470 config.startShouldSetResponder.captured.parent = {471 order: 1,472 returnVal: false,473 };474 config.startShouldSetResponder.captured.child = {475 order: 2,476 returnVal: false,477 };478 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};479 config.responderGrant.child = {order: 4};480 config.responderStart.child = {order: 5};481 run(config, three, startConfig(three.child, [three.child], [0]));482 expect(ResponderEventPlugin._getResponder()).toBe(483 getInstanceFromNode(three.child),484 );485 config = oneEventLoopTestConfig(three);486 config.responderEnd.child = {order: 0};487 config.responderRelease.child = {order: 1};488 run(config, three, endConfig(three.child, [three.child], [0]));489 expect(ResponderEventPlugin._getResponder()).toBe(null);490 });491 it('should grant responder parent while bubbling', () => {492 var config = oneEventLoopTestConfig(three);493 config.startShouldSetResponder.captured.grandParent = {494 order: 0,495 returnVal: false,496 };497 config.startShouldSetResponder.captured.parent = {498 order: 1,499 returnVal: false,500 };501 config.startShouldSetResponder.captured.child = {502 order: 2,503 returnVal: false,504 };505 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};506 config.startShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};507 config.responderGrant.parent = {order: 5};508 config.responderStart.parent = {order: 6};509 run(config, three, startConfig(three.child, [three.child], [0]));510 expect(ResponderEventPlugin._getResponder()).toBe(511 getInstanceFromNode(three.parent),512 );513 config = oneEventLoopTestConfig(three);514 config.responderEnd.parent = {order: 0};515 config.responderRelease.parent = {order: 1};516 run(config, three, endConfig(three.child, [three.child], [0]));517 expect(ResponderEventPlugin._getResponder()).toBe(null);518 });519 it('should grant responder grandParent while bubbling', () => {520 var config = oneEventLoopTestConfig(three);521 config.startShouldSetResponder.captured.grandParent = {522 order: 0,523 returnVal: false,524 };525 config.startShouldSetResponder.captured.parent = {526 order: 1,527 returnVal: false,528 };529 config.startShouldSetResponder.captured.child = {530 order: 2,531 returnVal: false,532 };533 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: false};534 config.startShouldSetResponder.bubbled.parent = {535 order: 4,536 returnVal: false,537 };538 config.startShouldSetResponder.bubbled.grandParent = {539 order: 5,540 returnVal: true,541 };542 config.responderGrant.grandParent = {order: 6};543 config.responderStart.grandParent = {order: 7};544 run(config, three, startConfig(three.child, [three.child], [0]));545 expect(ResponderEventPlugin._getResponder()).toBe(546 getInstanceFromNode(three.grandParent),547 );548 config = oneEventLoopTestConfig(three);549 config.responderEnd.grandParent = {order: 0};550 config.responderRelease.grandParent = {order: 1};551 run(config, three, endConfig(three.child, [three.child], [0]));552 expect(ResponderEventPlugin._getResponder()).toBe(null);553 });554 /**555 * Simple Move Granting556 * --------------------557 */558 it('should grant responder grandParent while capturing move', () => {559 var config = oneEventLoopTestConfig(three);560 config.startShouldSetResponder.captured.grandParent = {order: 0};561 config.startShouldSetResponder.captured.parent = {order: 1};562 config.startShouldSetResponder.captured.child = {order: 2};563 config.startShouldSetResponder.bubbled.child = {order: 3};564 config.startShouldSetResponder.bubbled.parent = {order: 4};565 config.startShouldSetResponder.bubbled.grandParent = {order: 5};566 run(config, three, startConfig(three.child, [three.child], [0]));567 config = oneEventLoopTestConfig(three);568 config.moveShouldSetResponder.captured.grandParent = {569 order: 0,570 returnVal: true,571 };572 config.responderGrant.grandParent = {order: 1};573 config.responderMove.grandParent = {order: 2};574 run(config, three, moveConfig(three.child, [three.child], [0]));575 expect(ResponderEventPlugin._getResponder()).toBe(576 getInstanceFromNode(three.grandParent),577 );578 config = oneEventLoopTestConfig(three);579 config.responderEnd.grandParent = {order: 0};580 config.responderRelease.grandParent = {order: 1};581 run(config, three, endConfig(three.child, [three.child], [0]));582 expect(ResponderEventPlugin._getResponder()).toBe(null);583 });584 it('should grant responder parent while capturing move', () => {585 var config = oneEventLoopTestConfig(three);586 config.startShouldSetResponder.captured.grandParent = {order: 0};587 config.startShouldSetResponder.captured.parent = {order: 1};588 config.startShouldSetResponder.captured.child = {order: 2};589 config.startShouldSetResponder.bubbled.child = {order: 3};590 config.startShouldSetResponder.bubbled.parent = {order: 4};591 config.startShouldSetResponder.bubbled.grandParent = {order: 5};592 run(config, three, startConfig(three.child, [three.child], [0]));593 config = oneEventLoopTestConfig(three);594 config.moveShouldSetResponder.captured.grandParent = {595 order: 0,596 returnVal: false,597 };598 config.moveShouldSetResponder.captured.parent = {order: 1, returnVal: true};599 config.responderGrant.parent = {order: 2};600 config.responderMove.parent = {order: 3};601 run(config, three, moveConfig(three.child, [three.child], [0]));602 expect(ResponderEventPlugin._getResponder()).toBe(603 getInstanceFromNode(three.parent),604 );605 config = oneEventLoopTestConfig(three);606 config.responderEnd.parent = {order: 0};607 config.responderRelease.parent = {order: 1};608 run(config, three, endConfig(three.child, [three.child], [0]));609 expect(ResponderEventPlugin._getResponder()).toBe(null);610 });611 it('should grant responder child while capturing move', () => {612 var config = oneEventLoopTestConfig(three);613 config.startShouldSetResponder.captured.grandParent = {order: 0};614 config.startShouldSetResponder.captured.parent = {order: 1};615 config.startShouldSetResponder.captured.child = {order: 2};616 config.startShouldSetResponder.bubbled.child = {order: 3};617 config.startShouldSetResponder.bubbled.parent = {order: 4};618 config.startShouldSetResponder.bubbled.grandParent = {order: 5};619 run(config, three, startConfig(three.child, [three.child], [0]));620 config = oneEventLoopTestConfig(three);621 config.moveShouldSetResponder.captured.grandParent = {622 order: 0,623 returnVal: false,624 };625 config.moveShouldSetResponder.captured.parent = {626 order: 1,627 returnVal: false,628 };629 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: true};630 config.responderGrant.child = {order: 3};631 config.responderMove.child = {order: 4};632 run(config, three, moveConfig(three.child, [three.child], [0]));633 expect(ResponderEventPlugin._getResponder()).toBe(634 getInstanceFromNode(three.child),635 );636 config = oneEventLoopTestConfig(three);637 config.responderEnd.child = {order: 0};638 config.responderRelease.child = {order: 1};639 run(config, three, endConfig(three.child, [three.child], [0]));640 expect(ResponderEventPlugin._getResponder()).toBe(null);641 });642 it('should grant responder child while bubbling move', () => {643 var config = oneEventLoopTestConfig(three);644 config.startShouldSetResponder.captured.grandParent = {order: 0};645 config.startShouldSetResponder.captured.parent = {order: 1};646 config.startShouldSetResponder.captured.child = {order: 2};647 config.startShouldSetResponder.bubbled.child = {order: 3};648 config.startShouldSetResponder.bubbled.parent = {order: 4};649 config.startShouldSetResponder.bubbled.grandParent = {order: 5};650 run(config, three, startConfig(three.child, [three.child], [0]));651 config = oneEventLoopTestConfig(three);652 config.moveShouldSetResponder.captured.grandParent = {653 order: 0,654 returnVal: false,655 };656 config.moveShouldSetResponder.captured.parent = {657 order: 1,658 returnVal: false,659 };660 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};661 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: true};662 config.responderGrant.child = {order: 4};663 config.responderMove.child = {order: 5};664 run(config, three, moveConfig(three.child, [three.child], [0]));665 expect(ResponderEventPlugin._getResponder()).toBe(666 getInstanceFromNode(three.child),667 );668 config = oneEventLoopTestConfig(three);669 config.responderEnd.child = {order: 0};670 config.responderRelease.child = {order: 1};671 run(config, three, endConfig(three.child, [three.child], [0]));672 expect(ResponderEventPlugin._getResponder()).toBe(null);673 });674 it('should grant responder parent while bubbling move', () => {675 var config = oneEventLoopTestConfig(three);676 config.startShouldSetResponder.captured.grandParent = {order: 0};677 config.startShouldSetResponder.captured.parent = {order: 1};678 config.startShouldSetResponder.captured.child = {order: 2};679 config.startShouldSetResponder.bubbled.child = {order: 3};680 config.startShouldSetResponder.bubbled.parent = {order: 4};681 config.startShouldSetResponder.bubbled.grandParent = {order: 5};682 run(config, three, startConfig(three.child, [three.child], [0]));683 config = oneEventLoopTestConfig(three);684 config.moveShouldSetResponder.captured.grandParent = {685 order: 0,686 returnVal: false,687 };688 config.moveShouldSetResponder.captured.parent = {689 order: 1,690 returnVal: false,691 };692 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};693 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};694 config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: true};695 config.responderGrant.parent = {order: 5};696 config.responderMove.parent = {order: 6};697 run(config, three, moveConfig(three.child, [three.child], [0]));698 expect(ResponderEventPlugin._getResponder()).toBe(699 getInstanceFromNode(three.parent),700 );701 config = oneEventLoopTestConfig(three);702 config.responderEnd.parent = {order: 0};703 config.responderRelease.parent = {order: 1};704 run(config, three, endConfig(three.child, [three.child], [0]));705 expect(ResponderEventPlugin._getResponder()).toBe(null);706 });707 it('should grant responder grandParent while bubbling move', () => {708 var config = oneEventLoopTestConfig(three);709 config.startShouldSetResponder.captured.grandParent = {order: 0};710 config.startShouldSetResponder.captured.parent = {order: 1};711 config.startShouldSetResponder.captured.child = {order: 2};712 config.startShouldSetResponder.bubbled.child = {order: 3};713 config.startShouldSetResponder.bubbled.parent = {order: 4};714 config.startShouldSetResponder.bubbled.grandParent = {order: 5};715 run(config, three, startConfig(three.child, [three.child], [0]));716 config = oneEventLoopTestConfig(three);717 config.moveShouldSetResponder.captured.grandParent = {718 order: 0,719 returnVal: false,720 };721 config.moveShouldSetResponder.captured.parent = {722 order: 1,723 returnVal: false,724 };725 config.moveShouldSetResponder.captured.child = {order: 2, returnVal: false};726 config.moveShouldSetResponder.bubbled.child = {order: 3, returnVal: false};727 config.moveShouldSetResponder.bubbled.parent = {order: 4, returnVal: false};728 config.moveShouldSetResponder.bubbled.grandParent = {729 order: 5,730 returnVal: true,731 };732 config.responderGrant.grandParent = {order: 6};733 config.responderMove.grandParent = {order: 7};734 run(config, three, moveConfig(three.child, [three.child], [0]));735 expect(ResponderEventPlugin._getResponder()).toBe(736 getInstanceFromNode(three.grandParent),737 );738 config = oneEventLoopTestConfig(three);739 config.responderEnd.grandParent = {order: 0};740 config.responderRelease.grandParent = {order: 1};741 run(config, three, endConfig(three.child, [three.child], [0]));742 expect(ResponderEventPlugin._getResponder()).toBe(null);743 });744 /**745 * Common ancestor tests746 * ---------------------747 */748 it('should bubble negotiation to first common ancestor of responder', () => {749 var config = oneEventLoopTestConfig(three);750 config.startShouldSetResponder.captured.grandParent = {751 order: 0,752 returnVal: false,753 };754 config.startShouldSetResponder.captured.parent = {755 order: 1,756 returnVal: true,757 };758 config.responderGrant.parent = {order: 2};759 config.responderStart.parent = {order: 3};760 run(config, three, startConfig(three.child, [three.child], [0]));761 expect(ResponderEventPlugin._getResponder()).toBe(762 getInstanceFromNode(three.parent),763 );764 // While `parent` is still responder, we create new handlers that verify765 // the ordering of propagation, restarting the count at `0`.766 config = oneEventLoopTestConfig(three);767 config.startShouldSetResponder.captured.grandParent = {768 order: 0,769 returnVal: false,770 };771 config.startShouldSetResponder.bubbled.grandParent = {772 order: 1,773 returnVal: false,774 };775 config.responderStart.parent = {order: 2};776 run(config, three, startConfig(three.child, [three.child], [0]));777 expect(ResponderEventPlugin._getResponder()).toBe(778 getInstanceFromNode(three.parent),779 );780 config = oneEventLoopTestConfig(three);781 config.responderEnd.parent = {order: 0};782 config.responderRelease.parent = {order: 1};783 run(config, three, endConfig(three.child, [three.child], [0]));784 expect(ResponderEventPlugin._getResponder()).toBe(null);785 });786 it('should bubble negotiation to first common ancestor of responder then transfer', () => {787 var config = oneEventLoopTestConfig(three);788 config.startShouldSetResponder.captured.grandParent = {789 order: 0,790 returnVal: false,791 };792 config.startShouldSetResponder.captured.parent = {793 order: 1,794 returnVal: true,795 };796 config.responderGrant.parent = {order: 2};797 config.responderStart.parent = {order: 3};798 run(config, three, startConfig(three.child, [three.child], [0]));799 expect(ResponderEventPlugin._getResponder()).toBe(800 getInstanceFromNode(three.parent),801 );802 config = oneEventLoopTestConfig(three);803 // Parent is responder, and responder is transferred by a second touch start804 config.startShouldSetResponder.captured.grandParent = {805 order: 0,806 returnVal: true,807 };808 config.responderGrant.grandParent = {order: 1};809 config.responderTerminationRequest.parent = {order: 2, returnVal: true};810 config.responderTerminate.parent = {order: 3};811 config.responderStart.grandParent = {order: 4};812 run(813 config,814 three,815 startConfig(three.child, [three.child, three.child], [1]),816 );817 expect(ResponderEventPlugin._getResponder()).toBe(818 getInstanceFromNode(three.grandParent),819 );820 config = oneEventLoopTestConfig(three);821 config.responderEnd.grandParent = {order: 0};822 // one remains\ /one ended \823 run(config, three, endConfig(three.child, [three.child, three.child], [1]));824 expect(ResponderEventPlugin._getResponder()).toBe(825 getInstanceFromNode(three.grandParent),826 );827 config = oneEventLoopTestConfig(three);828 config.responderEnd.grandParent = {order: 0};829 config.responderRelease.grandParent = {order: 1};830 run(config, three, endConfig(three.child, [three.child], [0]));831 expect(ResponderEventPlugin._getResponder()).toBe(null);832 });833 /**834 * If nothing is responder, then the negotiation should propagate directly to835 * the deepest target in the second touch.836 */837 it('should negotiate with deepest target on second touch if nothing is responder', () => {838 // Initially nothing wants to become the responder839 var config = oneEventLoopTestConfig(three);840 config.startShouldSetResponder.captured.grandParent = {841 order: 0,842 returnVal: false,843 };844 config.startShouldSetResponder.captured.parent = {845 order: 1,846 returnVal: false,847 };848 config.startShouldSetResponder.bubbled.parent = {849 order: 2,850 returnVal: false,851 };852 config.startShouldSetResponder.bubbled.grandParent = {853 order: 3,854 returnVal: false,855 };856 run(config, three, startConfig(three.parent, [three.parent], [0]));857 expect(ResponderEventPlugin._getResponder()).toBe(null);858 config = oneEventLoopTestConfig(three);859 // Now child wants to become responder. Negotiation should bubble as deep860 // as the target is because we don't find first common ancestor (with861 // current responder) because there is no current responder.862 // (Even if this is the second active touch).863 config.startShouldSetResponder.captured.grandParent = {864 order: 0,865 returnVal: false,866 };867 config.startShouldSetResponder.captured.parent = {868 order: 1,869 returnVal: false,870 };871 config.startShouldSetResponder.captured.child = {872 order: 2,873 returnVal: false,874 };875 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};876 config.responderGrant.child = {order: 4};877 config.responderStart.child = {order: 5};878 // / Two active touches \ /one of them new\879 run(880 config,881 three,882 startConfig(three.child, [three.parent, three.child], [1]),883 );884 expect(ResponderEventPlugin._getResponder()).toBe(885 getInstanceFromNode(three.child),886 );887 // Now we remove the original first touch, keeping the second touch that888 // started within the current responder (child). Nothing changes because889 // there's still touches that started inside of the current responder.890 config = oneEventLoopTestConfig(three);891 config.responderEnd.child = {order: 0};892 // / one ended\ /one remains \893 run(894 config,895 three,896 endConfig(three.child, [three.parent, three.child], [0]),897 );898 expect(ResponderEventPlugin._getResponder()).toBe(899 getInstanceFromNode(three.child),900 );901 // Okay, now let's add back that first touch (nothing should change) and902 // then we'll try peeling back the touches in the opposite order to make903 // sure that first removing the second touch instantly causes responder to904 // be released.905 config = oneEventLoopTestConfig(three);906 config.startShouldSetResponder.captured.grandParent = {907 order: 0,908 returnVal: false,909 };910 config.startShouldSetResponder.captured.parent = {911 order: 1,912 returnVal: false,913 };914 config.startShouldSetResponder.bubbled.parent = {915 order: 2,916 returnVal: false,917 };918 config.startShouldSetResponder.bubbled.grandParent = {919 order: 3,920 returnVal: false,921 };922 // Interesting: child still gets moves even though touch target is parent!923 // Current responder gets a `responderStart` for any touch while responder.924 config.responderStart.child = {order: 4};925 // / Two active touches \ /one of them new\926 run(927 config,928 three,929 startConfig(three.parent, [three.child, three.parent], [1]),930 );931 expect(ResponderEventPlugin._getResponder()).toBe(932 getInstanceFromNode(three.child),933 );934 // Now, move that new touch that had no effect, and did not start within935 // the current responder.936 config = oneEventLoopTestConfig(three);937 config.moveShouldSetResponder.captured.grandParent = {938 order: 0,939 returnVal: false,940 };941 config.moveShouldSetResponder.captured.parent = {942 order: 1,943 returnVal: false,944 };945 config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: false};946 config.moveShouldSetResponder.bubbled.grandParent = {947 order: 3,948 returnVal: false,949 };950 // Interesting: child still gets moves even though touch target is parent!951 // Current responder gets a `responderMove` for any touch while responder.952 config.responderMove.child = {order: 4};953 // / Two active touches \ /one of them moved\954 run(955 config,956 three,957 moveConfig(three.parent, [three.child, three.parent], [1]),958 );959 expect(ResponderEventPlugin._getResponder()).toBe(960 getInstanceFromNode(three.child),961 );962 config = oneEventLoopTestConfig(three);963 config.responderEnd.child = {order: 0};964 config.responderRelease.child = {order: 1};965 // /child end \ /parent remain\966 run(967 config,968 three,969 endConfig(three.child, [three.child, three.parent], [0]),970 );971 expect(ResponderEventPlugin._getResponder()).toBe(null);972 });973 /**974 * If nothing is responder, then the negotiation should propagate directly to975 * the deepest target in the second touch.976 */977 it('should negotiate until first common ancestor when there are siblings', () => {978 // Initially nothing wants to become the responder979 var config = oneEventLoopTestConfig(siblings);980 config.startShouldSetResponder.captured.parent = {981 order: 0,982 returnVal: false,983 };984 config.startShouldSetResponder.captured.childOne = {985 order: 1,986 returnVal: false,987 };988 config.startShouldSetResponder.bubbled.childOne = {989 order: 2,990 returnVal: true,991 };992 config.responderGrant.childOne = {order: 3};993 config.responderStart.childOne = {order: 4};994 run(995 config,996 siblings,997 startConfig(siblings.childOne, [siblings.childOne], [0]),998 );999 expect(ResponderEventPlugin._getResponder()).toBe(1000 getInstanceFromNode(siblings.childOne),1001 );1002 // If the touch target is the sibling item, the negotiation should only1003 // propagate to first common ancestor of current responder and sibling (so1004 // the parent).1005 config = oneEventLoopTestConfig(siblings);1006 config.startShouldSetResponder.captured.parent = {1007 order: 0,1008 returnVal: false,1009 };1010 config.startShouldSetResponder.bubbled.parent = {1011 order: 1,1012 returnVal: false,1013 };1014 config.responderStart.childOne = {order: 2};1015 var touchConfig = startConfig(1016 siblings.childTwo,1017 [siblings.childOne, siblings.childTwo],1018 [1],1019 );1020 run(config, siblings, touchConfig);1021 expect(ResponderEventPlugin._getResponder()).toBe(1022 getInstanceFromNode(siblings.childOne),1023 );1024 // move childOne1025 config = oneEventLoopTestConfig(siblings);1026 config.moveShouldSetResponder.captured.parent = {1027 order: 0,1028 returnVal: false,1029 };1030 config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};1031 config.responderMove.childOne = {order: 2};1032 run(1033 config,1034 siblings,1035 moveConfig(1036 siblings.childOne,1037 [siblings.childOne, siblings.childTwo],1038 [0],1039 ),1040 );1041 expect(ResponderEventPlugin._getResponder()).toBe(1042 getInstanceFromNode(siblings.childOne),1043 );1044 // move childTwo: Only negotiates to `parent`.1045 config = oneEventLoopTestConfig(siblings);1046 config.moveShouldSetResponder.captured.parent = {1047 order: 0,1048 returnVal: false,1049 };1050 config.moveShouldSetResponder.bubbled.parent = {order: 1, returnVal: false};1051 config.responderMove.childOne = {order: 2};1052 run(1053 config,1054 siblings,1055 moveConfig(1056 siblings.childTwo,1057 [siblings.childOne, siblings.childTwo],1058 [1],1059 ),1060 );1061 expect(ResponderEventPlugin._getResponder()).toBe(1062 getInstanceFromNode(siblings.childOne),1063 );1064 });1065 it('should notify of being rejected. responderStart/Move happens on current responder', () => {1066 // Initially nothing wants to become the responder1067 var config = oneEventLoopTestConfig(three);1068 config.startShouldSetResponder.captured.grandParent = {1069 order: 0,1070 returnVal: false,1071 };1072 config.startShouldSetResponder.captured.parent = {1073 order: 1,1074 returnVal: false,1075 };1076 config.startShouldSetResponder.captured.child = {1077 order: 2,1078 returnVal: false,1079 };1080 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1081 config.responderGrant.child = {order: 4};1082 config.responderStart.child = {order: 5};1083 run(config, three, startConfig(three.child, [three.child], [0]));1084 expect(ResponderEventPlugin._getResponder()).toBe(1085 getInstanceFromNode(three.child),1086 );1087 // Suppose parent wants to become responder on move, and is rejected1088 config = oneEventLoopTestConfig(three);1089 config.moveShouldSetResponder.captured.grandParent = {1090 order: 0,1091 returnVal: false,1092 };1093 config.moveShouldSetResponder.captured.parent = {1094 order: 1,1095 returnVal: false,1096 };1097 config.moveShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};1098 config.responderGrant.parent = {order: 3};1099 config.responderTerminationRequest.child = {order: 4, returnVal: false};1100 config.responderReject.parent = {order: 5};1101 // The start/move should occur on the original responder if new one is rejected1102 config.responderMove.child = {order: 6};1103 var touchConfig = moveConfig(three.child, [three.child], [0]);1104 run(config, three, touchConfig);1105 expect(ResponderEventPlugin._getResponder()).toBe(1106 getInstanceFromNode(three.child),1107 );1108 config = oneEventLoopTestConfig(three);1109 config.startShouldSetResponder.captured.grandParent = {1110 order: 0,1111 returnVal: false,1112 };1113 config.startShouldSetResponder.captured.parent = {1114 order: 1,1115 returnVal: false,1116 };1117 config.startShouldSetResponder.bubbled.parent = {order: 2, returnVal: true};1118 config.responderGrant.parent = {order: 3};1119 config.responderTerminationRequest.child = {order: 4, returnVal: false};1120 config.responderReject.parent = {order: 5};1121 // The start/move should occur on the original responder if new one is rejected1122 config.responderStart.child = {order: 6};1123 touchConfig = startConfig(three.child, [three.child, three.child], [1]);1124 run(config, three, touchConfig);1125 expect(ResponderEventPlugin._getResponder()).toBe(1126 getInstanceFromNode(three.child),1127 );1128 });1129 it('should negotiate scroll', () => {1130 // Initially nothing wants to become the responder1131 var config = oneEventLoopTestConfig(three);1132 config.startShouldSetResponder.captured.grandParent = {1133 order: 0,1134 returnVal: false,1135 };1136 config.startShouldSetResponder.captured.parent = {1137 order: 1,1138 returnVal: false,1139 };1140 config.startShouldSetResponder.captured.child = {1141 order: 2,1142 returnVal: false,1143 };1144 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1145 config.responderGrant.child = {order: 4};1146 config.responderStart.child = {order: 5};1147 run(config, three, startConfig(three.child, [three.child], [0]));1148 expect(ResponderEventPlugin._getResponder()).toBe(1149 getInstanceFromNode(three.child),1150 );1151 // If the touch target is the sibling item, the negotiation should only1152 // propagate to first common ancestor of current responder and sibling (so1153 // the parent).1154 config = oneEventLoopTestConfig(three);1155 config.scrollShouldSetResponder.captured.grandParent = {1156 order: 0,1157 returnVal: false,1158 };1159 config.scrollShouldSetResponder.captured.parent = {1160 order: 1,1161 returnVal: false,1162 };1163 config.scrollShouldSetResponder.bubbled.parent = {1164 order: 2,1165 returnVal: true,1166 };1167 config.responderGrant.parent = {order: 3};1168 config.responderTerminationRequest.child = {order: 4, returnVal: false};1169 config.responderReject.parent = {order: 5};1170 run(config, three, {1171 topLevelType: 'topScroll',1172 targetInst: getInstanceFromNode(three.parent),1173 nativeEvent: {},1174 });1175 expect(ResponderEventPlugin._getResponder()).toBe(1176 getInstanceFromNode(three.child),1177 );1178 // Now lets let the scroll take control this time.1179 config = oneEventLoopTestConfig(three);1180 config.scrollShouldSetResponder.captured.grandParent = {1181 order: 0,1182 returnVal: false,1183 };1184 config.scrollShouldSetResponder.captured.parent = {1185 order: 1,1186 returnVal: false,1187 };1188 config.scrollShouldSetResponder.bubbled.parent = {1189 order: 2,1190 returnVal: true,1191 };1192 config.responderGrant.parent = {order: 3};1193 config.responderTerminationRequest.child = {order: 4, returnVal: true};1194 config.responderTerminate.child = {order: 5};1195 run(config, three, {1196 topLevelType: 'topScroll',1197 targetInst: getInstanceFromNode(three.parent),1198 nativeEvent: {},1199 });1200 expect(ResponderEventPlugin._getResponder()).toBe(1201 getInstanceFromNode(three.parent),1202 );1203 });1204 it('should cancel correctly', () => {1205 // Initially our child becomes responder1206 var config = oneEventLoopTestConfig(three);1207 config.startShouldSetResponder.captured.grandParent = {1208 order: 0,1209 returnVal: false,1210 };1211 config.startShouldSetResponder.captured.parent = {1212 order: 1,1213 returnVal: false,1214 };1215 config.startShouldSetResponder.captured.child = {1216 order: 2,1217 returnVal: false,1218 };1219 config.startShouldSetResponder.bubbled.child = {order: 3, returnVal: true};1220 config.responderGrant.child = {order: 4};1221 config.responderStart.child = {order: 5};1222 run(config, three, startConfig(three.child, [three.child], [0]));1223 expect(ResponderEventPlugin._getResponder()).toBe(1224 getInstanceFromNode(three.child),1225 );1226 config = oneEventLoopTestConfig(three);1227 config.responderEnd.child = {order: 0};1228 config.responderTerminate.child = {order: 1};1229 var nativeEvent = _touchConfig(1230 'topTouchCancel',1231 three.child,1232 [three.child],1233 [0],1234 );1235 run(config, three, nativeEvent);1236 expect(ResponderEventPlugin._getResponder()).toBe(null);1237 });1238});

Full Screen

Full Screen

ReactHostOperationHistoryHook-test.js

Source:ReactHostOperationHistoryHook-test.js Github

copy

Full Screen

...37 it('gets recorded for host roots', () => {38 var node = document.createElement('div');39 ReactHostOperationHistoryHook._preventClearing = true;40 ReactDOM.render(<div><p>Hi.</p></div>, node);41 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);42 assertHistoryMatches([43 {44 instanceID: inst._debugID,45 type: 'mount',46 payload: ReactDOMFeatureFlags.useCreateElement47 ? 'DIV'48 : '<div data-reactroot="" data-reactid="1"><p data-reactid="2">Hi.</p></div>',49 },50 ]);51 });52 it('gets recorded for composite roots', () => {53 function Foo() {54 return <div><p>Hi.</p></div>;55 }56 var node = document.createElement('div');57 ReactHostOperationHistoryHook._preventClearing = true;58 ReactDOM.render(<Foo />, node);59 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);60 assertHistoryMatches([61 {62 instanceID: inst._debugID,63 type: 'mount',64 payload: ReactDOMFeatureFlags.useCreateElement65 ? 'DIV'66 : '<div data-reactroot="" data-reactid="1">' +67 '<p data-reactid="2">Hi.</p></div>',68 },69 ]);70 });71 it('gets ignored for composite roots that return null', () => {72 function Foo() {73 return null;74 }75 var node = document.createElement('div');76 ReactHostOperationHistoryHook._preventClearing = true;77 ReactDOM.render(<Foo />, node);78 // Empty DOM components should be invisible to hooks.79 assertHistoryMatches([]);80 });81 it('gets recorded when a native is mounted deeply instead of null', () => {82 var element;83 function Foo() {84 return element;85 }86 ReactHostOperationHistoryHook._preventClearing = true;87 var node = document.createElement('div');88 element = null;89 ReactDOM.render(<Foo />, node);90 element = <span />;91 ReactDOM.render(<Foo />, node);92 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);93 // Since empty components should be invisible to hooks,94 // we record a "mount" event rather than a "replace with".95 assertHistoryMatches([96 {97 instanceID: inst._debugID,98 type: 'mount',99 payload: 'SPAN',100 },101 ]);102 });103 });104 describe('update styles', () => {105 it('gets recorded during mount', () => {106 var node = document.createElement('div');107 ReactHostOperationHistoryHook._preventClearing = true;108 ReactDOM.render(109 <div110 style={{111 color: 'red',112 backgroundColor: 'yellow',113 }}114 />,115 node,116 );117 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);118 if (ReactDOMFeatureFlags.useCreateElement) {119 assertHistoryMatches([120 {121 instanceID: inst._debugID,122 type: 'update styles',123 payload: {124 color: 'red',125 backgroundColor: 'yellow',126 },127 },128 {129 instanceID: inst._debugID,130 type: 'mount',131 payload: 'DIV',132 },133 ]);134 } else {135 assertHistoryMatches([136 {137 instanceID: inst._debugID,138 type: 'mount',139 payload:140 '<div style="color:red;background-color:yellow;" ' +141 'data-reactroot="" data-reactid="1"></div>',142 },143 ]);144 }145 });146 it('gets recorded during an update', () => {147 var node = document.createElement('div');148 ReactDOM.render(<div />, node);149 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);150 ReactHostOperationHistoryHook._preventClearing = true;151 ReactDOM.render(<div style={{color: 'red'}} />, node);152 ReactDOM.render(153 <div154 style={{155 color: 'blue',156 backgroundColor: 'yellow',157 }}158 />,159 node,160 );161 ReactDOM.render(<div style={{backgroundColor: 'green'}} />, node);162 ReactDOM.render(<div />, node);163 assertHistoryMatches([164 {165 instanceID: inst._debugID,166 type: 'update styles',167 payload: {color: 'red'},168 },169 {170 instanceID: inst._debugID,171 type: 'update styles',172 payload: {color: 'blue', backgroundColor: 'yellow'},173 },174 {175 instanceID: inst._debugID,176 type: 'update styles',177 payload: {color: '', backgroundColor: 'green'},178 },179 {180 instanceID: inst._debugID,181 type: 'update styles',182 payload: {backgroundColor: ''},183 },184 ]);185 });186 it('gets ignored if the styles are shallowly equal', () => {187 var node = document.createElement('div');188 ReactDOM.render(<div />, node);189 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);190 ReactHostOperationHistoryHook._preventClearing = true;191 ReactDOM.render(192 <div193 style={{194 color: 'red',195 backgroundColor: 'yellow',196 }}197 />,198 node,199 );200 ReactDOM.render(201 <div202 style={{203 color: 'red',204 backgroundColor: 'yellow',205 }}206 />,207 node,208 );209 assertHistoryMatches([210 {211 instanceID: inst._debugID,212 type: 'update styles',213 payload: {214 color: 'red',215 backgroundColor: 'yellow',216 },217 },218 ]);219 });220 });221 describe('update attribute', () => {222 describe('simple attribute', () => {223 it('gets recorded during mount', () => {224 var node = document.createElement('div');225 ReactHostOperationHistoryHook._preventClearing = true;226 ReactDOM.render(<div className="rad" tabIndex={42} />, node);227 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);228 if (ReactDOMFeatureFlags.useCreateElement) {229 assertHistoryMatches([230 {231 instanceID: inst._debugID,232 type: 'update attribute',233 payload: {className: 'rad'},234 },235 {236 instanceID: inst._debugID,237 type: 'update attribute',238 payload: {tabIndex: 42},239 },240 {241 instanceID: inst._debugID,242 type: 'mount',243 payload: 'DIV',244 },245 ]);246 } else {247 assertHistoryMatches([248 {249 instanceID: inst._debugID,250 type: 'mount',251 payload:252 '<div class="rad" tabindex="42" data-reactroot="" ' +253 'data-reactid="1"></div>',254 },255 ]);256 }257 });258 it('gets recorded during an update', () => {259 var node = document.createElement('div');260 ReactDOM.render(<div />, node);261 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);262 ReactHostOperationHistoryHook._preventClearing = true;263 ReactDOM.render(<div className="rad" />, node);264 ReactDOM.render(<div className="mad" tabIndex={42} />, node);265 ReactDOM.render(<div tabIndex={43} />, node);266 assertHistoryMatches([267 {268 instanceID: inst._debugID,269 type: 'update attribute',270 payload: {className: 'rad'},271 },272 {273 instanceID: inst._debugID,274 type: 'update attribute',275 payload: {className: 'mad'},276 },277 {278 instanceID: inst._debugID,279 type: 'update attribute',280 payload: {tabIndex: 42},281 },282 {283 instanceID: inst._debugID,284 type: 'remove attribute',285 payload: 'className',286 },287 {288 instanceID: inst._debugID,289 type: 'update attribute',290 payload: {tabIndex: 43},291 },292 ]);293 });294 });295 describe('attribute that gets removed with certain values', () => {296 it('gets recorded as a removal during an update', () => {297 var node = document.createElement('div');298 ReactDOM.render(<div />, node);299 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);300 ReactHostOperationHistoryHook._preventClearing = true;301 ReactDOM.render(<div disabled={true} />, node);302 ReactDOM.render(<div disabled={false} />, node);303 assertHistoryMatches([304 {305 instanceID: inst._debugID,306 type: 'update attribute',307 payload: {disabled: true},308 },309 {310 instanceID: inst._debugID,311 type: 'remove attribute',312 payload: 'disabled',313 },314 ]);315 });316 });317 describe('custom attribute', () => {318 it('gets recorded during mount', () => {319 var node = document.createElement('div');320 ReactHostOperationHistoryHook._preventClearing = true;321 ReactDOM.render(<div data-x="rad" data-y={42} />, node);322 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);323 if (ReactDOMFeatureFlags.useCreateElement) {324 assertHistoryMatches([325 {326 instanceID: inst._debugID,327 type: 'update attribute',328 payload: {'data-x': 'rad'},329 },330 {331 instanceID: inst._debugID,332 type: 'update attribute',333 payload: {'data-y': 42},334 },335 {336 instanceID: inst._debugID,337 type: 'mount',338 payload: 'DIV',339 },340 ]);341 } else {342 assertHistoryMatches([343 {344 instanceID: inst._debugID,345 type: 'mount',346 payload:347 '<div data-x="rad" data-y="42" data-reactroot="" ' +348 'data-reactid="1"></div>',349 },350 ]);351 }352 });353 it('gets recorded during an update', () => {354 var node = document.createElement('div');355 ReactDOM.render(<div />, node);356 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);357 ReactHostOperationHistoryHook._preventClearing = true;358 ReactDOM.render(<div data-x="rad" />, node);359 ReactDOM.render(<div data-x="mad" data-y={42} />, node);360 ReactDOM.render(<div data-y={43} />, node);361 assertHistoryMatches([362 {363 instanceID: inst._debugID,364 type: 'update attribute',365 payload: {'data-x': 'rad'},366 },367 {368 instanceID: inst._debugID,369 type: 'update attribute',370 payload: {'data-x': 'mad'},371 },372 {373 instanceID: inst._debugID,374 type: 'update attribute',375 payload: {'data-y': 42},376 },377 {378 instanceID: inst._debugID,379 type: 'remove attribute',380 payload: 'data-x',381 },382 {383 instanceID: inst._debugID,384 type: 'update attribute',385 payload: {'data-y': 43},386 },387 ]);388 });389 });390 describe('attribute on a web component', () => {391 it('gets recorded during mount', () => {392 var node = document.createElement('div');393 ReactHostOperationHistoryHook._preventClearing = true;394 ReactDOM.render(<my-component className="rad" tabIndex={42} />, node);395 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);396 if (ReactDOMFeatureFlags.useCreateElement) {397 assertHistoryMatches([398 {399 instanceID: inst._debugID,400 type: 'update attribute',401 payload: {className: 'rad'},402 },403 {404 instanceID: inst._debugID,405 type: 'update attribute',406 payload: {tabIndex: 42},407 },408 {409 instanceID: inst._debugID,410 type: 'mount',411 payload: 'MY-COMPONENT',412 },413 ]);414 } else {415 assertHistoryMatches([416 {417 instanceID: inst._debugID,418 type: 'mount',419 payload:420 '<my-component className="rad" tabIndex="42" ' +421 'data-reactroot="" data-reactid="1"></my-component>',422 },423 ]);424 }425 });426 it('gets recorded during an update', () => {427 var node = document.createElement('div');428 ReactDOM.render(<my-component />, node);429 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);430 ReactHostOperationHistoryHook._preventClearing = true;431 ReactDOM.render(<my-component className="rad" />, node);432 ReactDOM.render(<my-component className="mad" tabIndex={42} />, node);433 ReactDOM.render(<my-component tabIndex={43} />, node);434 assertHistoryMatches([435 {436 instanceID: inst._debugID,437 type: 'update attribute',438 payload: {className: 'rad'},439 },440 {441 instanceID: inst._debugID,442 type: 'update attribute',443 payload: {className: 'mad'},444 },445 {446 instanceID: inst._debugID,447 type: 'update attribute',448 payload: {tabIndex: 42},449 },450 {451 instanceID: inst._debugID,452 type: 'remove attribute',453 payload: 'className',454 },455 {456 instanceID: inst._debugID,457 type: 'update attribute',458 payload: {tabIndex: 43},459 },460 ]);461 });462 });463 });464 describe('replace text', () => {465 describe('text content', () => {466 it('gets recorded during an update from text content', () => {467 var node = document.createElement('div');468 ReactDOM.render(<div>Hi.</div>, node);469 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);470 ReactHostOperationHistoryHook._preventClearing = true;471 ReactDOM.render(<div>Bye.</div>, node);472 assertHistoryMatches([473 {474 instanceID: inst._debugID,475 type: 'replace text',476 payload: 'Bye.',477 },478 ]);479 });480 it('gets recorded during an update from html', () => {481 var node = document.createElement('div');482 ReactDOM.render(483 <div dangerouslySetInnerHTML={{__html: 'Hi.'}} />,484 node,485 );486 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);487 ReactHostOperationHistoryHook._preventClearing = true;488 ReactDOM.render(<div>Bye.</div>, node);489 assertHistoryMatches([490 {491 instanceID: inst._debugID,492 type: 'replace text',493 payload: 'Bye.',494 },495 ]);496 });497 it('gets recorded during an update from children', () => {498 var node = document.createElement('div');499 ReactDOM.render(<div><span /><p /></div>, node);500 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);501 ReactHostOperationHistoryHook._preventClearing = true;502 ReactDOM.render(<div>Bye.</div>, node);503 assertHistoryMatches([504 {505 instanceID: inst._debugID,506 type: 'remove child',507 payload: {fromIndex: 0},508 },509 {510 instanceID: inst._debugID,511 type: 'remove child',512 payload: {fromIndex: 1},513 },514 {515 instanceID: inst._debugID,516 type: 'replace text',517 payload: 'Bye.',518 },519 ]);520 });521 it('gets ignored if new text is equal', () => {522 var node = document.createElement('div');523 ReactDOM.render(<div>Hi.</div>, node);524 ReactHostOperationHistoryHook._preventClearing = true;525 ReactDOM.render(<div>Hi.</div>, node);526 assertHistoryMatches([]);527 });528 });529 describe('text node', () => {530 it('gets recorded during an update', () => {531 var node = document.createElement('div');532 ReactDOM.render(<div>{'Hi.'}{42}</div>, node);533 var inst1 = ReactDOMComponentTree.getInstanceFromNode(534 node.firstChild.childNodes[0],535 );536 var inst2 = ReactDOMComponentTree.getInstanceFromNode(537 node.firstChild.childNodes[3],538 );539 ReactHostOperationHistoryHook._preventClearing = true;540 ReactDOM.render(<div>{'Bye.'}{43}</div>, node);541 assertHistoryMatches([542 {543 instanceID: inst1._debugID,544 type: 'replace text',545 payload: 'Bye.',546 },547 {548 instanceID: inst2._debugID,549 type: 'replace text',550 payload: '43',551 },552 ]);553 });554 it('gets ignored if new text is equal', () => {555 var node = document.createElement('div');556 ReactDOM.render(<div>{'Hi.'}{42}</div>, node);557 ReactHostOperationHistoryHook._preventClearing = true;558 ReactDOM.render(<div>{'Hi.'}{42}</div>, node);559 assertHistoryMatches([]);560 });561 });562 });563 describe('replace with', () => {564 it('gets recorded when composite renders to a different type', () => {565 var element;566 function Foo() {567 return element;568 }569 var node = document.createElement('div');570 element = <div />;571 ReactDOM.render(<Foo />, node);572 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);573 element = <span />;574 ReactHostOperationHistoryHook._preventClearing = true;575 ReactDOM.render(<Foo />, node);576 assertHistoryMatches([577 {578 instanceID: inst._debugID,579 type: 'replace with',580 payload: 'SPAN',581 },582 ]);583 });584 it('gets recorded when composite renders to null after a native', () => {585 var element;586 function Foo() {587 return element;588 }589 var node = document.createElement('div');590 element = <span />;591 ReactDOM.render(<Foo />, node);592 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);593 element = null;594 ReactHostOperationHistoryHook._preventClearing = true;595 ReactDOM.render(<Foo />, node);596 assertHistoryMatches([597 {598 instanceID: inst._debugID,599 type: 'replace with',600 payload: '#comment',601 },602 ]);603 });604 it('gets ignored if the type has not changed', () => {605 var element;606 function Foo() {607 return element;608 }609 var node = document.createElement('div');610 element = <div />;611 ReactDOM.render(<Foo />, node);612 element = <div />;613 ReactHostOperationHistoryHook._preventClearing = true;614 ReactDOM.render(<Foo />, node);615 assertHistoryMatches([]);616 });617 });618 describe('replace children', () => {619 it('gets recorded during an update from text content', () => {620 var node = document.createElement('div');621 ReactDOM.render(<div>Hi.</div>, node);622 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);623 ReactHostOperationHistoryHook._preventClearing = true;624 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Bye.'}} />, node);625 assertHistoryMatches([626 {627 instanceID: inst._debugID,628 type: 'replace children',629 payload: 'Bye.',630 },631 ]);632 });633 it('gets recorded during an update from html', () => {634 var node = document.createElement('div');635 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Hi.'}} />, node);636 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);637 ReactHostOperationHistoryHook._preventClearing = true;638 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Bye.'}} />, node);639 assertHistoryMatches([640 {641 instanceID: inst._debugID,642 type: 'replace children',643 payload: 'Bye.',644 },645 ]);646 });647 it('gets recorded during an update from children', () => {648 var node = document.createElement('div');649 ReactDOM.render(<div><span /><p /></div>, node);650 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);651 ReactHostOperationHistoryHook._preventClearing = true;652 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Hi.'}} />, node);653 assertHistoryMatches([654 {655 instanceID: inst._debugID,656 type: 'remove child',657 payload: {fromIndex: 0},658 },659 {660 instanceID: inst._debugID,661 type: 'remove child',662 payload: {fromIndex: 1},663 },664 {665 instanceID: inst._debugID,666 type: 'replace children',667 payload: 'Hi.',668 },669 ]);670 });671 it('gets ignored if new html is equal', () => {672 var node = document.createElement('div');673 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Hi.'}} />, node);674 ReactHostOperationHistoryHook._preventClearing = true;675 ReactDOM.render(<div dangerouslySetInnerHTML={{__html: 'Hi.'}} />, node);676 assertHistoryMatches([]);677 });678 });679 describe('insert child', () => {680 it('gets reported when a child is inserted', () => {681 var node = document.createElement('div');682 ReactDOM.render(<div><span /></div>, node);683 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);684 ReactHostOperationHistoryHook._preventClearing = true;685 ReactDOM.render(<div><span /><p /></div>, node);686 assertHistoryMatches([687 {688 instanceID: inst._debugID,689 type: 'insert child',690 payload: {toIndex: 1, content: 'P'},691 },692 ]);693 });694 });695 describe('move child', () => {696 it('gets reported when a child is inserted', () => {697 var node = document.createElement('div');698 ReactDOM.render(<div><span key="a" /><p key="b" /></div>, node);699 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);700 ReactHostOperationHistoryHook._preventClearing = true;701 ReactDOM.render(<div><p key="b" /><span key="a" /></div>, node);702 assertHistoryMatches([703 {704 instanceID: inst._debugID,705 type: 'move child',706 payload: {fromIndex: 0, toIndex: 1},707 },708 ]);709 });710 });711 describe('remove child', () => {712 it('gets reported when a child is removed', () => {713 var node = document.createElement('div');714 ReactDOM.render(<div><span key="a" /><p key="b" /></div>, node);715 var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild);716 ReactHostOperationHistoryHook._preventClearing = true;717 ReactDOM.render(<div><span key="a" /></div>, node);718 assertHistoryMatches([719 {720 instanceID: inst._debugID,721 type: 'remove child',722 payload: {fromIndex: 1},723 },724 ]);725 });726 });...

Full Screen

Full Screen

ReactEventListener-test.js

Source:ReactEventListener-test.js Github

copy

Full Screen

...62 });63 var calls = handleTopLevel.mock.calls;64 expect(calls.length).toBe(2);65 expect(calls[0][EVENT_TARGET_PARAM])66 .toBe(ReactDOMComponentTree.getInstanceFromNode(childControl));67 expect(calls[1][EVENT_TARGET_PARAM])68 .toBe(ReactDOMComponentTree.getInstanceFromNode(parentControl));69 });70 it('should propagate events two levels down', function() {71 var childContainer = document.createElement('div');72 var childControl = <div>Child</div>;73 var parentContainer = document.createElement('div');74 var parentControl = <div>Parent</div>;75 var grandParentContainer = document.createElement('div');76 var grandParentControl = <div>Parent</div>;77 childControl = ReactDOM.render(childControl, childContainer);78 parentControl =79 ReactDOM.render(parentControl, parentContainer);80 grandParentControl =81 ReactDOM.render(grandParentControl, grandParentContainer);82 ReactDOM.findDOMNode(parentControl).appendChild(childContainer);83 ReactDOM.findDOMNode(grandParentControl).appendChild(parentContainer);84 var callback = ReactEventListener.dispatchEvent.bind(null, 'test');85 callback({86 target: ReactDOM.findDOMNode(childControl),87 });88 var calls = handleTopLevel.mock.calls;89 expect(calls.length).toBe(3);90 expect(calls[0][EVENT_TARGET_PARAM])91 .toBe(ReactDOMComponentTree.getInstanceFromNode(childControl));92 expect(calls[1][EVENT_TARGET_PARAM])93 .toBe(ReactDOMComponentTree.getInstanceFromNode(parentControl));94 expect(calls[2][EVENT_TARGET_PARAM])95 .toBe(ReactDOMComponentTree.getInstanceFromNode(grandParentControl));96 });97 it('should not get confused by disappearing elements', function() {98 var childContainer = document.createElement('div');99 var childControl = <div>Child</div>;100 var parentContainer = document.createElement('div');101 var parentControl = <div>Parent</div>;102 childControl = ReactDOM.render(childControl, childContainer);103 parentControl =104 ReactDOM.render(parentControl, parentContainer);105 ReactDOM.findDOMNode(parentControl).appendChild(childContainer);106 // ReactBrowserEventEmitter.handleTopLevel might remove the107 // target from the DOM. Here, we have handleTopLevel remove the108 // node when the first event handlers are called; we'll still109 // expect to receive a second call for the parent control.110 var childNode = ReactDOM.findDOMNode(childControl);111 handleTopLevel.mockImplementation(112 function(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) {113 if (topLevelTarget === childNode) {114 ReactDOM.unmountComponentAtNode(childContainer);115 }116 }117 );118 var callback = ReactEventListener.dispatchEvent.bind(null, 'test');119 callback({120 target: childNode,121 });122 var calls = handleTopLevel.mock.calls;123 expect(calls.length).toBe(2);124 expect(calls[0][EVENT_TARGET_PARAM])125 .toBe(ReactDOMComponentTree.getInstanceFromNode(childNode));126 expect(calls[1][EVENT_TARGET_PARAM])127 .toBe(ReactDOMComponentTree.getInstanceFromNode(parentControl));128 });129 it('should batch between handlers from different roots', function() {130 var childContainer = document.createElement('div');131 var parentContainer = document.createElement('div');132 var childControl = ReactDOM.render(133 <div>Child</div>,134 childContainer135 );136 var parentControl = ReactDOM.render(137 <div>Parent</div>,138 parentContainer139 );140 ReactDOM.findDOMNode(parentControl).appendChild(childContainer);141 // Suppose an event handler in each root enqueues an update to the142 // childControl element -- the two updates should get batched together.143 var childNode = ReactDOM.findDOMNode(childControl);144 handleTopLevel.mockImplementation(145 function(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) {146 ReactDOM.render(147 <div>{topLevelTarget === childNode ? '1' : '2'}</div>,148 childContainer149 );150 // Since we're batching, neither update should yet have gone through.151 expect(childNode.textContent).toBe('Child');152 }153 );154 var callback =155 ReactEventListener.dispatchEvent.bind(ReactEventListener, 'test');156 callback({157 target: childNode,158 });159 var calls = handleTopLevel.mock.calls;160 expect(calls.length).toBe(2);161 expect(childNode.textContent).toBe('2');162 });163 });164 it('should not fire duplicate events for a React DOM tree', function() {165 var Wrapper = React.createClass({166 getInner: function() {167 return this.refs.inner;168 },169 render: function() {170 var inner = <div ref="inner">Inner</div>;171 return <div><div id="outer">{inner}</div></div>;172 },173 });174 var instance = ReactTestUtils.renderIntoDocument(<Wrapper />);175 var callback = ReactEventListener.dispatchEvent.bind(null, 'test');176 callback({177 target: ReactDOM.findDOMNode(instance.getInner()),178 });179 var calls = handleTopLevel.mock.calls;180 expect(calls.length).toBe(1);181 expect(calls[0][EVENT_TARGET_PARAM])182 .toBe(ReactDOMComponentTree.getInstanceFromNode(instance.getInner()));183 });...

Full Screen

Full Screen

ce23cbEventPluginUtils.js

Source:ce23cbEventPluginUtils.js Github

copy

Full Screen

...146executeDirectDispatch:executeDirectDispatch,147executeDispatchesInOrder:executeDispatchesInOrder,148executeDispatchesInOrderStopAtTrue:executeDispatchesInOrderStopAtTrue,149hasDispatches:hasDispatches,150getInstanceFromNode:function getInstanceFromNode(node){151return ComponentTree.getInstanceFromNode(node);152},153getNodeFromInstance:function getNodeFromInstance(node){154return ComponentTree.getNodeFromInstance(node);155},156isAncestor:function isAncestor(a,b){157return TreeTraversal.isAncestor(a,b);158},159getLowestCommonAncestor:function getLowestCommonAncestor(a,b){160return TreeTraversal.getLowestCommonAncestor(a,b);161},162getParentInstance:function getParentInstance(inst){163return TreeTraversal.getParentInstance(inst);164},165traverseTwoPhase:function traverseTwoPhase(target,fn,arg){...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.fill('input[type="text"]', 'Hello World');7 const elementHandle = await page.$('input[type="text"]');8 const instance = await elementHandle._internalHandler.getInstanceFromNode();9 console.log(instance);10 await browser.close();11})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { webkit } = require('playwright');2(async () => {3 const browser = await webkit.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const element = await page.$('text=Get started');7 const playwright = require('playwright');8 const internal = playwright._impl;9 const elementHandle = await internal.getExistingElementHandle(element);10 const internalElement = internal.getInstanceFromNode(elementHandle);11 console.log(internalElement);12 await browser.close();13})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 const frame = page.mainFrame();6 const elementHandle = await frame.$('input');7 const elementHandle2 = await frame.$('button');8 const page2 = elementHandle2._page;9 const frame2 = elementHandle2._frame;10 const elementHandle3 = await frame2.$('div');11 const page3 = elementHandle3._page;12 const frame3 = elementHandle3._frame;13 const elementHandle4 = await frame3.$('span');14 const page4 = elementHandle4._page;15 const frame4 = elementHandle4._frame;16 const elementHandle5 = await frame4.$('div');17 const page5 = elementHandle5._page;18 const frame5 = elementHandle5._frame;19 const elementHandle6 = await frame5.$('div');20 const page6 = elementHandle6._page;21 const frame6 = elementHandle6._frame;22 const elementHandle7 = await frame6.$('div');23 const page7 = elementHandle7._page;24 const frame7 = elementHandle7._frame;25 const elementHandle8 = await frame7.$('div');26 const page8 = elementHandle8._page;27 const frame8 = elementHandle8._frame;28 const elementHandle9 = await frame8.$('div');29 const page9 = elementHandle9._page;30 const frame9 = elementHandle9._frame;31 const elementHandle10 = await frame9.$('div');32 const page10 = elementHandle10._page;33 const frame10 = elementHandle10._frame;34 const elementHandle11 = await frame10.$('div');35 const page11 = elementHandle11._page;36 const frame11 = elementHandle11._frame;37 const elementHandle12 = await frame11.$('div');38 const page12 = elementHandle12._page;39 const frame12 = elementHandle12._frame;40 const elementHandle13 = await frame12.$('div');41 const page13 = elementHandle13._page;42 const frame13 = elementHandle13._frame;43 const elementHandle14 = await frame13.$('div');44 const page14 = elementHandle14._page;

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright');2const playwright = new Playwright();3const { chromium } = playwright;4const browser = await chromium.launch();5const context = await browser.newContext();6const page = await context.newPage();7const element = await page.$('button');8const page1 = element._page;9await browser.close();10const { chromium } = require('playwright');11const browser = await chromium.launch();12const context = await browser.newContext();13const page = await context.newPage();14const element = await page.$('button');15const page1 = await page.evaluateHandle((element) => element.ownerDocument.defaultView, element);16await browser.close();17## 3. Using `page.mainFrame().executionContext()` method18const { chromium } = require('playwright');19const browser = await chromium.launch();20const context = await browser.newContext();21const page = await context.newPage();22const element = await page.$('button');23const page1 = await element.executionContext().evaluateHandle((element) => element.ownerDocument.defaultView, element);24await browser.close();25## 4. Using `page.mainFrame().executionContext()` method with `page.$eval` method26const { chromium } = require('playwright');27const browser = await chromium.launch();28const context = await browser.newContext();29const page = await context.newPage();30const page1 = await page.$eval('button', (element) => element.ownerDocument.defaultView);31await browser.close();32## 5. Using `page.mainFrame().executionContext()` method with `page.$$eval` method33const { chromium } = require('playwright');34const browser = await chromium.launch();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getInstanceFromNode } = require('playwright/lib/protocol/helper');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const page = await browser.newPage();6 const frame = page.mainFrame();7 const frameManager = getInstanceFromNode(frame, 'FrameManager');8 const frameTree = await frameManager.frameTree();9 console.log(frameTree);10 await browser.close();11})();12#### frameManager.frameTree()13const { chromium } = require('playwright');14const { getInstanceFromNode } = require('playwright/lib/protocol/helper');15(async () => {16 const browser = await chromium.launch({ headless: false });17 const page = await browser.newPage();18 const frame = page.mainFrame();19 const frameManager = getInstanceFromNode(frame, 'FrameManager');20 const frameTree = await frameManager.frameTree();21 console.log(frameTree);22 await browser.close();23})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getInstanceFromNode } = require("playwright/lib/server/dom");2const { chromium } = require("playwright");3const { expect } = require("chai");4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const handle = await getInstanceFromNode(button);9 expect(handle._remoteObject.description).to.equal("HTMLInputElement");10 await browser.close();11})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getInstanceFromNode } = require('playwright');2const page = getInstanceFromNode(document.querySelector('iframe')).page;3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch({ headless: false });6 const page = await browser.newPage();7 await page.screenshot({ path: `google.png` });8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getInstanceFromNode } = require('playwright/lib/server/dom');2const { chromium } = require('playwright');3const path = require('path');4const fs = require('fs');5const expect = require('expect');6(async () => {7 const browser = await chromium.launch();8 const context = await browser.newContext();9 const page = await context.newPage();10 const input = await page.$('input[name="q"]');11 const inputHandle = await input.asElement();12 const inputImpl = await getInstanceFromNode(inputHandle);13 expect(inputImpl._node.name).toBe('q');14 await browser.close();15})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getInstanceFromNode } = require('playwright/lib/server/dom');2const element = await page.$('button');3const internalElement = getInstanceFromNode(element);4const internalElement2 = await page.evaluateHandle((element) => {5 return getInstanceFromNode(element);6}, element);7const internalElement3 = await page.evaluateHandle((element) => {8 return element._delegate;9}, element);10const internalElement4 = await page.evaluateHandle((element) => {11 return element._element;12}, element);13const internalElement5 = await page.evaluateHandle((element) => {14 return element._page._delegate;15}, element);16const internalElement6 = await page.evaluateHandle((element) => {17 return element._page._delegate._browserContext;18}, element);19const internalElement7 = await page.evaluateHandle((element) => {20 return element._page._delegate._browserContext._browser;21}, element);22const internalElement8 = await page.evaluateHandle((element) => {23 return element._page._delegate._browserContext._browser._connection;24}, element);25const internalElement9 = await page.evaluateHandle((element) => {26 return element._page._delegate._browserContext._browser._connection._transport;27}, element);28const internalElement10 = await page.evaluateHandle((element) => {29 return element._page._delegate._browserContext._browser._connection._transport._ws;30}, element);31const internalElement11 = await page.evaluateHandle((element) => {32 return element._page._delegate._browserContext._browser._connection._transport._ws._socket;33}, element);34const internalElement12 = await page.evaluateHandle((element) => {35 return element._page._delegate._browserContext._browser._connection._transport._ws._socket._handle;36}, element);37const internalElement13 = await page.evaluateHandle((element) => {38 return element._page._delegate._browserContext._browser._connection._transport._ws._socket._handle._externalStream;39}, element);40const internalElement14 = await page.evaluateHandle((element) => {41 return element._page._delegate._browserContext._browser._connection._transport._ws._socket._handle._externalStream._handle;42}, element);43const internalElement15 = await page.evaluateHandle((element) => {

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful